"""
Class to do elementary row operations on augmented matrices.
"""

# import commonly used libraries
import numpy as np


class augmentedMatrix :
  """
  Define a class to perform elementary row operations on augmented matrices.
  The augmented matrix is stored as a object variable.
  The three standard EROS are defined as methods along with methods to 
  print and return the augmented matrix.
  """    
  
  def __init__(self, initialMatrix) :
    # store the initial matrix into the object variable m
    self.m = np.array(initialMatrix)

  def row_swap(self, i, j) :
    # Swap rows i and j of the matrix.
    t = self.m[i,:].copy() # copy row i of the matrix
    self.m[i,:] = self.m[j,:] # copy row j of the matrix into row i
    self.m[j,:] = t # put the copy of the original row i into row j
    # note that we don't return the matrix, it stays in the object

  def scalar_mult(self, i, c) :
    # Multiply row i of matrix m by c.
    self.m[i,:] = c*self.m[i,:] # multiply row i by c and put it back into row i

  def row_add(self, i, j, c) :
    # multiply row i by c, add to row j, and put sum back into row j
    self.m[j,:] = c*self.m[i,:]+self.m[j,:]

  def print(self) :
    # print the matrix
    print(self.m)



m = augmentedMatrix([[1.0, 1.0, 27],[2, -1, 0]]) # define augmented matrix
print('Starting matrix')
m.print()

print('Swap rows 0 and 1.')
m.row_swap(0, 1)
m.print()

print('Scalar multiply row 0 by 0.5.')
m.scalar_mult(0, 0.5)
m.print()

print('Add -1 times row 0 to row 1.')
m.row_add(0, 1, -1)
m.print()

print('Scalar multiply row 1 by 2/3.')
m.scalar_mult(1, 2.0/3.0)
m.print()

# Multiply R1 by 1/2 and add to R0 to make second entry in R0 = 0
print('Add 0.5 times row 0 to row 1.')
m.row_add(1, 0, 0.5)
m.print()

# Print Results
print('Reduced row echelon form of matrix is:')
m.print()

