how to find cycle in data

5 views (last 30 days)
Max Bernstein
Max Bernstein on 30 Sep 2011
Commented: Walter Roberson on 15 Jul 2017
Hello, I have a set of data points similar to one below named "data". The first column is time, second column is voltage. One voltage cycles start at V>=70 and ends at V<=70, and can varies from 70-150. There are two cycles in this example. How can I find the indices where the cycle starts and ends? I tried to use the the find command but it returns all indices of the values w/in that range, not where it starts or ends.
Thanks!
cycle=find(data(:,2)>=70 & data(:,2) <= 150)
0 0
0.001 0
0.002 10
0.003 60
0.004 70
0.005 75
0.006 150
0.007 72
0.008 150
0.009 100
0.01 130
0.011 100
0.012 90
0.013 70
0.014 50
0.015 6
0.016 0
0.017 0
0.018 60
0.019 10
0.02 77
0.021 92
0.022 100
0.023 130
0.024 120
0.025 85
0.026 65
0.027 20
0.028 0
0.029 0

Accepted Answer

Walter Roberson
Walter Roberson on 30 Sep 2011
logind = [false, data(:,2)>=70 & data(:,2) <= 150, false];
cyclestart = strfind([false true], logind);
cycleend = strfind([true false], logind) - 1;
cyclestart(K) will be the index of the beginning of cycle #K, and cycleend(K) will be the index of the end of cycle #K. The code protects against boundary conditions (cycle starts at beginning of data or ends at the end of data)
  5 Comments
Christine Nee
Christine Nee on 14 Jul 2017
What did you add that made it work? Im returning no values
Walter Roberson
Walter Roberson on 15 Jul 2017
data = [ 0 0
0.001 0
0.002 10
0.003 60
0.004 70
0.005 75
0.006 150
0.007 72
0.008 150
0.009 100
0.01 130
0.011 100
0.012 90
0.013 70
0.014 50
0.015 6
0.016 0
0.017 0
0.018 60
0.019 10
0.02 77
0.021 92
0.022 100
0.023 130
0.024 120
0.025 85
0.026 65
0.027 20
0.028 0
0.029 0];
logind = [false; data(:,2)>=70 & data(:,2) <= 150; false] .';
cyclestart = strfind(logind, [false true]);
cycleend = strfind(logind, [true false]) - 1;
This code has a small difference compared to the original specification: it does not consider the cycle ended until the data is below 70, whereas the original specification said that it ended at <= 70. With the original specification, the 70 in row 5 would have to be considered to both start and end a cycle, and then the next entry would have to be considered to be a different cycle, unless a further restriction was added that cycles are to be at least length 2.

Sign in to comment.

More Answers (1)

Andrei Bobrov
Andrei Bobrov on 30 Sep 2011
more variant
d1 = data(:,2)>=70 & data(:,2) <= 150;
b = find([true;diff(d1)~=0;true]);
b2 = [b(1:end-1),b(2:end)-1];
out = b2(d1(b(1:end-1)),:)
  3 Comments
Walter Roberson
Walter Roberson on 30 Sep 2011
d1 would be the only large array explicitly generated: Andrei's b and b2 and out arrays would have only as many entries as there are cycles.
However, data(:,2)>=70 & data(:,2) <= 150 is going to construct a number of intermediate arrays that are going to be large.
If I recall correctly, someone recently added a File Exchange contribution written in MEX in order to do fast find of the elements within a given range. Unfortunately, I do not recall whom now, and when I poke around the File Exchange, I do not come up with anything. Perhaps someone else will remember.
Max Bernstein
Max Bernstein on 5 Oct 2011
This method works too. thanks!

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!