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中,可以利用以下代码来实现非线性方程组最小二乘法的计算: function [x, resnorm, residual, exitflag, output, lambda, jacobian] = lsqnonlin(fun,x0,LB,UB,options,varargin) 其中,fun是需要求解的非线性方程组,x0是变量的初始值,LB和UB是变量的上下界,options是优化选项,varargin是额外的参数。该函数将求解结果返回给x、resnorm、residual、exitflag、output、lambda和jacobian这七个变量。 而高斯牛顿最小二乘法matlab代码实现如下: function [x,resnorm,residual,exitflag,output,lambda,jacobian] = lsqnonlin(FUN,x0,lb,ub,options,varargin) % FUN - function handle % x0 - starting point % lb - lower bound % ub - upper bound % options - optimization options % varargin - additional arguments for function handle % x - solution vector % resnorm - residual norm squared % residual - residual vector % exitflag - optimization exit flag % output - optimization output % lambda - Lagrange multipliers % jacobian - Jacobian matrix % Initialize variables x = x0; resnorm = Inf; exitflag = -1; lambda = []; jacobian = []; % Run optimization until successful or maximum number of iterations is reached for iter = 1:options.MaxIter [F,J] = feval(FUN,x,varargin{:}); residual = F; resnorm = norm(residual,2)^2; % Check for successful optimization if resnorm <= options.TolFun exitflag = 1; output.iterations = iter; break; end % Compute next point using Gauss-Newton update p = -(J'*J)\(J'*residual); x = x + p; % Project onto feasible region if ~isempty(lb) x(x < lb) = lb(x < lb); end if ~isempty(ub) x(x > ub) = ub(x > ub); end end % Return Lagrange multipliers and Jacobian matrix if nargout > 5 lambda = (-J'*J)\(J'*residual); end if nargout > 6 jacobian = J; end % Create output structure if exitflag ~= 1 output.iterations = iter; end output.funcCount = iter; output.algorithm = 'Gauss-Newton'; output.message = sprintf('Optimization terminated.'); % Display warning if maximum number of iterations is reached if iter == options.MaxIter && exitflag ~= 1 warning('lsqnonlin:MaxIterReached','Maximum number of iterations reached without convergence.'); end 该代码使用了feval函数来求解非线性方程组,使用了高斯牛顿法求解最小化问题。其中,options是优化选项,可以设置包括最大迭代次数、函数值容许误差等多个参数。函数返回求解的解向量x,残差的平方和resnorm,残差向量residual,退出标志exitflag,优化输出output,拉格朗日乘数lambda和雅各比矩阵jacobian。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值