大规模稀疏矩阵的广义特征值问题——CLAPACK, IETL库尝试

 

大规模稀疏矩阵的广义特征值问题——CLAPACK, IETL库尝试

  在尝试自己写程序解决失败之后开始在网上找各种解特征值与特征向量的库,特别是解大规模稀疏矩阵的特征值问题,没有考虑广义特征值问题是因为广义特征值问题可以比较容易的转换成一般的特征值问题。在网上我搜到一篇比较好的文章来讲述该作者寻找的各种库,这为我节省了不少的时间:http://blog.csdn.net/MulinB/archive/2010/04/17/5496853.aspx

  1. 我最先看的是CLAPACK库,因为在我自己查找的时候,LAPACK几乎是最有名的,很多知名的库或者软件都引用了该库,而CLAPACK则是LAPACK的C语言版本(LAPACK库是FORTRAN语言的)。我在这里下载到了CLAPACK-3.1.1-VisualStudio.zip,即VS2005下的CLAPACK工程及已经编译好的静态链接库,并按照这里的一篇关于如何配置CLAPACK工程的中文介绍完成了配置。在配置的过程中,执行了中文介绍里的步骤后,还有错误如下:

    error LNK2005: __invoke_watson 已经在 MSVCRTD.lib(MSVCR80D.dll) 中定义

  应该是与MSVCRTD.lib有冲突,因此我又在工程属性里设置忽略MSVCRTD.lib库,就没有错误了,只剩下一堆warning也没有管。

  配置通过之后,基本就是要找自己所需要的功能是什么函数了,LAPACK的命名是比较奇怪的,想要找到自己想要的函数还是比较困难的......我在LAPACK的User Guide里查找到了自己想要的功能:Generalized Symmetric Definite Eigenproblems ,按照里面的介绍,我在clapack里找到了相应的函数,但看函数的源代码里的注释,感觉与网站上的说明并不完全相同,不知道是不是由于User Guide是LAPACK的,而我看的代码是CLAPACK的。按照网站上的介绍我并没有找到想要的解广义特征值问题的函数,但我在代码的注释里看到了这个库里的广义特征问题是用A*x = lambda*B*x来表示的,就直接在库的源代码库里面搜索A*x = lambda*B*x,得到了一个函数dggev_,试了一下,可以正常的解广义特征值问题。但我看了一下,没找到在CLAPACK库里针对稀疏矩阵有特殊的函数,也没有找到如何解矩阵的部分特征值(并不是说它一定没有,可能只是我没有找到),也暂时放弃了对它的探索。个人觉得在LAPACK函数库里找自己需要的函数简直太难了。

  2. IETL库:在其网站上下载了IETL 2.2,应该就是它的最新版。IETL库依赖boost库,而且是1.31版的,已经比较老了,我这里有1.41的boost库,试了一下,不可以正常用,就又下载了一个1.31的boost,而且很多例子需要uBlas bindings而且这个东西要放到boost的文件夹里,而 Blitz++我倒是没怎么发现有例子中使用。我使用的是VS2005,新建一个console工程后,把下载的IETL拷到其目录下,把例子power1.cpp放到工程中,在工程属性里把boost的头文件及库文件的目录正确添加进去,就可以正常跑了(需要下载ublas bindings并放在boost文件夹的相应位置,如果没有的话会提示一些头文件找不到)。但如果需要跑inverse或者lanczos的例子,就需要使用lapack和blas的库了,否则会出下面的问题(可能是多个这样的错误):

    error LNK2019: 无法解析的外部符号 _dstev

  dstev就是在LAPACK库里定义的函数,我在前面下载的CLAPACK库里查了一下,是有这个函数的,但函数名称是dstev_,多一个下划线,可能是CLAPACK与LAPACK也有一些小区别吧。我在网上找了各种版本的lapack和blas库,但都无法解决上面这个错误信息(这两个库都是用FORTRAN编译过来的,我下载的都是已经编译好的库)。使用dumpbin来查看lapack库,可以看到有dstev的接口,不知道是不是跟库的版本有关系。搞了一天没弄出来之后突然想到使用前面调出来的CLAPACK库,这个库是自己编译出来的,多少可以试一下。于是把lapack_name.h里的#define LAPACK_DSYSV FORTRAN_ID( dsysv )改成了#define LAPACK_DSYSV FORTRAN_ID( dsysv_ ),如果有别的类似的错误也用同样的方法在后面加一个下划线;然后在项目属性的依赖库中添加libf2cd.lib BLASd.lib clapackd.lib tmglibd.lib,并设置好依赖库的路径,上述错误就得以解决了。

  这个库的网站上介绍说:对于稠密矩阵的特征值问题LAPACK已经解决的很好了,而本库致力于解决稀疏矩阵的特征值问题。言下之意对于稀疏矩阵的特征值问题应该是有独到之处的吧,但我还没有进行比较详细的测试,只是解了几个小一点儿的矩阵,与matlab的结果对比了一下,先保证了结果的正确性。

  我调试通过IETL库之后,使用它的lanczos例子(这是用来解大规模稀疏对称矩阵公认几乎最有效的方法),发现N>200之后,求出来的特征向量都是0,在代码里跟过去看了一下,计算时的误差小到一定程度之后反而越来越大,而程序并没有处理,只到迭代次数超出限制才退出视为计算不出来这个特征值对应的特征向量。查看了论文之后,发现lanczos有很多种改进方法,来弥补它本身不一定收敛的缺点,可能IETL库并没有考虑这个吧。但是它还是可以正确解出来特征值的,只是特征向量解的时候有问题。如果看中了IETL库以够求解大规模对称稀疏矩阵特征值的优点而使用IETL库,建议还是不要用了。


PS:CLAPACK的官方网站:http://www.netlib.org/clapack/

你可能感兴趣的:(算法研究,fortran,lambda,matlab,语言,user,测试)