Excellent. The first idea is exactly what I needed. 

I don't think the second one would work because the number of 
multiplication calls I need is dynamic (notice we have `@nexprs $N-d+1`).

On Thursday, May 7, 2015 at 1:11:41 PM UTC-4, Tim Holy wrote:
>
> 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