我尝试使用lsqcurvefit
来拟合添加了一些干扰的正弦曲线:
A=3.75;
omega=2;
phi=2;
t=1:10000;
y=A*sin(omega*t/1000+phi);
noise1=(rand(1,10000)-0.5)*0.2;
noise2=0.1*sin(2*t);
sig_out=A*sin(omega*t/1000+(phi-0.5))+noise1+noise2;
figure;
plot(t,y);
hold on;
plot(t,sig_out);
grid on;
上面的代码创建了一个随机噪声、一个围绕理论曲线值的小振荡和一个相位,我已使用此代码执行拟合:
close all;
f=@(x,xdata) x(1)*sin(x(2)*xdata+x(3));
x0=[3.75 2 2];
%definiamo i limiti inferiore e superiore della regressione
lob=ones(1,10000)*x0(1)*1.05*-1;
upb=ones(1,10000)*x0(1)*1.05;
options=optimoptions('lsqcurvefit','Diagnostic','on','MaxIteration',1000000000,'Display','iter-detailed','FunctionTolerance',1e-100,'FiniteDifferenceType','central','StepTolerance',1e-100,'FiniteDifferenceStepSize',100);
[reg,EXITFLAG]=lsqcurvefit(f,x0,t,sig_out,lob,upb,options);
但输出只给我一条以0为中心的带有小振荡的直线。我已经尝试了不同的选择。我错过了什么?非常感谢
2条答案
按热度按时间vcirk6k61#
lsqcurvefit
似乎不能用于解决一般问题。可以从非常接近的初始条件开始:
然后你会看到你确实得到了一个类似的解。但是解算器仍然抱怨局部最小值。
如果你尝试其他的初始条件,你会发现无论你在什么初始条件下,结果系数几乎没有变化。这是一个迹象,说明求解器不能解决手头的问题。在某种程度上,这是可以预期的。2阶段是周期性的。3所以目标函数相对于阶段的变化将是周期性的。频率不是周期性的,但可以想象,改变频率也会导致目标函数发生振荡变化。这似乎超出了
lsqcurvefit
的设计范围。也许可以考虑先使用傅里叶变换或其他技术进行波形分析。qv7cva1a2#
拟合正弦曲线总是很棘手的。有几种方法,但我最喜欢的一种(只使用内置函数)在MATLAB Central的答案中描述:正弦函数的曲线拟合
对于您的数据,它将如下所示:
输出参数向量
s
(函数中b
)的元素为:s(1)
:正弦波振幅(单位:y
)s(2)
:周期(单位为x
)s(3)
:相位(相位为s(2)/(2*s(3))
,单位为x
)s(4)
:偏移量(以y
为单位)这将产生以下与原始数据的拟合: