-
Notifications
You must be signed in to change notification settings - Fork 0
/
inverse.py
78 lines (60 loc) · 2.25 KB
/
inverse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import gauss_elimination
import ulm
import gauss
import determinant
import fractions
def aside_matrix(m1, m2):
matrix = []
for row1, row2 in zip(m1, m2):
new_row = row1 + row2
matrix.append(new_row)
return matrix
def half_matrix_rows(matrix):
m1 = []
m2 = []
half_length = int(len(matrix[0])/2)
for row in matrix:
first = row[:half_length]
m1.append(first)
second = row[half_length:]
m2.append(second)
return m1, m2
def setup_inversion(matrix):
ordine = len(matrix)
identity = ulm.costruisci_matrice_identita(ordine)
matrix_plus_identity = aside_matrix(matrix, identity)
return matrix_plus_identity
def mirror_matrix(matrix):
mirrored = []
for i in range(len(matrix), 0, -1):
mirrored.append(matrix[i - 1][::-1])
return mirrored
def mirror_and_glue(matrix):
halfed_matrices = half_matrix_rows(matrix)
matrices = []
for matrix in halfed_matrices:
matrices.append(mirror_matrix(matrix))
matrix = aside_matrix(matrices[0], matrices[1])
return matrix, matrices[0]
def fix_diagonal(matrix, diagonal_original):
for i in range(len(diagonal_original)):
element = diagonal_original[i][i]
if element != 1:
multiplicator = fractions.Fraction(1/element)
for j in range(len(matrix[i])):
matrix[i][j] *= multiplicator
return matrix
def main(matrix):
gauss.convert_to_fractions(matrix)
matrix_plus = setup_inversion(matrix)
scaled, _, _ = gauss_elimination.main(matrix_plus) # whole gauss reduction
matrix, first_matrix = mirror_and_glue(scaled) # returns a mirrored version of the same individual matrices
det = determinant.product_determinant(first_matrix)
if det != 0: # invertibility check on the original matrix
scaled, _, _ = gauss_elimination.main(matrix) # gauss-jordan last step
matrix, scaled_original = mirror_and_glue(scaled) # re-mirroring to have the correct reduced matrix
matrix = fix_diagonal(matrix, scaled_original) # fix diagonal with row multiplication
identity, inverse = half_matrix_rows(matrix) # splitting to return only the inverted
return inverse
else:
return "La matrice non è invertibile."