牛顿迭代法其原理是通过泰勒展开的方式,将非线性方程线性化以方便求解。
首先是简单的一元非线性方程:设 f(x)为关于 x 的非线性函数,且在给定值 xk-1 附近连续可导,
对其进行泰勒展开,再通过 xk-1 对应函数值和导数求得增量,将增量叠加至估值上,反复
进行直至增量小于某个设定条件,即停止迭代。
%定义函数变量
对应程序:
%% 牛顿迭代(一元)
syms a
f(a) = a^(3/2) + 2^a - 24; %方程式(其待求解为 4)
df(a) = diff(f(a),a);
%% 牛顿迭代
x(1) = 0;
dt(1) = 1;
%对其一阶求导
%迭代赋初值
%迭代增量初值,任意值大于迭代停止条件即可
ii = 1;
while abs(dt(ii))>1e-3
%牛顿迭代,当增量小于 1E-3 停止迭代
ii = ii + 1;
dt(ii) = - f(x(ii-1))/df(x(ii-1));
x(ii) = x(ii-1) + dt(ii);
end
%% 绘图
figure
plot(x)
xlabel('\fontname{宋体}\fontsize{10}迭代次数');
ylabel('\fontname{宋体}\fontsize{10}迭代值');
grid on
对于多元非线性方程组,原理同样基于一元方程,只不过泰勒展开时需要对每个变量求偏微
分。
设多元方程组为 f(x,y,z,u)=v,其中 x,y,z 为待测未知量,u 为输入量(可能为一个也可能为多
个),v 为输出量。将其进行泰勒展开,化为矩阵的形式得到:
对其求解即为
对于超定方程(譬如 GPS 中的多颗卫星求解 4 个未知量),使用最小二乘法:
% 得到的观测量 1(输出量 1)
% 在测量点 2(1,2,2)处观测(输入量 2)
% 得到的观测量 2(输出量 2)
% 在测量点 1(3,2,4)处观测(输入量 1)
% 待测值 x,y,z (解为 3,2,1)观测点(输入量):xn yn zn
对应程序:
%% 牛顿迭代(多元)
%% 观测方程描述
syms x y z xn yn zn;
f(x,y,z,xn,yn,zn) = (x-xn)^2+(y-yn)^2+(z-zn)^2; % 观测方程(此处为三维距离平方)
f1(x,y,z) = f(x,y,z,3,2,4);
f1_result = f(3,2,1,3,2,4);
f2(x,y,z) = f(x,y,z,1,2,2);
f2_result = f(3,2,1,1,2,2);
f3(x,y,z) = f(x,y,z,7,2,3);
f3_result = f(3,2,1,7,2,3);
%% 方程描述(打印至主窗口)
XX=['观测方程:'];
disp(XX)
XX = [f1(x,y,z),f1_result;f2(x,y,z),f2_result;f3(x,y,z),f3_result];
disp(XX)
XX=['偏微分方程:'];
disp(XX)
% 在测量点 3(7,2,3)处观测(输入量 3)
% 得到的观测量 3(输出量 3)
G(x,y,z) = [diff(f1,x),diff(f1,y),diff(f1,z);diff(f2,x),diff(f2,y),diff(f2,z);diff(f3,x),diff(f3,y),diff(f3,z)]; %
求偏微分
disp(G(x,y,z))
%% 牛顿迭代
X(:,1) = [0,0,0]';
dt(1) = 1;
ii = 1;
while abs(dt(ii))>1e-3
%迭代赋初值
%迭代增量初值,任意值,大于迭代收敛条件
%牛顿迭代,当增量小于 1E-3 停止迭代
ii = ii + 1;
B
=
[f1_result-f1(X(1,ii-1),X(2,ii-1),X(3,ii-1));f2_result-f2(X(1,ii-1),X(2,ii-1),X(3,ii-1));f3_result-f3(X(1,ii-1)
,X(2,ii-1),X(3,ii-1))];
DX = inv(G(X(1,ii-1),X(2,ii-1),X(3,ii-1)))*B; % G*DX=B DX = inv(G)*B
X(:,ii) = X(:,ii-1) + DX;
% X = X(ii-1) + DX
dt(ii) = sqrt(DX(1)^2+DX(2)^2+DX(3)^2); %求增量平方和开根号,利用增量判断迭代停止
条件
end
%% 绘图
n = 1:ii;
figure
plot(n,X(1,:),n,X(2,:),n,X(3,:))
xlabel('\fontname{宋体}\fontsize{10}迭代次数');
ylabel('\fontname{宋体}\fontsize{10}迭代结果');
legend('X','Y','Z')
grid on