# Properties
**Runtime analysis**:
...
**Implementation**:
```run-python
# Elementary row operations
def swap(A, i, j):
# procedure to swap rows i and j
A[i], A[j] = A[j], A[i]
def add(A, i, j, scalar):
# procedure to add row i to row j lambda times
A[j] = [Aj + float(scalar)*Ai for Ai,Aj in zip(A[i],A[j])]
def mult(A, i, scalar):
#procedure to multiply row i by lambda
A[i] = [Aix*float(scalar) for Aix in A[i]]
def row_echelon(A, top_row, pivot_column): #procedure
m, n = A.shape
if top_row == m-1:
for i in range(n):
if A[0][i] != 0:
pivot = A[0][i]
pivot_column = i
break
mult(A,top_row, 1/pivot)
else:
pivot_column =
pivot_row =
pivot = A[pivot_row][pivot_column]
swap(A, top_row, pivot_row)
for i in range(top_row+1,m): # transform pivot_column to standard basis element
scalar = - A[i][pivot_column]/pivot
add(A, top_row, i, scalar)
row_reduce(A, top_row + 1 , pivot_column+1)
merge(A, top_row, pivot_column)
def merge(A, top_row, pivot_column):
```
The following is adapted from [Rosetta Code](https://rosettacode.org/wiki/Reduced_row_echelon_form#Python):
```run-python
def row_echelon(M):
if not M: return
lead = 0
rowCount = len(M)
columnCount = len(M[0])
for r in range(rowCount):
if lead >= columnCount:
return
i = r
while M[i][lead] == 0:
i += 1
if i == rowCount:
i = r
lead += 1
if columnCount == lead:
return
M[i],M[r] = M[r],M[i]
lv = M[r][lead]
M[r] = [ mrx / float(lv) for mrx in M[r]]
for i in range(rowCount):
if i != r:
lv = M[i][lead]
M[i] = [ iv - lv*rv for rv,iv in zip(M[r],M[i])]
lead += 1
mtx = [
[ 3, 1, -2],
[ 1, 1, 1],
[2, 4, 1],]
ToReducedRowEchelonForm( mtx )
for rw in mtx:
print( ', '.join( (str(rv) for rv in rw) ))
```