C# - 通过二次拟合在给定宽度内找到峰值

时间:2011-03-14 19:10:42

标签: c# mathematical-optimization labview quadratic derivative

我正在研究一种算法来查找List对象中的峰值。我想到了我认为这是一个好的(或足够好的)算法,通过查看一个点和它的邻居来做到这一点,如果它是一个峰值,将它添加到结果列表中。但是,鉴于最近的一些结果,我认为这种方法并不像我最初希望的那样好。 (我已经包含了我正在使用的代码,并希望在下面替换)。我以前做过一些LabView的工作,我知道他们的模块找到峰值/谷值的方式适用于我需要做的事情。我做了一些关于LabView如何做到这一点的研究并发现了这个:

  

“此峰值检测器VI基于将二次多项式拟合到连续数据点组的算法。拟合中使用的数据点数量由宽度指定。

     

对于每个峰或谷,针对阈值测试二次拟合。高度低于阈值的峰值或低于阈值的谷值被忽略。只有在VI处理超出峰值或谷值位置的近似宽度/ 2个数据点之后才能检测到峰和谷。这种延迟只对实时处理有影响。“

好的,所以现在我一直在尝试在C#中做类似的事情,但是,在我的所有搜索中,似乎将二次多项式拟合到数据当然不是微不足道的。我认为这个问题会被探索很多很多次,但是我找不到能够做到这一点的算法或者找到一个可以用来做这个的库是不成功的。

非常感谢任何有关此问题的帮助。感谢。

原始/当前代码:

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

1 个答案:

答案 0 :(得分:0)

我在c#中使用Math.NET进行矩阵运算。它具有您可能需要的所有工具,用于最小化问题,例如QR分解或SVD。有关如何应用它们的一般概述,我认为wikipedia做得非常好。