Matlab实现最小二乘法的高斯牛顿迭代算法

一、算法解释

给定一组观测值(测量值)(x_{i},y_{i}),以及观测方程Y=H(x,\theta)+v,求\theta.

对任意给定的初值\theta_{0},观测方程在\theta_0处展开有

Y=H(\theta)+\frac{\partial H}{\partial\theta}|_{\theta=\theta_{0}}(\theta - \theta_{0})+o^{1}+v

也就是

 Y\approx H(\theta)+J(\theta_{0})(\theta - \theta_{0})+v

忽略高阶小量并记\theta-\theta_{0}=\Delta \theta; Y-H(\theta_{0})=\Delta Y; \frac{\partial H}{\partial\theta}|_{\theta=\theta_{0}}=J(\theta)

则可以把关于\theta的非线性最小二乘问题化为关于\Delta \theta的线性最小二乘问题

\Delta Y = J(\theta_{0})\Delta \theta+v

则可以采用线性最小二乘法的方法求得每一次迭代的\Delta \theta

\Delta \theta=[J^{T}J]^{-1}J^{T}DY

二、实例

已知数据集数据如下图所示

 已知数据点存于data.txt中,其中第一列是x,第二列是y数据。且已知数据点的表达式为下式

y=\theta_{1} \exp \left(-\frac{1392}{x}\right)+\frac{1}{\theta_{2} \exp \left(-\sqrt{\frac{\theta_{3}}{\theta_{4}+x}}\right)}=H(x,\theta)+0

其中有未知参数\theta_{1},\theta_{2},\theta_{3},\theta_{4}.

【问题】通过非线性最小二乘法的高斯牛顿算法对未知参数进行估计,误差保证在10^{-3}以内。

【求解】对观测矩阵H求雅可比矩阵

J(x,\theta))=\left[\begin{array}{llll} \frac{\partial y}{\partial \theta_{1}} & \frac{\partial y}{\partial \theta_{2}} & \frac{\partial y}{\partial \theta_{3}} & \frac{\partial y}{\partial \theta_{4}} \end{array}\right]=\left[\exp \left(-\frac{1392}{x}\right), \frac{-\exp \left(\sqrt{\frac{\theta_{3}}{\theta_{4}+x}}\right)}{\theta_{2}^{2}}, \frac{\exp \left(\sqrt{\frac{\theta_{3}}{\theta_{4}+x}}\right)}{\left.2 \theta_{2} \sqrt{\theta_{3}\left(\theta_{4}+x\right.}\right)}, \frac{-\exp \left(\sqrt{\frac{\theta_{3}}{\theta_{4}+x}}\right)\left(\frac{\theta_{3}}{\theta_{4}+x}\right)^{3 / 2}}{2 \theta_{2} \theta_{3}}\right]

编写Matlab代码实现高斯牛顿算法对参数迭代求解

%非线性最小二乘法,高斯牛顿法进行迭代求解
clc
clear

theta0 = [1;1;1;1];
data=importdata('data.txt');
length = size(data);

%牛顿迭代法求解
e = 1e-3; thetak=theta0; k=0;
Y = data(:,2);
H = [];       
J = [];

while 1>0
    k = k+1;
    for i=1:length(1)
        H(i) = funy(thetak,data(i,1));
        J(i,:) =  funJ(thetak,data(i,1));
    end
    DY = Y - H';
    Dtheta = inv(J'*J) * J'*DY;
    
    thetak1 = thetak+Dtheta;
    %判断是否跳出迭代
    if Dtheta < e
        break
    end  
    thetak = thetak1;
end

disp('迭代的次数k为:')
disp(k)
disp('近似最优解θ为:')
disp(thetak1)

% tk1=[0.0098;1158.8;11.225;63.892];
yls = [];
for i=1:length
    yls(i) = thetak1(1)*exp(-1392/data(i,1)) +...
             1 / (thetak1(2)*exp(-sqrt(thetak1(3)/(thetak1(4)+data(i,1)))));
end
plot(data(:,1),yls,'*')
hold on 
plot(data(:,1),data(:,2))
hold off
xlabel('x');ylabel('y');


function H=funJ(tk,x)
H = [exp(-1392/x) ...
    -exp(sqrt(tk(3)/(tk(4)+x)))/(tk(2)^2) ...
    exp(sqrt(tk(3)/(tk(4)+x)))  /  ( 2 * tk(2) * sqrt( tk(3) * (tk(4)+x) ) ) ...
    -exp(sqrt(tk(3)/(tk(4)+x))) * (tk(3)/(tk(4)+x))^(3/2) /  (2 * tk(2) * tk(3) ) ];%1*4
end


function y=funy(theta,x)
    y = theta(1)*exp(-1392/x)+1/(theta(2)*exp(-sqrt(theta(3)/(theta(4)+x))));
end

求解结果

命令行窗口:

迭代的次数k为:
    16

近似最优解θ为:
   1.0e+03 *

    0.0000
    1.1588
    0.0112
    0.0639

这里参数θ的精确值为

0.009763268177082

1.158759625196295e+03

11.225544366770176

63.894293303247480

拟合结果图像:

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最小二乘法高斯牛顿法都是用来求解非线性最小二乘问题的方法。下面是MATLAB代码实现最小二乘法: ```matlab function [x,resnorm,residual,exitflag,output] = mylsqnonlin(fun,x0,lb,ub,options,varargin) % fun: 目标函数 % x0: 初始解 % lb: 下界 % ub: 上界 % options: 选项 % 设置默认选项 defaultopt = struct('Display','final','TolX',1e-6,'TolFun',1e-6,'MaxIter',400,'MaxFunEvals',10000); if nargin == 5 options = []; end options = setdefaultoptions(options,defaultopt); % 求解 [x,resnorm,residual,exitflag,output] = lsqnonlin(fun,x0,[],[],options,varargin{:}); end ``` 高斯牛顿法: ```matlab function [x,resnorm,residual,exitflag,output] = mylsqnonlin_gn(fun,x0,lb,ub,options,varargin) % fun: 目标函数 % x0: 初始解 % lb: 下界 % ub: 上界 % options: 选项 % 设置默认选项 defaultopt = struct('Display','final','TolX',1e-6,'TolFun',1e-6,'MaxIter',400,'MaxFunEvals',10000); if nargin == 5 options = []; end options = setdefaultoptions(options,defaultopt); % 求解 [x,resnorm,residual,exitflag,output] = lsqnonlin(fun,x0,[],[],options,varargin{:},'Jacob',@myjacobian); end function J = myjacobian(x,varargin) % 计算雅克比矩阵 % x: 当前解 % varargin: 其他参数 % 计算偏导数 J = zeros(length(varargin{1}),length(x)); h = 1e-8; for i = 1:length(x) x1 = x; x1(i) = x1(i) + h; f1 = feval(varargin{:},x1); x1(i) = x1(i) - 2*h; f2 = feval(varargin{:},x1); J(:,i) = (f1 - f2) / (2*h); end end ``` 其中,`mylsqnonlin`和`mylsqnonlin_gn`分别是最小二乘法高斯牛顿法的函数实现,`fun`是目标函数,`x0`是初始解,`lb`和`ub`是变量下界和上界,`options`是选项参数。在高斯牛顿法中,需要计算雅克比矩阵,可以通过`myjacobian`函数实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值