-
Notifications
You must be signed in to change notification settings - Fork 0
/
row_echelon.py
43 lines (37 loc) · 1.33 KB
/
row_echelon.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
import numpy as np
def row_echelon(M):
""" Return Row Echelon Form of matrix A """
A = np.copy(M)
if (issubclass(A.dtype.type, np.integer)):
A = A.astype(float)
#A = M.astype(float)
# if matrix A has no columns or rows,
# it is already in REF, so we return itself
r, c = A.shape
if r == 0 or c == 0:
return A
# we search for non-zero element in the first column
for i in range(len(A)):
if A[i,0] != 0:
break
else:
# if all elements in the first column is zero,
# we perform REF on matrix from second column
B = row_echelon(A[:,1:])
# and then add the first zero-column back
return np.hstack([A[:,:1], B])
# if non-zero element happens not in the first row,
# we switch rows
if i > 0:
ith_row = A[i].copy()
A[i] = A[0]
A[0] = ith_row
# we divide first row by first element in it
A[0] = A[0] / A[0,0]
# we subtract all subsequent rows with first row (it has 1 now as first element)
# multiplied by the corresponding element in the first column
A[1:] -= A[0] * A[1:,0:1]
# we perform REF on matrix from second row, from second column
B = row_echelon(A[1:,1:])
# we add first row and first (zero) column, and return
return np.vstack([A[:1], np.hstack([A[1:,:1], B]) ])