使用Eigen进行LM算法实现(自动求导)
2018-03-15 23:15
2056 查看
引入头文件
#include "iostream" #include "vector" #include "list" using namespace std; #include "Eigen/Dense" #include "Eigen/Core" #include <unsupported/Eigen/NonLinearOptimization> #include <unsupported/Eigen/NumericalDiff> using namespace Eigen;
基本算子
// Generic functor template<typename _Scalar, int NX = Eigen::Dynamic, int NY = Eigen::Dynamic> struct Functor { typedef _Scalar Scalar; enum { InputsAtCompileTime = NX, ValuesAtCompileTime = NY }; typedef Eigen::Matrix<Scalar, InputsAtCompileTime, 1> InputType; typedef Eigen::Matrix<Scalar, ValuesAtCompileTime, 1> ValueType; typedef Eigen::Matrix<Scalar, ValuesAtCompileTime, InputsAtCompileTime> JacobianType; int m_inputs, m_values; Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {} Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {} int inputs() const { return m_inputs; } int values() const { return m_values; } };
基本算子定义了输入输出和雅克比矩阵的大小。
自定义算子
struct my_functor : Functor<double> { // 输出个数必须大于输入个数, 故用2不用1; my_functor(void) : Functor<double>(2, 2) {} int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const { // Implement y = 10*(x0+3)^2 + (x1-5)^2+aa*2 fvec(0) = 10.0*pow(x(0) + 3.0, 2) + pow(x(1) - 5.0, 2); fvec(1) = 0; return 0; } };
自定义算子主要对operator()接口进行实现,输入输出维度需要得到保证。
主函数入口
int main(int argc, char *argv[]) { Eigen::VectorXd x(2); x(0) = 1.0; x(1) = 3.0; my_functor functor; Eigen::NumericalDiff<my_functor> numDiff(functor); Eigen::LevenbergMarquardt<Eigen::NumericalDiff<my_functor>, double> lm(numDiff); Eigen::VectorXd y(2); functor.operator()(x, y); std::cout << "x first input: \n" << x << std::endl; std::cout << "y first outpout: \n" << y << std::endl; lm.parameters.maxfev = 1000; lm.parameters.xtol = 1.0e-8; int iRet = lm.minimize(x); std::cout << "迭代次数:\n" << lm.iter << std::endl; std::cout << "计算标志:\n" << iRet << std::endl; std::cout << "x finnal: \n" << x << std::endl; functor.operator()(x, y); std::cout << "y outpout((minimized): \n" << y << std::endl; return 0; }
相关文章推荐
- Intellij IDEA 使用jrebel运行spring-boot并实现自动编译进行热部署
- cocos2d-x 如何使用CCProgressTimer作为血条,实现跟随怪物进行移动,自动掉血,然后死亡。
- 关于oracle 11g自动分区+分区改名+定时任务综合使用实现自动分区后可以进行分区查询
- Intellij IDEA 使用jrebel运行spring-boot并实现自动编译进行热部署
- Python笔记–IAR使用Python脚本实现自动对烧录文件进行处理
- ViewFlipper的使用---自动播放(轮播图)的实现以及多个view进行切换
- cocos2d-x 如何使用CCProgressTimer作为血条,实现跟随怪物进行移动,自动掉血,然后死亡。
- Eclipse环境下 使用Gradle进行编译实现自动分包
- 使用Python实现博客上进行自动翻页
- 图片验证码自动识别,使用tess4j进行验证码自动识别(java实现)
- 使用ASP.NET Atlas AutoComplete Behavior或AutoComplete Extender实现自动完成功能(下)
- 使用异或进行简单的密码加密(JAVA实现)
- 实现Weblogic应用的灵活、自动、快速部署:使用wlst+ant+jython+xbean
- 使用ASP.NET Atlas AutoComplete Behavior或AutoComplete Extender实现自动完成功能(上)
- 如何使用ANT自动进行数据库的相关操作
- Atlas学习手记(4):使用AutoComplete Extender实现自动完成功能
- Atlas学习手记(4):使用AutoComplete Extender实现自动完成功能
- 使用 HttpWebRequest 轻松实现站外提交(可用于自动登陆,自动网上投票等)
- (转)使用一个下拉框或文本框+列表框的方式实现类似IE地址栏自动完成的功能
- .NET1.1下,使用C#自动生成Word2003文档(通过操作COM组件实现)