Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding Local Maxima Over a Dynamic Range

Tags:

c#

algorithm

Working in C#, I need to find all local peaks in a List of doubles and return them as another List doubles. This seems simple enough if I have a set number of values I'm comparing in any given 'window' of values, but I need to be able to actually pass this window size into the function itself. That may be confusing, but basically I need something like this:

public List<double> FindPeaks(List<double> values, double rangeOfPeaks)

where if 'rangeOfPeaks' was 5, the 'current' value would be compared to 2 values on each side of it to determine if it was a peak or not. If 'rangeOfPeaks' was 11, the current value would be compared to 5 values on each side. I'd think this was a pretty basic algorithm, however, I've been unsuccessful in finding any good methods for detecting a peak like this. Has anyone ever done this before? Any help at all would be appreciated. Thanks in advance!

like image 598
JToland Avatar asked Mar 11 '11 04:03

JToland


1 Answers

I suggest a few changes to Levy's post...

1) Levy's code threw an exception when the specified values IList was a nearly straight line.

2) I think the index of the peaks in the array is the desired result. Consider for example what would happen if we had two peaks with identical doubles? Ops. Changed to return index of peaks in specified IList.

    public static IList<int> FindPeaks(IList<double> values, int rangeOfPeaks)
    {
        List<int> peaks = new List<int>();
        double current;
        IEnumerable<double> range;

        int checksOnEachSide = rangeOfPeaks / 2;
        for (int i = 0; i < values.Count; i++)
        {
            current = values[i];
            range = values;

            if (i > checksOnEachSide)
            {
                range = range.Skip(i - checksOnEachSide);
            }

            range = range.Take(rangeOfPeaks);
            if ((range.Count() > 0) && (current == range.Max()))
            {
                peaks.Add(i);
            }
        }

        return peaks;
    }
like image 105
BMoney Avatar answered Oct 02 '22 15:10

BMoney