# 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) )) ```