Thanks a lot for the detailed answer. I changed a bit your macro, 
introducing conj() instead of ' and splicing the Kronecker sum to get a 
functional version:

macro M(m,n, ε1,ε2,ε3, X1,X2,X3, A1,A2,A3)
   ε = [ε1,ε2,ε3]
   X = [X1,X2,X3]
   A = [A1,A2,A3]
   Asum = {:+}
   for q=1:3, t=1:3
     if m+q == n+t
         push!(Asum, :(conj($(A[q])) * $(A[t])))
     end
   end
   if m == n
      :($(ε[m]) + 2*abs2($(X[m])) * $(Expr(:call, Asum...)))
   else
      :(2 * conj($(X[m])) * $(X[n]) * $(Expr(:call, Asum...)))
   end
end

I also defined a macro for the elements of Q:
macro Q(m,n, X1,X2,X3, A1,A2,A3)
   X = [X1,X2,X3]
   A = [A1,A2,A3]
   Asum = {:+}
   for q=1:3, t=1:3
     if m+n == q+t
         push!(Asum, :($(A[q]) * $(A[t])))
     end
   end
    :(conj($(X[m])) * conj($(X[n])) * $(Expr(:call, Asum...)))
end

and now I'm a bit stuck on putting it all together to get the full L 
matrix. Im trying to calculated L(i,j) based on M and Q for the 4 separate 
blocks. I only implemented the upper left block but I get an error

macro L(i,j, ε1,ε2,ε3, X1,X2,X3, A1,A2,A3)
    if i<4
        if j<4
            @M(i,j, ε1,ε2,ε3, X1,X2,X3, A1,A2,A3)
        end
    end
end

`+` has no method matching +(::Symbol, ::Int64)

It seems that the @M macro needs a value for the m,n indices for the comparison
if m+q == n+t

Any ideas how to solve this? The end-result I want is a function L(k, A1, A2, 
A3, etc) which would return the full 6x6 matrix.

//A




On Thursday, August 28, 2014 10:42:29 PM UTC+2, Steven G. Johnson wrote:
>
> On Thursday, August 28, 2014 6:36:16 AM UTC-4, Andrei Berceanu wrote:
>>
>> Steven, could you detail your macro proposal please? What exactly do you 
>> have in mind?
>>
>
> e.g. you could have a macro like (caution: untested):
>
> macro M(m,n, ε1, ε2, ε3, X1,X2,X3, A1,A2,A3)
>    ε = [ε1, ε2, ε3]
>    X = [X1,X2,X3]
>    A = [A1,A2,A3]
>    Asum = {:+}
>    for q=1:3, t=1:3
>      if m+q == n+t
>          push!(Asum, :($(A[q])' * $(A[t])))
>      end
>    end
>    if m == n
>       :($(ε[m]) + 2*abs2($(X[m])) * $(Expr(:call, Asum)))
>    else
>       :(2 * $(X[m])' $(X[n]) * $(Expr(:call, Asum)))
>    end
> end
>
> Then calling e.g. @M(1,2,ε1, ε2, ε3, X1,X2,X3, A1,A2,A3) would insert a 
> hard-coded
> expression for M[1,2] according to your formula, with only the nonzero 
> delta terms.  Here εm denotes the m'th case of your expression [ε(k_m+k) 
> .... ] in brackets, Xm denotes X(k_m+k), and Am denotes Ã_m.
>
> Macros are essentially functions evaluated at parse-time, not at runtime, 
> so they are exactly what you want in order to auto-generate fast inlined 
> code resulting from some complicated symbolic expression that is known in 
> advance, with whatever simplifications you can devise.
>
> You could write another macro for the entries of Q, and another macro to 
> put it all together and evaluate the whole matrix if you want. 
>

Reply via email to