我将不同意其他一些答案,并说我相信弄清楚如何使用 LAPACK在科学计算领域很重要。
但是,使用 LAPACK 有很大的学习曲线。这是因为它是在非常低的级别上编写的。这样做的缺点是它看起来很神秘,而且感觉不愉快。它的优点是界面明确,基本不会改变。此外,LAPACK 的实施,例如英特尔数学内核库,速度非常快。
出于我自己的目的,我有自己的更高级别的 C++ 类,这些类包含 LAPACK 子例程。许多科学图书馆也在底层使用 LAPACK。有时只使用它们会更容易,但在我看来,理解下面的工具有很多价值。为此,我提供了一个使用 LAPACK 用 C++ 编写的小型工作示例来帮助您入门。这适用于 Ubuntu,安装了liblapack3
软件包,以及其他必要的构建软件包。它可能可以在大多数 Linux 发行版中使用,但是 LAPACK 的安装和链接可能会有所不同。
这是文件test_lapack.cpp
#include <iostream>
#include <fstream>
using namespace std;
// dgeev_ is a symbol in the LAPACK library files
extern "C" {
extern int dgeev_(char*,char*,int*,double*,int*,double*, double*, double*, int*, double*, int*, double*, int*, int*);
}
int main(int argc, char** argv){
// check for an argument
if (argc<2){
cout << "Usage: " << argv[0] << " " << " filename" << endl;
return -1;
}
int n,m;
double *data;
// read in a text file that contains a real matrix stored in column major format
// but read it into row major format
ifstream fin(argv[1]);
if (!fin.is_open()){
cout << "Failed to open " << argv[1] << endl;
return -1;
}
fin >> n >> m; // n is the number of rows, m the number of columns
data = new double[n*m];
for (int i=0;i<n;i++){
for (int j=0;j<m;j++){
fin >> data[j*n+i];
}
}
if (fin.fail() || fin.eof()){
cout << "Error while reading " << argv[1] << endl;
return -1;
}
fin.close();
// check that matrix is square
if (n != m){
cout << "Matrix is not square" <<endl;
return -1;
}
// allocate data
char Nchar='N';
double *eigReal=new double[n];
double *eigImag=new double[n];
double *vl,*vr;
int one=1;
int lwork=6*n;
double *work=new double[lwork];
int info;
// calculate eigenvalues using the DGEEV subroutine
dgeev_(&Nchar,&Nchar,&n,data,&n,eigReal,eigImag,
vl,&one,vr,&one,
work,&lwork,&info);
// check for errors
if (info!=0){
cout << "Error: dgeev returned error code " << info << endl;
return -1;
}
// output eigenvalues to stdout
cout << "--- Eigenvalues ---" << endl;
for (int i=0;i<n;i++){
cout << "( " << eigReal[i] << " , " << eigImag[i] << " )\n";
}
cout << endl;
// deallocate
delete [] data;
delete [] eigReal;
delete [] eigImag;
delete [] work;
return 0;
}
这可以使用命令行构建
g++ -o test_lapack test_lapack.cpp -llapack
这将生成一个名为test_lapack
. 我已将其设置为读取文本输入文件。这是一个名为matrix.txt
包含 3x3 矩阵的文件。
3 3
-1.0 -8.0 0.0
-1.0 1.0 -5.0
3.0 0.0 2.0
要运行程序,只需键入
./test_lapack matrix.txt
在命令行,输出应该是
--- Eigenvalues ---
( 6.15484 , 0 )
( -2.07742 , 3.50095 )
( -2.07742 , -3.50095 )
评论:
- 您似乎对 LAPACK 的命名方案感到厌烦。这里有一个简短的描述。
- DGEEV 子程序的接口在这里。您应该能够将那里的参数描述与我在这里所做的进行比较。
- 请注意
extern "C"
顶部的部分,我在dgeev_
. 这是因为该库是用 Fortran 编写和构建的,因此在链接时需要使符号匹配。这取决于编译器和系统,所以如果你在 Windows 上使用它,它都必须改变。
- 有些人可能会建议使用LAPACK 的 C 接口。他们可能是对的,但我一直都是这样做的。