Matlab 非线性迭代法(3)阻尼牛顿法 L-M

高斯牛顿法详解_我只是一只自动小青蛙的博客-CSDN博客

一、思想

先看一下牛顿高斯迭代法的缺点:

1、在计算的过程中可能会出现奇异矩阵(不满秩),比如:J(k)​)TJ(k) 为病态矩阵的时候就不能得到正确的解,或者在求inv((J(k)​)TJ(k) )的时候不可逆,那么这个就无法在计算下去了​

2、当Δxk的过大的时候可能会导致,x(k+1)=x(k)+Δxk ​迭代不准确,算法不收敛

因此:在这个基础上提出了置信区间u

 对于病态矩阵,L-M提出了采用系数矩阵阻尼的方法来改造矩阵J(k)​)TJ(k)使得算法能计算下去。

二、步骤

1、初始值设定 u 和系数初始值 a  b  c d 

2、计算(Jf'*Jf  +uI)delta_x=Jf'f(x) ,解出delta_x,

3、判断精度

4、xk=xk+delta_x

5、判断p 并迭代出新的u

p>0.75  u=2u  

p<0.25  u=0.5u

当ρ接近1时,近似效果好;
当ρ 太小时,实际减小的值远小于近似函数减小的值,近似效果差,需要缩小近似范围μ 
当ρ较大时,实际减小的值大于近似函数减小的值,近似效果差,需要增大近似范围μ 
 

% L-M 迭代算法 
close all;
clear ;
clc;
% y(i)=a*exp(-(x(i)-b).^2/c.^2)+0.1*rand(1); 函数模型
% 在拟合数据的时候用的系数是
% a=1;
% b=4;
% c=10;
% 因此在拟合参数的时候,这里用 a=0.866
a=0.966;
b=3.98;
c=9.98;
d=0;
% 设置优化半斤
u=0.001;

segma=0.0000000001;% 精度
iterator_num=100;% 最大跌代次数
x=load('x.mat');
act_x=x.x;
y=load('y.mat');
len=length(act_x);
jacobian_d=ones(len,1);
I=ones(4,4);
act_y=y.y;
plot(act_x,act_y,'.');
hold on;
for i=1:iterator_num
  % 计算误差
    y=a*exp(-(act_x-b).^2/c.^2)+d;
    r=act_y-y;
    % 开始计算偏导数矩阵
    jacobian_a=exp(-(act_x - b).^2/c.^2);
    jacobian_b=(a*exp(-(act_x - b).^2/c.^2).*(2.*act_x - 2*b))/c.^2;
    jacobian_c=(2*a*exp(-(act_x - b).^2/c.^2).*(act_x - b).^2)/c.^3;
    % jacobian_d
    Jf=[jacobian_a,jacobian_b,jacobian_c,jacobian_d];
    gx=Jf'*r;
    %(Jf'*Jf  +uI)delta_abcd=Jf'f(x)
    % H =Jf'*Jf
    H=Jf'*Jf;
    delta_abcd=inv(Jf'*Jf+u.*I)*Jf'*r;
    %delta_abcd=inv(Jf'*Jf)*Jf'*r;
    %Jf'*Jf+u
    % g=H*delta_abc  增量方程
    if norm(delta_abcd)<segma
        break;
    end
    
    % 计算 pa pb pc pd 
    a_iterator=a+delta_abcd(1);
    b_iterator=b+delta_abcd(2);
    c_iterator=c+delta_abcd(3);
    d_iterator=d+delta_abcd(4);
    u=correction_p(act_x,delta_abcd,u,y,a_iterator,b_iterator,c_iterator,d_iterator,Jf);
    
    a=a_iterator;
    b=b_iterator;
    c=c_iterator;
    d=d_iterator;
end
it_y=a*exp(-(act_x-b).^2/c.^2)+d;
plot(act_x,it_y,'-');
legend('act','fit','Location','southoutside','Orientation','horizontal')

% 计算相关性
function  u=correction_p(act_x,delta,u,y,a,b,c,d,Jf)
 y_1=a*exp(-(act_x-b).^2/c.^2)+d;
 pp=Jf*delta;
 ys=y_1-y;
 p=ys\pp;
 if p>0.75
   x=2*u;
 elseif p<0.25
    x=0.5*u;
 end
 u=x;
end 

 

 

有误请指出共同探讨!!! 

猜你喜欢

转载自blog.csdn.net/weixin_39354845/article/details/130642106