I am trying to completely vectorize a sliding window operation that involves an arbitrary slide distance in order to minimize the run time for this code.
I have two vectors: (1) A time vector which records in sample number a series of event times and (2) A channel vector which indicates on which channel each event time was recorded. So:
time = [1,13,58,96,1002];
channel = [1,1,1,2,2];
Which means, for example, that an event was detected at sample number 1 on channel 1. I want to calculate a sliding event count with an arbitrary slide length. For example, if there were only one channel, it would look something like this:
binary = sparse(1,time,1,1,max(time));
nx = max(time); %length of sequence
nwind = <some window size>;
noverlap = <some size smaller than nwind>;
ncol = fix((nx-noverlap)/(nwind-noverlap)); %number of sliding windows
colindex = 1 + (0:(ncol-1))*(nwind-noverlap); %starting index of each
idx = bsxfun(@plus, (1:nwind)', colindex)-1;
eventcounts=sum(binary(idx),1);
I was wondering whether (1) anyone has an idea how to expand this for multiple channels without adding a loop? and (2) perhaps there is an even faster way of making the calculation in general?
Thanks a lot for any ideas. :)
Here is a sample solution without vectorization:
fs = 100; %number of samples in a window
lastwin = max(time);
slide = fs/2; %slide by a half a window
winvec = 0:slide:lastwin;
for x=1:max(channel)
t = histcounts(time(channel==x),winvec);
t = conv(t, [1,1], 'same'); %convolve to get window size of fs
eventcounts(x,:) = t;
end
Ideally, the script would return an [MxN]
array, called eventcounts
, where M
is the total number of channels and N
is the total number of windows numel(winvec)
. In each position (i,j)
, eventcounts(i,j)
would contain the number of events for channel i
and window j
.