【问题标题】:Curve fitting in MATLAB, for a Sinusoidal function with more than 8 terms?MATLAB中的曲线拟合,用于超过8项的正弦函数?
【发布时间】:2016-08-17 11:39:46
【问题描述】:

我正在尝试将一些数据拟合到 MATLAB 中的正弦函数之和,但是,MATLAB 中正弦函数的项数是有限的,即到 1 ≤ n ≤ 8。但是,我希望我的拟合函数中有更多项,即超过 50 个项。有没有办法让 MATLAB 将我的数据拟合到具有超过 8 个正弦项的正弦函数的总和?为什么在 MATLAB 中有这样的约束(它是技术上的还是任意的)?是否有适合正弦函数的工具箱(尤其是能够支持加权数据的工具箱)?

>f = fit(X,Y, 'sin10')
>Error using fittype>iCreateFromLibrary (line 412)
>Library function sin10 not found.

'sin8' 或 'sin9' 参数都可以。

感谢任何回答。

【问题讨论】:

  • 使用傅里叶拟合代替mathworks.com/help/curvefit/… 对于超过 8 个术语,您应该自己实现拟合。但是,对于大多数情况,8 项傅立叶拟合可能绰绰有余。

标签: matlab signal-processing curve-fitting


【解决方案1】:

我在浏览 MATLAB 帮助时意外找到了我的问题的解决方案。我发布这个答案是为了帮助有同样问题的人。

作为解决此问题的第一枪,我尝试了“适合”指令。由于某些原因,自定义的基于“适合”的拟合代码如下所示,没有锻炼:

FitOptions = fitoptions('Method','NonlinearLeastSquares', 'Algorithm', 'Trust-Region', 'MaxIter');
FitType = fittype('a*sin(1*f) + b*sin(2*f) + c*sin(3*f) + d*sin(4*f) + e*sin(5*f) + g*sin(6*f) + h*sin(7*f) + k*sin(8*f) + l*sin(9*f) + m*sin(10*f) + n*sin(11*f)', 'independent', 'f');
[FittedModel, GOF] = fit(freq, data, FitType)
% `In above code, phase parameters are not included, they might be added.

我发现使用优化工具箱中的“lsqcurvefit”指令,自定义函数拟合比“拟合”函数更可行、更容易。我在下面的代码中测试了它以使我的数据适合 12 (>8) 个正弦的总和:

clear;clc
xdata=1:0.1:10; % X or Independant Data
ydata=sin(xdata+0.2)+0.5*sin(0.3*xdata+0.3)+ 2*sin( 0.2*xdata+23 )+...
    0.7*sin( 0.34*xdata+12 )+.76*sin( .23*xdata+.3 )+.98*sin(.76 *xdata+.56 )+...
    +.34*sin( .87*xdata+.123 )+.234*sin(.234 *xdata+23 ); % Y or Dependant data 
x0 = randn(36,1);  % Initial Guess
fun = @(x,xdata)x(1)*sin(x(2)*xdata+x(3))+... 
                x(4)*sin(x(5)*xdata+x(6))+...
                x(7)*sin(x(8)*xdata+x(9))+...
              x(10)*sin(x(11)*xdata+x(12))+...
              x(13)*sin(x(14)*xdata+x(15))+...
              x(16)*sin(x(17)*xdata+x(18))+...
              x(19)*sin(x(20)*xdata+x(21))+...
              x(22)*sin(x(23)*xdata+x(24))+...
              x(25)*sin(x(26)*xdata+x(27))+...
              x(28)*sin(x(29)*xdata+x(30))+...
              x(31)*sin(x(32)*xdata+x(33))+...
              x(34)*sin(x(35)*xdata+x(36)); % Goal function which is Sum of 12 sines
options = optimoptions('lsqcurvefit','Algorithm','trust-region-reflective');% Options for fitting 
x=lsqcurvefit(fun,x0,xdata,ydata) % the main instruction
times = linspace(xdata(1),xdata(end));
plot(xdata,ydata,'ko',times,fun(x,times),'r-')
legend('Data','Fitted Sum of 12 Sines')
title('Data and Fitted Curve')

结果令人满意(到现在为止),如下图:

【讨论】:

    【解决方案2】:

    上述问题是,当我使用matlab fit 函数时,指定Sum of Sines 拟合的参数(例如fit(xdata,ydata,'sin6')),它很容易收敛到最优解,拟合结果如下所示:

    但是当我尝试使用自定义函数拟合相同的数据时,结果完全不令人满意,如下图所示:

    fun=@(x,xdata)a1*sin(b1*xdata+c1)+...+a6*sin(b6*xdata+c6); %Sum if Six Sines
    f=fit(xdata,ydata,fun);
    

    首先,我觉得这是 fit 指令,所以我尝试了其他指令,例如 lsqcurvefit ,它对某些数据运行良好,但一旦使用其他数据,它就开始表现不佳。 从 Maltab 文档中,我发现 Sum of Sine 拟合和 Fourier 拟合对起始点或初始点,或者拟合算法为第一次迭代的拟合参数(幅度、频率和相位)假定的值非常敏感。通过检查 Matlab 拟合工具箱 .m 文件,我注意到当您使用预定义的函数拟合时,matlab 做了一些巧妙的技巧来获取起点(例如 fit(x,y,'sin1'), or fit(x,y,'sin2'),... 但是当您选择输入自定义函数时,初始点是随机生成的!这个这就是为什么 Matlab 构建函数起作用而我的自定义函数拟合不起作用(即使我输入相同的函数)。 顺便说一句,Matlab 计算 ydata 的 FFT,并通过一些(似乎很贪婪)方法提取幅度、频率和相位的初始点(一个名为 startpt.m 的函数会这样做)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多