在 C 中使用 lapack 计算矩阵的逆
我希望能够使用 lapack 计算 C/C++ 中一般 NxN
矩阵的逆。
我的理解是,在 lapack 中进行反转的方法是使用 dgetri 函数,但是,我无法弄清楚它的所有参数应该是什么。
这是我的代码:
void dgetri_(int* N, double* A, int* lda, int* IPIV, double* WORK, int* lwork, int* INFO);
int main(){
double M [9] = {
1,2,3,
4,5,6,
7,8,9
};
return 0;
}
您如何完成它以使用 dgetri_ 获得 3x3
矩阵 M 的逆?
I would like to be able to compute the inverse of a general NxN
matrix in C/C++ using lapack.
My understanding is that the way to do an inversion in lapack is by using the dgetri
function, however, I can't figure out what all of its arguments are supposed to be.
Here is the code I have:
void dgetri_(int* N, double* A, int* lda, int* IPIV, double* WORK, int* lwork, int* INFO);
int main(){
double M [9] = {
1,2,3,
4,5,6,
7,8,9
};
return 0;
}
How would you complete it to obtain the inverse of the 3x3
matrix M using dgetri_?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
以下是在 C/C++ 中使用 lapack 计算矩阵逆的工作代码:
Here is the working code for computing the inverse of a matrix using lapack in C/C++:
首先,M 必须是二维数组,例如 double M[3][3]。从数学上来说,你的数组是一个 1x9 向量,它是不可逆的。
N 是一个指向 int 的指针
矩阵的阶数 - 在这种情况下,
N=3。
A 是指向 LU 的指针
矩阵因式分解,其中
你可以通过运行 LAPACK 来获得
例程
dgetrf
。LDA 是一个整数,表示“前导
矩阵的元素”,这使得
你挑选出一个更大的子集
如果你只想反转矩阵
小块。如果你想反转
整个矩阵,LDA 应该是
等于 N。
IPIV 是
矩阵,换句话说,它是一个列表
交换哪些行的指令
以便对矩阵求逆。 IPIV
应由 LAPACK 生成
例程
dgetrf
。LWORK 和 WORK 是“工作空间”
由 LAPACK 使用。如果你正在反转
整个矩阵,LWORK 应该是
int 等于 N^2,并且 WORK 应该是
具有 LWORK 元素的双精度数组。
INFO 只是一个状态变量
告诉你是否操作
成功完成。由于并非所有
矩阵是可逆的,我会
建议您将此发送给某些人
一种错误检查系统。 INFO=0 表示操作成功,INFO=-i 如果第 i 个参数的输入值不正确,并且 INFO > 。如果矩阵不可逆
所以,对于你的代码,我会做这样的事情:
First, M has to be a two-dimensional array, like
double M[3][3]
. Your array is, mathematically speaking, a 1x9 vector, which is not invertible.N is a pointer to an int for the
order of the matrix - in this case,
N=3.
A is a pointer to the LU
factorization of the matrix, which
you can get by running the LAPACK
routine
dgetrf
.LDA is an integer for the "leading
element" of the matrix, which lets
you pick out a subset of a bigger
matrix if you want to just invert a
little piece. If you want to invert
the whole matrix, LDA should just be
equal to N.
IPIV is the pivot indices of the
matrix, in other words, it's a list
of instructions of what rows to swap
in order to invert the matrix. IPIV
should be generated by the LAPACK
routine
dgetrf
.LWORK and WORK are the "workspaces"
used by LAPACK. If you are inverting
the whole matrix, LWORK should be an
int equal to N^2, and WORK should be
a double array with LWORK elements.
INFO is just a status variable to
tell you whether the operation
completed successfully. Since not all
matrices are invertible, I would
recommend that you send this to some
sort of error-checking system. INFO=0 for successful operation, INFO=-i if the i'th argument had an incorrect input value, and INFO > 0 if the matrix is not invertible.
So, for your code, I would do something like this:
这是使用 OpenBlas 与 LAPACKE 接口的上述工作版本。
与 openblas 库的链接(LAPACKE 已包含)
示例:
Here is a working version of the above using OpenBlas interface to LAPACKE.
Link with openblas library (LAPACKE is already contained)
Example:
这是上面 Spencer Nelson 示例的工作版本。关于它的一个谜团是输入矩阵是按行优先顺序排列的,尽管它似乎调用了底层的 fortran 例程
dgetri
。我被引导相信所有底层的 Fortran 例程都需要列主顺序,但我不是 LAPACK 专家,事实上,我正在使用这个示例来帮助我学习它。但是,抛开这个谜团不谈:示例中的输入矩阵是奇异的。 LAPACK 尝试通过在
errorHandler
中返回3
来告诉您这一点。我将该矩阵中的9
更改为19
,获得0
表示成功的errorHandler
,并比较了结果来自Mathematica
。比较也很成功,并确认示例中的矩阵应按行优先顺序排列,如所示。这是工作代码:
我在 Mac 上构建并运行它,如下所示:
我在 LAPACKE 库上执行了
nm
并发现了以下内容:看起来有一个 LAPACKE [原文如此] 包装器大概可以让我们不必为了 Fortran 的方便而到处获取地址,但我可能不会抽出时间去尝试它,因为我有前进的道路。
编辑
这是一个绕过 LAPACKE [原文如此] 的工作版本,直接使用 LAPACK fortran 例程。我不明白为什么行主输入会产生正确的结果,但我在 Mathematica 中再次确认了这一点。
像这样构建和运行:
编辑
这个谜团似乎不再是一个谜团。我认为计算是按列优先顺序完成的,因为它们必须如此,但我输入和打印矩阵就好像它们按行优先顺序一样。我有两个互相抵消的错误,所以即使它们是列式的,但它们看起来还是行式的。
Here is a working version of Spencer Nelson's example above. One mystery about it is that the input matrix is in row-major order, even though it appears to call the underlying fortran routine
dgetri
. I am led to believe that all the underlying fortran routines require column-major order, but I am no expert on LAPACK, in fact, I'm using this example to help me learn it. But, that one mystery aside:The input matrix in the example is singular. LAPACK tries to tell you that by returning a
3
in theerrorHandler
. I changed the9
in that matrix to a19
, getting anerrorHandler
of0
signalling success, and compared the result to that fromMathematica
. The comparison was also successful and confirmed that the matrix in the example should be in row-major order, as presented.Here is the working code:
I built and ran it as follows on a Mac:
I did an
nm
on the LAPACKE library and found the following:and it looks like there is a LAPACKE [sic] wrapper that would presumably relieve us of having to take addresses everywhere for fortran's convenience, but I am probably not going to get around to trying it because I have a way forward.
EDIT
Here is a working version that bypasses LAPACKE [sic], using LAPACK fortran routines directly. I do not understand why a row-major input produces correct results, but I confirmed it again in Mathematica.
built and run like this:
EDIT
The mystery no longer appears to be a mystery. I think the computations are being done in column-major order, as they must, but I am both inputting and printing the matrices as if they were in row-major order. I have two bugs that cancel each other out so things look row-ish even though they're column-ish.