Created
June 16, 2021 12:58
-
-
Save ialexpovad/9a864c46eb8f09df03f7fd32ca938394 to your computer and use it in GitHub Desktop.
Solving a system of linear algebraic equations using the inverse matrix without the use of modules NumPy/SciPy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Program for determining the inverse matrix and solve | |
system linear equation without using additional | |
modules NumPy or SciPy. | |
###################################################### | |
Ax=b -> A^(-1)Ax=A^(-1)b -> Ix=A^(-1)b -> x=A^(-1)b # | |
###################################################### | |
''' | |
def printout_matrix(title_matrix, matrix): | |
''' | |
Output of the matrix and its contents | |
rounding the components to the second digit | |
''' | |
print(title_matrix) | |
for item in matrix: | |
print([round(x,3) for x in item]) | |
def printout_matrices(action_for_matrices,title_1,\ | |
matrix_1, title_2, matrix_2): | |
''' | |
Output of the matrices and its contents | |
format digit | |
''' | |
print(action_for_matrices) | |
print(title_1, '\t'*int(len(matrix_1))+"\t"*len(matrix_1),title_2) | |
for item in range(len(matrix_1)): | |
# {0} - null argument, {f} - specifies that it is a floating-point number format | |
# The part up to the point {5} defines the minimum width that the number can occupy | |
row_1=['{0:3.1f}'.format(x) for x in matrix_1[item]] | |
row_2=['{0:3.1f}'.format(x) for x in matrix_2[item]] | |
print(row_1,'\t', row_2) | |
#printout_matrices("Initialization...", 'Matrix A:', A, 'Matrix I:', A) | |
def null_matrix(rows: int, columns: int): | |
''' | |
The function returns a null matrix | |
/ | |
Other example 1: | |
def null_matrix(rows: int, columns: int): | |
return [[0]*columns for _ in range(rows)] | |
/ | |
Other example 2: | |
def null_matrix(rows: int, columns: int): | |
matrix = [] | |
for item in range(rows): | |
matrix.append([0] * columns) | |
return matrix | |
/ | |
''' | |
matrix=[] | |
for i in range(rows): | |
matrix.append([]) | |
for j in range(columns): | |
matrix[-1].append(0.0) | |
return matrix | |
#print(null_matrix(3, 3)) | |
def copymatrix(matrix): | |
rows, columns = len(matrix), len(matrix[0]) | |
copymatrix=null_matrix(rows, columns) | |
for i in range(rows): | |
for j in range(columns): | |
copymatrix[i][j]=matrix[i][j] | |
return copymatrix | |
def matrix_multiplication(A:list,B:list): | |
''' | |
The function returns the result of matrix multiplication A*B=X. | |
Condition: A=[m,n]; B=[n,p] -> X=[m,p] | |
/ | |
Other example: | |
def multiplication(A, B): | |
m = len(A) | |
n = len(B) | |
p = len(B[0]) | |
C = [[None for _ in range(p)] | |
for _ in range(m)] | |
for i in range(m): | |
for j in range(p): | |
C[i][j] = sum(A[i][k] * B[k][j] for k in range(n)) | |
return C | |
/ | |
''' | |
m,n,p = len(A), len(A[0]), len(B[0]) | |
X=null_matrix(m,p) | |
for i in range(m): | |
for j in range(p): | |
total=0 | |
for ii in range(n): | |
total += A[i][ii] * B[ii][j] | |
X[i][j]=int(total) | |
return X | |
def identity_matrix(n: int): | |
''' | |
The function creates and returns an identity matrix. | |
param n: the square size of the matrix | |
return: a square identity matrix | |
''' | |
matrix=null_matrix(n, n) | |
for item in range(n): | |
matrix[item][item]=1.0 | |
return matrix | |
# The generalized prder of steps | |
# The first step for each column is to multiply the row that has the focusDiagonal in it by {1/focusDiagonal}. We then operate on the remaining rows, the ones without focusDiagonal in them, as follows: | |
# | |
# • use the element that’s in the same column as focusDiagonal and make it a multiplier; | |
# • replace the row with the result of … [current row] – multiplier * [row that has focusDiagonal], and do this operation to the I matrix also. | |
# • this will leave a zero in the column shared by focusDiagonal in the A matrix. | |
''' | |
# Basic matrix A from Ax=b: | |
A=[[5.,3.,1.],[3.,9.,4.],[1.,3.,5.]] | |
n=len(A) # numbers of rows matrix A (size A) | |
# Identi primary matrix I: | |
I=identity_matrix(n) | |
# Copies of the original matrices: | |
Acopy=copymatrix(A) | |
Icopy=copymatrix(I) | |
######## Sequential steps ######## | |
focusDiagonal=0 | |
scaler_focusDiagonal=1.0/Acopy[focusDiagonal][focusDiagonal] | |
index=list(range(n)) | |
for j in range(n): | |
Acopy[focusDiagonal][j]=scaler_focusDiagonal*Acopy[focusDiagonal][j] | |
Icopy[focusDiagonal][j]=scaler_focusDiagonal*Icopy[focusDiagonal][j] | |
# Now, we can use that first row, that now has a 1 in the first diagonal position, to drive the other elements in the first column to 0. | |
for i in index[0:focusDiagonal]+index[focusDiagonal+1:]: | |
numberCurrentRow=Acopy[i][focusDiagonal] | |
for j in range(n): | |
Acopy[i][j] = Acopy[i][j] - numberCurrentRow * Acopy[focusDiagonal][j] | |
Icopy[i][j] = Icopy[i][j] - numberCurrentRow * Icopy[focusDiagonal][j] | |
# For the remaining columns: | |
for focusDiagonal in range(1,n): | |
scaler_focusDiagonal=1.0/Acopy[focusDiagonal][focusDiagonal] | |
for j in range(n): | |
Acopy[focusDiagonal][j]*=scaler_focusDiagonal | |
Icopy[focusDiagonal][j]*=scaler_focusDiagonal | |
for i in index[:focusDiagonal]+index[focusDiagonal+1:]: | |
numberCurrentRow=Acopy[i][focusDiagonal] | |
for j in range(n): | |
Acopy[i][j]=Acopy[i][j]-numberCurrentRow*Acopy[focusDiagonal][j] | |
Icopy[i][j]=Icopy[i][j]-numberCurrentRow*Icopy[focusDiagonal][j] | |
######## Sequential steps ######## | |
''' | |
def inv(A): | |
''' | |
The function returns the inverse of | |
the passed in matrix. | |
''' | |
n=len(A) | |
Acopy=copymatrix(A) | |
I=identity_matrix(n) | |
Icopy=copymatrix(I) | |
index=list(range(n)) | |
for focusDiagonal in range(n): | |
scaler_focusDiagonal=1.0/Acopy[focusDiagonal][focusDiagonal] | |
for j in range(n): | |
Acopy[focusDiagonal][j]=Acopy[focusDiagonal][j]*scaler_focusDiagonal | |
Icopy[focusDiagonal][j]=Icopy[focusDiagonal][j]*scaler_focusDiagonal | |
for i in index[0:focusDiagonal]+index[focusDiagonal+1:]: | |
numberCurrentRow=Acopy[i][focusDiagonal] | |
for j in range(n): | |
Acopy[i][j]=Acopy[i][j]-numberCurrentRow*Acopy[focusDiagonal][j] | |
Icopy[i][j]=Icopy[i][j]-numberCurrentRow*Icopy[focusDiagonal][j] | |
return Icopy | |
def solve(A,b): | |
InerseMatrix=inv(A) | |
x=matrix_multiplication(InerseMatrix, b) | |
return x | |
if __name__=='__main__': | |
A=[[5,15,56],[-4,-11,-41],[-1,-3,-11]] | |
b=[[35],[-26],[-7]] | |
printout_matrix("Matrix A:", A) | |
printout_matrix("Vector b:", b) | |
printout_matrix("Inverse matrix", inv(A)) | |
printout_matrix('Solve:',solve(A,b)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cool =)