用一个简单的例子理解 C++ 中的 LAPACK 调用
我是 LAPACK 和 C++/Fortran 接口的初学者.我需要在 Mac OS-X Lion 上使用 LAPACK/BLAS 解决线性方程和特征值问题.OS-X Lion 提供优化的 BLAS 和 LAPACK 库(在/usr/lib 中),我链接这些库而不是从 netlib 下载它们.
I am a beginner with LAPACK and C++/Fortran interfacing. I need to solve linear equations and eigenvalues problems using LAPACK/BLAS on Mac OS-X Lion. OS-X Lion provides optimized BLAS and LAPACK libraries (in /usr/lib) and I am linking these libraries instead of downloading them from netlib.
我的程序(转载如下)正在编译和运行良好,但它给了我错误的答案.我在网络和 Stackoverflow 中进行了研究,问题可能必须处理 C++ 和 Fortran 如何以不同格式存储数组(行专业与列专业).但是,正如您将在我的示例中看到的那样,我示例的简单数组在 C++ 和 fortran 中应该看起来相同.反正就这样吧.
My program (reproduced below) is compiling and running fine, but it is giving me wrong answers. I have researched in the web and Stackoverflow and the issue may have to deal with how C++ and Fortran store arrays in differing formats (row major vs Column major). However, as you will see in my example, the simple array for my example should look identical in C++ and fortran. Anyway here goes.
假设我们要解决以下线性系统:
Lets say we want to solve the following linear system:
x + y = 2
x - y = 0
解是 (x,y) = (1,1).现在我尝试使用 Lapack 解决这个问题,如下所示
The solution is (x,y) = (1,1). Now I tried to solve this using Lapack as follows
// LAPACK test code
#include<iostream>
#include<vector>
using namespace std;
extern "C" void dgetrs(char *TRANS, int *N, int *NRHS, double *A,
int *LDA, int *IPIV, double *B, int *LDB, int *INFO );
int main()
{
char trans = 'N';
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info;
vector<double> a, b;
a.push_back(1);
a.push_back(1);
a.push_back(1);
a.push_back(-1);
b.push_back(2);
b.push_back(0);
int ipiv[3];
dgetrs(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info);
std::cout << "solution is:";
std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl;
std::cout << "Info = " << info << std::endl;
return(0);
}
这段代码编译如下:
g++ -Wall -llapack -lblas lapacktest.cpp
但是,在运行它时,我得到的解决方案是 (-2,2),这显然是错误的.我已经尝试了矩阵 a
的所有行/列重新排列组合.还要注意 a
的矩阵表示在行和列格式中应该是相同的.我认为让这个简单的例子工作将使我开始使用 LAPACK,任何帮助将不胜感激.
On running this, however, I get the solution as (-2,2) which is obviously wrong. I have tried all combination of row/column re-arrangement of my matrix a
. Also observe the matrix representation of a
should be identical in row and column formats. I think getting this simple example to work will get me started with LAPACK and any help will be appreciated.
推荐答案
你需要分解矩阵(通过调用dgetrf
)才能使用<代码>dgetrs代码>.或者,您可以使用 dgesv
例程,它会为您完成这两个步骤.
You need to factor the matrix (by calling dgetrf
) before you can solve the system using dgetrs
. Alternatively, you can use the dgesv
routine, which does both steps for you.
顺便说一句,你不需要自己声明接口,它们在 Accelerate 头文件中:
By the way, you don't need to declare the interfaces yourself, they are in the Accelerate headers:
// LAPACK test code
#include <iostream>
#include <vector>
#include <Accelerate/Accelerate.h>
using namespace std;
int main()
{
char trans = 'N';
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info;
vector<double> a, b;
a.push_back(1);
a.push_back(1);
a.push_back(1);
a.push_back(-1);
b.push_back(2);
b.push_back(0);
int ipiv[3];
dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info);
dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info);
std::cout << "solution is:";
std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl;
std::cout << "Info = " << info << std::endl;
return(0);
}
相关文章