Levenberg-Marquardt已经成为现在最为通用的非线性最小二乘算法,而levmar库提供了一个非常简便和鲁棒的实现。
levmar给出了c++和matlab两个版本。在msvc下编译levmar,网上有很多现有的教程,这里不再赘述。要注意的是,levmar依赖于lapack\blas库来求解一些基本的线性代数问题,可以直接下载MSWin下编译好binary files。然后在CMake中将lapack\blas的目录和lib名字做出相应的修改。
下面是本文的重点,在matlab下编译levmar。本质上我们是用mex命令将levmar.c文件编译成 .mexw32文件。可是levmar(我使用的的最新版本2.6)中的levmar.c另外调用了刚才msvc编译好的levmar库。因此在执行mex命令时需要添加三个库levmar、lapack和blas。在我的本机上,mex命令是这样的:
mex -DHAVE_LAPACK -O -IE:\library\levmar-2.6\ -LE:\library\levmar-2.6\build\Release\ -LE:\library\lapack-MD-release\ levmar.c -llevmar -llapack_win32_MD -lblas_win32_MD
-DHAVE_LAPACK 定义了一个宏,表示使用lapack来解线性代数。
-O 表示在编译的过程中优化,可以缺省。
-IE:\library\levmar-2.6\ 添加levmar.c中#include<levmar.h> 的文件目录,目录名可以打单引号也可以不打。
-LE:\library\levmar-2.6\build\Release\ 之前msvc下编译好的levmar.lib所在文件目录。
-LE:\library\lapack-MD-release\ lapack和blas所在的文件目录。
levmar.c 要编译的c源文件名。
-llevmar levmar库,注意不要加.lib。
-llapack_win32_MD lapack库,我使用的是动态链接版本。
-lblas_win32_MD blas库,同样是动态链接版本。
编译好之后,将lapcak\blas的两个dll, lapack_win32_MD.dll和blas_win32_MD.dll拷贝到matlab当前的工作目录。然后运行lmdemo.m,如果能得到结果,证明编译成功。