Levmar:Levenberg-Marquardt非线性最小二乘算法

eryar@163.com

Abstract. Levmar is GPL native ANSI C implementations of the Levenberg-Marquardt optimization algorithm.The blog focus on the compilation of levmar on Windows with Visual Studio.

Key Words. Levmar, C, LM least squares

1. levmar简介

Gauss-Newton算法是一个古老的处理非线性最小二乘问题的方法。该方法在迭代过程中要求矩阵J(x)满秩。为了克服这个困难,Levenberg(1944)提出了一种新的方法,但未受到重视。后来Marquardt(1963)又重新提出,并在理论上进行了控讨,得到Levenberg-Marquardt方法,简称LM方法。在此基础上,Fletcher(1971)对其实现策略进行了改进,得到了Levenberg-Marquardt-Fletcher方法(LMF)。再后来,More(1978)将LM方法与信赖域方法结合,建立了带信赖域的LM方法。

LM算法的产生主要是解决曲线最小二乘拟合问题,现在很多软件使用LM算法来解决通用的曲线拟合问题。

本文主要介绍GPL开源库levmar2.6使用Visual Studio在Windows上进行编译。这个开源库的官方网站是:http://users.ics.forth.gr/~lourakis/levmar/

2. 编译levmar

下载源码levmar-2.6解压,在其README.txt中对levmar的授权GPL、编译等进行了说明。在Windows操作系统中,可以使用nmake /f Makefile.vc来编译levmar和一个示例程序。

从官网介绍可知,levmar有些算法依赖LAPACK库,一个线性代数计算开源库。所以如果要使用那些算法,编译的时候必须包含这个库。从示例程序的源文件lmdemo.c中可以看出,有些问题的求解是需要LAPACK库的,相关源码列出如下:

  /* uncomment the appropriate line below to select a minimization problem */
problem=
//0; // Rosenbrock function
//1; // modified Rosenbrock problem
//2; // Powell's function
//3; // Wood's function
; // Meyer's (reformulated) problem
//5; // Osborne's problem
//6; // helical valley function
#ifdef HAVE_LAPACK
//7; // Boggs & Tolle's problem 3
//8; // Hock - Schittkowski problem 28
//9; // Hock - Schittkowski problem 48
//10; // Hock - Schittkowski problem 51
#else // no LAPACK
#ifdef _MSC_VER
#pragma message("LAPACK not available, some test problems cannot be used")
#else
#warning LAPACK not available, some test problems cannot be used
#endif // _MSC_VER #endif /* HAVE_LAPACK */
//11; // Hock - Schittkowski problem 01
//12; // Hock - Schittkowski modified problem 21
//13; // hatfldb problem
//14; // hatfldc problem
//15; // equilibrium combustion problem
#ifdef HAVE_LAPACK
//16; // Hock - Schittkowski modified #1 problem 52
//17; // Schittkowski modified problem 235
//18; // Boggs & Tolle modified problem #7
//19; // Hock - Schittkowski modified #2 problem 52
//20; // Hock - Schittkowski modified problem #76"
#endif /* HAVE_LAPACK */ switch(problem){
default: fprintf(stderr, "unknown problem specified (#%d)! Note that some minimization problems require LAPACK.\n", problem);
exit();
break;

从上述源码可知,如果LAPACK库不可用的时候,示例程序中的问题

l 7 Boggs & Tolle’s problem 3

l 8 Hock - Schittkowski problem 28

l 9 Hock - Schittkowski problem 48

l 10 Hock - Schittkowski problem 51

l 16 Hock - Schittkowskit modified #1 problem 52

l 17 Schittkowski modified problem 235

l 18 Boggs & Tolle modified problem #7

l 19 Hock - Schittkowski modified #2 problem 52

l 20 Hock - Schittkowski modified probem #76

这些问题的求解功能是不能使用的。从头文件levmar.h中要以看出,

