How to create a sliding window function?

I have a code called SampEn and would like to modify it to allow multiple calculations over a sliding window in the following fashion: 1. SampEn(data1:200) 2. SampEn(data(2:201) 3. SampEn(data(3:202) 4. and so on, moving one element forward each time until I reach the end of that data set (e.g. if 1000 elements, then the last analyzed set is data(801:1000).
The original code for SampEn is:
function saen = SampEn(data)
r = 0.2*std(data);
N = length(data);
correl = zeros(1,2);
dataMat = zeros(2+1,N-2);
for i = 1:2+1
dataMat(i,:) = data(i:N-2+i-1);
end
for m = 2:2+1
count = zeros(1,N-2);
tempMat = dataMat(1:m,:);
for i = 1:N-m
dist = max(abs(bsxfun(@minus,tempMat(:,i+1:N-2),tempMat(:,i))));
D = (dist < r);
count(i) = sum(D)/(N-2);
end
correl(m-2+1) = sum(count)/(N-2);
end
saen = log(correl(1)/correl(2));
end
There has to be a faster way to do this than manually having to type in each interval..and I can't wrap my brain around it..Thanks

 Akzeptierte Antwort

Star Strider
Star Strider am 17 Okt. 2015

15 Stimmen

Assuming the length of ‘saen’ does not change between iterations, this is one (partially-tested because I did not run it with ‘SampEn’) way:
L = 1000;
w = 200;
for k1 = 1:L-w+1
datawin(k1,:) = k1:k1+w-1;
saen(k1,:) = SampEn(data(datawin(k1,:)));
end
This saves the index ranges in the event you need them. If you don’t, eliminate the subscript references in ‘datawin’.

11 Kommentare

mejali
mejali am 17 Okt. 2015
Hmm can't seem to get it to work. Where did you insert this for-loop? I presume it needs a new function.
Star Strider
Star Strider am 17 Okt. 2015
Bearbeitet: Star Strider am 17 Okt. 2015
What doesn’t work? What is it not doing that you want it to do, or doing that you don’t want it to do? Is it throwing errors or warnings? (If so, please copy the entire red text in your Command Window to a Comment here so we can see it and analyse it.)
The loop does not need to be a new function. It can run independently in your main script.
The loop includes a call to ‘SampEn’ in the code. It is set up to create ‘datawin’ as a range of indices with a window length of 200 (given by ‘w’), spanning 1 to 1000. (The loop is set up to retain ‘datawin’ in the event you need it, but you don’t have to store it if you don‘t want to.) You then use those indices to refer to a range of ‘data’ (that I assume is a vector), to then pass to your ‘SampEn’ function. The code then stores saen as a matrix (or vector if it is a scalar), corresponding to the selected ‘datawin’ iteration.
Ok I inserted it into the SampEn function:
function saen = SampEn(data)
r = 0.2*std(data);
N = length(data);
correl = zeros(1,2);
dataMat = zeros(2+1,N-2);
for i = 1:2+1
dataMat(i,:) = data(i:N-2+i-1);
end
for m = 2:2+1
count = zeros(1,N-2);
tempMat = dataMat(1:m,:);
for i = 1:N-m
dist = max(abs(bsxfun(@minus,tempMat(:,i+1:N-2),tempMat(:,i))));
D = (dist < r);
count(i) = sum(D)/(N-2);
end
correl(m-2+1) = sum(count)/(N-2);
end
saen = log(correl(1)/correl(2));
end
L = 1000;
w = 200;
for k1 = 1:L-w+1
datawin(k1,:) = k1:k1+w-1;
saen(k1,:) = SampEn(data(datawin(k1,:)));
end
Then I attempt to run it for a row vector (I call it Interval) that consists of 1000 elements (each element represents a specific heart rate) by typing SampEn(Interval) in the command window. I get the following error reply:
x=SampEn(Interval)
Error: File: SampEn.m Line: 23 Column: 1
This statement is not inside any function.
(It follows the END that terminates the definition of the function "SampEn".)
My goal is for it to return a row vector with calculation of SampEn for each window length; the row vector should have 801 elements if the window length is 200 and it moves forward by 1 each time up to 1000.
Thanks!!!!
Star Strider
Star Strider am 17 Okt. 2015
Please do not insert my code inside your function! It will not work that way, and will probably cause recursion errors.
I intend that the loop in my code calls your function in every iteration of the loop, each time with a different window of your data, and stores the output.
mejali
mejali am 17 Okt. 2015
Salutations to you, thank you for helping me figure that out. It works beautifully now!
Star Strider
Star Strider am 17 Okt. 2015
Thank you. As always, my pleasure!
fizza tariq
fizza tariq am 9 Mai 2017
Bearbeitet: fizza tariq am 9 Mai 2017
@Star Strider if i want to use your code to call my function every 25th observation instead of every other observation, how should i edit your code?
Using the example function above with L=4000 and w=2500, i want to call it in the following fashion: 1. SampEn(data(1:2500) 2. SampEn(data(26:2525) 3. SampEn(data(51:2550) and so on, moving 25 elements forward each time until I reach the end of that data set. Basically i want to call the function 60 [(4000-2500)/25] times in total every 25th obs
I’ve been away from this code for 1½ years! If I remember correctly how it works (no promises), inserting a step in the for vector may do what you want:
L = 4000;
w = 2500;
for k1 = 1:25:L-w+1
datawin(k1,:) = k1:k1+w-1;
saen(k1,:) = SampEn(data(datawin(k1,:)));
end
fizza tariq
fizza tariq am 9 Mai 2017
@Star Strider thanks a lot! it worked
Star Strider
Star Strider am 9 Mai 2017
My pleasure!
I would appreciate a Vote for my Answer.
Pragati Patel
Pragati Patel am 29 Mär. 2022
@Star Strider Hi! My query is i want to calculate the feature i.e SampEn with a 200 bin sliding window and a 100 bin overlap; 1. SampEn(1:200) 2. SampEn(100:300) 3.SampEn(200:400) and so on. How shall i edit the code? Please respond.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by