【发布时间】:2019-04-09 19:28:14
【问题描述】:
我正在尝试实现矩阵的伪逆计算 A*,以求解具有 C++ 维度的方形 nxn 矩阵 A 的 Ax=b。 A* 的算术公式是通过 SVD 分解。
所以首先我计算 SVD(A)=USV^T 然后 A*=VSU^T,其中 S 是反对角线 S,其非零元素 si 在 S* 中变为 1/si。最后我计算解 x=A*b
但是我没有得到正确的结果。我将 LAPACKE 接口用于 c++ 和 cblas 用于矩阵乘法。这是我的代码:
double a[n * n] = {2, -1, 2,1};
double b[n]={3,4};
double u[n * n], s[n],vt[n * n];
int lda = n, ldu = n, ldvt = n;
int info = LAPACKE_dgesdd(LAPACK_COL_MAJOR, 'A', n, n, a, lda, s,
u, ldu, vt, ldvt);
for (int i = 0; i < n; i++) {
s[i] = 1.0 / s[i];
}
const int a = 1;
const int c = 0;
double r1[n];
double r2[n];
double res[n];
//compute the first multiplication s*u^T
cblas_dgemm( CblasColMajor,CblasNoTrans, CblasTrans, n, n, n, a, u, ldvt, s, ldu, c, r1, n);
//compute the second multiplication v^T^T=vs*u^T
cblas_dgemm( CblasColMajor,CblasTrans, CblasNoTrans, n, n, n, a, vt, ldvt, r1, ldu, c, r2, n);
//now that we have the pseudoinverse A* solve by multiplying with b.
cblas_dgemm( CblasColMajor,CblasNoTrans, CblasNoTrans, n, 1, n, a, r2, ldvt, b, ldu, c, res, n);
在第二个 cblas_dgemm 之后,预计在 r2 中有 A* 伪逆。但是,在与 matlab pinv 比较后,我没有得到相同的结果。如果我打印 r2 结果给出:
0.25 0.50
0.25 0.50
但应该是
0.25 -0.50
0.25 0.50
【问题讨论】:
-
一个
n x n矩阵只有一个逆矩阵,而不是一个伪逆矩阵。要存在不同的伪逆矩阵,您需要不相等的维度。 -
仍然为什么不像在 matlab 或 numpy 中那样计算伪逆?
标签: c++ lapack svd lapacke cblas