C# - 通过二次拟合找到一个给定的宽度内的峰 [英] C# - Finding Peaks within a Given Width via Quadratic Fit

查看:495
本文介绍了C# - 通过二次拟合找到一个给定的宽度内的峰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个算法来找到一个List对象峰。我已经想出了我认为是通过看一个点,它的邻国做一个很好的(或不够好)的算法,如果它是一个高峰,将它添加到结果列表中。然而,鉴于最近的一些成果,我不认为这种方法可行,以及我最初希望。 (我已经包括了代码我目前使用,并希望更换,下同)。我已经做了之前的LabView一点的工作,我知道他们的模块发现波峰/波谷的方式适用于什么,我需要做的。我做了一些研究,LabVIEW如何做到这一点,发现这样的:




这峰值检波器VI是基于适合二次多项式算法到的数据点的连续组。以宽度指定在拟合中使用的数据点的数目。



有关每个峰或谷,二次拟合针对阈值测试与比阈值高度低于或与槽比阈值高谷峰仅在VI过程大约宽度/ 2个数据点之外的峰或谷的位置后忽略。峰并检测山谷。这种延迟只具有意义实时处理。




好了,现在我一直试图做在C#中类似的东西,但是,在我所有的搜索似乎二次多项式拟合数据肯定是不平凡的。我倒是觉得,这个问题会为一个探讨了很多,很多次,但我一直不成功得到一个算法,做这口井还是找到一个库,做到这一点。



这个问题的任何帮助是极大的赞赏。谢谢



原始/电流代码:



 公共静态列表<双> FindPeaks(列表<双>的价值观,双rangeOfPeaks)
{
名单,LT;双>峰=新的List<双>();

INT checksOnEachSide =(int)的Math.Floor(rangeOfPeaks / 2);
的for(int i = checksOnEachSide; I< values.Count - checksOnEachSide;我++)
{
双电流=值[I]
IEnumerable的<双>窗口=值;
如果(I> checksOnEachSide)
窗口= window.Skip(I - checksOnEachSide);
窗口= window.Take((INT)rangeOfPeaks);
如果(当前== window.Max())
peaks.Add(电流);
}
回报率的峰值;
}


解决方案

我用的 Math.NET 在C#这样的矩阵运算。它有可能需要为最小二乘问题,如QR分解或SVD的所有工具。有关如何应用它们的总体概述我觉得维基确实相当不错


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 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.

这篇关于C# - 通过二次拟合找到一个给定的宽度内的峰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