牛顿法,高斯牛顿法,列文伯格-马夸尔特(LM)法

news2024/10/6 6:05:09

文章目录

    • 一:牛顿法 (Newton's method)
      • 1:概述
      • 2:牛顿方向与牛顿法
      • 3:牛顿法的基本步骤
      • 4:举例
    • 二:高斯牛顿法 (Gauss–Newton algorithm)
      • 1:概述
      • 2:高斯牛顿法推导
      • 3:高斯牛顿法算法流程
      • 4:高斯牛顿法 C++ 代码
    • 三:列文伯格-马夸尔特法(Levenberg-Marquardt algorithm)
      • 1:概述
      • 2:LM算法流程
      • 3:列文伯格-马夸尔特法 C++ 代码
    • 四:总结


个人笔记:
牛顿(Newton) 法、高斯牛顿(GaussNewton)法、Levenberg-Marquardt(LM)算法等。结合自己需要实现功能的目的,下面主要给出推导结果、代码实现和实际一些应用。推导过程最后会放一些个人参考的一些文章和资料。

一:牛顿法 (Newton’s method)

1:概述

牛顿法是一种函数逼近法,它的基本思想是:在极小点附近用 x ( k ) x^{(k)} x(k)点的二阶泰勒多项式来近似目标函数 f ( x ) f(x) f(x),并用选代点 x ( k ) x^{(k)} x(k)处指向近似二次函数的极小点方向作为搜索方向 p ( k ) p^{(k)} p(k)
设规划问题 : m i n f ( x ) , x ∈ R n min f(x),x∈R^n minf(x),xRn
其中 f ( x ) f(x) f(x)在点 x ( k ) x^{(k)} x(k)处具有二阶连续偏导数,黑森矩阵 ▽ 2 f ( x ( k ) ) ▽^2f(x^{(k)}) 2f(x(k))正定。
现已有 f ( x ) f(x) f(x)极小点的第 k k k级估计值 x ( k ) x^{(k)} x(k),并将 f ( x ) f(x) f(x)作二阶泰勒展开:
在这里插入图片描述其中主要的是前三项,最后一项为高阶无穷小。

2:牛顿方向与牛顿法

记上式中的主要部分为:
在这里插入图片描述

x ( k ) x^{(k)} x(k)附近可用 Q ( x ) Q(x) Q(x)来近似 f ( x ) f(x) f(x), Q ( x ) ≈ f ( x ) Q(x) ≈ f(x) Q(x)f(x)
故可以用 Q ( x ) Q(x) Q(x)的极小点来近似 f ( x ) f(x) f(x)的极小点,求 Q ( x ) Q(x) Q(x)的驻点:
在这里插入图片描述

由梯度 ▽ Q ( x ) = 0 ▽Q(x) = 0 Q(x)=0 Q ( x ) Q(x) Q(x)的平稳点 x ( k + 1 ) x^{(k+1)} x(k+1) p ( k ) p^{(k)} p(k)是牛顿方向,步长为 1 1 1

在这里插入图片描述
也就是下面描述,其中 H H H是黑塞矩阵
在这里插入图片描述

3:牛顿法的基本步骤

1:选取初始数据:初始点 x ( 0 ) x^{(0)} x(0),终止条件 ε > 0 ε>0 ε>0,令 k : = 0 k:=0 k:=0
2:求梯度向量 ▽ f ( k ) ▽f^{(k)} f(k),并计算 ∣ ∣ ▽ f ( k ) ∣ ∣ ||▽f^{(k)}|| f(k):

∣ ∣ ▽ f ( k ) ∣ ∣ < ε ||▽f^{(k)}||<ε f(k)<ε,停止选代,输出 x ( k ) x^{(k)} x(k),否则转下一步。

3:构造牛顿方向:
在这里插入图片描述
4:算法迭代:

计算 x ( k + 1 ) = x ( k ) + p ( k ) x^{(k+1)} = x^{(k)} + p^{(k)} x(k+1)=x(k)+p(k),以 x ( k + 1 ) x^{(k+1)} x(k+1)作为下一轮迭代点,令 k : = k + 1 k := k+1 k:=k+1,转第2步。

4:举例

试用牛顿法求函数 f ( x ) = x 1 2 + 25 x 2 2 f(x) = x_1^2 + 25x_2^2 f(x)=x12+25x22 的极小点,其中初始点为 x ( 0 ) = ( 2 , 2 ) T x^{(0)} = (2, 2)^T x(0)=(2,2)T, ε = 1 0 − 6 ε = 10^{-6} ε=106.
解(1)求梯度和黑塞矩阵:
在这里插入图片描述

(2)确定牛顿方向:
在这里插入图片描述即: x 1 = 0 , x 2 = 0 x_1 = 0,x_2=0 x1=0x2=0

这里使用三维坐标系来查看 x 1 = 0 , x 2 = 0 x_1 = 0,x_2=0 x1=0x2=0存在极值
在这里插入图片描述

二:高斯牛顿法 (Gauss–Newton algorithm)

1:概述

高斯-牛顿算法用于求解非线性最小二乘问题,相当于最小化函数值的平方和。它是牛顿求非线性函数最小值方法的扩展。由于平方和必须是非负的,因此该算法可以看作是使用牛顿法迭代地逼近和的零点,从而使和最小化。它的优点是不需要计算可能具有挑战性的二阶导数(也就是黑塞矩阵)。
这里说一下,牛顿法使用黑塞矩阵有个缺点:计算量特别大。高斯牛顿法是在牛顿法的基础上用雅可比矩阵代替了黑森矩阵。

注意:高斯牛顿法针对非线性最小二乘问题。最小二乘详解

2:高斯牛顿法推导

①:目标函数问题:自变量 x x x 经过模型函数得出因变量 y y y m m m个观测点:
X = [ x 1 , x 2 , . . . x m ] T X=[x_1,x_2,...x_m]^T X=[x1,x2,...xm]T Y = [ y 1 , y 2 , . . . y m ] T Y=[y_1,y_2,...y_m]^T Y=[y1,y2,...ym]T
②:模型函数: Y = f ( X ; β 1 , β 2 , . . . , β n ) Y = f(X;β_1,β_2,...,β_n) Y=f(X;β1,β2,...,βn) => f ( x ; β ) f(x;β) f(x;β)

其中 x x x 是自变量 , y y y 是因变量, β β β 是目标参数。 x 和 y x和y xy是已知的,优化 β β β 目标参数。

③:优化目标函数: m i n S = ∑ i = 1 n ( f ( x i ; β ) − y i ) 2 min S = \displaystyle\sum_{i=1}^{n}(f(x_i;β)-y_i)^2 minS=i=1n(f(xi;β)yi)2
④:第 i i i 次观测点的预测偏差: r i = f ( x i ; β ) − y i ) 2 r_i = f(x_i;β)-y_i)^2 ri=f(xi;β)yi)2,那么每次的偏差组成一个向量形式: R = [ r 1 , r 2 , . . . r m ] T R = [r_1,r_2,...r_m]^T R=[r1,r2,...rm]T
⑤:对于③目标函数 可以写成: m i n S = ∑ i = 1 n r i 2 = R T R min S = \displaystyle\sum_{i=1}^{n}r_i^2 = R^TR minS=i=1nri2=RTR
⑥:那么目标函数梯度: ▽ S ( β ) = [ ∂ S ∂ β 1 , ∂ S ∂ β 2 , . . . , ∂ S ∂ β n ] T ▽S(β) = [\frac{\partial S}{\partial β_1},\frac{\partial S}{\partial β_2},...,\frac{\partial S}{\partial β_n}]^T S(β)=[β1S,β2S,...,βnS]T,其中对每个参数 β j β_j βj 求偏导 ∂ S ∂ β j = 2 ∑ i = 1 m r i ∂ r i ∂ β j \frac{\partial S}{\partial β_j} = 2 \displaystyle\sum_{i=1}^{m}r_i\frac{\partial r_i}{\partial β_j} βjS=2i=1mriβjri

