非线性曲线拟合是已知输入向量xdata和输出向量ydata,并且知道输入与输出的函数关系为ydata=F(x, xdata),但不知道系数向量x。今进行曲线拟合,求x使得输出的如下最小二乘表达式成立:
例 1
拟合如下非线性函数
函数曲线如下所示。
fit_fun.m
function diff = fit_fun(param, X)
a = param(1);
m = param(2);
c = param(3);
diff = c + 1./(1 + X.*a).^m;
main.m,调用lsqcurvefit函数,完成非线性数据拟合。
clear all;
close all;
clc;
X = 0:0.01:50;
a = 0.15;
m = 1.8;
c = 0.1;
Y = c + 1./(1 + X.*a).^m;
param_0 = [1 1 1];
param = lsqcurvefit(@fit_simp, param_0, X, Y)
Y_new = param(3) + 1./(1 + X.*param(1)).^param(2);
plot(X, Y, '*r', X, Y_new, 'b');
拟合结果如下:
>> x = 0.1500 1.8000 0.1000
例 2
拟合如下三维曲线
fun.m
function diff = fit_simp(param, Xin)
a = param(1);
b = param(2);
m = param(3);
c = param(4);
x = Xin(:, 1);
y = Xin(:, 2);
diff = c + 1./(1 + x.*a + y.*b).^m;
main.m
xdata = 0:1:50;
ydata = 0:1:40;
Xin = zeros(length(xdata),2);
Xin(:, 1) = xdata;
Xin(:, 2) = linspace(min(ydata), max(ydata), length(xdata));
a = 0.15;
b = 0.1;
m = 1.8;
c = 0.1;
zdata = c + 1./(1 + Xin(:, 1).*a + Xin(:, 2).*b).^m;
param0 = [1 1 1 1];
param = lsqcurvefit(@fit_simp_3, param0, Xin, zdata)
Z_new = param(4) + 1./(1 + Xin(:, 1).*param(1) + Xin(:, 2).*param(2)).^param(3);
plot3(Xin(:,1), Xin(:,2), zdata - Z_new, '-*b');
拟合结果为:
>> param = [ 6.3753 -7.7816 1.8 0.1]
拟合残差如图所示。由图可知残差非常小,说明拟合效果理想。
注:由于初始参数的设置问题,拟合出的参数与实际参数并不一致, 这是因为lsqcurvefit求解的并不是全局最优解,而是局部最优。