#c #polynomial-math #curve-fitting
#c #многочлен-математика #подгонка кривой
Вопрос:
Я пытаюсь преобразовать приведенную ниже функцию matlab / octave в C (обычный способ — понять функцию matlab и закодировать ее на C с нуля). Это подгонка данных к кривой гаусса с использованием полиномиальной подгонки.
function y=func(data)
N=128;
y1=gausswin(N,4);
x1=[0:1/N:1-1/N]';
P=polyfit(x1,y1,12);
y=polyval(P,data);
Но когда я проверил функции polyfit, это показалось мне большой работой, поскольку включает в себя множество вызовов дополнительных функций библиотеки octave. Сначала он вычисляет матрицу Вандермонда, затем выполняет ее QR-разложение и вычисляет норму вектора и т.д…
- Какие другие параметры / обработку я могу использовать, чтобы иметь аналогичную функциональность (приближение к фактической операции, описанной выше), но с некоторыми более простыми методами подгонки кривой или интерполяции.
Любые указатели были бы полезны.
Комментарии:
1. Я скажу только, что подгонять полиномиальную кривую высокого порядка к гауссовским данным — глупое занятие. 12-я степень высока.
2. @ Хотя это не относится к моему OP, почему не полезно подгонять полиномиальную кривую более высокой степени к гауссовским данным?
3. Вы писали о подгонке «кривой Гаусса с использованием полиномиальной подгонки». У вас есть причина использовать полиномиальную подгонку?
4. Если вы хотите подогнать многочлен к гауссову, я рекомендую разложение в ряд Тейлора 😉
Ответ №1:
Помимо практической ценности подгонки такого многочлена к гауссову, вы можете просто проанализировать поведение вашего кода:
N=128;
y1=gausswin(N,4);
x1=[0:1/N:1-1/N]';
P=polyfit(x1,y1,12);
Выходные данные этого раздела всегда будут одинаковыми, поэтому вы можете выполнить это в MATLAB или Octave и просто извлечь многочлен P
для использования в вашем коде на C, где вы включаете его в качестве константы. Это менее гибко, чем переписывать все на C, но это также быстрее.
В противном случае, вы могли бы взглянуть на BLAS: BLAS определяет API для библиотек, используемых для линейной алгебры, таких как LAPACK (который используется MATLAB). Я подозреваю, что многие из этих библиотек будут реализовывать основные операции, которые вам нужны.
Дополнение: Если у вас есть небольшой опыт в числовых вычислениях или вы просто хотите, чтобы у вас было много работы, вы можете рассмотреть Matlab Coder.
Комментарии:
1. @Egon: Что касается получения коэффициентов полинома P, возможно, вы правы в том, что выходные данные могут быть постоянными и могут использоваться в C как постоянный массив с плавающей запятой или что-то в этом роде, но y = polyval (P, data); не является постоянным, и реализация этого в C может быть сложной / утомительной.
2. @goldenmean: Я сильно сомневаюсь, что
polyval
самостоятельная реализация была бы сложной или утомительной. В любом случае, если возникнут численные проблемы, доступно много литературы. Но это, безусловно, будет более утомительным, чем поручать кому-то другому выполнять работу за вас.3. Проверил оба — BLAS src и ATLAS src. Не удалось найти ничего, связанного с подгонкой кривой / полиномом.
4. @goldenmean: Возможно, вы не найдете полиномиальной подгонки внутри BLAS или ATLAS напрямую, но вы найдете там QR-разложение (что, на мой взгляд, самая сложная часть). Подгонка полинома не сложна, вам нужно построить матрицу Вандермонда и решить для коэффициентов. Однако, как я уже сказал: эта первая часть может быть предварительно рассчитана с использованием MATLAB, вам даже не нужны матрицы Вандермонда и QR, единственное, что вам нужно сделать, это написать свою собственную
polyval
альтернативу.5. @Egon: На самом деле для моего случая. Многочлен всегда постоянен для каждого вызова. Поэтому я сохранил его в виде констант массива с плавающей запятой. Теперь рассмотрим преобразование функции polyfit из Matlab, что не так уж сложно. В основном он вычисляет многочлен в этих точках (точка данных, возведенная в степени x), умноженный на коэффициенты. Это происходит для каждой точки данных во входном / векторном массиве. Итак, реализуем это на C. Спасибо за указатели и подсказки.