CLAPACKvc++6.0中成功调用
Kevin Wong
2010-3-24
序:
CLAPACKLAPACKC语言接口。LAPACK的全称是Linear Algebra Package,是非常著名的线性代数库。原版的LAPACK是用Fortran写的,为了方便C/C++程序的使用,就有了LAPACKC接口CLAPACK
网上虽然给出了一些关于CLAPACKwindows下的调用讲解, 但用起来总会有这样那样的问题. 对于Visual Studio C++ 6.0环境如何实现对CLAPACK的调用,基本上就没有相关资料了.
本人青睐于vc++6.0的运行速度, 研究了一下再此环境中调用CLAPACK的攻略. 终于功夫不负苦心人, 在此将基本步骤梳理一下,希望对大家有所帮助.
 
一、你需要准备什么?
(1) MS vc++6.0. (有些费话了,呵呵)
(2)下载 clapack-3.并解压缩.
(3)下载 CMAKE 并安装.
有了(2)(3)的准备可以提供vc各个版本需要的项目和工程文件了.
 
二、编译库文件
1) 使用CMAKE
☑▪▪▪▪▪打开CMAKE-gui
☑▪▪▪▪▪Source目录指向你的CLAPACK-3.2.1-CMAKE文件夹;
☑▪▪▪▪▪Bulid目录指向你准备存放生成文件的文件夹(最好不同于Source文件夹)
☑▪▪▪▪▪点击configure, 选择vc++6.0作为你的编译器.(如果你的电脑上没有其他编译器,默认就可以了)
☑▪▪▪▪▪你需要再次点击configure直到所有选项都变成白.
☑▪▪▪▪▪点击generate, 将会生成Visual Studio 需要的项目和工程文件, 这就完成了.
☑▪▪▪▪▪关闭CMAKE
2)查看"build"指向的文件夹,打开CLAPACK.dsw.
3)激活"ALL_BUILD"工程,就可以组建(bulid)出所需要的所有的库文件了.
编译完成后,到libf2c.lib blas.lib lapack.lib tmglib.lib。这些都是你自己编写程序时需要调用的库。另外,在lapack-3.解压的文件夹\INCLUDE中的包含了这些库的头文件。
 
三、如何调用库文件。
1)头文件
头文件就是.h文件。存放在\INCLUDE中。在自己的工程里加入这个目录就行了。程序中主要调用的头文件是f2c.hclapack.h
2)库文件
库文件就是我们前面编译生成的那些lib文件了。
3)vc工程本身的一些设置:
(这个很重要,很多时候就是因为这里设置不对,才会出问题的)
//开始设置////////////////////////////////////////////////////////////////////////////////////////////////////////
1在设置中选择所有设置。
2VC++IDE中选择Projectssettingscmake如何使用C/C++
1)category中选择Code Gfengeration,在Use run-time library中选择Debug Multithread D
LL(必须的)
2)category中选择Precompiled Headers,中选择Automatic use of precomplid headers,并且在Through header下面添加stdafx.h(可省去)
3)Category中选择Preprocessor,在Preprocessor definitions中添加 MSVC,MSWIND (可以省略)
3VC++IDE中选择ProjectssettingsLink
1)Categories中选择Input,在Ignore libraries中填入:msvcrt.lib(必须的)
2) Object/Library Modules 框中,添加库文件名:libf2c.lib blas.lib lapack.lib tmglib.lib (必须的)
//设置完成////////////////////////////////////////////////////////////////////////////////////////////////////////
 
注意: 因为BLAS库通常比LAPACK库提供的子程序的版本要新,所以BLAS库要列在LAPACK库之前。
注意: 如果想在调试时能对库函数进行源码级调试。那么需要在VS 工具--选项--项目和解决方案--VC++目录 中添加\SRC的目录。
 
四、vc++6.0调用实例
//////////////////// 以下代码例子来自 Kaien的博文 ///////////////////////
本文,我们将调用CLAPACK的一个函数dgesvd_()来学习使用的方法。
注意: 包括此函数在内的所有的CLAPACK函数可以在\SRC下到源代码,并在代码中有函数参数的说明信息。dgesvd_的代码文件就是dgesvd.c
 
dgesvd_的函数声明:
int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
doublereal *a, integer *lda, doublereal *s, doublereal *u, integer *
ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
integer *info)
 
dgesvd_的功能是对一个实矩阵A进行SVD分解(singular value decomposition)
A = U * SIGMA * transpose(V)
 
dgesvd.c文件里有详细地函数说明和参数说明。
    SIGMA is an M-by-N matrix which is zero except for its 
    min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and 
    V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA 
    are the singular values of A; they are real and non-negative, and 
    are returned in descending order. The first min(m,n) columns of 
    U and V are the left and right singular vectors of A. 
 
    Note that the routine returns V**T, not V. 
    .........................................
 
//test.cpp代码///////////////////////////////////////////////////
#include <stdio.h>
#include <process.h>
#include <f2c.h>
//因为程序是C++,而CLAPACKf2c程序转换的C语言版本,所以在此处用extern关键字调用
extern"C"
{
#include <clapack.h>
}
 
#define SIZE 4
int main()
{
    char JOBU;
    char JOBVT;
    int i;
    //数据类型integerfortran里的。这里在C++下可以使用的原因是f2c.h文件中已经作了定义
    integer M = SIZE;
    integer N = SIZE;
    integer LDA = M;
    integer LDU = M;
    integer LDVT = N;
    integer LWORK;
    integer INFO; 
    integer mn = min( M, N );   
    integer MN = max( M, N );   
    double a[SIZE*SIZE] = { 16.0, 5.0, 9.0 , 4.0, 2.0, 11.0, 7.0 , 14.0, 3.0, 10.0, 6.0, 15.0, 13.0, 8.0, 12.0, 1.0};
    double s[SIZE];
    double wk[201];
    double uu[SIZE*SIZE];
    double vt[SIZE*SIZE];
   
    JOBU = 'A';   
JOBVT = 'A';
    LWORK = 201;
   
/* Subroutine int dgesvd_(char *jobu, char *jobvt, integer *m, integer *n,
        doublereal *a, integer *lda, doublereal *s, doublereal *u, integer *
        ldu, doublereal *vt, integer *ldvt, doublereal *work, integer *lwork,
        integer *info)
*/
    dgesvd_( &JOBU, &JOBVT, &M, &N, a, &LDA, s, uu, &LDU, vt, &LDVT, wk, &LWORK, &INFO);
         
    printf("INFO=%d \n", INFO );

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。