Levmar使用小结(一)

2019-07-13 07:45发布

            Levmar是非线性优化的一个库,使用起来很方便。但是刚开始接触时会有点头疼,尤其是如果不懂LM算法,直接使用的话,就会满脑子“这是啥?这都是啥?”  最近在学习非线性优化的方法,总结一下希望可以帮助到大家。Levmar的安装配置大家可以看这篇文章:http://blog.sina.com.cn/s/blog_45b747f70101he1t.html     Levmar的官网是这个:http://users.ics.forth.gr/~lourakis/levmar/index.html   其实学习任何一种工具最好的方法还是看原版资料,六级以上的英语基本都能看懂的。         从那篇安装的文章,我们可以看出,Levmar依赖于一个叫LAPACK的库,这个库是Fortran语言编写的,可用于解多元线性方程式、计算特征向量、计算矩阵的QR分解奇异值分解等等。事实上,Levmar不依赖于这个库也是可以的。Levmar包含多个函数,如下图所示:
      这些函数中,前4个是无约束的优化,后面的是有约束的优化,函数的名字也很容易理解。Levmar提供了两种版本的精度,双精度(函数名字首字母为d, double)和单精度(函数名字首字母为s, single)。Levmar支持有约束的非线性最小二乘问题,包括linear equation constraints(第5-8个函数),box constraints(第9-12个函数),box & linear equation constraints(第13-16个函数),box, linear equation & inequality constraints(第17-20个函数),从函数名的中间字母,可以区分出这些函数。在非线性优化中,需要计算Jacobian矩阵,有的有解析形式的Jacobian矩阵,使用der后缀的函数;有的没有解析形式的Jacobian矩阵,使用有限差分方法来近似,使用dif后缀的函数。最后提到的Convenience wrappers,x开头的几个函数我不是很了解,这里不讨论。 综上,Levmar是比较全面的非线性优化算法。       实际上,并不是所有的函数都依赖LAPACK库,其中dlevmar_der(),dlevmar_dif(),slevmar_der(),slevmar_dif(),dlevmar_bc_der(),dlevmar_bc_dif(),slevmar_bc_der(),slevmar_bc_dif()是不需要依赖这个库的,其他的需要。     下载好Levmar文件解压缩后(我用的2.6版本),里面有个matlab文件夹,这是Levmar的Matlab版本,这里不做讨论,其余的就是C文件,建议大家先读一下README.txt,有助于大家对这个库的理解。     打开levmar.h文件,代码开始后首先有一段配置选项,如下图所示:
        这段代码就是用来设置一些选项,第一个就是LAPACK库的设置,如果不想依赖这个库,就将 #define HAVE_LAPACK 注释掉,当然,注释掉后需要用到这个库的那些函数就不能用了。接下来的一长段我不是特别理解,保持默认状态就行。后面是单精度和双精度的设置,如果注释掉 #define LM_DBL_PREC ,所有的双精度函数都不能用(即d开头的函数),同理,如果注释掉 #define LM_SNGL_PREC,所有的单精度函数都不能用(即s开头的函数)。当然也可以保持默认状态,即都不注释。这些可以根据实际需要来配置。           另外有一点需要注意,如果不使用Cmake编译,而是直接用Visual c++编译,在解压缩后的Levmar文件夹里,有一些后缀是core的C文件(*_core.c),这些文件是不能直接编译的,即不需要添加到Visual c++ 的工程里。            这里所说的基本上在 README.txt 文件里都有说明。我们的工程需要非线性优化,用到了dlevmar_dif()函数,原来以为必须依赖LAPACK库,这样的话就没办法做嵌入式,后来才发现这个LAPACK库可以不依赖的,这样的话就方便很多。希望这篇文章可以帮到大家。