⑦:对于 R = [ r 1 , r 2 , . . . r m ] T 和 β R = [r_1,r_2,...r_m]^T和β R=[r1,r2,...rm]Tβ的偏导形式就可以写成 雅可比矩阵

J ( R ( β ) ) = [ ∂ r 1 ∂ β 1 . . . ∂ r 1 ∂ β n ⋮ ⋱ ⋮ ∂ r m ∂ β 1 . . . ∂ r m ∂ β n ] J(R(β)) = \begin{bmatrix} \frac{\partial r_1}{\partial β_1}&...&\frac{\partial r_1}{\partial β_n}\\ \vdots & \ddots & \vdots \\ \frac{\partial r_m}{\partial β_1}&...&\frac{\partial r_m}{\partial β_n}\end{bmatrix} J(R(β))=β1r1β1rm......βnr1βnrm

⑧:目标函数梯度(一阶偏导): ▽ S ( β ) = [ ∂ S ∂ β 1 , ∂ S ∂ β 2 , . . . , ∂ S ∂ β n ] T = > ∂ S ∂ β j = 2 ∑ i = 1 m r i ∂ r i ∂ β j = > ▽ S = 2 J T R ▽S(β) = [\frac{\partial S}{\partial β_1},\frac{\partial S}{\partial β_2},...,\frac{\partial S}{\partial β_n}]^T => \frac{\partial S}{\partial β_j} = 2 \displaystyle\sum_{i=1}^{m}r_i\frac{\partial r_i}{\partial β_j} => ▽S = 2J^TR S(β)=[β1S,β2S,...,βnS]T=>βjS=2i=1mriβjri=>S=2JTR
⑨:求目标函数黑塞矩阵(二阶偏导):
由梯度向量元素 ∂ S ∂ β j = 2 ∑ i = 1 m r i ∂ r i ∂ β j \frac{\partial S}{\partial β_j} = 2 \displaystyle\sum_{i=1}^{m}r_i\frac{\partial r_i}{\partial β_j} βjS=2i=1mriβjri 到黑塞矩阵元素 ∂ 2 S ∂ β k ∂ β j = 2 ∂ ∂ β k ( ∑ i = 1 m r i ∂ r i ∂ β j ) \frac{\partial ^2S}{\partial β_k\partial β_j} = 2\frac{\partial }{\partial β_k} (\displaystyle\sum_{i=1}^{m}r_i\frac{\partial r_i}{\partial β_j}) βkβj2S=2βk(i=1mriβjri)
应用链式法则得: ∂ 2 S ∂ β k ∂ β j = 2 ∑ i = 1 m ( ∂ r i ∂ β k ∂ r i ∂ β j + r i ∂ 2 r i ∂ β k ∂ β j ) \frac{\partial ^2S}{\partial β_k\partial β_j} = 2 \displaystyle\sum_{i=1}^{m}(\frac{\partial r_i}{\partial β_k}\frac{\partial r_i}{\partial β_j} + r_i\frac{\partial^2 r_i}{\partial β_k\partial β_j}) βkβj2S=2i=1m(βkriβjri+riβkβj2ri)
其中 O O O矩阵元素 : O k j = ∑ i = 1 m r i ∂ 2 r i ∂ β k ∂ β j O_{kj} = \displaystyle\sum_{i=1}^{m}r_i\frac{\partial^2 r_i}{\partial β_k\partial β_j} Okj=i=1mriβkβj2ri
黑塞矩阵: H = 2 ( J T J + O ) H = 2(J^TJ + O) H=2(JTJ+O)
⑩:写成牛顿法形式:如果模型比较好,其中 O O O矩阵 r i r_i ri是趋近于0的。这里就把 O O O矩阵忽略掉,方便计算。
在这里插入图片描述

