You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MATLAB拟合正弦函数遇MaxFunEvals超限及NaN问题求助

MATLAB正弦函数拟合出现NaN及迭代次数超限问题

我尝试用以下MATLAB代码将数据集拟合成正弦函数:

data = importdata('analisipicco.txt') ;  
x = data(:,1) ; y = data(:,2) ; 
yu = max(y);
yl = min(y);
yr = (yu-yl);                               % Range of ‘y’
yz = y-yu+(yr/2);
zx = x(yz .* circshift(yz,[0 1]) <= 0);     % Find zero-crossings
per = 2*mean(diff(zx));                     % Estimate period
ym = mean(y);                               % Estimate offset

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

xp = linspace(min(x),max(x));

figure(1)
plot(x,y,'b',  xp,fit(s,xp), 'r')
grid

参数向量s(即函数中的b)各元素含义:

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

运行代码后,命令窗口报错:

Maximum number of function evaluations has been exceeded
         - increase MaxFunEvals option.
         Current function value: NaN 
s =

   1.0e+05 *

    1.0466
       NaN
   -0.0000
    2.4885

不确定是数据不适合正弦拟合,还是代码有问题,我的数据集如下:

-200 183966
-192 189734
-184 195724
-176 201663
-168 207557
-160 213278
-152 219000
-144 224677
-136 229500
-128 236024
-120 241968
-112 247787
-104 252963
-96 257491
-88 261967
-80 267373
-72 273494
-64 278599
-56 281476
-48 282610
-40 283097
-32 283839
-24 284971
-16 286169
-8  287164
0   287968
8   288561
16  288626
24  288107
32  286967
40  285132
48  282828
56  279847
64  276296
72  272299
80  268080
88  263564
96  258926
104 254052
112 248894
120 243694
128 238177
136 232665
144 227143
152 221959
160 216874
168 211678
176 206540
184 201537
192 196748
200 192091

我是MATLAB新手,恳请帮忙解答,谢谢!


问题分析与解决方案

  1. 拟合函数相位项的隐患
    原拟合函数中相位部分写为2*pi/b(3),当b(3)趋近于0时会触发无穷大计算,直接导致NaN。建议简化参数定义,把相位作为独立的弧度参数:
fit = @(b,x)  b(1).*sin(2*pi*x./b(2) + b(3)) + b(4);

此时s(3)直接代表相位(弧度),避免分母为0的风险,也符合常规正弦拟合的参数逻辑。

  1. 初始值估计偏差
    原代码通过零交叉点计算周期的方式不适用于当前单峰对称数据:你的x范围(-200到200)仅覆盖半个周期,导致per估计错误。手动设置更合理的初始值:
amp_guess = (max(y)-min(y))/2;  % 幅值应为峰值到偏移量的差值,而非全范围
period_guess = 800;
phase_guess = 0;
offset_guess = mean(y);
initial_guess = [amp_guess; period_guess; phase_guess; offset_guess];
  1. 迭代次数限制
    默认fminsearch的迭代次数不足以完成拟合,需通过参数设置扩容:
options = optimset('MaxFunEvals', 10000, 'MaxIter', 5000);
s = fminsearch(fcn, initial_guess, options);
  1. 数据适配性验证
    你的数据集是对称单峰曲线,完全符合余弦/相位偏移正弦函数的特征,不存在数据不适合拟合的问题。

修改后的完整代码

data = importdata('analisipicco.txt') ;  
x = data(:,1) ; y = data(:,2) ; 

% 合理估计初始参数
amp_guess = (max(y)-min(y))/2;
period_guess = 800;
phase_guess = 0;
offset_guess = mean(y);
initial_guess = [amp_guess; period_guess; phase_guess; offset_guess];

% 简化拟合函数,避免分母为0
fit = @(b,x)  b(1).*sin(2*pi*x./b(2) + b(3)) + b(4);
fcn = @(b) sum((fit(b,x) - y).^2);

% 设置迭代参数
options = optimset('MaxFunEvals', 10000, 'MaxIter', 5000);
s = fminsearch(fcn, initial_guess, options);

xp = linspace(min(x),max(x),1000);  % 增加点数让拟合曲线更平滑

figure(1)
plot(x,y,'b.',  xp,fit(s,xp), 'r-','LineWidth',1.5)
grid on
xlabel('x')
ylabel('y')
legend('原始数据','拟合曲线')

% 输出参数含义
fprintf('幅值: %.2f\n周期: %.2f\n相位(弧度): %.2f\n偏移量: %.2f\n', s(1), s(2), s(3), s(4));

内容的提问来源于stack exchange,提问作者Jack_01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:37:03