MATLAB lsqcurvefit给出的是直线而不是正弦曲线

lc8prwob  于 2022-11-24  发布在  Matlab
关注(0)|答案(2)|浏览(283)

我尝试使用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为中心的带有小振荡的直线。我已经尝试了不同的选择。我错过了什么?非常感谢

vcirk6k6

vcirk6k61#

lsqcurvefit似乎不能用于解决一般问题。
可以从非常接近的初始条件开始:

x0=[4 1/500 2];
x = lsqcurvefit(f,x0,t,sig_out),
plot(t,f(x,t))

然后你会看到你确实得到了一个类似的解。但是解算器仍然抱怨局部最小值。
如果你尝试其他的初始条件,你会发现无论你在什么初始条件下,结果系数几乎没有变化。这是一个迹象,说明求解器不能解决手头的问题。在某种程度上,这是可以预期的。2阶段是周期性的。3所以目标函数相对于阶段的变化将是周期性的。频率不是周期性的,但可以想象,改变频率也会导致目标函数发生振荡变化。这似乎超出了lsqcurvefit的设计范围。也许可以考虑先使用傅里叶变换或其他技术进行波形分析。

qv7cva1a

qv7cva1a2#

拟合正弦曲线总是很棘手的。有几种方法,但我最喜欢的一种(只使用内置函数)在MATLAB Central的答案中描述:正弦函数的曲线拟合
对于您的数据,它将如下所示:

yu = max(y);
yl = min(y);
yr = (yu-yl);                               % Range of ‘y’
yz = y-yu+(yr/2);

zti = find(diff(sign(yz)));                 % find zero crossings
zt = t(zti);

per = 2*mean(diff(zt));                     % Estimate period
ym = mean(y);                               % Estimate offset
fit = @(b,t)  b(1).*(sin(2*pi*t./b(2) + 2*pi/b(3))) + b(4);    % Function to fit
fcn = @(b) sum((fit(b,t) - y).^2);                             % Least-Squares cost function
s = fminsearch(fcn, [yr;  per;  -1;  ym])                      % Minimise Least-Squares

输出参数向量s(函数中b)的元素为:

  • s(1):正弦波振幅(单位:y
  • s(2):周期(单位为x
  • s(3):相位(相位为s(2)/(2*s(3)),单位为x
  • s(4):偏移量(以y为单位)

这将产生以下与原始数据的拟合:

figure;
plot(t,y,'--k','linewidth',3,'DisplayName','Original sine');
hold on;
plot(t,sig_out,'b','DisplayName','Noisy sine');
tp = linspace(min(t),max(t));
plot(tp,fit(s,tp), 'r','DisplayName','fitted sine');
grid on ; legend show

相关问题