如何求近似奇异矩阵的逆? 我用C++和CUDA实现了一个算法。但当我试图找到一个特殊矩阵的逆矩阵时,我遇到了麻烦。 该矩阵具有以下特点: 它是一个方阵(假设:(m+3)x(m+3),m>0) 其转置矩阵是其自身 其主对角线必须为零 它必须在右下角有一个3x3的零矩阵 你可以在这个形式中考虑这个矩阵:H= [A,B,B’,0 ];

如何求近似奇异矩阵的逆? 我用C++和CUDA实现了一个算法。但当我试图找到一个特殊矩阵的逆矩阵时,我遇到了麻烦。 该矩阵具有以下特点: 它是一个方阵(假设:(m+3)x(m+3),m>0) 其转置矩阵是其自身 其主对角线必须为零 它必须在右下角有一个3x3的零矩阵 你可以在这个形式中考虑这个矩阵:H= [A,B,B’,0 ];,c++,matlab,math,matrix,C++,Matlab,Math,Matrix,我尝试了一些方法,但都失败了: 伪逆矩阵: 我最初使用matlab,当我尝试使用inv(H'*H)时得到错误或警告:警告:矩阵对工作精度是奇异的或矩阵接近奇异或缩放不良 一些近似方法: 参考资料在这里:我发现了两种方法:高斯-乔丹消去法和Cholesky分解法。当我在matlab中尝试chol时,我得到了以下错误:矩阵必须是正定的 有人能给我一些建议吗?伪逆矩阵是inv(H'*H)*H',因为H的条件数非常高(trycond(H)),你可能需要一个正则化因子来获得伪逆矩阵:inv(H'*H+

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

  • 伪逆矩阵:

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

  • 一些近似方法:

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


  • 有人能给我一些建议吗?

    伪逆矩阵是
    inv(H'*H)*H'
    ,因为
    H
    的条件数非常高(try
    cond(H)
    ),你可能需要一个正则化因子来获得伪逆矩阵:
    inv(H'*H+lambda*eye(size(H))*H'
    。λ
    越小
    ,这种估计将获得越低的偏差。但是
    lambda
    的值太小将导致高方差(病态)。你可以试一套最合算的衣服

    当然,您可以直接使用
    pinv(H)
    。之所以
    pinv(H)*H~=eye(size(H))
    是因为
    pinv(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
    的行。查看此项了解更多详细信息。

    最好了解有关特定问题的更多信息,特别是如果您需要求逆,或者只需要求线性方程组的逆。我会尽力给你两种情况的说明

    让我从考虑矩阵几乎是奇异的开始,因此系统是病态的

    确定近似奇异矩阵的逆

    正如上面的评论和回答中所阐明的,寻求近似奇异矩阵的逆是毫无意义的。有意义的是构造矩阵的正则化逆。您可以借助矩阵的谱分解(奇异值分解,或SVD)来实现这一点。更详细地说,您可以构造奇异系统,删除作为矩阵近似奇异行为来源的最低有效奇异值,然后使用奇异值和向量形成近似逆。当然,在这种情况下,
    A*A_inv
    只会给出单位矩阵的近似值

    如何在GPU上实现这一点?首先,让我说,在C++或CUDA中实现SVD算法绝不是一项简单的任务。您应该根据所需的精度选择几种技术,例如,确定奇异值。不管怎样,Matlab有一套。另外,和是两个提供SVD计算例程的库。此外,您可以考虑使用也提供线性代数例程,包括SVD。 将一个近乎奇异的系统反转

    在这种情况下,你应该考虑使用某种吉洪诺夫正则化,它包括将线性系统的反演公式化为一个优化问题,并增加一个正则化项,这可能取决于你已经知道的关于未知函数的特征。 对于以上两种情况,我建议阅读一些理论。书


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

    通过“伪逆”您指的是由
    pinv
    计算的摩尔-彭罗斯伪逆吗?我不知道你在用inv(H'*H)做什么,但它看起来不像伪逆。@horchler,我只是按照伪逆矩阵的说明:1.得到转置:H';2.矩阵乘法:H'*H;3.计算新矩阵的逆:inv(H'*H);4.获取H:inv(H'*H)*H'@horchler的伪逆矩阵,我尝试了pinv()来获取逆矩阵:H_inv,但奇怪的是H*H_inv不是单位矩阵。这只是我算法的一步。所以,使用像pinv()这样的东西可能会给我带来潜在的bug…好的。这是一种天真的计算方法,警告是意料之中的。通常使用
    svd
    –键入
    edit pinv
    查看使用的代码。伪逆的全部要点是它不是真逆(当无法获得时使用),因此您不应该期望
    H*pinv(H)
    是单位矩阵。相反,根据文档和定义:
    H*pinv(H)*H
    equals
    H
    pinv(H)*H*pinv(H)
    equals
    pinv(H)
    @oilpig,我怀疑你的矩阵在结构上是奇异的,在这种情况下你无法将它们反转。但是我没有找到一个证明…我想用C++和CUDA来实现整个过程。当我在matlab中键入“edit pinv”时,我知道它使用SVD(),但它是一个内置函数,我看不到详细信息。那么,你有什么想法用C++实现这个功能吗?是的,你的资料很有用!非常感谢,我知道opencv有自己的函数来计算伪逆矩阵:cv::invert。那么,你能告诉我吗