3:高斯牛顿法算法流程

1:给定初始参数值 β 0 β_0 β0 (默认是为 1 1 1 的向量)。设 ε = 1 − 10 ε = 1^{-10} ε=110
2:对于第 k k k 次选代,求出当前的雅可比矩阵 J ( β k ) J(β_k) J(βk) 和残差值 f ( β k ) f(β_k) f(βk)也就是 R R R
3:求解增量方程: H Δ β k = − g H\Delta β_k = -g HΔβk=g
=> Δ β k = − H − 1 g \Delta β_k= -H^{-1}g Δβk=H1g
=> Δ β k ≈ − ( J T J ) − 1 J T R \Delta β_k≈ -(J^TJ)^{-1}J^TR Δβk(JTJ)1JTR 。这里用雅可比矩阵 J T J J^TJ JTJ 近似黑塞矩阵 H H H
4:若 Δ β k < ε \Delta β_k<ε Δβk<ε ,则停止。否则,令 β k + 1 = β k + Δ β k β_{k+1} = β_k +\Delta β_k βk+1=βk+Δβk,返回第2步。

4:高斯牛顿法 C++ 代码

    //求雅克比矩阵
    template <class FunctionPredictedValue>
    MatrixXd Jacobi(const VectorXd& inVectorValue, const VectorXd& params,FunctionPredictedValue funPV)
    {
        int rowNum = inVectorValue.rows();
        int colNum = params.rows();

        MatrixXd Jac(rowNum, colNum);

        for (int i = 0; i < rowNum; i++)
        {
            for (int j = 0; j < colNum; j++)
            {
                Jac(i, j) = Deriv(inVectorValue, i, params, j,funPV);
            }
        }
        return Jac;
    }
    //残差值向量
    template <class FunctionPredictedValue>
    ArrayXd ResidualsVector(const VectorXd& inVectorValue, const VectorXd& outVectorValue,const VectorXd& params,FunctionPredictedValue funPV)
    {
        int dataCount = inVectorValue.rows();
        //保存残差值
        ArrayXd residual(dataCount);
        //获取预测偏差值 r= ^y(预测值) - y(实际值)
        for(int i=0;i<dataCount;++i)
        {
            //获取预测值
            double predictedValue = funPV(inVectorValue(i),params);
            residual(i) = predictedValue - outVectorValue(i);
        }
        return residual;
    }

    //求导
    template <class FunctionPredictedValue>
    double Deriv(const VectorXd& inVectorValue, int objIndex, const VectorXd& params,int paraIndex,FunctionPredictedValue funPV)
    {
        VectorXd para1 = params;
        VectorXd para2 = params;
        para1(paraIndex) -= DERIV_STEP;
        para2(paraIndex) += DERIV_STEP;

        double obj1 = funPV(inVectorValue(objIndex), para1);
        double obj2 = funPV(inVectorValue(objIndex), para2);

        return (obj2 - obj1) / (2 * DERIV_STEP);
    }

    /* 高斯牛顿法(GNA) 解决非线性最小二乘问题 确定目标函数和约束来对现有的参数优化
     */

    template <class FunctionPredictedValue>
    ArrayXd GaussNewtonAlgorithm(const ArrayXd & inVectorValue,const ArrayXd & outVectorValue,ArrayXd params,FunctionPredictedValue funPV,int maxIteCount = 1,double epsilon = 1e-10)
    {
        int k=0;
        //数据个数
        int dataCount = inVectorValue.size();
        // ε 终止条件
        //double epsilon = 1e-10;
        //残差值
        ArrayXd residual(dataCount);

        //found 为true 结束循环
        bool found = false;
        while(!found && k<maxIteCount)
        {
            //迭代增加
            k++;
            //获取预测偏差值 r= ^y(预测值) - y(实际值)
            residual = ResidualsVector( inVectorValue, outVectorValue,params, funPV);

            //求雅克比矩阵
            MatrixXd Jac = Jacobi(inVectorValue,params,funPV);

            // Δx = - (Jac^T * Jac)^-1 * Jac^T * r
            ArrayXd delta_x =  -  (((Jac .transpose() * Jac ).inverse()) * Jac.transpose() * residual.matrix()).array();

            qDebug()<<QString("高斯牛顿法:第 %1 次迭代 --- 精度:%2  ").arg(k).arg(delta_x.abs().sum());
            //达到精度,结束
            if(delta_x.abs().sum() < epsilon)
            {
                found = true;
            }

            //x(k+1) = x(k) + Δx
            params = params + delta_x;

        }
        return params;
    }

