搞这个clapack 花了很长时间,成功之后决定写个博客整理一下:
【写在前面】:LAPACK全称是 Linear Algebra PACKage, LAPACK, BLAS 本身是Fortran写的。函数以XYYZZZ形式命名,首字母代表数据类型,
- d: 双精度double
- c: 单精度复数 complex
- s: 单精度实数singble real
windows: 载VS配置的,根据需要生成debug,release,win32,x64的lib:
http://www.netlib.org/clapack/CLAPACK-3.1.1-VisualStudio.zip
linux: http://www.netlib.org/clapack/clapack-3.1.1.1.tgz
build 3个项目 blas clapck libf2c (Testing 的不用管)
生成的lib可以放到不用的文件夹 (debug的lib的命名结尾加d,我这里用的都是MT或者MTd)
├── 32_debug
│ ├── BLASd.lib
│ ├── clapackd.lib
│ └── libf2cd.lib
├── 32_release
│ ├── BLAS.lib
│ ├── clapack.lib
│ └── libf2c.lib
├── 64_debug
│ ├── BLASd.lib
│ ├── clapackd.lib
│ └── libf2cd.lib
└── 64_release
├── BLAS.lib
├── clapack.lib
└── libf2c.lib
也可以重命名为 blas_win64_MTd.lib, blas_win32_MT.lib, 方便自己后续调用
tar xzvf clapack-3.1.1.1.tgz
cd CLAPACK-3.1.1.1
mv make.inc.example make.inc
make f2clib
make blaslib
make
生产的4个库为:(不要重命名!!! 我就是重名为liblapack.a 折腾了好久,最后回到最初的名字)
F2CLIBS/libf2c.a
blas_LINUX.a
lapack_LINUX.a
tmglib_LINUX.a
下面是一个svd分解的例子(test1.c)
#include "stdio.h"
#include "f2c.h"
#include "clapack.h"
#define SIZE 4
int main()
{
char JOBU;
char JOBVT;
int i;
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);
if (INFO > 0) {
printf("The algorithm computing SVD failed to converge\n");
exit(1);
}
for (i = 0; i< SIZE; i++) {
printf("\n s[ %d ] = %f", i, s[i]);
}
getchar();
return 0;
}
输出结果为:
s[ 0 ] = 34.000000
s[ 1 ] = 17.888544
s[ 2 ] = 4.472136
s[ 3 ] = 0.000000
再来一个例子,给一个向量乘上一个常量(test2.c)
#include
#include "f2c.h"
#include "blaswrap.h"
// scale a vector.
void main()
{
int i, j, n, one;
double coefficient;
double x[] = { 1, 1, 1 };
coefficient = 5;
one = 1;
n = 3;
dscal_(&n, &coefficient, x, &one);
for (i = 0; i "%f\n", x[i]);
getchar();
}
输出结果为:
5.000000
5.000000
5.000000
gcc test1.c -L./ lapack_LINUX.a blas_LINUX.a libf2c.a -lm -o test
./test1
输出结果为
s[ 0 ] = 34.000000
s[ 1 ] = 17.888544
s[ 2 ] = 4.472136
s[ 3 ] = 0.000000
另外我也尝试了用cmake, 自己写CMakeLists.txt
# 头文件放在include文件夹
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
# 生成的可执行文件放在bin文件夹
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 生成的可执行文件用的源文件source.c
ADD_EXECUTABLE(test source.c)
# 设置静态库的路径(绝对路径)
SET(lib_dir $ENV{HOME}/test/lib)
# 加入依赖库(注意要加入数学库 m )
TARGET_LINK_LIBRARIES(test ${lib_dir}/lapack_LINUX.a ${lib_dir}/blas_LINUX.a ${lib_dir}/libf2c.a m)