我正在实现一种使用C ++和CUDA的算法。但是当我试图找到一个特殊矩阵的逆时,我遇到了麻烦。 该矩阵具有以下特征:
我尝试了一些方法,但都失败了:
伪逆矩阵:
我首先使用了matlab,当我尝试使用inv(H'* H)时出现错误或警告: 警告:Matrix对于工作精度是单数的 或< strong> 矩阵接近单一或严重缩放
一些近似方法:
参考资料在这里:approximation我发现了两种方法:Gauss-Jordan消除和Cholesky分解。当我在matlab中尝试chol时,我得到以下 错误:Matrix必须是正定的
任何人都可以给我一些建议吗?
答案 0 :(得分:1)
最好了解一些有关特定问题的信息,特别是如果您需要反向本身,或者您只需要反转一个线性方程组。我会尽力给你两个案例的指示。
让我首先考虑你的矩阵几乎是单数,因此你的系统是病态的。
确定近似奇异矩阵的反转
正如上面的评论和答案中所阐明的那样,寻找近似奇异矩阵的逆是没有意义的。有意义的是构造矩阵的正则化逆。您可以通过使用矩阵的谱分解(奇异值分解或SVD)来做到这一点。更详细地说,您可以构造奇异系统,去除最不重要的奇异值,这些奇异值是矩阵的近似奇异行为的来源,然后使用奇异值和向量来形成近似逆。当然,在这种情况下,A*A_inv
仅给出单位矩阵的近似值。
如何在GPU上完成?首先,我要说在C ++或CUDA中实现SVD算法绝非易事。根据您需要的精度,您应该选择几种技术,例如,确定奇异值。无论如何,Matlab有一组linear algebra functions working on GPU。此外,CULA和Magma是提供SVD计算例程的两个库。此外,您可以考虑使用Arrayfire,它还提供线性代数例程,包括SVD。
倒置一个奇异的奇异系统
在这种情况下,您应该考虑使用某种Tikhonov正则化,其中包括将线性系统的反演作为优化问题并添加正则化项,这可能取决于您已知的有关您的未知数的特征。
对于上述两种情况,我建议阅读一些理论。这本书
M. Bertero, P. Boccacci, Introduction to Inverse Problems in Imaging
如果你必须找到一个近似的逆或者你明确地反转了线性系统,那么会很有用。
答案 1 :(得分:0)
伪逆矩阵是inv(H'*H)*H'
,因为H
的条件数非常高(try cond(H)
),你可能需要一个正则化因子来获得伪逆矩阵:inv(H'*H + lambda*eye(size(H)))*H'
。 lambda
越小,这种估计的偏差越小。但lambda
的值太小会导致高度差异(病态)。您可以尝试最佳套装价值。
您当然可以直接使用pinv(H)
。 pinv(H)*H ~= eye(size(H))
之所以是因为pinv(H)
只是矩阵H
的倒数的近似值,其等级低于size(H,1)
。换句话说,H
中的列并非完全独立。
我想向您展示一个非常简单的例子:
>>a =
0 1 0
0 0 1
0 1 0
pinv(a) * a
>>
ans =
0 0 0
0 1.0000 0
0 0 1.0000
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>>a =
1 0
0 1
1 0
pinv(a) * a
>>
ans =
1.0000 0
0 1.0000
注意a * pinv(a)
不是单位矩阵,因为a
的列是线性独立的,而不是a
的行。有关详细信息,请查看此page。