Hi Johan,

Thanks for posting that example, that really helped to speed things up.

Pre-allocating the array and storing the computation directly into that 
array is what I was hoping the array comprehension could do, but I can't 
trick it into inserting the array directly into a 2D array

I meant to have the first entry be the input signal not t alone. I also 
want a syntax that will keep all the important information in a single line 
that is easy to understand what the input signal is and what arguments are 
being passed to the number crunching function, so I came up with this 
alternative:

function lowpass(input::Float64, lp::Float64, g::Float64)
    hp::Float64 = input - lp
    lp += g * hp
    [lp, hp]
end
function processarray(f, input::Vector{Float64}, args...)
    ret = f(input[1], args...)
    output = Array(Float64, length(input), length(ret)+1)
    output[1,:] = [input[1], ret]
    for i in 1:length(input)-1
        ret = f(input[i], args...)
        output[i,:] = [input[i], ret]
    end
    output
end
s = 0.0;
data = processarray(lowpass, [sin(t) for t in linspace(0,2pi,2*44100)], s, 
0.5)

So the last line here you can see the function lowpass being called with 
the input of sin(t) and arguments s, and 0.5, so not quite as nice as the 
array comprehension syntax, but not too bad.

I would love to see support for parametric multi-dimensional array 
comprehensions, since then I could write something like this, which is 
really powerful:

s = 0.0;
data = [begin input=sin(t); [t, input, lowpass(input, s, 0.5)]... end for t 
in linspace(0,2pi,2*44100)]

88200x4 Array{Float64,2}:
 0.0          0.0           0.0            0.0                             
   
 7.12387e-5   7.12387e-5    3.56194e-5     7.12387e-5    
 0.000142477  0.000142477   7.12387e-5     0.000142477 
 0.000213716  0.000213716   0.000106858    0.000213716
 0.000284955  0.000284955   0.000142477    0.000284955
 0.000356194  0.000356194   0.000178097    0.000356194
 0.000427432  0.000427432   0.000213716    0.000427432
 0.000498671  0.000498671   0.000249336    0.000498671
 0.00056991   0.00056991    0.000284955    0.00056991   
 0.000641149  0.000641149   0.000320574    0.000641149
 0.000712387  0.000712387   0.000356194    0.000712387
 0.000783626  0.000783626   0.000391813    0.000783626
 0.000854865  0.000854865   0.000427432    0.000854865
 ⋮                                                   
 6.2824      -0.000783626  -0.000391813  -0.000783626  
 6.28247     -0.000712387  -0.000356194  -0.000712387 
 6.28254     -0.000641149  -0.000320574  -0.000641149 
 6.28262     -0.00056991   -0.000284955  -0.00056991   
 6.28269     -0.000498671  -0.000249336  -0.000498671 
 6.28276     -0.000427432  -0.000213716  -0.000427432 
 6.28283     -0.000356194  -0.000178097  -0.000356194 
 6.2829      -0.000284955  -0.000142477  -0.000284955  
 6.28297     -0.000213716  -0.000106858  -0.000213716 
 6.28304     -0.000142477  -7.12387e-5   -0.000142477  
 6.28311     -7.12387e-5   -3.56194e-5   -7.12387e-5    
 6.28319     -2.44929e-16  -1.22465e-16  -2.44929e-16 


On Monday, June 16, 2014 5:36:20 PM UTC+8, Johan Sigfrids wrote:
>
> I suspect it is easier to just pre-allocate an array of the correct 
> dimensions and then assign into it. Something like this:
>
> function lowpassarray(arr::Vector{Float64})
>     out = Array(Float64, length(arr), 3)
>     s = 0.0
>     for i in 1:length(arr)
>         out[i, 1] = arr[i]
>         out[i, 2], out[i, 3] = lowpass(s, sin(arr[i]), 0.5)
>     end
>     out
> end
>
> data = linspace(0, 2pi, 20)
> data = lowpassarray(data, 0.0)
>
>
> 20x3 Array{Float64,2}:
>  0.0        0.0           0.0        
>  0.330694   0.16235       0.324699   
>  0.661388   0.307106      0.614213   
>  0.992082   0.418583      0.837166   
>  1.32278    0.4847        0.9694     
>  1.65347    0.498292      0.996584   
>  1.98416    0.457887      0.915773   
>  2.31486    0.367862      0.735724   
>  2.64555    0.237974      0.475947   
>  2.97625    0.0822973     0.164595   
>  3.30694   -0.0822973    -0.164595   
>  3.63763   -0.237974     -0.475947   
>  3.96833   -0.367862     -0.735724   
>  4.29902   -0.457887     -0.915773   
>  4.62972   -0.498292     -0.996584   
>  4.96041   -0.4847       -0.9694     
>  5.2911    -0.418583     -0.837166   
>  5.6218    -0.307106     -0.614213   
>  5.95249   -0.16235      -0.324699   
>  6.28319   -1.22465e-16  -2.44929e-16
>
>
>
>
> On Monday, June 16, 2014 9:54:57 AM UTC+3, Andrew Simper wrote:
>>
>> When I'm working with time series data I often end up with things like 
>> this:
>>
>> function lowpass(lp::Float64, input::Float64, g::Float64)
>>     hp::Float64 = input - lp
>>     lp += g * hp
>>     [lp, hp]
>> end
>> s = 0.0;
>> data=[flatten([t, lowpass(s, sin(t), 0.5)]) for t in linspace(0,2pi,20)]
>>
>> 20-element Array{Any,1}:
>>  [0.0,0.0,0.0]                      
>>  [0.330694,0.16235,0.324699]        
>>  [0.661388,0.307106,0.614213]       
>>  [0.992082,0.418583,0.837166]       
>>  [1.32278,0.4847,0.9694]            
>>  [1.65347,0.498292,0.996584]        
>>  [1.98416,0.457887,0.915773]        
>>  [2.31486,0.367862,0.735724]        
>>  [2.64555,0.237974,0.475947]        
>>  [2.97625,0.0822973,0.164595]       
>>  [3.30694,-0.0822973,-0.164595]     
>>  [3.63763,-0.237974,-0.475947]      
>>  [3.96833,-0.367862,-0.735724]      
>>  [4.29902,-0.457887,-0.915773]      
>>  [4.62972,-0.498292,-0.996584]      
>>  [4.96041,-0.4847,-0.9694]          
>>  [5.2911,-0.418583,-0.837166]       
>>  [5.6218,-0.307106,-0.614213]       
>>  [5.95249,-0.16235,-0.324699]       
>>  [6.28319,-1.22465e-16,-2.44929e-16]
>>
>>
>>
>> Can anyone please help out with how to turn an array of arrays like this 
>> into a 2D array? (or even to pass data as a single chunk into DataFrames to 
>> do the job?)
>>
>>
>>
>>  
>>
>>

Reply via email to