CLAPACK
是
LAPACK
的
C
语言接口。
LAPACK
的全称是
Linear Algebra PACKage
,是非常著名的线性代数库。
LAPACK
是用
Fortran
写的,为了方便
C/C++
程序的使用,就有了
LAPACK
的
C
接口库
CLAPACK
。
LAPACK
的主页是
http://www.netlib.org/lapack/
,
CLAPACK
则在
http://www.netlib.org/clapack/
。
安装
CLAPACK
首先自从其主页上下载
CLAPACK
包
http://www.netlib.org/clapack/clapack.tgz
,解压。在其目录下的
INSTALL
目录中有
make.inc
的范本文件,比如在
linux
下就是
make.inc.LINUX
,将这个文件拷到
CLAPACK
目录下并改名为
make.inc
,并修改此文件中的相应参数,如果需要的话。
CLAPACK
需要
F2CLIBS
的
libI77.a
和
libF77.a
,一个
tmglib
和
blas
,这几个库都包含在了
CLAPACK
的安装包中,但是
blas
可以选用其他优化过的版本以得到更好的性能。在此我们使用
CLAPACK
中的
blas
。
首先编译
F2CLIBS
,用于将
fortran
转换为
c
语言,在
CLAPACK
目录下,
make f2clib
,在
CLAPACK/F2CLIBS
下就会生成
libI77.a
和
libF77.a
。
编译
tmglib
,
在
CLAPACK
目录下,
make tmglib
,会生成
CLAPACK/tmglib_LINUX.a
。
编译
blas
,
在
CLAPACK
目录下,
make blaslib
,会生成
CLAPACK/blas_LINUX.a
。
最后是编译
CLAPACK
,
make
,会生成
CLAPACK/lapack_LINUX.a
CLAPACK
下的
clapack.h
就是所需要的头文件,除此之外还需要的一个头文件是
F2CLIBS/f2c.h
。
现在就通过使用
CLAPACK
中的一个函数
sgesv_
解线性方程组来学习一下使用的方法。
包括此函数在内的所有函数可以在
CLAPACK/SRC
下找到源代码,并在代码中有函数参数的说明信息。
sgesv_
的代码文件就是
sgesv.c
。
int sgesv_(integer *n, integer *nrhs, real *a, integer *lda, integer *ipiv, real *b, integer *ldb, integer *info)
sgesv_
的功能是使用
LU
分解法解线性方程组
AX=B
,其中
A
是一个
n*n
的方阵。
integer *n,
方程的个数,也就是
A
的行数和列数
integer *nrhs, B
的列数
real *a,
存储矩阵
A
数据的一维数组,在
fortran
中,数组是列主序存储,在此
a
中的二维数据也必须是列主序
integer *lda,
等于
n
integer *ipiv,
一个输出数据数组,数组大小是
n
,具体什么功能不太明白,但是似乎不影响最后结果,谁明白请告诉我
real *b,
存储矩阵
B
数据的一维数组,在
fortran
中,数组是列主序存储,在此
b
中的二维数据也必须是列主序
integer *ldb,
等于
n
integer *info,
输出参数,如果返回此参数为
0
,表示函数正常退出,否则表示出错
在此,我用了高教同济大学版线性代数第二版
106
页,
2
题
(1)
的数据。
A:
4,2,
-
1
3,
-
1,2
11,0,3
B:
2
10
8
代码:
#include
<iostream>
using
namespace
std;
#include
<F2CLIBS/f2c.h>
//
因为程序是
C++
,而
CLAPACK
是
C
语言写的,所以在此处用
extern
关键字
extern
"C"
{
#include
<clapack.h>
}
int
main(
void
) {
integer M=3 ;
integer N=1;
real a[9]={4,3,11,2,-1,0,-1,2,3};
real b[3]={2,10,8};
integer lda;
integer ldb;
integer INFO;
lda=M;
ldb=M;
integer ipiv[M];
sgesv_(&M, &N, a, &lda,ipiv, b, &ldb, &INFO);
if
(INFO==0)
{
for
(
int
i=0;i<M;i++)
{
cout<<b[i]<<
endl
;
}
}
else
{
cout<<
"Failed."
<<
endl
;
}
return
EXIT_SUCCESS;
}
程序编译链接的时候,
lapack_LINUX.a
,
tmglib_LINUX.a
,
blas_LINUX.a
,
libF77.a
,
libI77.a
这几个库文件都需要链接进去。
运算结果:
-14
56
54