简体   繁体   English

为什么在 Matlab 和 Octave 中 inv() 和 pinv() 的输出不相等?

[英]Why is the output of inv() and pinv() not equal in Matlab and Octave?

I have noticed that if A is a NxN matrix and it has the inverse matrix.我注意到如果 A 是 NxN 矩阵并且它有逆矩阵。 But what the inv() and pinv() function output is different.但是 inv() 和 pinv() 函数输出的是什么不同。 - My environment is Win7x64 SP1, Matlab R2012a, Cygwin Octave 3.6.4, FreeMat 4.2 - 我的环境是 Win7x64 SP1、Matlab R2012a、Cygwin Octave 3.6.4、FreeMat 4.2

Have a look at the examples from Octave:看看 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
  • It's all the same ans result by running the same command above in Matlab.这一切都同ans运行上面在Matlab相同的命令造成的。

  • And I calculate inv(A)*A or A*inv(A) , the result is identity 3x3 matrix in both Octave and Matlab.我计算inv(A)*AA*inv(A) ,结果是 Octave 和 Matlab 中的恒等 3x3 矩阵。
  • The result of A*pinv(A) and pinv(A)*A are identity 3x3 matrix in Matlab and FreeMat. A*pinv(A)pinv(A)*A是 Matlab 和 FreeMat 中的恒等 3x3 矩阵。
  • The result of A*pinv(A) is identity 3x3 matrix in Octave. A*pinv(A)是 Octave 中的恒等 3x3 矩阵。
  • The result of pinv(A)*A is not identity 3x3 matrix in Octave. pinv(A)*A的结果不是Octave 中的恒等 3x3 矩阵。

I don't know the reason why inv(A) != pinv(A) , I have considered the details of the element in the matrix.我不知道为什么inv(A) != pinv(A) ,我已经考虑了矩阵中元素的细节。 It seems to be the floating accuracy problem which causes this problem.似乎是浮动精度问题导致了这个问题。

The 10+ digits after the dot point may be different like this:点后的 10+ 位数字可能会不同,如下所示:

  • 6.65858991579923298331777914427220821380615200000000 element in inv(A)(1,1) against 6.65858991579923298331777914427220821380615200000000 inv(A)(1,1)中的元素反对

  • 6.65858991579923209513935944414697587490081800000000 element in pinv(A)(1,1) 6.65858991579923209513935944414697587490081800000000 pinv(A)(1,1)元素

This question is quite old, but I'll answer it anyway because it appears almost on top in some google searches. 这个问题很老了,但无论如何我都会回答它,因为它似乎在一些谷歌搜索中几乎排在最前面。

I'll use for my example the magic(N) function which returns an N-by-N magic square. 我将在我的例子中使用魔法(N)函数,该函数返回N-by-N魔方。

I'll create a 3x3 magic square M3, take the pseudoinverse PI_M3 and multiply them: 我将创建一个3x3魔方M3,取伪逆PI_M3并乘以它们:

prompt_$ M3 = magic(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

  ans =

     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

As you can see the answer is the identity matrix save for some rounding errors. 正如您所看到的,答案是单位矩阵,以节省一些舍入误差。 I'll repeat the operation with a 4x4 magic square: 我将用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

  ans =

     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

The result is not the identity matrix, it means that the 4x4 magic square does not have an inverse. 结果不是单位矩阵,这意味着4x4魔方不具有逆。 I can verify this by trying one of the rules of the Moore-Penrose pseudoinverse: 我可以通过尝试Moore-Penrose伪逆的一个规则来验证这一点:

prompt_$ M4 * PI_M4 * M4
ans =

   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

The rule A*B*A = A is satisfied. 满足规则A * B * A = A. This shows that pinv returns the inverse matrix when it is available and the pseudoinverse when the inverse is not available. 这表明pinv在可用时返回逆矩阵,而当逆矩阵不可用时返回伪逆。 This is the reason why in some situations you get a small difference, just some rounding errors, and in other situations you get a bigger difference. 这就是为什么在某些情况下你会得到一个小的差异,只是一些舍入错误,在其他情况下你会得到更大的差异。 To show it I'll get the inverse of both magic quadrants and subtract them from the pseudoinverse: 为了显示它,我将获得两个魔术象限的倒数并从伪逆中减去它们:

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

  warning: inverse: matrix singular to machine precision, 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

It seems to me like you answered your own question in the bottom here. 在我看来,你在底部回答了自己的问题。 The reason is floating point arithmetic. 原因是浮点运算。 The algortihms for inv() and pinv() are not exactly the same, as pinv() must be able to handle non-square matrices. inv()pinv()不完全相同,因为pinv()必须能够处理非方形矩阵。 Therefore the answers will not be exactly the same. 因此答案将不完全相同。

If you look at the value of pinv(A)*A , you will see that it's very very close to the identity matrix. 如果你看一下pinv(A)*A ,你会发现它非常接近单位矩阵。

I get: 我明白了:

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

Instead of comparing the matrices with == , use < tolerance_limit 不要将矩阵与==进行比较,而是使用< tolerance_limit

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

(c-d) < 1e-10

Sidenote: 边注:

x = A^-1*b should not be solved x = inv(A)*b; x = A^-1*b不应解决x = inv(A)*b; , but rather x = A \\ b; ,而是x = A \\ b; See the link Shai posted for explanations. 请参阅Shai发布的链接以获取解释。

Floating point arithmetic has a certain precision, you can not rely on equality. 浮点运算具有一定的精度,可以不依赖于等式。 To avoid such errors, you could try to work with the symbolic toolbox of matlab. 为避免此类错误,您可以尝试使用matlab的符号工具箱。

Very simple line of code in octave to demonstrate the problems: 非常简单的八度代码行来演示问题:

>>> (1/48)*48==(1/49)*49
ans = 0
>>> (1/48)*48-(1/49)*49
ans =  1.1102e-16
>>>

I computed the pseudo-inverse matrix of A=[1,1,0;1,0,1;2,1,1] (which is of rank 2) by using pinv(A) .我通过使用pinv(A)计算了A=[1,1,0;1,0,1;2,1,1] (等级为 2)的伪逆矩阵。 A*pinv(A) gives a non-identity matrix, which is A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667] A*pinv(A)给出了一个非单位矩阵,即A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667] A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667] A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667] . A*pinv(A)=[0.667, -0.333, 0.333; -0.333, 0.667,0.333; 0.333, 0.333, 0.667] I think for singular matrices, it is better to compute the pseudo-inverse matrix using svd() manually.我认为对于奇异矩阵,最好使用svd()手动计算伪逆矩阵。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM