Using eval like this is not a good idea. For one thing, the scope is all wrong.
> On Jun 17, 2014, at 11:38 PM, Andrew Simper <[email protected]> wrote: > > 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 >> >>
