help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: running Person's correlation


From: Francesco Potortì
Subject: Re: running Person's correlation
Date: Wed, 04 Sep 2013 13:10:40 +0200

I had written:

>>I have a signal (long) and a template (short, fixed).  I have to compute
>>the Pearson's correlation of the short signal with a sliding window of
>>the long signal.  This is a convolution where each sample is divided by
>>the (fixed) standard deviation of the short signal and the running
>>standard deviation of the long signal.
>>
>>The only loopless way I can think of is to compute a running sum, a
>>running sum of squares, and use them to compute a running standard
>>deviation to be multiplied with the convolution.  Any more
>>straightforward methods?

And then:

>Thanks again to all who have tried an answer.  Here is my solution to
>the problem.  If it turns out that there is already a canned solution
>analogous to mine, I'll adopt that one, else I'm open to suggestions and
>possibly willing to create a better solution to incorporate into the
>signal package (this one is subject to numerical cancellation).

However, I see that the code was mangled, and that a very simple change
improves code readability and reduces cancellation problems, so here is
a second version.

Also, the example provided does not work with most recent Octave.  To
test the function, try this:

octave> t=interp1([1 7 15],[1 0 0],1:15);
octave> runningcor(t,t)
ans =  1.00000
octave> plot(runningcor(t,[sin(1:15).^2 t sqrt(1:7)]))


===File ~/math/octavelib/signal/runningcor.m================
## © Francesco Potortì 2013
## $Revision: 1.2 $
## This program is licensed under the terms of the GPL v3

## Running Pearson's correlation between X and Y
##
## Useful as a detector with automatic gain control.
## Compares the two arguments vectors X and Y, giving a result of
## lenght abs(length(x)-lenght(y))+1.
## It takes the shortest of X and Y (the prototype) and computes a
## correlation of it versus a moving window of the longest (the signal).
## The absolute magnitude of the result is not greater than 1.

function rcor = runningcor (x, y)
  if (length(x) > length(y))
    signal = x; proto = y;
  else
    signal = y; proto = x;
  endif
  proto -= mean(proto);         # standardise prototype for simpler
  proto /= std(proto,1);        # code and better numerical stability
  plen = length(proto);         # length of prototype is equal to
                                # length of running correlation window
  slen = length(signal);        # length of signal
  ps = prepad(signal,slen+1);   # prepend signal with a single 0
  scsum = cumsum(ps);           # signal cumulative sum
  scsqr = cumsum(ps.^2);        # signal cumulative sum of squares
  we = 1+(plen:slen);           # moving window end
  ws = we-plen;                 # moving window start
  srsum = scsum(we)-scsum(ws);  # signal running sum
  srsqr = scsqr(we)-scsqr(ws);  # signal running sum of squares
  srmean = srsum/plen;          # signal running mean
  srmsqr = srsqr/plen;          # signal running mean of squares
  srvar = (srmsqr-srmean.^2);   # signal running population variance
  srstd = sqrt(srvar);          # signal running population standard deviation
  p = (rot90(proto,2));         # invert prototype
  rprod = fftconv(signal,p);    # running product of signal and prototype
  cw = plen:slen;               # central window of convolution discarding tails
  rcov = rprod(cw)/plen;        # running covariance of signal and prototype
  rcor = rcov ./ srstd;         # running Pearson's correlation
endfunction

## Local Variables:
## fill-column: 100
## End:
============================================================

-- 
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
(entrance 20, 1st floor, room C71)     Web:    http://fly.isti.cnr.it


reply via email to

[Prev in Thread] Current Thread [Next in Thread]