Любое альтернативное приближение к этому методу в matlab?

#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. Какие другие параметры / обработку я могу использовать, чтобы иметь аналогичную функциональность (приближение к фактической операции, описанной выше), но с некоторыми более простыми методами подгонки кривой или интерполяции.

Любые указатели были бы полезны.

Комментарии:

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. Спасибо за указатели и подсказки.