Saya akan tidak setuju dengan beberapa jawaban lain dan mengatakan bahwa saya percaya bahwa mencari tahu cara menggunakan LAPACK adalah penting dalam bidang komputasi ilmiah.
Namun, ada kurva belajar yang besar untuk menggunakan LAPACK. Ini karena ini ditulis pada tingkat yang sangat rendah. Kerugian dari itu adalah bahwa itu tampak sangat samar, dan tidak menyenangkan indra. Keuntungannya adalah bahwa antarmuka tidak ambigu dan pada dasarnya tidak pernah berubah. Selain itu, implementasi LAPACK, seperti Perpustakaan Intel Math Kernel sangat cepat.
Untuk keperluan saya sendiri, saya memiliki kelas C ++ tingkat tinggi saya sendiri yang membungkus subrutin LAPACK. Banyak perpustakaan ilmiah juga menggunakan LAPACK di bawahnya. Terkadang lebih mudah untuk hanya menggunakannya, tetapi menurut saya ada banyak nilai dalam memahami alat di bawahnya. Untuk itu, saya telah memberikan contoh kerja kecil yang ditulis dalam C ++ menggunakan LAPACK untuk membantu Anda memulai. Ini berfungsi di Ubuntu, dengan liblapack3
paket diinstal, dan paket lain yang diperlukan untuk membangun. Ini mungkin dapat digunakan di sebagian besar distribusi Linux, tetapi instalasi LAPACK dan menghubungkannya dapat bervariasi.
Ini filenya 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;
}
Ini dapat dibangun menggunakan baris perintah
g++ -o test_lapack test_lapack.cpp -llapack
Ini akan menghasilkan nama yang dapat dieksekusi test_lapack
. Saya telah mengatur ini untuk dibaca dalam file input teks. Berikut adalah file bernama yang matrix.txt
mengandung matriks 3x3.
3 3
-1.0 -8.0 0.0
-1.0 1.0 -5.0
3.0 0.0 2.0
Untuk menjalankan program cukup ketik
./test_lapack matrix.txt
di baris perintah, dan output seharusnya
--- Eigenvalues ---
( 6.15484 , 0 )
( -2.07742 , 3.50095 )
( -2.07742 , -3.50095 )
Komentar:
- Anda sepertinya terlempar oleh skema penamaan untuk LAPACK. Deskripsi singkat ada di sini .
- Antarmuka untuk subroutine DGEEV ada di sini . Anda harus dapat membandingkan deskripsi argumen di sana dengan apa yang saya lakukan di sini.
- Perhatikan
extern "C"
bagian di atas, dan saya telah menambahkan garis bawah ke dgeev_
. Itu karena perpustakaan ditulis dan dibangun di Fortran, jadi ini perlu untuk membuat simbol cocok ketika menghubungkan. Ini adalah kompiler dan bergantung pada sistem, jadi jika Anda menggunakan ini pada Windows, semuanya harus berubah.
- Beberapa orang mungkin menyarankan menggunakan antarmuka C ke LAPACK . Mereka mungkin benar, tetapi saya selalu melakukannya dengan cara ini.