ฉันจะไม่เห็นด้วยกับคำตอบอื่น ๆ และบอกว่าฉันเชื่อว่าการหาวิธีใช้ LAPACK นั้นมีความสำคัญในด้านการคำนวณทางวิทยาศาสตร์
อย่างไรก็ตามมีช่วงการเรียนรู้ขนาดใหญ่สำหรับการใช้ LAPACK นี่เป็นเพราะมันถูกเขียนในระดับต่ำมาก ข้อเสียของมันคือมันดูลึกลับมากและไม่พอใจกับความรู้สึก ข้อดีของมันคืออินเทอร์เฟซไม่ชัดเจนและโดยทั่วไปจะไม่เปลี่ยนแปลง นอกจากนี้การใช้งาน LAPACK เช่นไลบรารี Intel Math Kernelนั้นรวดเร็วมาก
สำหรับวัตถุประสงค์ของฉันฉันมีคลาส C ++ ระดับสูงกว่าของฉันซึ่งล้อมรอบรูทีนย่อย LAPACK ห้องสมุดวิทยาศาสตร์หลายแห่งใช้ LAPACK ภายใต้ บางครั้งมันง่ายกว่าที่จะใช้มัน แต่ในความคิดของฉันมีค่ามากในการทำความเข้าใจเครื่องมือที่อยู่ด้านล่าง ด้วยเหตุนี้ฉันจึงได้ยกตัวอย่างการทำงานเล็ก ๆ ที่เขียนใน C ++ โดยใช้ LAPACK เพื่อให้คุณเริ่มต้นได้ สิ่งนี้ใช้ได้ใน Ubuntu พร้อมกับliblapack3
แพ็คเกจที่ติดตั้งและแพ็คเกจอื่น ๆ ที่จำเป็นสำหรับการสร้าง มันอาจถูกใช้ในลีนุกซ์ส่วนใหญ่, แต่การติดตั้ง 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 ทุกอย่างจะต้องเปลี่ยน
- บางคนอาจจะแนะนำให้ใช้อินเตอร์เฟซ C ถึง LAPACK พวกมันอาจจะถูก แต่ฉันก็ทำแบบนี้มาตลอด