-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeterminant.py
73 lines (41 loc) · 1.04 KB
/
determinant.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
from numbers import gcd , prod
def det ( A , n ) :
"""
Using Gaussian elimination and gcd. For integers only!
>>> det( [ [ 4 , 1 ] , [ 1 , 2 ] ] , 2 )
7
>>> det( [ [ -2 , 2 , -3 ] , [ -1 , 1 , 3 ] , [ 2 , 0 , -1 ] ] , 3 )
18
>>> det( [ [ -1 , 1 , 3 ] , [ -2 , 2 , -3 ] , [ 2 , 0 , -1 ] ] , 3 )
-18
"""
d = 1
for i in range ( n - 1 ) :
# find first non zero row
if A[i][i] == 0 :
j = i + 1
while j < n :
if A[j][i] != 0 : break
j += 1
if j == n : return 0
# make it the ith row
A[i] , A[j] = A[j] , A[i]
d = -d
for j in range ( i + 1 , n ) :
a = A[i][i]
b = A[j][i]
c = gcd( a , b )
a //= c
b //= c
# we want to cancel A[j][i]
# assert a * A[j][i] == b * A[i][i]
A[j][i] = 0
# so we multiply both rows so that
#
# A[i][i] = A[j][i] = lcm( A[i][i] , A[j][i] )
#
# and we remove the ith row from the jth row
for k in range ( i + 1 , n ) :
A[j][k] = a * A[j][k] - b * A[i][k]
d *= a
return prod( A[i][i] for i in range( n ) ) // d