Have you read through this section of the docs?
http://docs.julialang.org/en/release-0.3/manual/metaprogramming/ It's quite
helpful on this topic.
In particular, note that expressions consist of three building blocks: the
head, the arguments, and the return type. Don't worry about the latter
(return type) for now. Let's focus on the first two.
The arguments are symbols or expressions out of which the target expression
is built. The head provides the context in which the arguments interact.
For your example, let's turn x^0 * y^1 * z^0 into an expression by *quoting*
it with ':()' :
julia> expr = :(x^0 * y^1 * z^0)
:(x^0 * y^1 * z^0)
Here I've bound the above expression to the variable ex just for the sake
of concision. We can use the dump() function to see the expression's
building blocks, i.e. its head, arguments and return type:
julia> dump(expr)
Expr
head: Symbol call
args: Array(Any,(4,))
1: Symbol *
2: Expr
head: Symbol call
args: Array(Any,(3,))
1: Symbol ^
2: Symbol x
3: Int64 0
typ: Any
3: Expr
head: Symbol call
args: Array(Any,(3,))
1: Symbol ^
2: Symbol y
3: Int64 1
typ: Any
4: Expr
head: Symbol call
args: Array(Any,(3,))
1: Symbol ^
2: Symbol z
3: Int64 0
typ: Any
typ: Any
We see that ex consists of four arguments: the '*' symbol, and three
expressions, i.e. :(x^0), :(y^1) and :(z^1). The head, symbol call,
indicates that the first argument, *, is being called on the latter
arguments.
Having seen the structure of the target expression, we now have everything
we need to build it up from scratch, i.e. just from the tuple (0, 1, 0). We
first need to build the argument expressions :(x^0), :(y^1) and :(z^1).
Let's take the first such expression as an example. To build expressions,
we use the Expr() constructor:
julia> expr_x = Expr(:call, ^, :x, 0)
:((^)(x,0))
The arguments passed to the constructor are the head, then the expression
arguments. Note that the expression arguments are *symbols* -- ':x' means
the symbol x.
How did I know which head and arguments I needed in order to construct the
right expression? I just looked above at the second argument of the
original target expression:
2: Expr
head: Symbol call
args: Array(Any,(3,))
1: Symbol ^
2: Symbol x
3: Int64 0
typ: Any
That gave me everything I needed to know. Similar for the y and z
expressions. Here's how I would turn that all into a function that takes
3-tuples and spits out expressions:
function makepowers(xpower::Int64, ypower::Int64, zpower::Int64)
expr_powers = Expr(:call, *)
dict_symbols = [:x=>xpower, :y=>ypower, :z=>zpower]
for symb in [:x, :y, :z]
push!(expr_powers.args, Expr(:call, ^, symb, dict_symbols[
symb]))
end
return expr_powers
end
makepowers (generic function with 1 method)
julia> makepowers(0,1,0)
:((*)((^)(x,0),(^)(y,1),(^)(z,0)))
The resultant expression, though it looks a little different than expr
above, is equivalent. We can check that it has given us the correct
expression by evaluating it for definite values of x, y, z:
julia> x = 1
1
julia> y = 5
5
julia> z = 1
1
julia> eval(makepowers(0,1,0))
5
Hope this all helps. Once you're comfortable analyzing the constituents of
an expression using dump() you can build pretty much any expression you
like.
On Wednesday, May 20, 2015 at 1:47:07 AM UTC-4, Júlio Hoffimann wrote:
>
> Hi Steven,
>
> I'm actually trying to pass in a matrix X and get out the associated
> Vandermonde-like matrix as numbers. I thought of expressions because the
> loop itself is not trivial, we have to deal with all those combinatorial
> indexing somehow.
>
> I have a code that generates the exponents of all the monomials as a
> tuple, but going from this tuple to the actual product is not clear to me.
> Let's say I have (0,1,0) meaning x^0*y^1*z^0 = y^1. How to do this
> conversion? Any trick?
>
> -Júlio
>