在 Matlab 中,我正在对一组点进行曲线拟合,这些点遵循幂律。如果我使用
'log(a*x^n)'
幂律作为 fittype 函数的主要参数,一切都会正常运行:
% input
x = [4 9 15 25 35 45 55 65 75 85 95 150 250 350 450 900];
y = [335 28 37 9 4 3.5 2 1 0.7 0.6 0.5 0.3 0.1 0.01 0.005 0.001];
% curve fitting
ft = fittype('log(a*x^n)','independent','x');
[fitresult, gof] = fit(x',log(y)',ft,'Startpoint', [1 -1]);
% plots
hold on
plot(x,y,'o-','Color','b')
plot(x,(fitresult.a .* (x.^fitresult.n)),'-','color','r')
set(gca, 'XScale', 'log', 'YScale', 'log');
但是,如果我在
fittype函数中向之前的幂律添加一个附加参数
b
(即 y 轴截距),即现在为 'log(a*x^n + b)'
...
% input
x = [4 9 15 25 35 45 55 65 75 85 95 150 250 350 450 900];
y = [335 28 37 9 4 3.5 2 1 0.7 0.6 0.5 0.3 0.1 0.01 0.005 0.001];
% curve fitting
ft = fittype('log(a*x^n + b)','independent','x');
[fitresult, gof] = fit(x',log(y)',ft,'Startpoint', [1 -1 1]);
% plots
hold on
plot(x,y,'o-')
plot(x,(fitresult.a .* (x.^fitresult.n)),'-')
set(gca, 'XScale', 'log', 'YScale', 'log');
我收到以下错误:
Error using fit>iFit
Complex value computed by model function, fitting cannot continue.
Try using or tightening upper and lower bounds on coefficients.
Error in fit (line 117)
[fitobj, goodness, output, convmsg] = iFit( xdatain, ydatain, fittypeobj, ...
Error in untitled6 (line 6)
[fitresult, gof] = fit(x',log(y)',ft,'Startpoint', [1 -1 1]);
我怎样才能解决这个错误并 - 一般来说 - 使 fittype 函数适用于包含 y 截距的记录幂律?
看起来在拟合过程中,Matlab 正在尝试 b
的
负值,这给出了对数的复杂结果。
为避免这种情况,请为
0
指定较低的 b
值。您可以使用 'lower'
中的 fit
可选输入来完成此操作。这需要为所有系数指定较低的值,因此对于其他系数使用 -inf
。
添加或修改的行标有
%%
:
% input
x = [4 9 15 25 35 45 55 65 75 85 95 150 250 350 450 900];
y = [335 28 37 9 4 3.5 2 1 0.7 0.6 0.5 0.3 0.1 0.01 0.005 0.001];
% curve fitting
ft = fittype('log(a*x^n + b)','independent','x');
ind_b = strcmp(coeffnames(ft), 'b'); %% index of 'b' coefficient
lower_values = -inf(1, numel(ind_b)); %% lower value -inf for all coefficients...
lower_values(ind_b) = 0; %% ...except for b, which has lower value 0
[fitresult, gof] = fit(x',log(y)',ft,'Startpoint', [1 -1 1],...
'lower',lower_values); %% use 'lower' option
% plots
hold on
plot(x,y,'o-')
plot(x,(fitresult.a .* (x.^fitresult.n)),'-')
set(gca, 'XScale', 'log', 'YScale', 'log');