首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用MATLAB进行曲线拟合,对于一个大于8个项的正弦函数?

用MATLAB进行曲线拟合,对于一个大于8个项的正弦函数?
EN

Stack Overflow用户
提问于 2016-08-08 14:57:18
回答 2查看 4.3K关注 0票数 2

我试图将一些数据拟合成MATLAB中的正弦函数之和,但是MATLAB中的正弦函数项的数目是有限的,即1≤n≤8,但是,在拟合函数中需要更多的项,即超过50项。是否要用MATLAB将我的数据拟合成一个正弦函数之和,其中有超过8个正弦项?为什么MATLAB中存在这样的约束(技术上还是任意的)?是否有适合正弦函数的工具箱(特别是能够支持访问数据的工具)?

代码语言:javascript
复制
>f = fit(X,Y, 'sin10')
>Error using fittype>iCreateFromLibrary (line 412)
>Library function sin10 not found.

可以使用“sin8”或“sin9”参数。

我很感激你的回答。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-16 17:09:03

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

但是,当我试图使用常规定义的函数来拟合相同的数据时,结果一点也不令人满意,如图中所示:

代码语言:javascript
复制
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'),...,但当您选择ti进入自定义函数时,初始点是随机生成的!这就是为什么Matlab构建函数可以工作,而我的自定义函数拟合不能工作的原因(尽管我输入了相同的函数)。顺便说一句,Matlab计算ydata的FFT,并通过某种(似乎贪婪的)方法提取幅值、频率和相位的初始点(称为startpt.m的函数这样做)。

票数 1
EN

Stack Overflow用户

发布于 2016-08-10 13:30:19

在浏览MATLAB帮助时,我意外地找到了我的问题的解决方案。我贴出这个答案是希望能帮助那些有同样问题的人。

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

代码语言:javascript
复制
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.

我发现,使用优化工具箱中的“lsq弧度”指令,定制函数拟合比“fit”函数更可行、更容易。我在下面的代码中测试了它,使我的数据符合12 (>8) sines的总和:

代码语言:javascript
复制
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')

结果令人满意(到目前为止),如下所示:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38832474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档