# Revision history [back]

In case it saves anyone some time, I am using the following routine. Since this is for pedagogical purposes only, I restricted the matrices to rational entries. Bug reports welcome.

# Naive Gaussian reduction
"""Describe the reduction to echelon form of the given matrix of rationals.

M  matrix of rationals   e.g., M = matrix(QQ, [[..], [..], ..])

Returns: None.  Side effect: M is reduced.  Note: this is echelon form,
not reduced echelon form; this routine does not end the same way as does
M.echelon_form().

"""
num_rows=M.nrows()
num_cols=M.ncols()
print M

col = 0   # all cols before this are already done
for row in range(0,num_rows):
# ?Need to swap in a nonzero entry from below
while (col < num_cols
and M[row][col] == 0):
for i in M.nonzero_positions_in_column(col):
if i > row:
print " swap row",row+1,"with row",i+1
M.swap_rows(row,i)
print M
break
else:
col += 1

if col >= num_cols:
break

# Now guaranteed M[row][col] != 0
and M[row][col] != 1):
print " take",1/M[row][col],"times row",row+1
M.rescale_row(row,1/M[row][col])
print M
change_flag=False
for changed_row in range(row+1,num_rows):
if M[changed_row][col] != 0:
change_flag=True
factor=-1*M[changed_row][col]/M[row][col]
print " take",factor,"times row",row+1,"plus row",changed_row+1