MATLAB Answers

0

How do I find multiple times in one array the first index of 25 samples exceeding the threshold

Asked by Anne Bohm on 18 Jun 2019 at 12:54
Latest activity Commented on by Anne Bohm on 18 Jun 2019 at 18:53
So, I am working with a binairy variable. To identify the onset of a muscle the binairy variable needs to be '1' for at least 25 samples consecutive.
it sometimes occures that the variable is '1' for 40 samples than '0' for few samples and then '1' again for more than 25 samples. Now i have MATLAB code where i can identify the index for the first string of 25 samples '1', but I can not seem to get the first index for the second string of 25 or more samples '1'.
is there anybody that can help me out?
here is my matlab code so far(including creating the binairy variable):
%create binairy variable
ex_threshold_preDC2= prestroke1(:,3) > threshold(:,3);
%initialising
ones_window = ones(1,25);
for idx = 1:length(ex_threshold_preDC2)-25
window_preDC2 = ex_threshold_preDC2(idx:idx+24);
if window_preDC2==ones_window
index_preDC2 = idx;
end
end
However, this only gives me the index of the last iteration of the for loop. but I want all iteration saved.

  0 Comments

Sign in to comment.

2 Answers

Answer by Guillaume
on 18 Jun 2019 at 16:07
 Accepted Answer

You never needed a loop to do what you want. The below will find the start indices of all runs of 1 of length 25 or more:
%demo array. Has a run starting at indices 6 (length = 40), 49 (length = 25) and 112 (length = 30)
%also has a run of 24 at index 78
ex_threshold_postDC1 = [zeros(1, 5), ones(1, 40), zeros(1, 3), ones(1, 25), zeros(1, 4), ones(1, 24), zeros(1,10), ones(1, 30)]
%find start indices of runs of length 25 or more:
indices = find(diff(movsum(ex_threshold_postDC1, [0 24], 'Endpoints', 'discard') == 25) == 1) + 1
What this does is calculate the moving sum of your vector over 25 consecutive elements. If the moving sum is 25, that means we have 25 consecutive 1s. So movsum(...) == 25 is a logical array that is true for any 1 in the input that is followed by 24 1s. The start of each run is 1 index after when the array goes from false to true, which is easy to find with find(diff(logical array) == 1).

  1 Comment

Thank you so much Guillaume! It works wonderful and so much easier than my FOR loop.

Sign in to comment.


Answer by Bob Nbob
on 18 Jun 2019 at 13:14

If you want to retain all answers then you need to index index_preDC2 within your loop. I would suggest adding a separate counting variable as well so you don't have a bunch of extra elements in the array.
c = 0;
for ...
if window_preDC2==ones_window
c = c + 1;
index_preDC2(c) = idx;
end
end
Be careful, the method you have set up will give you a lot of extra results as it is. For the section where you have 40 1s in a row, you will end up with ~15 indexes for that section.

  3 Comments

@Bob Nbob. Thanks this solves my initial question.
But yes thats right. I did not think of the ~15 indexes. So somehow i would have to find a way to include a statement that says I want equal or greater than 25 (>=25) consecutive samples.
Would you have any suggestions to how to do that. Could be by defining Ones_window completely different maybe?
The simplest way I can think of to do this is to add a trigger for a previous fail case.
if window_preDC2==ones_window & t == 0;
c = c + 1;
index_preDC2(c) = idx;
t = 1;
elseif window_preDC2==ones_window & t == 1;
else
t = 0;
end
For the record, I think that Guillaume's solution is ultimately better than mine.
Thank you so much Bob Nbob! i wil use Guillaime's solutution, but appreciate your time!

Sign in to comment.