C # - Нахождение пиков в пределах данной ширины с помощью квадратичной подгонки - PullRequest
1 голос
/ 14 марта 2011

Я работаю над алгоритмом поиска пиков в объекте 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 голосов
/ 30 сентября 2012

Я использовал Math.NET для матричных операций, подобных этому в c #. В нем есть все инструменты, которые могут вам понадобиться для решения задач наименьших квадратов, таких как декомпозиция QR или SVD. Для общего обзора того, как их применять, я думаю, Википедия довольно хорошо справляется с работой.

...