Matrix是Eigen库中的一个矩阵类,这里引入Eigen库方便代数运算。

三:列文伯格-马夸尔特法(Levenberg-Marquardt algorithm)

1:概述

在数学和计算中,Levenberg–Marquardt 算法(LMA或简称LM),也称为 阻尼最小二乘法( DLS ),用于解决非线性最小二乘法问题。这些最小化问题尤其出现在最小二乘 曲线拟合中。LMA 在高斯-牛顿算法(GNA) 和梯度下降法之间进行插值。LMA 更稳健比 GNA,这意味着在许多情况下,即使它开始时离最终最小值很远,它也能找到解决方案。对于性能良好的函数和合理的启动参数,LMA 往往比 GNA 慢。LMA 也可以被视为使用信赖域方法的高斯-牛顿。
LMA 在许多软件应用程序中用于解决一般曲线拟合问题。通过使用高斯-牛顿算法,它通常比一阶方法收敛得更快。然而,与其他迭代优化算法一样,LMA 只能找到局部最小值,不一定是全局最小值。与其他数值最小化算法一样,Levenberg–Marquardt 算法是一个迭代过程。要开始最小化,用户必须提供参数向量的初始猜测 β β β, 在只有一个最小值的情况下,一个不知情的标准猜测就像 β = [ 1 , 1 , . . . , 1 ] T β = [1,1,...,1]^T β=[1,1,...,1]T会工作得很好;在有多个最小值的情况下,只有当初始猜测已经有点接近最终解决方案时,算法才会收敛到全局最小值。

