Python 2.7中Matrix类的评估

时间:2014-10-28 21:18:34

标签: python matrix

所以我一直在使用python中的Matrix类作为概念证明,我想对代码中的潜在错误以及清理它的方法提出一些建议。一旦我知道基本代码有效,我就会添加正确的错误处理和文档。

我遇到的具体问题是:

matrix = [
           [ 0, 3, -6, 6, 4, -5 ],
           [ 3, -7, 8, -5, 8, 9 ],
           [ 3, -9, 12, -9, 6, 15 ],
]

rref()方法返回:

[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]

第二行的第一列中有-0.0,我不确定是什么导致了这一点。

课程如下:

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()

1 个答案:

答案 0 :(得分:0)

请记住,您正在处理由IEEE 754 standard定义的浮点数。它定义了+0和-0。

请参阅:negative zero in python