Re: Find maxima in lists of data
- To: mathgroup at smc.vnet.net
- Subject: [mg105790] Re: Find maxima in lists of data
- From: Bill Rowe <readnews at sbcglobal.net>
- Date: Sat, 19 Dec 2009 06:25:34 -0500 (EST)
On 12/18/09 at 6:23 AM, david.leipold at tu-ilmenau.de (David) wrote: >I need to find maxima in lists of numerical (measured) data. My >basic idea is to apply Differences[] to the data and find pairs >which differ in Sign[]. My working solution is: >AllMaxima[lst_] := Flatten[Position[ >Partition[Differences[lst], 2, 1], {x_, y_} /; >Sign[x] > Sign[y]]]; >which behaves as i want. Since it was hard to work this out, i ask >myself whether i haved overlooked the simple solution. So does >anybody know the really cool way to achieve this? It appears you are looking for the position of a local maximum in your data. If I have this correct, the built-in function Ordering will do the job. For example, Create a data list with known maxima data = Table[Sin[x], {x, 0, 4 \[Pi], .01}]; Your code outputs: In[6]:= AllMaxima[data] Out[6]= {157,785} and with Ordering I get: In[7]:= Ordering[data, -2] Out[7]= {786,158} This result differs from your result by 1 since Differences trims the data list by 1. In using Ordering, I took advantage of knowing there were 2 maxima to find which is clearly something you would have to determine in general. Both methods require essentially noise free data. In the presence of noise, there will be local sign changes throughout the data which will obviously cause your approach to fail. Using Ordering has a similar problem since a values near the n highest values could be near a single peak rather than correctly showing multiple peaks. If you do have noisy data and still need to find the position of the maxima, my approach is to use as follows Floor[Median@#] & /@ Split[Most[ ArrayRules[ SparseArray[Chop[data-.5 ,tol]]]] /. HoldPattern[{a_} -> _] :> a, Abs[#2 - #1] < 100 &] What this code does is rescale the data to a known range (0 to 1), then uses Chop to zero the data within tol of .5 for the rescaled data. I assume the data is reasonably symmetric causing the minima/maxima to be near the center of the portion of the data not zeroed by Chop. The hard coded factor 100 forces a peak to have a width of greater than 100. I've done this as additional filtering of noise.