如何找到近乎奇异矩阵的逆矩阵?

How to find an inverse of a nearly singular matrix?

本文关键字:何找      更新时间:2023-10-16

我正在使用C++和CUDA实现一种算法。但是当我试图找到一个特殊矩阵的逆矩阵时,我遇到了麻烦。 此矩阵具有以下功能:

  1. 它是一个方阵(假设:(m+3)x(m+3),m>0);
  2. 它的
  3. 转置矩阵是它的自我;
  4. 它的主要对角线必须是零;
  5. 它的右下角必须有一个 3x3 零矩阵;
  6. 你可以以这种形式考虑这个矩阵:H = [A ,B ;B' ,0];

我尝试了一些方法,但都失败了:

  1. 伪逆矩阵:

    我最初使用 matlab,当我尝试使用 inv(H'*H) 时收到错误或警告:警告:矩阵对工作精度是单数,或者矩阵接近单数或缩放不良

  2. 一些近似方法:

    参考资料在这里:近似 我发现了两种方法:高斯-乔丹消除和乔列斯基分解.当我在 matlab 中尝试 chol 时,我得到以下错误:矩阵必须是正定的

有人可以给我一些建议吗?

最好了解有关您的特定问题的更多信息,特别是如果您需要逆本身或只需要反转线性方程组。我会尽量给你指导这两种情况。

让我从你的矩阵几乎是奇异的,所以你的系统状况不佳的考虑开始。

确定近奇异矩阵的逆

矩阵正如在上面的评论和回答中已经澄清的那样,寻求近乎奇异矩阵的逆矩阵是没有意义的。有意义的是构造矩阵的正则化逆。您可以通过诉诸矩阵的光谱分解(奇异值分解或 SVD)来做到这一点。更详细地说,您可以构造奇异系统,删除作为矩阵近奇异行为的来源的最不重要的奇异值,然后使用奇异值和向量形成近似逆。当然,在这种情况下,A*A_inv只会给出单位矩阵的近似值。

如何在 GPU 上完成此操作?首先,我要说的是,在C++或 CUDA 中实现 SVD 算法绝非易事。您应该根据所需的精度选择几种技术,例如,确定奇异值。无论如何,Matlab 有一组在 GPU 上运行的线性代数函数。此外,CULA 和 Magma 是两个提供 SVD 计算例程的库。此外,您可以考虑使用Arrayfire,它也提供线性代数例程,包括SVD。

反转一个近乎奇异的系统

在这种情况下,您应该考虑使用某种 Tikhonov 正则化,其中包括将线性系统的反演表述为优化问题并添加一个正则化项,这可能取决于您已经了解的关于您的 uknowns 的特征。

对于上述两种情况,我建议阅读一些理论。本书

M. Bertero, P. Boccacci, 成像中的逆问题简介

如果您必须找到近似逆,或者如果您具有显式反转线性系统,这将很有用。

伪逆矩阵是inv(H'*H)*H'的,因为H的条件数非常高(试试cond(H)),你可能需要正则化因子来得到伪逆矩阵:inv(H'*H + lambda*eye(size(H)))*H'lambda越小,这种估计将达到的偏差越低。但是lambda值太小会导致高方差(条件不佳)。您可以尝试最适合的值。

您当然可以直接使用pinv(H)。之所以pinv(H)*H ~= eye(size(H))是因为pinv(H)只是秩低于size(H,1)的矩阵H的倒数的近似值。换句话说,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行。查看此页面以获取更多详细信息。