2:LM算法流程

1:给定初始参数值 β 0 β_0 β0 (默认是为 1 1 1 的向量)。初始 μ 0 μ_0 μ0的选择可以依赖于 H 0 = J ( β 0 ) T J ( β 0 ) H_0=J(β_0)^TJ(β_0) H0=J(β0)TJ(β0) 中的元素,一般我们选择 μ 0 = τ ∗ m a x i { H i i ( 0 ) } μ_0 =τ*max_i\{H_{ii}^{(0)}\} μ0=τmaxi{Hii(0)},一般 τ = 1 0 − 6 τ=10^{−6} τ=106,这里设置 ε 1 = 1 − 10 ε_1 = 1^{-10} ε1=110 ε 2 = 1 − 10 ε_2 = 1^{-10} ε2=110
2:若 ∣ ∣ g ∣ ∣ ∞ ≤ ε 1 ||g||_\infty≤ε_1 gε1 成立,则停止。
3:对于第 k k k 次选代,求出当前的雅可比矩阵 J ( β k ) J(β_k) J(βk) 和残差值 f ( β k ) f(β_k) f(βk)也就是 R R R
4:求解增量方程: ( H + μ k I ) Δ β k = − g (H+μ_kI)\Delta β_k = -g (H+μkI)Δβk=g
=> Δ β k = − ( H + μ k I ) − 1 g \Delta β_k= -(H+μ_kI)^{-1}g Δβk=(H+μkI)1g
=> Δ β k ≈ − ( J T J + μ k I ) − 1 J T R \Delta β_k≈ -(J^TJ+μ_kI)^{-1}J^TR Δβk(JTJ+μkI)1JTR 。这里用雅可比矩阵 J T J J^TJ JTJ 近似黑塞矩阵 H H H
5:若 ∣ ∣ Δ β k ∣ ∣ ≤ ε 2 ( ∣ ∣ β k ∣ ∣ + ε 2 ) ||\Delta β_k||≤ε_2(||β_k|| + ε_2) Δβkε2(βk+ε2) 成立,则停止。否则,令 β k + 1 = β k + Δ β k β_{k+1} = β_k +\Delta β_k βk+1=βk+Δβk
6: ρ = ∣ ∣ F ( β k ) ∣ ∣ 2 2 − ∣ ∣ F ( β k + Δ β k ) ∣ ∣ 2 2 L ( 0 ) − L ( Δ β k ) \rho = \frac{||F(β_k)||_2^2-||F(β_k+\Delta β_k)||_2^2}{L(0) - L(\Delta β_k)} ρ=L(0)L(Δβk)F(βk)22F(βk+Δβk)22,如果 ρ > 0 \rho >0 ρ>0,求出当前的黑塞矩阵 H ≈ J ( β k ) T J ( β k ) H ≈ J(β_k)^TJ(β_k) HJ(βk)TJ(βk) 和梯度 g = J ( β k ) T f ( β k ) g = J(β_k)^Tf(β_k) g=J(βk)Tf(βk)。若 ∣ ∣ g ∣ ∣ ∞ ≤ ε 1 ||g||_\infty≤ε_1 gε1 成立,则停止。更新 μ k μ_k μk μ k = μ k ∗ m a x { 1 3 , 1 − ( 2 ρ − 1 ) 3 } ; v = 2 μ_k =μ_k*max\{\frac{1}{3},1-(2\rho-1)^3\};v=2 μk=μkmax{31,1(2ρ1)3};v=2。如果 ρ ≤ 0 \rho ≤0 ρ0 μ k = μ k ∗ v ; v = 2 ∗ v μ_k =μ_k*v; v=2*v μk=μkv;v=2v

