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

MATLAB中含x^d项的自定义拟合函数报错及结果不佳问题求助

MATLAB自定义广义伽马分布拟合问题解决建议

问题背景

尝试用带$x^d$项的广义伽马分布(形式为 $a \cdot x^d \cdot \exp\left(-\left(\frac{x-b}{c}\right)^2\right)$)拟合一组数据,高斯拟合正常,但自定义函数拟合遇报错,添加约束和初始值后参数无更新。

已做尝试

1. 高斯拟合成功

使用gauss1模型拟合以下数据:

  • data_x:
0   0.0500000000000000  0.100000000000000   0.150000000000000   0.200000000000000   0.250000000000000   0.300000000000000   0.350000000000000   0.400000000000000   0.450000000000000   0.500000000000000   0.550000000000000   0.600000000000000   0.650000000000000   0.700000000000000   0.750000000000000   0.800000000000000   0.850000000000000   0.900000000000000   0.950000000000000   1   1.05000000000000    1.10000000000000    1.15000000000000    1.20000000000000    1.25000000000000    1.30000000000000    1.35000000000000    1.40000000000000    1.45000000000000
  • data_y:
4.82569292042591    6.15748191498009    4.31807282776559    2.46795497033244    1.17871657319353    0.518857189303422   0.242237665610014   0.121149313175648   0.0619970738844184  0.0346663415427132  0.0237950093473137  0.0164594001463058  0.00944891489880517 0.00268227261643502 0.00288547508737706 0.00247907014549297 0.00195074372104365 0.00213362594489149 0.00174754125010160 0.00168658050881899 0.00140209704950012 0.00138177680240592 0.00146305779078274 0.00125985531984069 0.00111761359018126 0.00123953507274648 4.06404941884093e-05    0   0   0

代码:

fit_result = fit(data_x, data_y, 'gauss1');

得到系数:a1=5.79, b1=0.04453, c1=0.1165。

2. 自定义函数拟合报错

使用自定义广义伽马分布函数:

gamma_distribution = @(a, d, b, c, x) a * x.^d .* exp(-((x-b)/c).^2);
fit_result = fit(data_x, data_y, gamma_distribution);

报错:

Error using fit>iFit (line 340)
Inf computed by model function, fitting cannot continue.
Try using or tightening upper and lower bounds on coefficients.

3. 添加参数约束仍报错

添加上下限后代码:

gamma_distribution = @(a, d, b, c, x) a * x.^d .* exp(-((x-b)/c).^2);
fit_result = fit(data_x, data_y, gamma_distribution, 'Lower', [-10, -10, -10, -10], 'Upper', [10, 10, 10, 10]);

报错问题未解决。

4. 添加初始值后参数无更新

用高斯拟合结果作为初始值(d设为0):

gamma_distribution = @(a, d, b, c, x) a * x.^d .* exp(-((x-b)/c).^2);
fit_result = fit(data_x, data_y, gamma_distribution, 'Start', [5.79, 0, 0.04453, 0.1165], 'Lower', [-10, -10, -10, -10], 'Upper', [10, 10, 10, 10]);

运行成功但参数与初始值完全一致,d始终为0,拟合无改进。

解决建议

1. 修复函数的x=0处数值问题

当d<0时,x=0会导致0^d变成Inf,这是报错的核心原因。修改函数,对x=0做特殊处理:

gamma_distribution = @(a, d, b, c, x) a .* (x + eps).^d .* exp(-((x-b)/c).^2);

添加eps(MATLAB的极小值)避免x=0时出现Inf。

2. 优化参数约束范围

根据数据特征和物理意义缩小约束,避免参数进入无意义区间:

  • a:数据峰值在6左右,设Lower=0,Upper=10(y值均为正,a无需负数)
  • d:先尝试[-2,2]的合理范围,避免极端值
  • b:峰值在x=0.05附近,约束在[0, 0.5]
  • c:控制分布宽度,设[0.05, 0.5](必须为正,避免分母为0)

修改后的代码:

gamma_distribution = @(a, d, b, c, x) a .* (x + eps).^d .* exp(-((x-b)/c).^2);
fit_result = fit(data_x, data_y, gamma_distribution, ...
    'Start', [5.79, 0.5, 0.04453, 0.1165], ...  % 给d一个非0初始值,打破局部最优
    'Lower', [0, -2, 0, 0.05], ...
    'Upper', [10, 2, 0.5, 0.5]);

3. 更换拟合算法

默认拟合算法可能陷入局部最优,尝试用lsqcurvefit手动控制优化过程:

% 定义拟合函数
gamma_fun = @(params, x) params(1) .* (x + eps).^params(2) .* exp(-((x-params(3))/params(4)).^2);
% 初始参数
start_params = [5.79, 0.5, 0.04453, 0.1165];
% 参数约束
lb = [0, -2, 0, 0.05];
ub = [10, 2, 0.5, 0.5];
% 执行拟合
params_fit = lsqcurvefit(gamma_fun, start_params, data_x, data_y, lb, ub);
% 可视化拟合结果
y_fit = gamma_fun(params_fit, data_x);
plot(data_x, data_y, 'o', data_x, y_fit, '-');
legend('原始数据', '拟合曲线');

4. 数据预处理

x≥1.35后y值为0,这些无效点会干扰拟合,可只保留x∈[0,1.3]的数据进行拟合:

valid_idx = data_x <= 1.3;
data_x_valid = data_x(valid_idx);
data_y_valid = data_y(valid_idx);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:18:14