Skip to content

Commit 9390565

Browse files
kituuucclaussCaedenPHChrisO345
authored
added support for inverse of 3x3 matrix (TheAlgorithms#7355)
* added support for inverse of 3x3 matrix * Modified Docstring and improved code * fixed an error * Modified docstring * Apply all suggestions from code review Co-authored-by: Caeden Perelli-Harris <[email protected]> Co-authored-by: Chris O <[email protected]> Co-authored-by: Christian Clauss <[email protected]> Co-authored-by: Caeden Perelli-Harris <[email protected]> Co-authored-by: Chris O <[email protected]>
1 parent abf0909 commit 9390565

File tree

1 file changed

+122
-15
lines changed

1 file changed

+122
-15
lines changed

matrix/inverse_of_matrix.py

+122-15
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,154 @@
22

33
from decimal import Decimal
44

5+
from numpy import array
6+
57

68
def inverse_of_matrix(matrix: list[list[float]]) -> list[list[float]]:
79
"""
810
A matrix multiplied with its inverse gives the identity matrix.
9-
This function finds the inverse of a 2x2 matrix.
11+
This function finds the inverse of a 2x2 and 3x3 matrix.
1012
If the determinant of a matrix is 0, its inverse does not exist.
1113
1214
Sources for fixing inaccurate float arithmetic:
1315
https://stackoverflow.com/questions/6563058/how-do-i-use-accurate-float-arithmetic-in-python
1416
https://docs.python.org/3/library/decimal.html
1517
18+
Doctests for 2x2
1619
>>> inverse_of_matrix([[2, 5], [2, 0]])
1720
[[0.0, 0.5], [0.2, -0.2]]
1821
>>> inverse_of_matrix([[2.5, 5], [1, 2]])
1922
Traceback (most recent call last):
20-
...
23+
...
2124
ValueError: This matrix has no inverse.
2225
>>> inverse_of_matrix([[12, -16], [-9, 0]])
2326
[[0.0, -0.1111111111111111], [-0.0625, -0.08333333333333333]]
2427
>>> inverse_of_matrix([[12, 3], [16, 8]])
2528
[[0.16666666666666666, -0.0625], [-0.3333333333333333, 0.25]]
2629
>>> inverse_of_matrix([[10, 5], [3, 2.5]])
2730
[[0.25, -0.5], [-0.3, 1.0]]
31+
32+
Doctests for 3x3
33+
>>> inverse_of_matrix([[2, 5, 7], [2, 0, 1], [1, 2, 3]])
34+
[[2.0, 5.0, -4.0], [1.0, 1.0, -1.0], [-5.0, -12.0, 10.0]]
35+
>>> inverse_of_matrix([[1, 2, 2], [1, 2, 2], [3, 2, -1]])
36+
Traceback (most recent call last):
37+
...
38+
ValueError: This matrix has no inverse.
39+
40+
>>> inverse_of_matrix([[],[]])
41+
Traceback (most recent call last):
42+
...
43+
ValueError: Please provide a matrix of size 2x2 or 3x3.
44+
45+
>>> inverse_of_matrix([[1, 2], [3, 4], [5, 6]])
46+
Traceback (most recent call last):
47+
...
48+
ValueError: Please provide a matrix of size 2x2 or 3x3.
49+
50+
>>> inverse_of_matrix([[1, 2, 1], [0,3, 4]])
51+
Traceback (most recent call last):
52+
...
53+
ValueError: Please provide a matrix of size 2x2 or 3x3.
54+
55+
>>> inverse_of_matrix([[1, 2, 3], [7, 8, 9], [7, 8, 9]])
56+
Traceback (most recent call last):
57+
...
58+
ValueError: This matrix has no inverse.
59+
60+
>>> inverse_of_matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
61+
[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]
2862
"""
2963

30-
d = Decimal # An abbreviation for conciseness
64+
d = Decimal
3165

3266
# Check if the provided matrix has 2 rows and 2 columns
3367
# since this implementation only works for 2x2 matrices
34-
if len(matrix) != 2 or len(matrix[0]) != 2 or len(matrix[1]) != 2:
35-
raise ValueError("Please provide a matrix of size 2x2.")
68+
if len(matrix) == 2 and len(matrix[0]) == 2 and len(matrix[1]) == 2:
69+
# Calculate the determinant of the matrix
70+
determinant = float(
71+
d(matrix[0][0]) * d(matrix[1][1]) - d(matrix[1][0]) * d(matrix[0][1])
72+
)
73+
if determinant == 0:
74+
raise ValueError("This matrix has no inverse.")
75+
76+
# Creates a copy of the matrix with swapped positions of the elements
77+
swapped_matrix = [[0.0, 0.0], [0.0, 0.0]]
78+
swapped_matrix[0][0], swapped_matrix[1][1] = matrix[1][1], matrix[0][0]
79+
swapped_matrix[1][0], swapped_matrix[0][1] = -matrix[1][0], -matrix[0][1]
80+
81+
# Calculate the inverse of the matrix
82+
return [
83+
[(float(d(n)) / determinant) or 0.0 for n in row] for row in swapped_matrix
84+
]
85+
elif (
86+
len(matrix) == 3
87+
and len(matrix[0]) == 3
88+
and len(matrix[1]) == 3
89+
and len(matrix[2]) == 3
90+
):
91+
# Calculate the determinant of the matrix using Sarrus rule
92+
determinant = float(
93+
(
94+
(d(matrix[0][0]) * d(matrix[1][1]) * d(matrix[2][2]))
95+
+ (d(matrix[0][1]) * d(matrix[1][2]) * d(matrix[2][0]))
96+
+ (d(matrix[0][2]) * d(matrix[1][0]) * d(matrix[2][1]))
97+
)
98+
- (
99+
(d(matrix[0][2]) * d(matrix[1][1]) * d(matrix[2][0]))
100+
+ (d(matrix[0][1]) * d(matrix[1][0]) * d(matrix[2][2]))
101+
+ (d(matrix[0][0]) * d(matrix[1][2]) * d(matrix[2][1]))
102+
)
103+
)
104+
if determinant == 0:
105+
raise ValueError("This matrix has no inverse.")
106+
107+
# Creating cofactor matrix
108+
cofactor_matrix = [
109+
[d(0.0), d(0.0), d(0.0)],
110+
[d(0.0), d(0.0), d(0.0)],
111+
[d(0.0), d(0.0), d(0.0)],
112+
]
113+
cofactor_matrix[0][0] = (d(matrix[1][1]) * d(matrix[2][2])) - (
114+
d(matrix[1][2]) * d(matrix[2][1])
115+
)
116+
cofactor_matrix[0][1] = -(
117+
(d(matrix[1][0]) * d(matrix[2][2])) - (d(matrix[1][2]) * d(matrix[2][0]))
118+
)
119+
cofactor_matrix[0][2] = (d(matrix[1][0]) * d(matrix[2][1])) - (
120+
d(matrix[1][1]) * d(matrix[2][0])
121+
)
122+
cofactor_matrix[1][0] = -(
123+
(d(matrix[0][1]) * d(matrix[2][2])) - (d(matrix[0][2]) * d(matrix[2][1]))
124+
)
125+
cofactor_matrix[1][1] = (d(matrix[0][0]) * d(matrix[2][2])) - (
126+
d(matrix[0][2]) * d(matrix[2][0])
127+
)
128+
cofactor_matrix[1][2] = -(
129+
(d(matrix[0][0]) * d(matrix[2][1])) - (d(matrix[0][1]) * d(matrix[2][0]))
130+
)
131+
cofactor_matrix[2][0] = (d(matrix[0][1]) * d(matrix[1][2])) - (
132+
d(matrix[0][2]) * d(matrix[1][1])
133+
)
134+
cofactor_matrix[2][1] = -(
135+
(d(matrix[0][0]) * d(matrix[1][2])) - (d(matrix[0][2]) * d(matrix[1][0]))
136+
)
137+
cofactor_matrix[2][2] = (d(matrix[0][0]) * d(matrix[1][1])) - (
138+
d(matrix[0][1]) * d(matrix[1][0])
139+
)
36140

37-
# Calculate the determinant of the matrix
38-
determinant = d(matrix[0][0]) * d(matrix[1][1]) - d(matrix[1][0]) * d(matrix[0][1])
39-
if determinant == 0:
40-
raise ValueError("This matrix has no inverse.")
141+
# Transpose the cofactor matrix (Adjoint matrix)
142+
adjoint_matrix = array(cofactor_matrix)
143+
for i in range(3):
144+
for j in range(3):
145+
adjoint_matrix[i][j] = cofactor_matrix[j][i]
41146

42-
# Creates a copy of the matrix with swapped positions of the elements
43-
swapped_matrix = [[0.0, 0.0], [0.0, 0.0]]
44-
swapped_matrix[0][0], swapped_matrix[1][1] = matrix[1][1], matrix[0][0]
45-
swapped_matrix[1][0], swapped_matrix[0][1] = -matrix[1][0], -matrix[0][1]
147+
# Inverse of the matrix using the formula (1/determinant) * adjoint matrix
148+
inverse_matrix = array(cofactor_matrix)
149+
for i in range(3):
150+
for j in range(3):
151+
inverse_matrix[i][j] /= d(determinant)
46152

47-
# Calculate the inverse of the matrix
48-
return [[float(d(n) / determinant) or 0.0 for n in row] for row in swapped_matrix]
153+
# Calculate the inverse of the matrix
154+
return [[float(d(n)) or 0.0 for n in row] for row in inverse_matrix]
155+
raise ValueError("Please provide a matrix of size 2x2 or 3x3.")

0 commit comments

Comments
 (0)