最终伪代码如下:

在这里插入图片描述

3:列文伯格-马夸尔特法 C++ 代码


		
       /* 列文伯格马夸尔特法(LMA) ==  使用信赖域的高斯牛顿法,鲁棒性更好, 确定目标函数和约束来对现有的参数优化
     */

    template <class FunctionPredictedValue>
    ArrayXd LevenbergMarquardtAlgorithm(const ArrayXd &inVectorValue,const ArrayXd & outVectorValue, ArrayXd params,FunctionPredictedValue funPV,int maxIteCount = 1,double epsilon = 1e-10)
    {
        //数据个数
        int dataCount = inVectorValue.size();
        // ε 终止条件
        //double epsilon = 1e-10;
        // τ
        double tau = 1e-6;
        //迭代次数
        int k=0;
        int v=2;

        //求雅可比矩阵
        MatrixXd Jac = Jacobi(inVectorValue,params,funPV);

        //用雅可比矩阵近似黑森矩阵
        MatrixXd Hessen = Jac .transpose() * Jac ;

        //获取预测偏差值 r= ^y(预测值) - y(实际值)
        //保存残差值
        ArrayXd residual = ResidualsVector(inVectorValue, outVectorValue,params,funPV);
        //梯度
        MatrixXd g = Jac.transpose() * residual.matrix();

        //found 为true 结束循环
        bool found = ( g.lpNorm<Eigen::Infinity>() <= epsilon );

        //阻尼参数μ
        double mu =  tau * Hessen.diagonal().maxCoeff();
        while(!found && k<maxIteCount)
        {
            k++;

            //LM方向  uI => I 用黑森矩阵对角线代替
            //MatrixXd delta_x = - (Hessen + mu*Hessen.asDiagonal().diagonal()).inverse() * g;

            MatrixXd delta_x = - (Hessen + mu*MatrixXd::Identity(Hessen.cols(), Hessen.cols())).inverse() * g;

            if( delta_x.lpNorm<2>() <= epsilon * (params.matrix().lpNorm<2>() + epsilon ))
            {
                qDebug()<<QString("LM:第 %1 次迭代 --- 精度:%2  ").arg(k).arg(delta_x.lpNorm<2>());
                found = true;
            }
            else
            {
                MatrixXd newParams = params + delta_x.array();

                //保存残差值
                ArrayXd residualOld(dataCount),residualNew(dataCount);
                //获取预测偏差值 r= ^y(预测值) - y(实际值) 旧值
                residualOld = ResidualsVector( inVectorValue, outVectorValue,params, funPV);
                //获取预测偏差值 r= ^y(预测值) - y(实际值) 新值
                residualNew = ResidualsVector( inVectorValue, outVectorValue,newParams, funPV);

                //ρ         (-(delta_x.transpose()*g) - 0.5*(delta_x.transpose() * Hessen * delta_x)).sum();
                double rho = (residualOld.pow(2).sum() - residualNew.pow(2).sum()) / (0.5*delta_x.transpose()*(mu * delta_x - g)).sum()  ;

                if(rho>0)
                {
                    params = newParams;
                    Jac = Jacobi(inVectorValue,params,funPV);
                    Hessen = Jac.transpose() * Jac ;
                    //获取预测偏差值 r= ^y(预测值) - y(实际值)
                    residual = ResidualsVector( inVectorValue, outVectorValue,params, funPV);
                    g = Jac.transpose() * residual.matrix();
                    found = ( g.lpNorm<Eigen::Infinity>() <= epsilon );
                    qDebug()<<QString("LM:第 %1 次迭代 --- 精度:%2  ").arg(k).arg(g.lpNorm<Eigen::Infinity>());
                    mu = mu* qMax(1/3.0 , 1-qPow(2*rho -1,3));
                    v=2;
                }
                else
                {
                    mu = mu*v;
                    v = 2*v;
                }
            }
        }
        return params;
    }

//FunctionPredictedValue 是一个自定义函数,可以定义自己的函数 规则
//设置规则,获取预测值 ==》自变量和参数
//曲线拟合函数
class CurveFittingFunction
{
public:

