Error while executing code to find inverse of a matrix (via gauss elimination using lists as arrays). To find the inverse using row operations, first I duplicated the matrix and attempted to swap rows in case of zero elements on the diagonals and then tried executing the function to make the lower triangular region of the matrix all 0, that is to convert into row echelon form. But at this point the code also affecting the original matrix. (Reason for keeping a copy of the matrix is to check the matrix A times its found inverse gives identity matrix)
I tried debugging and found where the operation affect the original matrix(spot quoted as comment in the code below). But still am unable to figure out where I have gone wrong. A fresh eye could really help.
A = [[2,4],
[3,0]]
def inverse(A):
A_id = A[:] #appling operations on a copy of matrix A
A_id = squaremat(A_id)
indentitymat=identity(A_id)
return (lowertriangle(A_id,indentitymat))
def squaremat(A_id):
for i in range(len(A_id)):
if len(A_id)!=len(A_id[i]):
error="Sorry Matrix not invertible" # checks given matrix is a square matrix
return error
break
return swap(A_id)
def swap(A_id):
for j in range(len(A_id)):
if j!=len(A_id)-1 and A_id[j][j]==0:
Temp= A_id[j]
A_id[j]=A_id[j+1]
A_id[j+1]=Temp
elif j == len(A_id)-1 and A_id[j][j]==0:
Temp1= A_id[0]
A_id[0]=A_id[j]
A_id[j]=Temp1
for k in range(len(A_id)):
if A_id[k][k]==0:
return swap(A_id)
return A_id
def identity(A_id):
iden=[]
for i in range(len(A_id)):
iden.append([0]*len(A_id))
iden[i][i]=1
return iden
def lowertriangle(A_id,invert):
print(A_id)
for i in range(len(A_id)):
divisor = A_id[i][i]
for j in range(len(A_id)):
if divisor!=0:
A_id[i][j]=A_id[i][j]/divisor # to make diagonal one
invert[i][j]=invert[i][j]/divisor
for p in range(len(A_id)):
if p>i:
multiplier=A_id[p][i]
for k in range(len(A_id)):
A_id[p][k] = A_id[p][k] - multiplier*A_id[i][k] # to make the lower triangle all zero, (here the original matrix is being affected)
invert[p][k] = invert[p][k] - multiplier*invert[i][k]
print(A)
return uppertriangle(A_idlower,invert)
def uppertriangle(A_idlower,invert):
for i in range(len(A_idlower)):
for j in range(len(A_idlower)):
if j<i:
multiplier2= A_idlower[j][i]
for k in range(len(A_idlower)):
A_idlower[j][k] = A_idlower[j][k] - multiplier2*A_idlower[i][k]
invert[j][k] = invert[j][k] - multiplier2*invert[i][k]
return invert
print(inverse(A))
The problem is here:
A_id = A[:] #appling operations on a copy of matrix A
This performs a shallow copy of A
. In other words, it creates a new list with references to each row in the original list. But the rows are not themselves copied.
To fix the problem, you need to create a deep copy of the original matrix instead. One way to do it is with a list comprehension:
A_id = [row[:] for row in A]
This will work in the specific case of the question here, but is still not a general solution for deep copying any arbitrarily nested list.