3

In Matlab, is it possible to measure local variation of a signal across an entire signal without using for loops? I.e., can I implement the following:

window_length = <something>
for n = 1:(length_of_signal - window_length/2)
    global_variance(n) = var(my_signal(1:window_length))
end

in a vectorized format?

eykanal
  • 26,437
  • 19
  • 82
  • 113
  • Did you mean something like `global_variance(n) = var(my_signal(n:n + window_length - 1))`? – Eitan T Mar 10 '13 at 18:42
  • @EitanT - Yes, sorry, mixing up my R and Matlab syntax, sorry. – eykanal Mar 10 '13 at 18:55
  • Some possibly relevant questions for others seeking a more general answer: [this](http://stackoverflow.com/q/7991744/168775), [this](http://stackoverflow.com/questions/7974616/simple-sliding-window-filter-in-matlab), and [this](http://stackoverflow.com/questions/2202463/sliding-window-algorithm-for-activiting-recognition-matlab) – eykanal Mar 10 '13 at 20:04

3 Answers3

1

If you have the image processing toolbox, you can use STDFILT:

global_std = stdfilt(my_signal(:),ones(window_length,1));

% square to get the variance
global_variance = global_std.^2;
Jonas
  • 74,690
  • 10
  • 137
  • 177
0

You could create a 2D array where each row is shifted one w.r.t. to the row above, and with the number of rows equal to the window width; then computing the variance is trivial. This doesn't require any toolboxes. Not sure if it's much faster than the for loop though:

longSignal = repmat(mySignal(:), [1 window_length+1]);
longSignal = reshape(longSignal(1:((length_of_signal+1)*window_length)), [length_of_signal+1, window_length])';
global_variance = sum(longSignal.*longSignal, 2);
global_variance = global_variance(1:length_of_signal-window_length));

Note that the second column is shifted down by one relative to the one above - this means that when we have the blocks of data on which we want to operate in rows, so I take the transpose. After that, the sum operator will sum over the first dimension, which gives you a row vector with the results you want. However, there is a bit of wrapping of data going on, so we have to limit to the number of "good" values.

I don't have matlab handy right now (I'm at home), so I was unable to test the above - but I think the general idea should work. It's vectorized - I can't guarantee it's fast...

Floris
  • 45,857
  • 6
  • 70
  • 122
0

Check the "moving window standard deviation" function at Matlab Central. Your code would be:

movingstd(my_signal, window_length, 'forward').^2

There's also moving variance code, but it seems to be broken.

The idea is to use filter function.

eykanal
  • 26,437
  • 19
  • 82
  • 113
Dmitry Galchinsky
  • 2,181
  • 2
  • 14
  • 15