至于LAPACK是什么在这里就不多说了,编译,安装的步骤如下
1、CLAPACK的编译与安装
以下链接是CLAPACK的官方网站,也可以根据官方网站进行配置、
http://icl.cs.utk.edu/lapack-for-windows/clapack/index.html#install
我用的是clapack-3.2.1 对应的CMake用的是3.0.2的版本----**注意:这个地方好像有版本的对应关系,开始用CMake2.9对clapack-3.2.1进行编译时出现错误,后来换成CMake3.0.2版本后错误消失
1.下载clapack-3.2.1 clapack-3.2.1-CMAKE.tgz and unzip.
2.下载CMake3.0.2 http://www.cmake.org/
3.打开CMake
where is the source code:填写clapack-3.2.1-CMAKE文件夹所在的路径(例如 C:/clapack-3.2.1-CMAKE,该文件夹包含CMakeLists.txt文件,用于CMake的编译之用)
where to build the binaries:最好填写一个与上面文件夹不同的文件夹,可以自己新建一个。也可以使用上面的文件夹,但后续的文件会不方便找
点击configure,这时会让你选择visual studio solution,请选择vs2010(也就是vs10),这里如果用默认的vs2008,会出现错误
再次点击configure,直到下面的对话框编程白色为止
点击generate,显示generate done,表示编译成功
关闭CMake
4.打开where to build the binaries所指向的文件夹,里面会用vs2010的工程,用vs2010打开它
5.build“ALL_BUILD”将会build解决方案
6.build“INSTALL”会把lib 和 .h文件放到cmake创建的目录中 一般在C:\Program Files\CLAPACK中
7.bulid“RUN_TEST” 执行测试文件
如果没修改CMAKE中的设置,那么搞定第6个步骤后,你会在C:\Program Files\CLAPACK发现你所需要的*.h和*.lib
备注:在RUN_TESTS有部分不能通过,也不影响其余功能的正常使用
2、CLAPACK的使用
使用CLPACK前,要先清楚四点:
首先是Levels of Routines,即函数的层次。LAPACK将整个库分为三大块:driver, computional, auxiliary,具体哪块是做什么的,请自行看链接。
其次是Naming Scheme,即命名规则。LAPACK的driver 和 computational 的函数名通常为XYYZZZ,其中X指使用的数据类型,YY指矩阵类型,ZZZ指函数的功能。例如SGEBRD的意思是单精度(S)的在一般的矩阵(GE)上执行bidiagonal reduction(BRD)操作,还是那句,具体的,请自行看链接。
再次是CLAPACK的函数不接收二维数组,即只能用一维数组代替二维数组,例如我想要个array[2][2] = { {1,2}, {3,4} },那么正确的写法是array[2*2] = { 1, 2, 3, 4}。
最后是行主序与列主序的问题。CLAPACK看一维数组时会将其看成是按列存放的。所以习惯将一维数组看成是按行存放的要特别注意了。如果说就是不爽按列存放呢?那么可以在计算前,先将其转置。
这里以使用dgemm_函数为例,对CLAPACK的使用方法进行说明。从dgemm_的命名可以看出,这是双精度(d)的在一般矩阵(GE)执行matrix-matrix操作的函数,更具体来说,是执行C = alpha* op(A)* op(B) + beta * C操作。在clapack.h中的声明如下:
int dgemm_(char *transa, char *transb, integer *m, integer *n, integer *k, doublereal *alpha, doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *beta, doublereal *c__, integer *ldc);
其中
transa表示op(A)的操作,若transa = 'T',则表示对A进行转置
transa表示op(B)的操作
m表示矩阵A的行数
n表示矩阵B的列数
k表示矩阵A的列数
alpha就是alpha的值
a就是矩阵A的一维存储,注意调用的函数会认为其是列主序的
lda表示矩阵A的第一维(LDA specifies the first dimension of A),其值根据transa的值而变
b是矩阵B的一维存储
ldb表示矩阵B的第一维,其值根据transb的值而变
c是矩阵C的一维存储
ldc表示矩阵C的第一维。
以下程序将计算
//author: Zero #include "iostream" #include "f2c.h" #include "clapack.h" using namespace std; int main() { char transa = 'T', transb = 'T'; integer M = 2, N = 2, K = 2, LDA = K, LDB = N, LDC = M; double alpha = 1.0, A[4] = { 1, 2, 3, 4}, B[4] = { 5, 6, 7, 8 }, beta = 0.0, C[4]; //下面的函数的意思是C = 1.0 * T(A) * T(B) + 0 * C,其中T()表示将某个矩阵转置 //注意此时得到的C是按列存放的 dgemm_(&transa, &transb, &M, &N, &K, &alpha, A, &LDA, B, &LDB, &beta, C, &LDC); cout<<C[0]<<" "<<C[2]<<endl; cout<<C[1]<<" "<<C[3]<<endl; return 0; }
要成功执行此测试代码,请将vs2010设置成如下所示