Ok, so I just figured out I can stick the for loop inside the second @eval 
:) I think I am starting to get my head around the power of Julia. The 
following is very fast indeed, but any further recommendations for 
improvements are welcomed:

function lowpass(input::Float64, lp::Float64, g::Float64)
    hp::Float64 = input - lp
    lp += g * hp
    [lp, hp]
end
function processarrayexpr(expr, exprt, time::Vector{Float64})
    len = length(time)
    ret = @eval begin
        $exprt = $time[1]
        $expr
    end
    output = Array(Float64, len, length(ret))
    output[1,:] = ret
    @eval begin
        for i in 1:$len-1
            $exprt = $time[i]
            $output[i,:] = $expr
        end
    end
    output
end
s = 0.0;
data = processarrayexpr(:(begin input=sin(100.0*t); [t, input, 
lowpass(input, s, 0.5)] end), :(t), linspace(0.0,2.0pi,2*44100))



On Wednesday, June 18, 2014 11:30:52 AM UTC+8, Andrew Simper wrote:
>
> I have an expression of an M-element Array{Float64, 1}, and I have N 
> points I would like to evaluate this expression on and store the results 
> into an NxM Array{Float64,2}. I can get the output I want by passing  the 
> expression to be evaluated (expr), the parametric variable (exprt), and a 
> vector of the time values to a function that calls @eval for each of the N 
> values of time, and this works fine but is a bit slow. An ideas how to 
> speed this up?
>
> I'm not sure of the correct terminology but to me this is longhand for 
> what I view as parametric array comprehension, where you specify P ranges 
> and get a P+1 dim array back, instead of the regular non-parametric 
> comprehension where you have to specify P ranges and get a P dim array back.
>
> function lowpass(input::Float64, lp::Float64, g::Float64)
>     hp::Float64 = input - lp
>     lp += g * hp
>     [lp, hp]
> end
> function processarrayexpr(expr, exprt, time::Vector{Float64})
>     len = length(time)
>     ret = @eval begin
>         $exprt = $time[1]
>         $expr
>     end
>     output = Array(Float64, len, length(ret))
>     output[1,:] = ret
>     for i in 1:len-1
>         output[i,:] = @eval begin
>             $exprt = $time[$i]
>             $expr
>         end
>     end
>     output
> end
> s = 0.0;
> data = processarrayexpr(:(begin input=sin(100.0*t); [t, input, 
> lowpass(input, s, 0.5)] end), :(t), linspace(0.0,2.0pi,2*44100))
>
> 88200x4 Array{Float64,2}:
>  0.0           0.0          0.0          0.0       
>  7.12387e-5    0.00712381   0.00356191   0.00712381
>  0.000142477   0.0142473    0.00712363   0.0142473 
>  0.000213716   0.02137      0.010685     0.02137   
>  0.000284955   0.0284916    0.0142458    0.0284916 
>  0.000356194   0.0356118    0.0178059    0.0356118 
>  0.000427432   0.0427302    0.0213651    0.0427302 
>  0.000498671   0.0498465    0.0249232    0.0498465 
>  0.00056991    0.0569601    0.0284801    0.0569601 
>  0.000641149   0.0640709    0.0320355    0.0640709 
>  0.000712387   0.0711785    0.0355892    0.0711785 
>  0.000783626   0.0782824    0.0391412    0.0782824 
>  0.000854865   0.0853824    0.0426912    0.0853824 
>  ⋮                                                 
>  6.2824       -0.0782824   -0.0391412   -0.0782824 
>  6.28247      -0.0711785   -0.0355892   -0.0711785 
>  6.28254      -0.0640709   -0.0320355   -0.0640709 
>  6.28262      -0.0569601   -0.0284801   -0.0569601 
>  6.28269      -0.0498465   -0.0249232   -0.0498465 
>  6.28276      -0.0427302   -0.0213651   -0.0427302 
>  6.28283      -0.0356118   -0.0178059   -0.0356118 
>  6.2829       -0.0284916   -0.0142458   -0.0284916 
>  6.28297      -0.02137     -0.010685    -0.02137   
>  6.28304      -0.0142473   -0.00712363  -0.0142473 
>  6.28311      -0.00712381  -0.00356191  -0.00712381
>  0.0           0.0          0.0          0.0       
>
>
>
>

Reply via email to