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!
>
>