File Exchange Pick of the Week

Finding Local Extrema 22

Posted by Brett Shoelson,

Many times, I've wanted a quick way to find the local minima or maxima in my data. Carlos Adrian Vargas Aguilera's submission EXTREMA makes it easy to do, and is Brett's selection for the Pick of the Week.

Contents

The Problem:

This morning, I was asked to help a customer find local peaks (minima and maxima) in a trace from some sort of medical device. The particulars of the signal are not really relevant here; what is important is that the signal was large and jagged, with many local extrema. This clearly was not something the customer--or I!--wanted to do manually. Moreover, of course, there might be more traces on which we would want to repeat the analysis, so any algorithm we developed should be able to be incorporated in an automation routine. My first thought was to search MATLAB's documentation for extrema detection. I found that the Signal Processing Blockset has a Peak Detection Block that finds local minima and maxima, but that solution, of course, requires Simulink. Being the MATLAB geek that I am, I wanted to do this entirely in m-code. Next, though implementing my own algorithm wouldn't be too difficult, I thought to search for someone else's implementation of an extrema detector. (No sense reinventing the wheel!)

Finding local maxima and minima

A quick search turned up Carlos's highly rated, much-downloaded EXTREMA. I happily grabbed his code and took it for a test spin. Result: problem solved! Consider the following artificial noisy data:

t= 0:pi/16:8*pi;
y = sin(t).*rand(size(t));
plot(t,y)

Now consider how easy it is to find the extrema with Carlos's EXTREMA function:

figure
plot(t,y)
[ymax,imax,ymin,imin] = extrema(y);
hold on
plot(t(imax),ymax,'r*',t(imin),ymin,'g*')

What about smoothing those data?

By the way, given a noisy source, it might also be nice to have a way to smooth the data. A quick search for SMOOTH in MATLAB's help browser shows how to do that with the always-useful Curve Fitting Toolbox:

y2 = smooth(y,20);
figure
plot(t,y2)
[ymax2,imax2,ymin2,imin2] = extrema(y2);
hold on
plot(t(imax2),ymax2,'r*',t(imin2),ymin2,'g*')
hold off

(Note that there are lots of options for SMOOTH. I've just implemented a [default] moving average filter, using a 20-point sliding neighborhood.)

Carlos also bundled EXTREMA with a second function called EXTREMA2 that extends the functionality to three-dimensional data, and he provided a nice graphic that shows off the utility of his code. I see that his functions also inspired another submission, called MinimaMaxima3D. Very nice work, Carlos!


Get the MATLAB code

Published with MATLAB® 7.6

22 CommentsOldest to Newest

Hey Doug,

I really enjoy reading your blog. I just wanted to point out that this task can be done in just 9 lines of code, compared to over 100 in Carlos’ file! The code that follows behaves a bit differently when a straight part is encountered within the data (detects 2 extrema at its endspoints, instead of placing a single extremum at its middle), but other than that it does the same thing! I don’t reinvent the wheel for sure, probably helping it roll faster :)

Cheers

N


function [Imin,Imax]=FindExtrema(Y)
    Y = [NaN;Y(:);NaN];
    D = diff(Y);
    S = D(1:end-1).*D(2:end);
    I = find(S0);
    In(D(In)<0)-1 ;
    Io(D(Io)<0)-1]);
    Imin=sort([I(D(I)0)-1;
    Io(D(Io)>0)-1]);

Nikos,
Thanks for the reply. While Carlos’s file could be tightened up, note that it does a lot of very nice error checking, and deals with edge cases that might wreak havoc on your code–if indeed it were working. Your code won’t run as posted (there are some bugs in there!); but I’d encourage you to polish your algorithm a bit and post it to the File Exchange.
Brett

the blog was very useful
is there any structure availbele to implement this work?
that is any architecture or block diagram to find the local maxima and minima for a given signal?

