1

我正在研究一种算法来查找 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;
}
4

1 回答 1

0

我在 c# 中使用过Math.NET进行这样的矩阵运算。它具有最小二乘问题(例如 QR 分解或 SVD)可能需要的所有工具。对于如何应用它们的一般概述,我认为维基百科做得很好。

于 2012-09-30T14:00:01.313 回答