Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
617 views
in Technique[技术] by (71.8m points)

c# - Finding Local Maxima Over a Dynamic Range

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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...