You could do

tmp = one(eltype(z))
@nexprs $N j->(tmp *= z[r, i_j])
out[r,ix] = tmp

Does that do what you want?

Alternatively, build up the expression outside the quote block:

args = [:(z[r, $i]) for i = 1:N]
ex = Expr(:call, :*, args...)

and then use $ex where your former @nexprs is.

--Tim


On Thursday, May 07, 2015 09:03:08 AM Spencer Lyon wrote:
> Consider the following expression:
> 
> julia> macroexpand(:(@nexprs 3 j->(out[r, ix] *= z[r, i_{3-j+1}]) ))
> quote
>     out[r,ix] *= z[r,i_3]
>     out[r,ix] *= z[r,i_2]
>     out[r,ix] *= z[r,i_1]
> end
> 
> 
> What I would really like to be able to do is have a macro generate the
> expression
> 
> julia> ... some magic incantation here
> quote
>     out[r,ix] = z[r,i_3]*z[r,i_2]*z[r,i_3]
> end
> 
> 
> Does anyone see an easy way to do this?
> 
> For some context, this appears in the following block of code:
> 
> immutable Degree{N} end
> 
> function n_complete(n::Int, D::Int)
>     out = 1
>     for d=1:D
>         tmp = 1
>         for j=0:d-1
>             tmp *= (n+j)
>         end
>         out += div(tmp, factorial(d))
>     end
>     out
> end
> 
> @generated function complete_polynomial!{N}(z::Matrix, d::Degree{N},
>                                             out::Matrix)
>     complete_polynomial_impl!(z, d, out)
> end
> 
> function complete_polynomial_impl!{T,N}(z::Type{Matrix{T}},
> 
> ::Type{Degree{N}},
> ::
>                                         ::Type{Matrix{T}})
> 
>     quote
>         nobs, nvar = size(z, 1), size(z, 2)
>         if size(out) != (nobs, n_complete(nvar, $N))
>             error("z, out not compatible")
>         end
>         out[:, 1] = 1.0
>         out[:, 2:nvar+1] = z
> 
>         # reset first column to ones
>         @inbounds for i=1nobs
>             out[i, 1] = 1.0
>         end
> 
>         # set next nvar columns to input matrix
>         @inbounds for n=2:nvar+1, i=1:nobs
>             out[i, n] = z[i, n-1]
>         end
> 
>         # reset all trailing columns to 1s
>         @inbounds for n=nvar+2:size(out, 2), i=1:nobs
>             out[i, n] = 1.0
>         end
> 
>         ix = nvar+1
>         @nloops($N, # number of loops
>                 i,  # counter
>                 d->((d == $N ? 1 : i_{d+1}) : nvar),  # ranges
>                 d->(d == $N ? nothing :
>                     (ix += 1 ; for r=1:nobs @nexprs $N-d+1 j->(out[r, ix]
> *= z[r, i_{$N-j+1}]) end)),
>                 Expr(:block, :nothing)  # bodyexpr
>                 )
>         out
>     end
> end
> 
> I would like to be able to generate the expression I mentioned before for
> two reasons: 1.) so I can avoid having to set all trailing columns to 1s
> before the @nloops and 2.) so I can only traverse out once in the prexpr
> part of the @nloops call.
> 
> Any suggestions would be most welcome. Thanks!

Reply via email to