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