-1

I am trying to find inverse of an np.matrix data type (It is also same for np.array). Calling np.linalg.inverse on matrix yields two close but different results. What causes this and which one is preferable to other?

Since matrix data type uses vector multiplication while using '*' operator, should not we get [m.T * m]^-1 = m^-1 * m.T^-1
m^-1 * m.T^-1 * m.T = m^-1

for result 1? Thus, result 1 would be equal to result 2.

I realized the way we calculate result 1 is the correct way to implement in order to get perspective projection matrix of an image since it gives the same result with cv2.getPerspectiveTransform. Is there a specific reason for this?

>>> m = np.matrix(v)
>>> m
>>> matrix([[  3.,   4.,   1.],
        [  2.,  44.,  55.],
        [ 99., 129., 343.]])

>>> res1 = np.linalg.inv(m.T * m) * m.T
>>> res2 = np.linalg.inv(m)

>>> res1
matrix([[ 0.2054252613732362, -0.0319299237072599,  0.0045210511443909],
        [ 0.122248195432692 ,  0.0238896452516133, -0.0041871098666807],
        [-0.1052685658506345,  0.000231190115337 ,  0.0031852860335482]])
>>> res2
matrix([[ 0.2054252613732693, -0.0319299237072619,  0.0045210511443911],
        [ 0.1222481954327108,  0.0238896452516119, -0.0041871098666804],
        [-0.1052685658506512,  0.0002311901153382,  0.0031852860335483]])
yokus
  • 145
  • 2
  • 10
  • 3
    Computations on floating point numbers are not exact, so both results only approximate the exact values of the inverse matrix. For example, the actual value of the element of the inverse matrix in the first row and the first column is 727/3539. The first 30 digits of the decimal expansion of this fraction are 0.205425261373269285108787793162. – bb1 Nov 08 '21 at 00:24
  • 2
    `*` does elementwise multiplication. if you want matrix multiplication, use `@` (a relatively new infix operator). -- the transpose is *not* generally equal to the inverse. pay attention to that. it's equal for special cases. – Christoph Rackwitz Nov 08 '21 at 00:27
  • 2
    @ChristophRackwitz For `np.matrix` objects `*` actually is the matrix multiplication operator. Also, mathematically both formulas OP is using give the inverse of `m`. – bb1 Nov 08 '21 at 00:44
  • Thank you @bb1 for the answer to the main question. You also might want to check more theoretical answer to the question about opencv getPerspectiveTransform. – yokus Nov 08 '21 at 18:26

1 Answers1

1

After watching this lecture from Gilbert Strang, I realized
(A.T * A)^-1 * A.T gives us only left side inverse. When you write (A.T*A)^-1 * A.T * A = I it equals to Identity. However, A * (A.T*A)^-1 * A.T(right side) does not give us Identity.

As a result using res1 = np.linalg.inv(m.T * m) * m.T, we get pseudo inverse solution. Since it is useful to find solutions for regression problem when matrices are singular, I guess opencv uses this kind of approach.

yokus
  • 145
  • 2
  • 10