15

我注意到如果 A 是 NxN 矩阵并且它具有逆矩阵。但是 inv() 和 pinv() 函数的输出是不同的。- 我的环境是 Win7x64 SP1、Matlab R2012a、Cygwin Octave 3.6.4、FreeMat 4.2

看看 Octave 的例子:

A = rand(3,3)
A =
0.185987   0.192125   0.046346
0.140710   0.351007   0.236889
0.155899   0.107302   0.300623

pinv(A) == inv(A)
ans =
0 0 0
0 0 0
0 0 0
  • ans通过在 Matlab 中运行上述相同的命令,结果都是一样的。

  • 我计算inv(A)*Aor A*inv(A),结果是 Octave 和 Matlab 中的单位 3x3 矩阵。
  • 和的结果是 MatlabA*pinv(A)pinv(A)*AFreeMat 中的身份 3x3 矩阵。
  • 结果A*pinv(A)是 Octave 中的单位 3x3 矩阵。
  • 结果pinv(A)*A不是Octave 中身份 3x3 矩阵。

我不知道为什么inv(A) != pinv(A),我已经考虑了矩阵中元素的细节。似乎是导致此问题的浮动精度问题。

点后的 10+ 位可能会有所不同,如下所示:

  • 6.65858991579923298331777914427220821380615200000000inv(A)(1,1)反对的元素

  • 6.65858991579923209513935944414697587490081800000000元素在pinv(A)(1,1)

4

4 回答 4

16

这个问题已经很老了,但无论如何我都会回答它,因为它在一些谷歌搜索中几乎出现在首位。

我将在我的示例中使用返回 N×N 幻方的 magic(N) 函数。

我将创建一个 3x3 幻方 M3,取伪逆 PI_M3 并将它们相乘:

   prompt_$ M3 = 魔法(3),PI_M3 = pinv(M3),M3 * PI_M3
  M3 =

    8 1 6
    3 5 7
    4 9 2

  PI_M3 =

     0.147222 -0.144444 0.063889
    -0.061111 0.022222 0.105556
    -0.019444 0.188889 -0.102778

  答案=

     1.0000e+00 -1.2212e-14 6.3283e-15
     5.5511e-17 1.0000e+00 -2.2204e-16
    -5.9952e-15 1.2268e-14 1.0000e+00

如您所见,答案是除一些舍入误差外的单位矩阵。我将使用 4x4 魔方重复该操作:

   prompt_$ M4 = magic(4) , PI_M4 = pinv(M4) , M4 * PI_M4
 
  M4 =

     16 2 3 13
      5 11 10 8
      9 7 6 12
      4 14 15 1

  PI_M4 =

     0.1011029 -0.0738971 -0.0613971 0.0636029
    -0.0363971 0.0386029 0.0261029 0.0011029
     0.0136029 -0.0113971 -0.0238971 0.0511029
    -0.0488971 0.0761029 0.0886029 -0.0863971

  答案=

     0.950000 -0.150000 0.150000 0.050000
    -0.150000 0.550000 0.450000 0.150000
     0.150000 0.450000 0.550000 -0.150000
     0.050000 0.150000 -0.150000 0.950000

结果不是单位矩阵,这意味着 4x4 幻方没有逆矩阵。我可以通过尝试 Moore-Penrose 伪逆的规则之一来验证这一点:

   prompt_$ M4 * PI_M4 * M4
  
答案=

   16.00000 2.00000 3.00000 13.00000
    5.00000 11.00000 10.00000 8.00000
    9.00000 7.00000 6.00000 12.00000
    4.00000 14.00000 15.00000 1.00000

满足规则 A*B*A = A。这表明 pinv 在逆矩阵可用时返回逆矩阵,在逆矩阵不可用时返回伪逆矩阵。这就是为什么在某些情况下您会得到很小的差异,只是一些舍入误差,而在其他情况下您会得到更大的差异。为了展示它,我将得到两个魔象限的倒数并从伪逆中减去它们:

   prompt_$ I_M3 = inv(M3) , I_M4 = inv(M4) , DIFF_M3 = PI_M3 - I_M3, DIFF_M4 = PI_M4 - I_M4
  I_M3 =

     0.147222 -0.144444 0.063889
    -0.061111 0.022222 0.105556
    -0.019444 0.188889 -0.102778

  警告:逆:矩阵奇异到机器精度,rcond = 1.30614e-17
  I_M4 =

     9.3825e+13 2.8147e+14 -2.8147e+14 -9.3825e+13
     2.8147e+14 8.4442e+14 -8.4442e+14 -2.8147e+14
    -2.8147e+14 -8.4442e+14 8.4442e+14 2.8147e+14
    -9.3825e+13 -2.8147e+14 2.8147e+14 9.3825e+13

  DIFF_M3 =

     4.7184e-16 -1.0270e-15 5.5511e-16
    -9.9226e-16 2.0470e-15 -1.0825e-15
     5.2042e-16 -1.0270e-15 4.9960e-16

  DIFF_M4 =

    -9.3825e+13 -2.8147e+14 2.8147e+14 9.3825e+13
    -2.8147e+14 -8.4442e+14 8.4442e+14 2.8147e+14
     2.8147e+14 8.4442e+14 -8.4442e+14 -2.8147e+14
     9.3825e+13 2.8147e+14 -2.8147e+14 -9.3825e+13
于 2015-08-10T13:41:00.660 回答
9

在我看来,您在这里的底部回答了您自己的问题。原因是浮点运算。inv()和的算法pinv()并不完全相同,因为pinv()必须能够处理非方阵。因此,答案不会完全相同。

如果您查看 的值pinv(A)*A,您会发现它非常接近单位矩阵。

我得到:

ans =

   1.0000e+00   6.1062e-16  -3.0809e-15
  -5.8877e-15   1.0000e+00   6.3942e-15
   2.4425e-15  -3.0184e-16   1.0000e+00

不要将矩阵与 进行比较,而是==使用< tolerance_limit

c = A*pinv(A);
d = pinv(A)*A;

(c-d) < 1e-10

边注:

x = A^-1*b不应该解决x = inv(A)*b;,而是x = A \ b;参见Shai 发布的链接以获得解释。

于 2013-10-17T10:34:04.767 回答
2

浮点运算具有一定的精度,不能依赖相等。为避免此类错误,您可以尝试使用 matlab 的符号工具箱。

八度音程中非常简单的代码行来演示问题:

>>> (1/48)*48==(1/49)*49
ans = 0
>>> (1/48)*48-(1/49)*49
ans =  1.1102e-16
>>>
于 2013-10-17T10:06:39.463 回答
0

A=[1,1,0;1,0,1;2,1,1]我通过使用计算了(秩为 2)的伪逆矩阵pinv(A)A*pinv(A)给出一个非恒等矩阵,即A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667]. 我认为对于奇异矩阵,最好svd()手动计算伪逆矩阵。

这是一些更新:A*pinv(A)它本身可能与单位矩阵不同,因为它是非满秩的。它可能不依赖于 Matlab 算法pinv(A)

于 2021-11-03T15:46:51.440 回答