Dr. Stanley Raj
Dr. Stanley Raj

Reputation: 87

Find the increasing and decreasing trend in a curve MATLAB

a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].

Here is an array i need to extract the exact values where the increasing and decreasing trend starts.

the output for the array a will be [2(first element) 2 6 9]

a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].
   ^       ^        ^               ^
   |       |        |               |

Kindly help me to get the result in MATLAB for any similar type of array..

Upvotes: 4

Views: 7639

Answers (2)

Gunther Struyf
Gunther Struyf

Reputation: 11168

You just have to find where the sign of the difference between consecutive numbers changes. With some common sense and the functions diff, sign and find, you get this solution:

a = [2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2];
sda = sign(diff(a));
idx = [1 find(sda(1:end-1)~=sda(2:end))+2 ];
result = a(idx);

EDIT:

The sign function messes things up when there are two consecutive numbers which are the same, because sign(0) = 0, which is falsely identified as a trend change. You'd have to filter these out. You can do this by first removing the consecutive duplicates from the original data. Since you only want the values where the trend change starts, and not the position where it actually starts, this is easiest:

a(diff(a)==0) = [];

Upvotes: 5

Ben A.
Ben A.

Reputation: 1039

This is a great place to use the diff function.

Your first step will be to do the following: B = [0 diff(a)]

The reason we add the 0 there is to keep the matrix the same length because of the way the diff function works. It will start with the first element in the matrix and then report the difference between that and the next element. There's no leading element before the first one so is just truncates the matrix by one element. We add a zero because there is no change there as it's the starting element.

If you look at the results in B now it is quite obvious where the inflection points are (where you go from positive to negative numbers).

To pull this out programatically there are a number of things you can do. I tend to use a little multiplication and the find command.

Result = find(B(1:end-1).*B(2:end)<0)

This will return the index where you are on the cusp of the inflection. In this case it will be:

ans =

     4     7    13

Upvotes: 1

Related Questions