    double operator()(const double &inValue ,const ArrayXd &params)
    {
        double value=0;
        int paramsCount = params.rows();
        for(int i=0;i<paramsCount;++i)
        {
            //这里使用曲线方程 y = a1*x^0 + a2*x^1 + a3*x^2 + ...      根据参数(a1,a2,a3,...)个数来设置
            value += params(i) * qPow(inValue,i);
        }
        return value;
    }
};


四:总结

1:工具:主要Qt + Eigen库 + QCustomPlot类
Eigen库是一个用于矩阵计算,代数计算库
QCustomPlot类是一个用于绘图和数据可视化

2:上面完整代码已上传GitHub

3:参考文献
黑塞矩阵和雅可比矩阵理解
高斯牛顿法详解
LM算法详解
LM论文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/46044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

若依、多选框前后端处理,MyBatis处理多对多关系

背景 很经典的CRUD&#xff0c;整理下笔记。 后端 实体类 /*** 专业方向主键&#xff0c;用于下拉框搜索*/private Long disasterTypeId;/*** 专业方向*/private List<DisasterType> disasterType;业务层 /*** 新增专家信息库** param expertInfo 专家信息库* return 结…

mac pro M1(ARM)安装:php开发环境

0. 引言 最近在处理各个语言的加密算法&#xff0c;正好需要安装php环境&#xff0c;特此记录&#xff0c;以供后续参考 1. 安装php 1、安装php包管理工具composer brew install composer2、安装php brew install php # 同时可以指定版本安装 brew install php8.0 # 查…

基于Java+SpringBoot+Mybatis+Vue+ElementUi的航空公司电子售票系统

项目介绍 本系统是利用Spring Boot框架而设计的一款结合用户的实际情况而设计的平台&#xff0c;前端利用VUE技术开发&#xff0c;将可供教师和管理员来使用的所有界面来显示出来&#xff0c;利用Java语言技术来编程实现用户和管理员所执行的各类操作业务逻辑&#xff0c;以My…

在MacOS上实现两个网络调试助手的UDP通信测试

文章目录一、背景二、网络调试助手软件三、UDP通信过程一、背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信。 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试。 二、网络调试助手软件 我使用的网络调试助手软件是&#xff1a;网络调试助…

Revit 中参数化多边形的画法?

Revit 中参数化多边形的画法 问题提出 :在 Revit 中&#xff0c;系统画多边形的命合都无法参数化&#xff0c;网上有“六边形”参数化的画法教学 ( 这个教学被收入《每日一技》第 76期“Revit 中族编辑时可控六边形的画法详解”)&#xff0c;却对任意多边形无可奈何。 网上及前…

Spring-全面详解(学习总结---从入门到深化)

目录 Spring简介 Spring体系结构 IOC_控制反转思想 IOC_自定义对象容器 IOC_Spring实现IOC IOC_Spring容器类型 ​ 容器实现类 IOC_对象的创建方式 使用构造方法 使用工厂类的方法…

少儿编程 电子学会图形化编程等级考试Scratch一级真题解析(判断题)2022年9月

2022年9月scratch编程等级考试一级真题 判断题(共10题,每题2分,共20分) 26、一个角色只能包含一个造型 答案:错 考点分析:考查角色造型,一个角色可以有多个造型,所以错误 27、我们可以根据需要将角色的任意一点设为造型中心 答案:对 考点分析:考查角色造型,角色…

CC1310F128RSMR Sub-1GHz射频微控制器 - MCU 433MHz 868MHz 915MHz ULP Wireless MCU

CC1310F128RSMR Sub-1GHz射频微控制器 - MCU 433MHz 868MHz 915MHz ULP Wireless MCU CC1310设备是德州仪器公司生产的一款性价比高、超低功耗、Sub-1GHz射频设备,这是SimpleLink的一部分,微控制器&#xff08;MCU&#xff09;平台。该平台包括Wi-Fi&#xff0c;蓝牙低能耗&am…

世界杯中隐藏的IoT物联网黑科技

世界杯首个大冷门上演&#xff01;&#xff01;夺冠热门阿根廷竟然一比二输给了沙特队&#xff0c;实在让人始料未及&#xff0c;让不少球迷都在黯然神伤。 回过头看&#xff0c;上半场4粒进球&#xff0c;被判越位无效的有3粒。整场比赛累计7次越位判罚&#xff0c;超过了上届…

