MATLAB中的曲线拟合,用于超过8项的正弦函数?

时间:2016-08-08 14:57:18

标签: matlab signal-processing curve-fitting

我试图在MATLAB中将一些数据拟合为正弦函数的总和,但是,MATLAB中正弦函数的项数是有限的,即。到1≤n≤8。但是,我想在我的拟合函数中有更多的术语,即超过50个术语。反正有没有让MATLAB将我的数据拟合到具有超过8个正弦项的正弦函数之和?为什么在MATLAB中存在这样的约束(技术上还是任意的)?是否有适合正弦函数的工具箱(特别是能够支持wieghted数据的东西)?

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

直到' sin8'或者' sin9'参数。

我感谢你的回答。

2 个答案:

答案 0 :(得分:0)

我在浏览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.

我发现使用Optimization Toolbox中的'lsqcurvefit'指令,自定义函数拟合比'fit'函数更可行,更容易。我测试了它以使我的数据与以下代码中的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')

结果令人满意(至今),如下所示:

result

答案 1 :(得分:0)

上面的问题是当我使用matlab fit函数时,使用Sum of Sines拟合的指定参数(例如fit(xdata,ydata,'sin6')),它很容易收敛到最优解,并且拟合结果是可以接受的如下: Image 1

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

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

Image 2

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