Taking a mean of a fixed length number of points

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Taking a mean of a fixed length number of points

hjborsje

This question is not of crucial importance, but I’m curious if there is a better alternative.

 

I need to calculate the columnar average of each k points out of an array of x(n,m) elements, resulting in a new array  x_avg (floor (n/k) , m) elements.

 

I use:

 

        tmp = reshape(x,k,[],m);                                      (1)

        x_avg = reshape(mean(tmp),[],m);                  (2)

 

I wonder if there is a simpler or more direct way, except for substituting equation (1) into (2)

 

Henk Borsje

Oudenbosch,

Netherlands



Reply | Threaded
Open this post in threaded view
|

Re: Taking a mean of a fixed length number of points

nrjank
On Fri, Nov 29, 2019 at 4:12 PM Henk Borsje <[hidden email]> wrote:

This question is not of crucial importance, but I’m curious if there is a better alternative.

 

I need to calculate the columnar average of each k points out of an array of x(n,m) elements, resulting in a new array  x_avg (floor (n/k) , m) elements.

 

I use:

 

        tmp = reshape(x,k,[],m);                                      (1)

        x_avg = reshape(mean(tmp),[],m);                  (2)

 

I wonder if there is a simpler or more direct way, except for substituting equation (1) into (2)



just for clarity, can you give a brief example of what your input looks like and what you would like the output to look like?  it seems your method is fairly compact. 


Reply | Threaded
Open this post in threaded view
|

Re: Taking a mean of a fixed length number of points

Augustin Lefèvre
Dear Henk,

You're asking a question about "the best possible way to encode a block average operator in octave".

One possible way you could try to save time is to write "for loops" in an oct-file

It would look like translating the following octave code into C++ :

h=floor(n/k);
y=zeros(h,m);
for ik=1:h
    tstart = (ik-1)*k+1;
    tstop = ik*k;
    y(ik,:)=mean(x(tstart:tstop,:));
end


But I can't guarantee it will be faster : it might depend on the ratio n/k. You will find as attachment an investigation into this matter, which I summarize in the post-scriptum.

If that does not work, you might try encoding your block average operator into a sparse matrix.

Best regards,
Augustin

Post-Scriptum :
"it might depend on the ratio n/k"

My bet would be :
n/k high (high n, small k) => for loop is faster
n/k low (small n, high k) =>  your code is faster

Assuming this, there should be a correlation between n/k and the ratio of (CPU time 1)/(CPU time 2).

To test this correlation write the for loop directly in octave, and if it holds, writing the oct file will actually make the "for loop"  competitive.

...

Ok, so I tried it (see attached script), and the correlation is weak, so either an oct-file will unconditionally save time or not.


On 30/11/2019 02:50, Nicholas Jankowski wrote:
On Fri, Nov 29, 2019 at 4:12 PM Henk Borsje <[hidden email]> wrote:

This question is not of crucial importance, but I’m curious if there is a better alternative.

 

I need to calculate the columnar average of each k points out of an array of x(n,m) elements, resulting in a new array  x_avg (floor (n/k) , m) elements.

 

I use:

 

        tmp = reshape(x,k,[],m);                                      (1)

        x_avg = reshape(mean(tmp),[],m);                  (2)

 

I wonder if there is a simpler or more direct way, except for substituting equation (1) into (2)



just for clarity, can you give a brief example of what your input looks like and what you would like the output to look like?  it seems your method is fairly compact. 


    




blockavg.m (812 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Taking a mean of a fixed length number of points

hjborsje
In reply to this post by nrjank

Here is a simple example:

 

n = 1000000;

m = 10;

k = 5;

a = rand(n,m);

tmp = reshape(a,k,[],m);

size(tmp)

aavg = reshape(mean(tmp),[],m);

size(aavg)

aavg(1,1)

mean(a(1:k,1))

 

Henk Borsje

 

 

From: Nicholas Jankowski <[hidden email]>
Sent: Saturday, November 30, 2019 2:50 AM
To: Henk Borsje <[hidden email]>
Cc: Help GNU Octave <[hidden email]>
Subject: Re: Taking a mean of a fixed length number of points

 

On Fri, Nov 29, 2019 at 4:12 PM Henk Borsje <[hidden email]> wrote:

This question is not of crucial importance, but I’m curious if there is a better alternative.

 

I need to calculate the columnar average of each k points out of an array of x(n,m) elements, resulting in a new array  x_avg (floor (n/k) , m) elements.

 

I use:

 

        tmp = reshape(x,k,[],m);                                      (1)

        x_avg = reshape(mean(tmp),[],m);                  (2)

 

I wonder if there is a simpler or more direct way, except for substituting equation (1) into (2)

 

 

just for clarity, can you give a brief example of what your input looks like and what you would like the output to look like?  it seems your method is fairly compact. 



Reply | Threaded
Open this post in threaded view
|

Re: Taking a mean of a fixed length number of points

Francesco Potortì
In reply to this post by hjborsje
>I need to calculate the columnar average of each k points out of an array of
>x(n,m) elements, resulting in a new array  x_avg (floor (n/k) , m) elements.
>
>I use:
>        tmp = reshape(x,k,[],m);                          (1)
>        x_avg = reshape(mean(tmp),[],m);                  (2)

I think that what you use is the simpler and most efficient way.  Rather
than resorting to 3-d arrays, I'd go columnar, by removing the fourth
argument in (1), which is cleaner to my eyes.

--
Francesco Potortì (ricercatore)        Voice:  +39.050.621.3058
ISTI - Area della ricerca CNR          Mobile: +39.348.8283.107
via G. Moruzzi 1, I-56124 Pisa         Skype:  wnlabisti
(gate 20, 1st floor, room C71)         Web:    http://fly.isti.cnr.it