I'm working on an algorithm to find peaks in a List object. I'd thought up what I thought was a good (or good enough) algorithm for doing this by looking at a point and it's neighbors and, if it was a peak, adding it to the results list. However, given some recent results, I don't think this method works as 开发者_Go百科well as I'd initially hoped. (I've included the code I'm currently using, and hope to replace, below). I've done a little work with LabView before and I know that the way their module finds peaks/valleys works for what I need to do. I did some research into how LabView does this and found this:
"This Peak Detector VI is based on an algorithm that fits a quadratic polynomial to sequential groups of data points. The number of data points used in the fit is specified by width.
For each peak or valley, the quadratic fit is tested against the threshold. Peaks with heights lower than the threshold or valleys with troughs higher than the threshold are ignored. Peaks and valleys are detected only after the VI processes approximately width/2 data points beyond the location of the peak or valley. This delay has implications only for real-time processing."
Okay, so now I've been trying to do something similar in C#, however, in all my searching it seems that fitting a quadratic polynomial to data is certainly not trivial. I'd think that this problem would be one explored many, many times, but I've been unsuccessful getting a algorithm that does this well or finding a library to do it with.
Any help with this problem is greatly appreciated. Thanks.
Original/Current Code:
public static List<double> FindPeaks(List<double> values, double rangeOfPeaks)
{
List<double> peaks = new List<double>();
int checksOnEachSide = (int)Math.Floor(rangeOfPeaks / 2);
for (int i = checksOnEachSide; i < values.Count - checksOnEachSide; i++)
{
double current = values[i];
IEnumerable<double> window = values;
if (i > checksOnEachSide)
window = window.Skip(i - checksOnEachSide);
window = window.Take((int)rangeOfPeaks);
if (current == window.Max())
peaks.Add(current);
}
return peaks;
}
I have used Math.NET for matrix operations like this in c#. It has all the tools you might need for least squares problems such as QR decomposition or SVD. For a general overview of how to apply them I think wikipedia does quite a good job.
精彩评论