Reputation: 13
I want to calculate this fomula.
I think the result is A.
So I write a python code using numpy.
But depending on the computation sequence, result is not A.
What brought this on?
import numpy as np
from numpy import *
from numpy.random import *
import decimal
#generate matrix A
A = randn(180,240)
A = np.array(A, dtype = decimal.Decimal )
#generate matrix P
h,w=A.shape
P = randn(0.9*h,h)
P = np.array(P, dtype = decimal.Decimal )
#it's OK. IA = A
PP = dot(P.T,P)
PPinv = np.linalg.inv(PP)
PPinvPP = dot(PPinv,PP)
PPinvPPinv = np.linalg.inv(PPinvPP)
I = dot(PPinvPPinv,PPinvPP)
IA = dot(I, A)
#I think IA2 must be A. but not A. Why?
PA = dot(P,A)
PPA = dot(P.T,PA)
PPinvPPA = dot(PPinv,PPA)
IA2 = dot(PPinvPPinv, PPinvPPA)
#print result
print "A;%0.2f" % A[0,0]
print "IA:%0.2f" % IA[0,0]
print "IA2:%0.2f" % IA2[0,0]
Upvotes: 0
Views: 206
Reputation: 5531
Not a direct answer to your question, but you could use Sympy for these kind of problems:
from IPython.display import display
import sympy as sy
sy.init_printing() # For LaTeX-like pretty printing in IPython
n = 5
A = sy.MatrixSymbol('A', 162, 240) # dimension 162x240
P = sy.MatrixSymbol('P', 162, 180) # dimensions 162x180
PTP = P*P.T
ex1 = (PTP.inverse() * PTP).inverse() * PTP.inverse() * PTP * A
display(ex1) # displays: A
Upvotes: 0
Reputation:
The main reason is when you use non-square matrix P, where height is less than width, determinant of the PP always has a zero value, but because of a calc error it's != 0. So after this it's impossible to calculate the real PPinv and any forward steps are meaningless.
P = randn(2,3)
P = np.array(P, dtype = decimal.Decimal )
PP = dot(P.T,P)
np.linalg.det(PP) #-5.2536080570332981e-34
So why is IA == A?
I think it's a situation when error*error gives you a normal result.
How to solve it?
Upvotes: 1
Reputation: 31339
What happens here is quite interesting:
In general your formula is only correct if PP
is non-singular.
So why then AI == A
?
PP = dot(P.T,P)
PPinv = np.linalg.inv(PP)
PPinvPP = dot(PPinv,PP)
PPinvPPinv = np.linalg.inv(PPinvPP)
I = dot(PPinvPPinv,PPinvPP)
IA = dot(I, A)
There are a couple of things to note here:
PP = dot(P.T,P)
is singularPPinv
is not a true inversePPinvPP
is invertible, so I
is indeed the identity matrixNote: You only get AI == A
because of your special order of evaluation of the terms.
In the second calculation of IA2
term you don't have this special evaluation order that gives you A
as result.
Upvotes: 2