parallel autocorrelation function

Hi there,

Any ideas on how to improve the serial or parallel performance of this autocorrelation function? It performs biased (1b) or unbiased (0b) normalization.

acf:{[series;lag;bias]

v:var series;

series-:avg series;

a:{[x;y] sum ((neg y) _ x)*y _x}[series;] peach 1+til lag;

n:(count series)-$[bias;0j;1+til lag];

1f,a%'(n*v)

}

Usage:              q) l:“f”$1+til 10

q) acf[l;5;1b]

1 0.7 0.4121212 0.1484848 -0.07878788 -0.2575758

 

Output for short lists can be verified here

https://www.easycalculation.com/statistics/autocorrelation.php

Scaling is decent going to 2 and 4 threads, with long lists, but I would like

to get a bit more out of the serial implementation especially…

          q)l:100000?40.0

q)\ts acf[l;90000;1b] (serial)

14703 6843472

q)\ts acf[l;90000;1b] ( x2 threads)

7450 6683360

Thanks

the autocorrelation function was discussed in 2011 on the k4 listbox forum available to licensed clients.

the fastest implementation was:

ac:{x%first x:x{(y#x)$neg[y]#x}/:c-til c:count x-:avg x}

it is also discussed on page 54 of the book Q Tips.

the function can be modified to include your three requirements:

  1. limit the number of lags computed (passing 5 returns 5 autocorrelations)

  2. optionally compute unbiased autocorrelations

  3. use peach to make the calculation faster

ac:{x%first x:$[z;::;%[;n]]{(y#x)$neg[y]#x} peach n:c-til y&c:count x-:avg x}

q)l:“f”$1+til 10
q)ac[;5;1b] l
1 0.7 0.4121212 0.1484848 -0.07878788

Excellent Nick. Thank you!

Looks like the dot product ($) is the key to the boost..

If I substitute that in place of sum ()*() I get the same time.