File Exchange Pick of the Week

May 9th, 2008

Finding Local Extrema

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

13 Responses to “Finding Local Extrema”

  1. Nikos replied on :

    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]);
    
  2. Brett replied on :

    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

  3. manimala replied on :

    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?

  4. Martin H.Skjelvareid replied on :

    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.

  5. Nara replied on :

    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?

  6. Brett replied on :

    @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.

  7. toto replied on :

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

  8. Brett replied on :

    toto: Try extrema2, by Carlos Adrian Vargas Aguilera:

    http://www.mathworks.com/matlabcentral/fileexchange/12275-extrema-m-extrema2-m

    Cheers,
    Brett

  9. Aslak Grinsted replied on :

    There is also the built-in function findpeaks from the signal processing toolbox:

    http://www.mathworks.se/help/toolbox/signal/findpeaks.html

  10. Sri replied on :

    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!

  11. Brett replied on :

    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

  12. sepid replied on :

    hi, i have the same problem like sri,

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

  13. bshoelso replied on :

    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

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


MathWorks

Brett & Jiro share their favorite user-contributed submissions from the File Exchange.

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