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