Levenberg–Marquardt算法
2016-11-24 14:43
274 查看
算法描述及示例引用自“Machine Learning An Algorithm Perspective 2nd Edition”
使用C++进行浮点数的比较时,一定要注意容差问题。
使用C++进行浮点数的比较时,一定要注意容差问题。
#include <iostream> #include <math.h> #include <Eigen/Core> #include <Eigen/Dense> using namespace std; double rx(const Eigen::MatrixXd &x,int i) { switch(i) { case 0: return 10*(x(1,0) - x(0,0) * x(0,0)); case 1: return 1-x(0,0); } return INT_MAX; } double fx(const Eigen::MatrixXd &x) { return 100 *(x(1,0) - x(0,0) * x(0,0)) * (x(1,0) - x(0,0) * x(0,0)) + (1-x(0,0)) * (1-x(0,0)); } double Jac(const Eigen::MatrixXd &x,int i,int j) { int index = 2*i+j; switch(index) { case 0: return -20 * x(0,0); case 1: return 10.0; case 2: return -1.0; case 3: return 0.0; } } void computeRelatedValues(const Eigen::MatrixXd& x,double &fval,Eigen::MatrixXd &r,Eigen::MatrixXd &J,Eigen::MatrixXd &grad) { fval = fx(x); for (int i = 0;i<2;++i) { r(i,0) = rx(x,i); } for(int i = 0;i<2;++i) for(int j = 0;j<2;++j) { J(i,j) = Jac(x,i,j); } grad = J.transpose() * r; } void LM() { Eigen::MatrixXd x(2,1); x(0,0) = -1.92; x(1,0) = 2.0; int max_iter = 100; double func_tol = pow(10.0,-5); int iter = 0; double fval = INT_MAX; Eigen::MatrixXd r(2,1); Eigen::MatrixXd J(2,2); Eigen::MatrixXd grad; computeRelatedValues(x,fval,r,J,grad); double nu = 0.01; cout<<fval<<" ["<<x(0,0)<<" "<<x(1,0)<<"] "<<grad.norm()<<" "<<nu<<endl; while(iter < max_iter && grad.norm() > func_tol) { ++iter; computeRelatedValues(x,fval,r,J,grad); Eigen::MatrixXd I = Eigen::MatrixXd::Identity(2,2); Eigen::MatrixXd H = J.transpose() *J + nu*I; Eigen::MatrixXd x_new = Eigen::MatrixXd::Zero(2,1); int iter1 = 0; double diff = (x-x_new).norm(); //注意如何比较两个向量是否相等 while(diff > pow(10.0,-5) && iter1 < max_iter) { ++iter1; Eigen::MatrixXd delta_x = H.colPivHouseholderQr().solve(grad); cout<<delta_x<<endl; Eigen::MatrixXd x_new = x - delta_x; cout<<x_new<<endl; double fval_new = INT_MAX; Eigen::MatrixXd r_new(2,1); Eigen::MatrixXd J_new(2,2); Eigen::MatrixXd grad_new; computeRelatedValues(x_new,fval_new,r_new,J_new,grad_new); double rho = abs(fval - fval_new) / (grad.transpose() * (x_new - x)).norm(); if (rho > 0) { x = x_new; diff = (x - x_new).norm(); cout<<diff<<endl; if (rho > 0.25) { nu = nu /10; } } else { nu = nu *10; } } cout<<fval<<" ["<<x(0,0)<<" "<<x(1,0)<<"] "<<grad.norm()<<" "<<nu<<endl; } } int main() { LM(); return 0; }
相关文章推荐
- 利用Levenberg_Marquardt算法求解无约束的非线性最小二乘问题~
- Eigen中Levenberg-Marquardt算法的应用
- Python 算例实现Levenberg-Marquardt算法
- 相机标定:关于用Levenberg-Marquardt算法在相机标定中应用
- 迭代求解最优化问题——Levenberg-Marquardt算法
- Levenberg-Marquardt Algorithm
- 优化算法(最小二乘,FANSAC,Levenberg-Marquardt,LMEDS,霍夫变换)
- A Brief Description of the Levenberg-Marquardt Algorithm Implemened by levmar
- Levenberg-Marquardt(列文伯格-马夸尔特)算法
- V-rep学习笔记:机器人逆运动学数值解法(Damped Least Squares / Levenberg-Marquardt Method)
- 高斯牛顿(Gauss Newton)、列文伯格-马夸尔特(Levenberg-Marquardt)最优化算法与VSLAM
- Levenberg-Marquardt(列文伯格-马夸尔特)算法
- LM(Levenberg-Marquard) c语言实现
- 【转】 Levenberg-Marquardt 算法快速入门教程
- Levenberg–Marquardt算法学习
- Levenberg-Marquardt优化算法
- 基于Levenberg-Marquardt训练算法的BP网络Python实现
- 【转】LM(Levenberg-Marquard) Matlab及C语言实现
- 训练数据常用算法之Levenberg–Marquardt(LM)
- LM(Levenberg-Marquard)算法的实现