import copy
def interchange(matrix, row1Index, row2Index): #swaps two rows with given indices
matrix[row1Index], matrix[row2Index] = matrix[row2Index], matrix[row1Index]
return matrix
def scaleBy(matrix, rowIndex, scalar): #multiplies any given row by a number
for i in range(len(matrix[rowIndex])):
matrix[rowIndex][i] = (matrix[rowIndex][i] * scalar)
return matrix
def addScaled(matrix, row1Index, row2Index, scalar): #adds multiple of one row to the other
for i in range(len(matrix[row1Index])):
matrix[row1Index][i] = matrix[row1Index][i] + (matrix[row2Index][i] * scalar)
return matrix
def zeroCheck(matrix): #checks for zero rows and puts all of them at the bottom.
nCols = len(matrix[0]) #puts rows with leading zeroes below the non-zero leading rows
nonzeroRows = list()
leadingzeroRows = list()
for row in range(len(matrix)):
RowElems = list(set(matrix[row]))
if(len(RowElems) == 1 and RowElems[0] == 0):
continue
elif(matrix[row][0] == 0):
leadingzeroRows.append(matrix[row])
else:
nonzeroRows.append(matrix[row])
nonzeroRows.extend(leadingzeroRows)
zeroRow = [0] * nCols
numZeroRow = len(matrix) - len(nonzeroRows)
for i in range(numZeroRow):
nonzeroRows.append(zeroRow)
return nonzeroRows
final = None
def printMatrix(matrix): #prints matrix. Rounds up till 3 decimal places. added constant spacing
between elements.
print()
global final
max_width = max(len(str(round(matrix[row][col], 3))) for row in range(len(matrix)) for col in
range(len(matrix[0])))
final = matrix
for row in range(len(matrix)):
for col in range(len(matrix[0])):
value = round(matrix[row][col], 3)
formatted_value = int(value) if type(value) is float and value.is_integer() else value
print("{:{}}".format(formatted_value, max_width), end=" ")
print()
return final
def zeroColCount(matrix): #counts number of zero columns. Returns the INDICIES of zero
columns.
zeroCols = list()
for j in range(len(matrix[0])):
s=0
for i in range(len(matrix)):
s = s + abs(matrix[i][j])
if(s == 0):
zeroCols.append(j)
return zeroCols
def scaledRowEliminator(matrix): #first checks if matrix is LC of another.
#If yes, then keeps smaller row and makes bigger row into a 0 row.
#Calls zerocheck to put this row at the bottom.
for i in range(len(matrix)):
for j in range(i+1, len(matrix), 1):
count = 0
for k in range(len(matrix[0])):
if min(matrix[i][k], matrix[j][k]) != 0 and min(matrix[i][k], matrix[j][k]) != 1 and
min(matrix[i][k], matrix[j][k]) != -1:
scale = max(matrix[i][k], matrix[j][k]) / min(matrix[j][k], matrix[i][k])
if(scale - int(scale) == 0):
count = count + 1
if(count == len(matrix[0])):
atleastOneScaled = True
reqdRow = 0
if(max(matrix[i][0], matrix[j][0]) == matrix[i][0]):
reqdRow = i
else:
reqdRow = j
for z in range(len(matrix[0])):
matrix[reqdRow][z] = 0
matrix = zeroCheck(matrix)
return matrix
def count_zero_rows(matrix): #counts and returns number of zero rows.
zero_rows = 0
for row in matrix:
if all(element == 0 for element in row):
zero_rows += 1
return zero_rows
def isRREF(matrix): #checks rref. Kind of extra but helps in verifying if input is already rref.
rref_check = True
one_found = 0
for i in range(len(matrix)):
first_nonzero_col = None
for j in range(len(matrix[0])):
if matrix[i][j] == 1:
one_found += 1
first_nonzero_col = j
break
if first_nonzero_col is not None:
for k in range(i):
if matrix[k][first_nonzero_col] != 0:
check1 = False
break
if one_found != len(matrix) - count_zero_rows(matrix):
rref_check = False
return rref_check
pivots_column = []
already_rref=0
def toEchelon(matrix, showSteps=True, reduced=False):
"""converts to rref using above functions
first calls zerocheck
checks for leading 0 element puts it at the top.
Then checks pivot elements and swaps rows to put into staircase pattern by checking
for gaps. Then uses current pivot row to make elements below it into zeroes by multiplying
negative and dividing by pivot element and sending into scaleadd.
Scales pivots down to 1 by multiplying multiplicative inverse.
Then takes first row and makes all pivot column
positions into 0's by dividing with a scalar."""
global already_rref
global pivots_column
nRows = len(matrix)
nCols = len(matrix[0])
if(showSteps):
print('Original Matrix:')
printMatrix(matrix)
matrix = zeroCheck(matrix)
"""if isRREF(matrix):
already_rref+=1
print("The matrix is already in Row Reduced Echelon Form!")
printMatrix(matrix)
return"""
scaledRowEliminator(matrix)
if(showSteps):
print()
print("Reaaranging Matrix:")
printMatrix(matrix)
minpos = 0
c=0
for i in range(1, nRows, 1):
if(matrix[i][0] == 0):
continue
elif(abs(matrix[i][0]) < abs(matrix[minpos][0]) and abs(matrix[i][0]) != 0):
minpos = i
c += 1
if(c > 0):
matrix = interchange(matrix, minpos, 0)
if(showSteps):
print()
print("Row 1 <--> Row", minpos+1)
printMatrix(matrix)
pivotsR = list()
pivotsC = list()
zColC = zeroColCount(matrix)
for col in range(nCols):
if(col not in zColC and col not in pivotsC):
for row in range(nRows):
if(row not in pivotsR and col not in pivotsC):
if(matrix[row][col] != 0):
if(len(pivotsR) != 0 and row != pivotsR[-1]+1):
matrix = interchange(matrix, row, pivotsR[-1]+1)
if(showSteps):
print()
print("Row", row+1, "<--> Row", pivotsR[-1]+2)
printMatrix(matrix)
pivotsR.append(pivotsR[-1]+1)
else:
pivotsR.append(row)
pivotsC.append(col)
currPivotRow = pivotsR[-1]
currPivotCol = pivotsC[-1]
for h in range(currPivotRow+1, nRows, 1):
if(matrix[h][currPivotCol] != 0):
reqdScalar = (-1) * (matrix[h][currPivotCol]) / (matrix[currPivotRow][currPivotCol])
matrix = addScaled(matrix, h, currPivotRow, reqdScalar)
if(showSteps):
print()
print("Row", h+1, "--> Row", h+1, "+ (", reqdScalar, ")x Row", currPivotRow+1)
printMatrix(matrix)
print()
pivots_column = pivotsC
if(reduced):
if(showSteps):
print("Further Reducing to Reduced Echelon Form:\n")
for k in range(len(pivotsC)):
if(matrix[pivotsR[k]][pivotsC[k]] != 1):
scaleFactor = 1 / matrix[pivotsR[k]][pivotsC[k]]
scale_factor_display = matrix[pivotsR[k]][pivotsC[k]]
matrix = scaleBy(matrix, pivotsR[k], scaleFactor)
if showSteps:
print()
print(f"Row {pivotsR[k]+1} = ( 1 / {scale_factor_display} ) x Row {pivotsR[k]
+1}")
printMatrix(matrix)
for k in range(len(pivotsC)):
for i in range(pivotsR[k]-1, -1, -1):
if(matrix[i][pivotsC[k]] != 0):
reqdScalar = (-1) * (matrix[i][pivotsC[k]]) / (matrix[pivotsR[k]][pivotsC[k]])
matrix = addScaled(matrix, i, pivotsR[k], reqdScalar)
if(showSteps):
print()
print("Row", i+1, "--> Row", i+1, "+ (", reqdScalar, ")x Row", pivotsR[k]+1)
printMatrix(matrix)
zeroCheck(matrix)
return matrix
print()
print("---------------------------------ROW REDUCED ECHELON
FORM----------------------------------\n")
while True:
try:
row_number = int(input('Enter the number of rows (n): '))
column_number = int(input('Enter the number of columns (m): '))
if row_number > 0 and column_number > 0:
break
else:
print()
print("Please enter positive integers for the number of rows and columns.")
print()
except ValueError:
print()
print("Invalid input! Please enter valid integers for the number of rows and columns.")
print()
a = []
for i in range(row_number):
while True:
try:
elements_str = input(f"Enter {column_number} numbers separated by spaces for row
number {i + 1}: ")
elements = [float(x) for x in elements_str.split()]
if len(elements) == column_number:
a.append(elements)
break
else:
print()
print(f"Invalid input! Please enter exactly {column_number} numbers.")
print()
except ValueError:
print()
print("Invalid input! Please enter valid numbers separated by spaces.")
print()
input_matrix = copy.deepcopy(a)
toEchelon(a, reduced=True)
if already_rref==0:
print()
print("The matrix is now in row reduced echelon form")
print()
print("Factorizing:")
threshold = 1e-10 # Define a threshold value for "close to zero"
for row in final:
for i in range(len(row)):
if abs(row[i]) < threshold:
row[i] = 0.0
number_of_zero = count_zero_rows(a)
non_zero_matrix = final[ : len(final)-number_of_zero]
def extract_pivot_columns(matrix, pivots_column):
pivot_matrix = []
for row in matrix:
pivot_row = [row[col] for col in pivots_column]
pivot_matrix.append(pivot_row)
return pivot_matrix
pivot_column_matrix = extract_pivot_columns(input_matrix, pivots_column)
printMatrix(non_zero_matrix)
print()
print("Multiplied By")
printMatrix(pivot_column_matrix)
print()
print("Equals")
printMatrix(input_matrix)
print()
print('The matrix has been rank factorized!')
print("------------------------------------------------------------------------------------------")