I also highly recommend Eli Billauer’s algorithm “peakdet” (http://www.billauer.co.il/peakdet.html ). This algorithm only detects “major” local peaks, ignoring noise peaks. The result is somewhat similar to that of the smoothed data above, but the peaks are found in the original time series. The trick that Eli does is to accept only those extrema for which the amplitude changes significantly afterwards (Unfortunately, this is done in a for-loop traversing the data). I’ve found that this algorithm is usually more useful for my applications than algorithms returning all extrema.

I have a set of data that resembles a step; few data points, a jump and few more points. The problem here is that the trend of the points before or after the jump is not quite plateau. They may increase or decrease gradually (but the variation is still smaller than the jump). The “EXTREMA” function can capture some max. or min. points but not all. Do you have any idea how to get all the extremums?

@Nara,
Hi Nara…hard to comment without seeing your data. Perhaps some filtering might be needed. Maybe even just a moving average filter might suffice.

thank you for sharing this code. I have a question for you. How to finding local extrema in 2D data. Thank you

I tried using the Carlos’s extrema code in Matlab, but it gives me the following error

??? Undefined function or method ‘extrema’ for input arguments of type ‘double’

Please help me out!

Sri,
It sounds like you have a path issue. Make sure Carlos’s function is download and that it lives somewhere on your MATLAB path, or in the directory you’re currently working in.
Brett

hi, i have the same problem like sri,

how can i download the exterma funtion? could u plz send this for me?

Sepid,
Click on the link to Extrema in the post above, then click to download Carlos’s package. Make sure those functions are on your MATLAB path, and you should be good to go.
Brett

Hi There,
I have been including extram function inside some of my scripts and lately i have been getting the following error message:

Maximum recursion limit of 500 reached. Use set(0,’RecursionLimit’,N)
to change the limit. Be aware that exceeding your available stack space can
crash MATLAB and/or your computer.

Error in extrema

Error while evaluating uicontrol Callback

Does anyone have an idea of how to solve this?

Thanks in advance!

Brett and Carlos Adrian Vargas Aguilera': Seriously I have go through that link but there is no Carlos function.Is there any way to run the above programmed?The problem is mentioned above.I cannot find the local maxima and minima of graph.This is my coding:

%imported data from excel sheet
x=xlsread(‘Data_Test.xls’,’A4:A65536′);
y=xlsread(‘Data_Test.xls’,’B4:B65536′);
%signal plot
figure
plot(x,y);
title(‘Ripple current’);
xlabel(‘Time’);
ylabel(‘Voltage’);
grid on

I have really don’t know any equation or function to solve this problem.I really really appreciate your help.

UMP…not sure what you’re asking. Click on the hyperlinked keyword “EXTREMA” in the first paragraph. It should take you to Carlos’s function. No?

Brett Shoelson:I have clicked on that link but there is no Carlo’s function.You mean that I need to download extrema.m and extrema2.m file?If that is requirement, I have already download them but there are error when run.How do I solve this problem?The first figure is look almost similar with my output after been filtered.I hope you understand.

UMP, it sounds like you’re looking for a function named “Carlos”??? No, no, no! You’ve already downloaded Carlos’s code; everything you need to run it should be in Extrema/Extrema2. (Plus MATLAB, of course.)

Brett Shoelson:w, I understand and I have used the command of extrema.m as you mentioned above. I have written the above command but I cannot produce the same graph for plotting the maximum and minimum signal. Only two plotted points which are (0.0) and (25.25) where the (t, y)is not plotted. Do I need to change the values or variable in the file extrema.m or is there something else missing in command? I still not understand how to use the above command for implement my project. I hope you can give me a brief explanation on the problem matter that I have faced. Some suggestion command from you also can be included. I need your help again. Thank you.

UMP, I don’t think I can help you. I suggest you put together a snippet of code that demonstrates what you want to demonstrate–and indicates the failure of this technique–and post it to the MATLAB newsgroup for additional feedback.
Brett

These postings are the author's and don't necessarily represent the opinions of MathWorks.