#ifdef LM_DBL_PREC
/* double precision LM, with & without Jacobian */
/* unconstrained minimization */
extern int dlevmar_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, int itmax, double *opts,
double *info, double *work, double *covar, void *adata); extern int dlevmar_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, int itmax, double *opts,
double *info, double *work, double *covar, void *adata); /* box-constrained minimization */
extern int dlevmar_bc_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_bc_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); #ifdef HAVE_LAPACK
/* linear equation constrained minimization */
extern int dlevmar_lec_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *A, double *b, int k,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_lec_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *A, double *b, int k,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box & linear equation constrained minimization */
extern int dlevmar_blec_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_blec_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *A, double *b, int k, double *wghts,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box, linear equations & inequalities constrained minimization */
extern int dlevmar_bleic_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub,
double *A, double *b, int k1, double *C, double *d, int k2,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); extern int dlevmar_bleic_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub,
double *A, double *b, int k1, double *C, double *d, int k2,
int itmax, double *opts, double *info, double *work, double *covar, void *adata); /* box & linear inequality constraints */
extern int dlevmar_blic_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_blic_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *lb, double *ub, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata); /* linear equation & inequality constraints */
extern int dlevmar_leic_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_leic_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *A, double *b, int k1, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata); /* linear inequality constraints */
extern int dlevmar_lic_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
void (*jacf)(double *p, double *j, int m, int n, void *adata),
double *p, double *x, int m, int n, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata); extern int dlevmar_lic_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, double *C, double *d, int k2,
int itmax, double opts[], double info[LM_INFO_SZ], double *work, double *covar, void *adata);
#endif /* HAVE_LAPACK */ #endif /* LM_DBL_PREC */

从头文件levmar.h中的代码可以看出,在#ifdef HAVE_LAPACK和#endif /* HAVE_LAPACK */之间的函数都是不可用的。除此之外的函数是可用的,如基本的dlevmar_der和dlevmar_dif等函数是不依赖LAPACK库的。如果只使用这几个函数,则可以不用配置LAPACK库,编译levmar就很简单了。

如果不使用LAPACK库,可以先在头文件levmar.h中把#define HAVE_LAPACK 这一行注释掉:

