我有这个函数来获取矩阵的行列式
def determinant(self) -> int:
"""
Calculates the Determinant of matrix objects.
Parameters
----------
self
Returns
-------
int
Example
-------
>>> _matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> _matrix = Matrix(_matrix)
>>> _matrix.determinant()
0
"""
if self.row != self.column:
raise ValueError('Cannot get determinant of this matrix! Must be a square Matrix')
else:
def det(matrix):
row = len(matrix)
col = len(matrix[0])
if (row, col) == (1, 1):
return matrix[0][0]
# hard coding for 2x2
elif (row, col) == (2, 2):
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
# using sarrus method to solve for 3x3, it's a little faster.
elif (row, col) == (3, 3):
matrix1 = matrix[:]
# Extending matrix to use Sarrus Rule.
for i in range(row - 1):
_col = []
for j in range(col):
_col.append(matrix1[i][j])
matrix1.append(_col)
# Calculating Determinant
# Adding part
add_pointers = [(i, i) for i in range(row)]
result = 0
for pointer in range(row):
temp = 1
for tup in add_pointers:
i, j = tup
temp *= matrix1[i + pointer][j]
result += temp
# Subtracting part
sub_pointers = [((row - 1) - i, 0 + i) for i in range(row)]
for pointers in range(row):
temp = 1
for tup in sub_pointers:
i, j = tup
temp *= matrix1[i + pointers][j]
result -= temp
return result
else:
sign = -1
result = 0
row1 = [matrix[0][i] * (sign ** i) for i in range(col)]
for x, y in enumerate(row1):
mat = matrix[:][1:]
sub_matrix = [[mat[i][j] for j in range(col) if j != x] for i in range(row - 1)]
result += y * det(sub_matrix)
return result
return det(self.matrix)
我有
2x2
和 3x3
矩阵的硬编码行列式,然后我重新讨论其余的
正如你所看到的,它使用
nxn
矩阵的递归...我确信有一种更快的方法,这是非常慢的
建议使用该方法的 python 实现,谢谢
这里是通过切片和简单乘法求 3x3 矩阵行列式的 Python 代码
import numpy as np
def crossMulti(smallMatrix):
# Calculate determinant of 2x2 matrix
return (smallMatrix[0][0] * smallMatrix[1][1]) - (smallMatrix[1][0] * smallMatrix[0][1])
def Determinant(matrix):
# Manual determinant calculation for 3x3 matrix
a = matrix[0][0]
b = matrix[0][1]
c = matrix[0][2]
det = (
a * crossMulti(matrix[1:, 1:]) -
b * crossMulti(matrix[1:, [0, 2]]) +
c * crossMulti(matrix[1:, :2])
)
return det
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("Matrix:")
print(matrix)
print()
print("Determinant using NumPy:", np.linalg.det(matrix))
print("Determinant using Manual Function:", Determinant(matrix))
import numpy as np
a = np.array([[1, 2], [3, 4]])
result = np.linalg.det(a)
print(result)
输出:
"""
M:
M11 M12 M13
M21 M22 M23
M31 M32 M33
detM:
M11 * det2D([ [M22, M23], [M32, M33] ]) -
M12 * det2D([ [M21, M23], [M31, M33] ]) +
M13 * det2D([ [M21, M22], [M31, M32] ])
"""
import numpy as np
def det3D(M):
a = M[0][0] * det2D(np.array([ [ M[1][1],M[1][2] ], [ M[2][1],M[2][2] ] ]))
b = M[0][1] * det2D(np.array([ [ M[1][0],M[1][2] ], [ M[2][0],M[2][2] ] ]))
c = M[0][2] * det2D(np.array([ [ M[1][0],M[1][1] ], [ M[2][0],M[2][1] ] ]))
return a - b + c
def det2D(M):
return M[0][0]*M[1,1] - M[0][1] * M[1][0]
M = [ [1,0,0], [0,2,2], [0,2,4] ]
A = det3D(M)
B = round(np.linalg.det(M))
print(A)
print(B)
print(A == B)
4
4
True
的运行速度比
smartDetNxN
快 35 倍以上。detNxN
输出:
import numpy as np
# compute partial determinant terms
def terms(M, col = 1, row = 1):
return [x[:col-1] + x[col:] for x in M[0:row-1] + M[row:]]
# compute determinant using first row
def detNxN(M):
N = len(M[0])
# Recursion Base: 2x2 determenant
if (N == 2):
M = np.array(M)
return M[0][0] * M[1,1] - M[0][1] * M[1][0]
# Recursion Loop
else:
rowValues = M[:1][0]
colsSigns = [1 if (col % 2 == 0) else -1 for col in range(N)]
colsDets = [detNxN(terms(M, col + 1)) for col in range(N)]
return sum([rowValues[col] * colsSigns[col] * colsDets[col] for col in range(N)])
# compute determinant using optimum row while skipping zero value columns
def smartDetNxN(M):
N = len(M[0])
# Recursion Base: 2x2 determenant
if (N == 2):
M = np.array(M)
return M[0][0] * M[1,1] - M[0][1] * M[1][0]
# Recursion Loop
else:
# find optimun row
flatM = [len(np.flatnonzero(x)) for x in M]
row = flatM.index(min(flatM))
rowSign = 1 if (row % 2 == 0) else -1
rowValues = M[row]
# compute partial determinants
colsSigns = [1 if (col % 2 == 0) else -1 for col in range(N)]
colsDets = [smartDetNxN(terms(M, col + 1, row + 1)) if (rowValues[col] != 0) else 0 for col in range(N)]
return sum([rowValues[col] * rowSign * colsSigns[col] * colsDets[col] for col in range(N)])
# test case for matrix
def testCase(M):
print()
N1 = len(M[0])
N2 = len(M[0])
A = smartDetNxN(M)
B = round(np.linalg.det(M))
print("Matrix %ix%i:" % (N1, N2))
print("Actual detM = %d, Expected detM = %d " % (A, B))
print("Test Pass:", A == B)
# main
def main():
# Matrix 2 x 2
M1 = [[1,2,],[0,1]]
testCase(M1)
# Matrix 3 x 3
M2 = [[1,2,3],[2,1,2],[3,2,1]]
testCase(M2)
# Matrix 4 x 4
M3 = [[1,2,3,4], [2,1,0,3], [3,0,1,2], [4,0,0,1]]
testCase(M3)
# Matrix 10 x 10
M4 = [
[0,1,2,3,4,5,6,7,8,9],
[1,1,0,0,0,0,0,0,0,8],
[2,0,1,0,0,0,0,0,0,7],
[3,0,0,1,0,0,0,0,0,6],
[4,0,0,0,1,0,0,0,0,5],
[5,0,0,0,0,1,0,0,0,4],
[6,0,0,0,0,0,1,0,0,3],
[7,0,0,0,0,0,0,1,0,2],
[8,0,0,0,0,0,0,0,1,1],
[9,0,0,0,0,0,0,0,0,0],
]
testCase(M4)
main()