0

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()
Himself12794
  • 251
  • 3
  • 13

1 Answers1

0

Remember you are dealing with floating point numbers that are defined by the IEEE 754 standard. It defines both a +0 and a -0.

See : negative zero in python

Community
  • 1
  • 1
William Denman
  • 3,046
  • 32
  • 34