然后再修改Makefile.vc文件,在Makefile.vc中可以看到如下图所示一句注释,即当不使用LAPACK库是,把那一行注释掉(前面加#):

这时就可以启动Visual Studio的编译器CL来编译levmar库了。配置好编译环境的命令工具从Visual Studio的菜单来启动:

要编译32位的levmar库,可以使用x86的命令工具,要编译64位的levmar,可以使用x64的命令工具。启动命令工具后,切换到levmar源码文件夹,并输入命令

nmake /f Makefile.vc

如下图所示:

编译成功生成levmar.lib和lmdemo.exe说明编译成功了。

接着在命令窗口中运行lmdemo.exe,测试levmar例子程序。如果lmdemo正常运行,说明levmar已经成功编译。

自己的程序如果要使用levmar,就可以像使用其他开源库一样,设置头文件路径及库levmar.lib的路径,就可以使用了。

Levmar:Levenberg-Marquardt非线性最小二乘算法的更多相关文章

  1. LM算法与非线性最小二乘问题

    摘录的一篇有关求解非线性最小二乘问题的算法--LM算法的文章,当中也加入了一些我个人在求解高精度最小二乘问题时候的一些感触: LM算法,全称为Levenberg-Marquard算法,它可用于解决非线 ...

  2. SLAM中的优化理论(二)- 非线性最小二乘

    本篇博客为系列博客第二篇,主要介绍非线性最小二乘相关内容,线性最小二乘介绍请参见SLAM中的优化理论(一)-- 线性最小二乘.本篇博客期望通过下降法和信任区域法引出高斯牛顿和LM两种常用的非线性优化方 ...

  3. matlab实现高斯牛顿法、Levenberg–Marquardt方法

    高斯牛顿法: function [ x_ans ] = GaussNewton( xi, yi, ri) % input : x = the x vector of 3 points % y = th ...

  4. Spark机器学习(10):ALS交替最小二乘算法

    1. Alternating Least Square ALS(Alternating Least Square),交替最小二乘法.在机器学习中,特指使用最小二乘法的一种协同推荐算法.如下图所示,u表 ...

  5. 数学规划模型的matlab求解 非线性最小二乘lsqnonlin

    LINK :http://blog.sina.com.cn/s/blog_49f037d60100ok8y.html

  6. Levenberg–Marquardt algorithm

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFubWVuZ3dlbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  7. 如何高效的通过BP算法来训练CNN

    < Neural Networks Tricks of the Trade.2nd>这本书是收录了1998-2012年在NN上面的一些技巧.原理.算法性文章,对于初学者或者是正在学习NN的 ...

  8. Levenberg-Marquardt算法基础知识

    Levenberg-Marquardt算法基础知识 (2013-01-07 16:56:17) 转载▼   什么是最优化?Levenberg-Marquardt算法是最优化算法中的一种.最优化是寻找使 ...

  9. Levenberg-Marquardt优化算法以及基于LM的BP-ANN

    一.LM最优化算法     最优化是寻找使得目标函数有最大或最小值的的参数向量.根据求导数的方法,可分为2大类.(1)若f具有解析函数形式,知道x后求导数速度快.(2)使用数值差分来求导数.根据使用模 ...

随机推荐

  1. Linux下离线安装MySQL

    Linux下安装mysql 1 检查并卸载已安装mysql 命令:rpm -qa|grep -i mysql 命令:rpm -e --nodeps ‘上个命令后显示的本机已安装mysql依赖’ 如果存 ...

  2. Mvc 返回文件直接下载

    今天碰到一个问题,前端点击下载文件,后端判断文件是否存在,不存在则自动生成文件(图片),返回前端会自动下载文件 网上查了一些  Mvc  action中返回File类型 设置一些contentType ...

  3. 关键字super

    1.super,相较于关键字this,可以修饰属性.方法.构造器 2.super修饰属性.方法:在子类的方法.构造器中,通过super.属性或者super.方法的形式,显式的调用父类的指定 属性或方法 ...

  4. Android RecyclerView和ScrollView嵌套使用

    我们的recyclerView有多个layoutmanager,通过重写layoutmanager的方法就可以让recyclerView和ScrollView嵌套了.但是请注意,如果recyclerV ...

  5. 华为nova 4取代刘海屏

    尽管首发被三星“截胡”,但华为依然是第一批发布“打孔屏”新机的厂商.官方已经确认,将于12月17日在长沙发布华为nova 4,主打自拍极点全面屏. 继真机谍照.配置曝光之后,今日华为官方发布一则华为n ...

  6. Intel投入5亿美元提升14nm工艺CPU需求

    虽然14nm行将收尾,但是却有大量的客户在赶“末班车”,导致CPU供货告急. Intel年初宣布增加10亿美元的额外资本支出用于转向更新的.更先进的生产工具,以便增加产能,在本周的第39届纳斯达克投资 ...

  7. Xshell查看日志的基础使用

    2018\11\26 下载安装不多说,官网免费版即可,附上链接:https://www.netsarang.com/products/xsh_overview.html 打开后新建连接,输入主机ip即 ...

  8. 20180929 北京大学 人工智能实践:Tensorflow笔记01

    北京大学 人工智能实践:Tensorflow笔记 https://www.bilibili.com/video/av22530538/?p=13 (完)

  9. 紫书 习题 10-2 UVa 808(建立坐标+找规律)

    这次是我遇见过最迷的一次 我写的程序uDebug全过 和ac程序对拍也过,求出来的坐标是一模一样的,最后结果输出的方式也是一样的 交上去就是错的 迷 第一次遇到这种情况 大佬在哪里 #include& ...

  10. Httphelper头信息(ContentType)默认为text/html无懈可击

    Httphelper头信息(ContentType)默认为text/html无懈可击转 http://www.sufeinet.com/thread-8623-1-1.html 我发现最近有几个网友提 ...