APS智能排产系统的优势

APS智能排产系统是通过同步考虑多种有限能力资源的约束&#xff0c;依据各种预设规则&#xff0c;针对解决&#xff1a;客户订单交期评估与答复、人工排产效率低、设备资源利用率低、物料计划与生产计划脱节、生产计划执行率低、库存积压与生产缺料等相关问题&#xff0c;依靠严…

WebRTC技术专题(2)【大势所趋,迈向认识 WebRTC 的第一步】

每日一句 人生的挑战&#xff0c;无处不在&#xff0c;满怀信心&#xff0c;轻装上路&#xff0c;明天永远是充满希望的战场。 承接上文 承接上文的内容介绍完相关WebRTC技术的概念和发展历程后&#xff0c;开始初步摸索一下相关WebRTC技术的功能和原理。 技术回顾 WebRTC概念…

字符串压缩(二)之LZ4

一、LZ4压缩与解压 LZ4有两个压缩函数。默认压缩函数原型&#xff1a; int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); 快速压缩函数原型&#xff1a; int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapaci…

router路由的配置和使用(详细教程)

vue路由的原理&#xff1a; 路由就是专门来实现单页面应用的&#xff1b;根据不同的路径&#xff0c;加载不同的组件&#xff1b;路径和组件之间一一映射的关系&#xff1b;路径&#xff0c;组件一一对应&#xff1b;加载这个路径&#xff0c;这个组件就出来了&#xff1b;原理…

第五章. 可视化数据分析分析图表—概念介绍

第五章. 可视化数据分析分析图表 5.1 概念介绍 1.如何选择合适的图标类型 1).图标分类框架示意图&#xff1a; 2.图表的基本组成 1).图表的基本组成部分&#xff1a;画布&#xff0c;图标标题&#xff0c;绘画区&#xff0c;数据系列&#xff0c;坐标轴&#xff0c;坐标轴标题…

publish前自动执行sonarqube

根据SonarQube官方描述&#xff0c;SonarQube由三个组件组成&#xff1a; SonarQube Server&#xff0c;运行如下进程&#xff1a; 一个服务于SonarQube用户界面的web服务器基于Elasticsearch的搜索服务器负责处理代码分析报告并将其保存在SonarQube数据库中的计算引擎 Databa…

多卡聚合通信设备在广电视频传输行业解决方案

1 背景介绍 现场视频回传作为信息量最大、信息表达最直观的一种方式&#xff0c;一直是各家电视台、报社等媒体单位获取素材最理想的方式。由于受技术、成本及基础设施的限制&#xff0c;视频素材的回传的距离、质量一直受到较大影响。而随着4G/5G技术的快速发展&#xff0c;多…

【JAVA案例】判断电话号码运营商

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录问题提出&#xff1a;如何判断电话号码属于哪个运营商&#xff1f;一、代码设计思路二、完整源…

Java SPI机制的使用和理解

前言&#xff1a; SPI(Service Provider Interface)&#xff0c;是JDK内置的一种服务提供发现机制&#xff0c;Java中 SPI 机制主要思想是将装配的控制权移到程序之外&#xff0c;在模块化设计中这个机制尤其重要&#xff0c;其核心思想就是解耦 1、大家都知道API&#xff0c;却…

01【高内聚低耦合、Spring概述、IOC容器、Bean的配置方式】

文章目录01【高内聚低耦合、Spring概述、IOC】一、高内聚低耦合1.1 程序架构设计1.2 低耦合1.2.1 耦合概念1.2.2 如何降低耦合1.3 高内聚1.4 不能完全低耦合二、Spring概述2.1 Spring 是什么2.2 Spring出现的背景2.3 Spring包详解三、Spring快速入门3.1 搭建Spring环境3.2 编写…

60 - 数组类模板

---- 整理自狄泰软件唐佐林老师课程 1. 预备知识 模板参数可以是 数值型参数&#xff08;非类型参数&#xff09; 数值型模板参数的 限制 变量不能作为模板参数浮点数不能作为模板参数类对象不能作为模板参数 本质&#xff1a;模板参数是在 编译阶段 被处理的单元&#xff0c…