先上实验效果,你觉得有帮助可以继续阅读。代码解析在B站有上传视频(用户昵称同名),代码也有详细备注。
拟合圆和球面:
拟合多元非线性函数:y = p1*x1+p2*x1^2+p3*x2+p4*x2^2+exp(-p5*x3)的拟合结果:
代码思路:数学原理不多赘述,网络上很多,我们主打实践。使用nlinfit命令,但是网络上它的说明不太易懂,结合案例就很明白了。
代码如下,需要自取哦:
案例一:拟合半圆
clc,clear,clf
%仿真必要参数输入
R = 10; %半径
DeltaR = 0.8; %正负误差
X0 = 2; %圆心横坐标
Y0 = -1; %圆心纵坐标
% 产生随机误差圆周数据
theta = rand(1,200)*2*pi;
rho=R+(rand(1,200)*2-1)*DeltaR;
x = rho.*cos(theta)+X0;
y = rho.*sin(theta)+Y0;
% 绘制随机误差圆数据
plot(x,y,'ro')
hold on
grid on
axis equal
% 数据标准化排序处理
x = x(:); y = y(:);
data=unique([x(:),y(:)],'rows');
MF=@(p,data)(data(:,1)-p(1)).^2+(data(:,2)-p(2)).^2-p(3)^2;
% 拟合
% 输入参数依次为:自变量,目标0,优化函数,初始值(起始点)
p=nlinfit(data,zeros(size(data,1),1),MF,[0 0 0]');
thetaf = linspace(0,2*pi,200);
rhof = p(3)*ones(1,200);
xf = rhof.*cos(thetaf)+p(1);
yf = rhof.*sin(thetaf)+p(2);
plot(xf,yf,'k-');
title(sprintf('圆心为(%f,%f),半径为%f',p(1),p(2),p(3)))
案例二:拟合球面
注:球坐标系符号规则如下:
clc,clear,clf
%仿真必要参数输入
R = 10; %半径
DeltaR = 0.8; %正负误差
X0 = 2; %圆心横坐标
Y0 = -1; %圆心纵坐标
Z0 = -2; %圆心纵坐标
% 产生随机误差圆周数据
phi = rand(1,200)*2*pi;
theta = (rand(1,200)*2-1)*pi;
rho=R+(rand(1,200)*2-1)*DeltaR;
x = rho.*cos(theta).*cos(phi)+X0;
y = rho.*cos(theta).*sin(phi)+Y0;
z = rho.*sin(theta)+Z0;
% 绘制随机误差圆数据
plot3(x,y,z,'ro')
hold on
grid on
axis equal
% 数据标准化排序处理
x = x(:); y = y(:); z = z(:);
data=unique([x(:),y(:),z(:)],'rows');
MF=@(p,data)(data(:,1)-p(1)).^2+(data(:,2)-p(2)).^2+(data(:,3)-p(3)).^2-p(4)^2;
% 拟合
% 输入参数依次为:自变量,目标0,优化函数,初始值(起始点)
p=nlinfit(data,zeros(size(data,1),1),MF,[0 0 0 0]');
%绘制球面
Rfit = p(4);
[X,Y,Z] = sphere;
Xfit = X * Rfit+p(1);
Yfit = Y * Rfit+p(2);
Zfit = Z * Rfit+p(3);
S = surf(Xfit,Yfit,Zfit);
S.EdgeColor = 'none';
S.FaceAlpha = 0.4;
title(sprintf('球心为(%f,%f,%f),半径为%f',p(1),p(2),p(3),p(4)))
案例三:拟合多元非线性函数
y = p1*x1+p2*x1^2+p3*x2+p4*x2^2+exp(-p5*x3)
clc,clear,clf
%自变量xi因变量y
x1 = (rand(1,100)*2-1)*5;
x2 = (rand(1,100)*2-1)*5;
x3 = (rand(1,100)*2-1)*5;
y = 0.2*x1+0.4*x1.^2+(-3)*x2.^2+exp(-0.1*x3);
%数据整理
x1 = x1(:);x2 = x2(:); x3 = x3(:); y = y(:);
data=unique([x1(:),x2(:),x3(:),y(:)],'rows');
%构造拟合函数,目标是0
MF=@(p,data)p(1)*x1+p(2)*x1.^2+p(3)*x2+p(4)*x2.^2+exp(-p(5)*x3)-y;
p=nlinfit(data,zeros(size(data,1),1),MF,[0 0 0 0 0]');%拟合的参数
%评价拟合结果
yfit = p(1)*x1+p(2)*x1.^2+p(3)*x2+p(4)*x2.^2+exp(-p(5)*x3);
xfit = 1:length(yfit);
Vfit = yfit-y;
avevfit = sum(Vfit)/length(Vfit);
%计算RMS
RMSfit = sqrt(sum((Vfit-avevfit).^2)/(length(Vfit)-1))
%绘制残差图
subplot(2,3,[4,5,6])
plot(xfit,Vfit,'ko')
title(sprintf('拟合残差RMS = %f x10^-^1^0',RMSfit*10^10))
%绘制自变量-因变量图
subplot(231)
plot(x1,y,'b.','LineWidth',1.5)
xlabel('x1')
ylabel('y')
subplot(232)
plot(x2,y,'b.','LineWidth',1.5)
xlabel('x2')
ylabel('y')
subplot(233)
plot(x3,y,'b.','LineWidth',1.5)
xlabel('x3')
ylabel('y')