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