나는 다른 답변들 중 일부에 동의하지 않고 과학 컴퓨팅 분야에서 LAPACK을 사용하는 방법을 알아내는 것이 중요 하다고 생각합니다 .
그러나 LAPACK 사용에는 큰 학습 곡선이 있습니다. 매우 낮은 수준으로 작성 되었기 때문입니다. 단점은 매우 비밀스럽고 감각이 즐겁지 않다는 것입니다. 그것의 장점은 인터페이스가 명확하고 기본적으로 변경되지 않는다는 것입니다. 또한 Intel Math Kernel Library 와 같은 LAPACK의 구현 은 실제로 빠릅니다.
내 자신의 목적을 위해 LAPACK 서브 루틴을 둘러싼 고급 C ++ 클래스가 있습니다. 많은 과학 도서관에서도 LAPACK을 사용합니다. 때로는 그냥 사용하는 것이 더 쉽지만 내 생각으로는 도구를 이해하는 데 많은 가치가 있습니다. 이를 위해 LAPACK을 사용하여 C ++로 작성된 작은 작업 예제를 제공했습니다. 우분투에서 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 인터페이스를 사용하도록 제안 할 수 있습니다 . 그들이 옳을 수도 있지만, 나는 항상 이런 식으로 해왔다.