-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeterminant.py
More file actions
127 lines (86 loc) · 4.51 KB
/
Copy pathdeterminant.py
File metadata and controls
127 lines (86 loc) · 4.51 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import copy
class MatrixDeterminantCalculator:
def multiplyRow(self, row: list[float], scaler: float) -> list[float]:
scaledRow = []
for number in row:
scaledRow.append(number*scaler)
return scaledRow
def substractRow(self, row1: list[float], row2: list[float]) -> list[float]:
subRow = []
for index in range(0, len(row2)):
subRow.append(row1[index] - row2[index])
return subRow
def isSquareMatrix(self, matrix: list[list[float]]) -> bool:
rowCount = len(matrix)
for row in matrix:
if len(row) != rowCount:
return False
return True
def swapToMakeNonZeroPivotPoints(self, matrix: list[list[float]]) -> tuple[int, list[list[float]]]:
matrixCopy = copy.deepcopy(matrix)
matrixSize = len(matrixCopy)
sign = 1
# Loop until row before the last row in the matrix
for rowIndex in range(0, (matrixSize - 1)):
# Set the pivot point index
pivotIndex = rowIndex
# If the matrix pivot point is not zero, then continue to the next row
if matrixCopy[rowIndex][pivotIndex] != 0:
continue
# go through the bottom rows and checks a row that has a non zero element for the pivot point
for downRowIndex in range(rowIndex+1, matrixSize):
# skip the downrow and go to next down row if current down row contains zero at the pivot point
if matrixCopy[downRowIndex][pivotIndex] == 0:
continue
# swap the rows because the down row contains non zero element at the pivot point
matrixCopy[rowIndex], matrixCopy[downRowIndex] = matrixCopy[downRowIndex], matrixCopy[rowIndex]
# change the sign to keep the track of the swapping
sign *= -1
# break the down row selection because the swapping already done
break
return sign, matrixCopy
# perform the guassian elimination to create the U ( upper triangle matrix )
def guassianElimination(self, matrix: list[list[float]]):
# get copy of the given matrix
matrixCopy = copy.deepcopy(matrix)
matrixSize = len(matrixCopy)
for pivotRowIndex in range(0, (matrixSize - 1)):
# get the main current row pivot point index
pivotColumnIndex = pivotRowIndex
# Skip processing the current row if the pivot point is zero, because it cause zero division error
if matrixCopy[pivotRowIndex][pivotColumnIndex] == 0:
continue
# Loop through the down rows. multiply each row by a scaler for the current row to make the down row pivot point 0
for downRowIndex in range(pivotRowIndex + 1, len(matrixCopy)):
# If the pivot point already zero, continue to the next down row
if matrixCopy[downRowIndex][pivotColumnIndex] == 0:
continue
# get the mulplier which makes the down row pivot index 0
multiplier = matrixCopy[downRowIndex][pivotColumnIndex] / \
matrixCopy[pivotRowIndex][pivotColumnIndex]
# get the substractor by multipling the current row with multiplier
substractor = self.multiplyRow(
matrixCopy[pivotRowIndex], multiplier)
# substract the substractor from down row to make the pivot point zero
matrixCopy[downRowIndex] = self.substractRow(
matrixCopy[downRowIndex], substractor)
return matrixCopy
# calculate the determinant of a upper triangle matrix
def determinantOfU(self, matrix: list[list[float]], sign: int):
pivotPoints = []
multiplication = 1
for rowIndex in range(0, len(matrix)):
value = matrix[rowIndex][rowIndex]
# if any of the diagonal value is zero, return 0 as the determinant
if value == 0:
return 0
multiplication *= value
return multiplication * sign
def calculateMatrixDeterminant(self, matrix: list[list[float]]) -> float:
if not self.isSquareMatrix(matrix=matrix):
raise ValueError("Matrix is not a square matrix")
sign, swappedMatrix = self.swapToMakeNonZeroPivotPoints(matrix)
upperTriangleMatrix = self.guassianElimination(swappedMatrix)
result = self.determinantOfU(
upperTriangleMatrix, sign)
return result