-
Notifications
You must be signed in to change notification settings - Fork 1
/
linalg.py
79 lines (69 loc) · 1.79 KB
/
linalg.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
79
#Linear Algebra stuff
import numpy
#elementary operations
#all arithmetic in F2
def rowSwap(A, i, j):
temp = numpy.copy(A[i, :])
A[i, :] = A[j, :]
A[j, :] = temp
def colSwap(A, i, j):
temp = numpy.copy(A[:, i])
A[:, i] = A[:, j]
A[:, j] = temp
def colCombine(A, addTo, scaleCol):
A[:, addTo] ^= A[:, scaleCol]
def rowCombine(A, addTo, scaleRow):
A[addTo, :] ^= A[scaleRow, :]
#column reduction of A via E (from right) and multiplying E^-1 to B from left
def simultaneousReduce(A, B):
if A.shape[1] != B.shape[0]:
raise Exception("Matrices have the wrong shape.")
numRows, numCols = A.shape # col reduce A
i,j = 0,0
while True:
if i >= numRows or j >= numCols:
break
if A[i][j] == 0:
nonzeroCol = j
while nonzeroCol < numCols and A[i,nonzeroCol] == 0:
nonzeroCol += 1
if nonzeroCol == numCols:
i += 1
continue
colSwap(A, j, nonzeroCol)
rowSwap(B, j, nonzeroCol)
for otherCol in range(0, numCols):
if otherCol == j:
continue
if A[i, otherCol] != 0:
colCombine(A, otherCol, j)
rowCombine(B, j, otherCol)
i += 1; j+= 1
return A,B
def finishRowReducing(B):
numRows, numCols = B.shape
i,j = 0,0
while True:
if i >= numRows or j >= numCols:
break
if B[i, j] == 0:
nonzeroRow = i
while nonzeroRow < numRows and B[nonzeroRow, j] == 0:
nonzeroRow += 1
if nonzeroRow == numRows:
j += 1
continue
rowSwap(B, i, nonzeroRow)
for otherRow in range(0, numRows):
if otherRow == i:
continue
if B[otherRow, j] != 0:
rowCombine(B, otherRow, j)
i += 1; j+= 1
return B
def numPivotCols(A):
z = numpy.zeros(A.shape[0])
return [numpy.all(A[:, j] == z) for j in range(A.shape[1])].count(False)
def numPivotRows(A):
z = numpy.zeros(A.shape[1])
return [numpy.all(A[i, :] == z) for i in range(A.shape[0])].count(False)