当前位置: 首页 > article >正文

C++ 用Eigen的非线性求解LevenbergMarquardt,亲测ok

Eigen的非线性求解LevenbergMarquardt_eigen求非线性方程-CSDN博客

#ifndef Optimization_HEADER
#define Optimization_HEADER
#endif
#pragma once

#include <Eigen/Eigen>
#include <unsupported/Eigen/NonLinearOptimization>
#include "../math/vector.h"

template <class T>
class CostFunction {

public:
    using Scalar = typename T::Scalar ;
    
    static constexpr auto InputsAtCompileTime = Eigen::Dynamic ;
	static constexpr auto ValuesAtCompileTime = Eigen::Dynamic ;
    using InputType = Eigen::Matrix<Scalar ,InputsAtCompileTime ,1> ;
	using ValueType = Eigen::Matrix<Scalar ,ValuesAtCompileTime ,1> ;
	using JacobianType = Eigen::Matrix<Scalar ,ValuesAtCompileTime ,InputsAtCompileTime> ;

private:
    T &mSolver ;

public:
    CostFunction () = delete ; 

    explicit CostFunction (T &solver) :
         mSolver (solver) {}

    int inputs () const {
        return mSolver.inputs () ;
    }
    
    int values () const {
        return mSolver.values () ;
    }

    inline int operator() (const Eigen::Matrix<Scalar ,Eigen::Dynamic ,1> &param ,Eigen::Matrix<Scalar ,Eigen::Dynamic ,1> &residual) const {
		mSolver.cost_function (param ,residual) ;
		return 0 ;
	}
};


class OptimizerSolver  {
public:
    using Scalar = double ;
private:
    
    friend CostFunction<OptimizerSolver> ;
    const std::vector<math::Vec3d>& mPoints ;
    Eigen::VectorXd& mParameters ;

    Eigen::Matrix<Scalar ,Eigen::Dynamic ,1> mOptimizingParam ;
	Eigen::DenseIndex mDenseIndex ;

public:
    OptimizerSolver () = delete ;

    explicit OptimizerSolver (const std::vector<math::Vec3d>&points ,
                              Eigen::VectorXd& parameter )
                              : mPoints (points) ,
                                mParameters (parameter) {}
    /*需要优化的参数个数*/
    int inputs () const {
        return 6 ;
    }

    /*cost function 的项数*/
    int values () const {
        return 100 ;
    }

    /** 优化方程 costfunction
     *  param1 param 需要优化的参数
     *  param2 residual cost function的每一项
    */
    void cost_function (const Eigen::VectorXd& param , Eigen::VectorXd& residual ) const {
   
        const auto r1x = decode_param (param) ;
        for (int i = 0 ; i < 100 ; i++) {
            // residual[i] = cost function的每一项 ;
        }
        
    }

    /*执行优化*/
    inline void operator() () {
		mOptimizingParam = encode_param (mParameters) ;
		mDenseIndex = Eigen::DenseIndex () ;
		const auto r1x = CostFunction<OptimizerSolver> (*this) ;
		const auto r2x = Eigen::LevenbergMarquardt<const CostFunction<OptimizerSolver> ,Scalar>::lmdif1 (r1x ,mOptimizingParam ,&mDenseIndex) ;
        assert(r2x > 0 ) ;
        const auto r3x = decode_param (mOptimizingParam) ;
        mParameters = r3x.row(0) ; // 更新参数
	}

private:
    /** 把需要优化的参数变成向量
    */
    static Eigen::VectorXd encode_param (const Eigen::VectorXd& parameter) {
        Eigen::VectorXd ret (6) ;
        
        return ret ;
    }

    /** 把之前编码成向量的参数变回原来的参数模式
    */
    static Eigen::MatrixXd decode_param (const Eigen::VectorXd& param) {
        Eigen::MatrixXd ret (2 ,4) ;

        return ret ;
    }
};

简直省了一大步,直接调用就行了。

用法:

		OptimizerSolver Lmsolver(points, initRigidParams);
		Lmsolver();

就是这么方便!


http://www.kler.cn/a/542028.html

相关文章:

  • PDF 2.0 的新特性
  • 【C++八股】 前置 ++i vs. 后置 i++ 的区别
  • 防御保护-----前言
  • 【网络安全】服务器安装Docker及拉取镜像教程
  • IBM服务器刀箱Blade安装Hyper-V Server 2019 操作系统
  • jemalloc的malloc案例来分析GOT表和PLT表有关流程
  • Python 透明数字时钟
  • 独立站赋能反向海淘:跨境代购系统的用户体验与支付解决方案
  • 2025.2.10 每日学习记录3:技术报告只差相关工作+补实验
  • 在npm上传属于自己的包
  • 【RabbitMQ的x-death头】消息死亡记录头流转示例
  • 攻防世界32 very_easy_sql【SSRF/SQL时间盲注】
  • android的第一个app项目(java版)
  • C++ Primer 简单语句
  • webpack配置之---output.publicPath
  • 【机器学习】 特征归一化的重要性及方式
  • 【Day37 LeetCode】动态规划DP Ⅹ 子序列问题
  • centos 8和centos 9 stream x64的区别
  • 寒假集训思维训练5题解
  • VSCode|IDEA|PyCharm接入DeepSeek R1
  • 【数据结构-Tire树】力扣1268. 搜索推荐系统
  • 如何在本地部署deepseek?
  • 【目标检测json2txt】label从COCO格式json文件转YOLO格式txt文件
  • 具身智能训练新思路!将生成视频用于训练机器人
  • SpringBoot旧物置换网站
  • 301.华为交换机堆叠技术基础