# Finding indices when the curve stops decreasing

조회 수: 1(최근 30일)
Lizan 20 Oct 2014
댓글: SK 21 Oct 2014
Hi,
I have a curve I like to find the maximum and then find the indices under the peak for which it stops decreasing on each sides.
How can I do this?
I can find the maximum by
max(y)
but how can I determine once the curve stops decreasing? The curve is a bit noisy.
I guess I could maybe use;
diff(y)
but how do I estimate the tolerance for which
diff(y) > some tolerance.
The noise level s kind of big and varies from curve to curve. The one I am looking at now goes from 1500 to -1500 at baseline. I would determine the tolerance automatically if possible.

로그인 to comment.

### 답변(3개)

Matt Tearle 20 Oct 2014
If you have Signal Processing TB, have a look at the findpeaks function.
Otherwise, you might want to try some kind of smoothing before looking for the max:
>> nwindow = 5;
>> ySmooth = conv(y,ones(nwindow,1)/nwindow,'same');
Then look for where the difference goes through zero (and the second difference is negative). You can use the diff function to do finite difference derivatives by providing the x values as well as the y.

#### 댓글 수: 0

로그인 to comment.

SK 20 Oct 2014
Suppose the maximum was at index im. Then take:
dyrgt = diff( y(im : end) );
dylft = diff( y(im : -1 : 1) );
irgt = im + find(dyrgt >= 0, 1) - 1;
ilft = im - find(dylft >= 0, 1) + 1;

#### 댓글 수: 3

Lizan 20 Oct 2014
I have tried this on different peaks. It doesn't always find the exact positions. I think it is the >= 0 part which is causing the problem.
Attaching an example of a curve.
Lizan 20 Oct 2014
A second plot where I have much more noise.
SK 21 Oct 2014
I did the following with your data sets:
data_s = smooth(data, 20);
plot(data_s);
[~, im] = max(data_s);
dyrgt = diff( data_s(im : end) );
dylft = diff( data_s(im : -1 : 1) );
irgt = im + find(dyrgt >= 0, 1) - 1;
ilft = im - find(dylft >= 0, 1) + 1;
hold on
plot(ilft, 1, '*r');
plot(irgt, 1, '*r');
% ____
data2_s = smooth(data2, 20);
[~, im] = max(data2_s);
dyrgt = diff( data2_s(im : end) );
dylft = diff( data2_s(im : -1 : 1) );
irgt = im + find(dyrgt >= 0, 1) - 1;
ilft = im - find(dylft >= 0, 1) + 1;
close all
plot(data2_s);
hold on
plot(ilft, 1, '*r');
plot(irgt, 1, '*r');
It appears to give the correct points, unless you want the small hump on the left of the peak in data2 to be treated as noise.

로그인 to comment.

SK 20 Oct 2014
편집: SK 20 Oct 2014
For some reason, didn't see the part about the noise. In that case prior smoothing would be an option. Another more involved, but in my opinion more robust, option would be to use a piecewise linear fit and then take the two points at the bottom of the W.

#### 댓글 수: 2

Lizan 20 Oct 2014
How would I do that?
SK 21 Oct 2014
I shouldn't have opened my mouth.
Can you assume that your data is essentially VV shaped? Meaning there is basically only one "real" peak and it falls off on both sides and then possibly rises again somewhat at the sides. Then you have an ansatz for your function shape ie: piecewise continuous with four linear pieces. You can then use nlinfit() with a custom model function. Read the docs for nlinfit(). Perhaps you can also use the fit() function with fittype as 'linearinterp'.
The advantage of picewise linear is that it is the 'roughest' approximation so it should cover all those bumps and jaggies and give you the "one true solution" for the troughs (but it probably wont give the exact minima). For example in your data2, you could leave it to take care of that hump on the left - it will decide whether it is significant or not.
On the other hand you could use a smooth approximation (cubic splines say) to approximate the curve, but the problem with smooth curves is that they may follow the shape of your data too closely so there may still be some ambiguity about points where the troughs are.
Anyway, you'll have to think about this, depending on the exact problem you want to solve and the amount of time you have on your hands.
Sorry, but I'm not sure I can be of more help.

로그인 to comment.

이 질문에 답변하려면 로그인을(를) 수행하십시오.

### 태그

아직 태그를 입력하지 않았습니다.