Search code examples
matlabdifferenceindices

Finding start and end indices of positive curves in data


Consider the following example where x is

x = [randi([10 20],1,10) zeros(1,11) randi([10 20],1,10) zeros(1,11) randi([10 20],1,10) zeros(1,12) randi([10 20],1,11) ];

which looks something like this in the plot:

image

Now what I want to find is the starting and ending index of each positive curve in the graph and store them in a matrix. The code I have written below works fine but it isn't what I will call elegant. Does anyone have a better and more efficient way of doing it?

zero_padding = zeros(1,2);
x = [randi([10 20],1,10) zeros(1,11) randi([10 20],1,10) zeros(1,11) randi([10 20],1,10) zeros(1,12) randi([10 20],1,11) ];
x = [x zero_padding]
stp(1) = find(x>0 , 1, 'first')
enp(1) = find(x(stp(1):end)==0 , 1, 'first') - 1
stoffset = enp(1);
i = 2
while(~isempty(find(x(stoffset + 1:end)>0 , 1, 'first')))        
    stp(i) = find(x(stoffset + 1:end)>0 , 1, 'first') + stoffset
    enp(i) = find(x(stp(i) + 1:end) == 0 , 1, 'first') + stp(i) - 1
    stoffset = (enp(i)) + 1;
    i = i + 1;    
end

and the output is:

>> stp =

     1    22    43    65


>> enp =

    10    31    52    75

which is correct.

NOTE: I have already tried using:

startindex = (find(diff(x)>0)) + 1
endindex = (find(diff(x)<0))

which would work just fine if the positive curves were just perfect squares but as you can see in the plots, it has many dips. So it's difficult to use it as diff will also give +1 or -1 at those dips.


Solution

  • Your second approach was pretty close i.e.

    startindex = (find(diff(x)>0)) + 1
    endindex = (find(diff(x)<0))
    

    Rather try

    posData = [0, x>0] %prepend with zero to catch if the data starts with a positive region
    startindex = find(diff(posData) == 1) 
    endindex = find(diff(posData) == -1)