So I've been working on a Matrix class in python as a proof of concept, and I'd like some advice on potential errors in the code, and ways to clean it up some. I'll add correct error handling and documentation once I know the base code works.
A specific question I have is that when:
matrix = [
[ 0, 3, -6, 6, 4, -5 ],
[ 3, -7, 8, -5, 8, 9 ],
[ 3, -9, 12, -9, 6, 15 ],
]
The rref() method returns:
[1.0, 0.0, -2.0000000000000004, 3.0, 0.0, -24.0]
[-0.0, 1.0, -2.0, 2.0, 0.0, -7.0]
[0.0, 0.0, 0.0, 0.0, 1.0, 4.0]
Which has a -0.0 in the first column of the second row, and I'm not sure what's causing that.
The class is below:
class Matrix:
def __init__( self, initMatrix = [] ):
# Check if matrix is valid size
# If valid, sets matrix, else sets as the 0 2x2 matrix
valid = True
if len( initMatrix ) != 0:
for i in range( len( initMatrix ) ):
if i > 1:
if ( len( initMatrix[ i ] ) != len( initMatrix[ i - 1 ] ) ) or ( len( initMatrix[ i ] ) == 0 ):
valid = False
if valid:
self._matrix = initMatrix
self._m = len( initMatrix )
self._n = len( initMatrix[ 0 ] )
else:
self.identityMatrix( 2 )
# Matrix generation
def generateMatrix( self, m, n, v ):
temp = []
for i in range( m ):
tempRow = []
for i2 in range( n ):
tempRow.append( v )
temp.append( tempRow )
self._matrix = temp
def identityMatrix( self, n ):
iMatrix = []
self._m = n
self._n = n
for i in range( n ):
row = []
for u in range( n ):
if u == i:
row.append( 1 )
else:
row.append( 0 )
iMatrix.append( row )
self._matrix = iMatrix
# Methods for solving RRE form and RE form
def _rowAdd( self, row1, row2 ):
for i, amount in enumerate( row2 ):
row1[ i ] += amount
return row1
def _rowDivide( self, row, divisor ):
row = [ ( float( value ) / divisor ) for value in row ]
#print( row )
return row
def _rowMultiply( self, row, factor ):
row = [ ( value * factor ) for value in row ]
return row
def isInRE( self, row = None ):
if row and ( row in range( len( self._matrix ) ) ):
copy = [ self._matrix[ row ] ]
else:
copy = self._matrix
verdict = True
for i, value in enumerate( copy ):
for i2, value2 in enumerate( value ):
if ( i2 == i ) and ( value2 != 1 ):
verdict = False
elif ( i2 < i ) and ( value2 != 0 ):
verdict = False
return verdict
def isInRRE( self ):
pass
def _findPivot( self, row ):
for id, value in enumerate( row ):
if value != 0:
return id
return None
def _removeDupe( self ):
temp = list( set( self._matrix ) )
return temp
def _checkBlank( self, row ):
for value in row:
if value != 0:
return False
return True
# Solving
def ref( self ):
if not self._n >= self._m:
return None
copy = self._matrix
copy.sort()
copy.reverse()
if not self.isInRE():
for id in range( len( copy ) ):
pivot_column = self._findPivot( copy[ id ] )
if not pivot_column:
pass
pivot = copy[ id ][ pivot_column ]
copy[ id ] = self._rowDivide( copy[ id ], pivot )
for i in range( id + 1, len( copy ) ):
if not self._checkBlank( copy[ i ] ):
copy[ i ] = self._rowAdd( self._rowMultiply( copy[ id ], -copy[ i ][ pivot_column ] ), copy[ i ] )
copy.sort()
copy.reverse()
self._matrix = copy
def rref( self ):
self.ref()
#self.display()
copy = self._matrix
for id in reversed( range( len( copy ) ) ):
#print( id )
pivot_column = self._findPivot( copy[ id ] )
if not pivot_column:
pass
for i in reversed( range( id ) ):
if not self._checkBlank( copy[ i ] ):
#print( copy[ i ] )
copy[ i ] = self._rowAdd( self._rowMultiply( copy[ id ], -copy[ i ][ pivot_column ] ), copy[ i ] )
#print( copy[ i ] )
self._matrix = copy
# Methods for outside matrix use
def addRow( self, row ):
if len( row ) == self._n:
self._matrix.append( row )
def display( self ):
for row in self._matrix:
print( row )
print( '\n' )
# Overloading operators
def __add__( self, other ):
dupe = self._matrix
if ( self._n == other._n ) and ( self._m == other._m ):
for i in range( self._m ):
for id, amount in enumerate( other._matrix[ i ] ):
dupe[ i ][ id ] += amount
return Matrix( dupe )
def __mul__( self, other ):
pass
test = Matrix( matrix )
test.rref()
test.display()