FC2ブログ
--.--
--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

06.16
Sat
以前にPythonで書いた行列を計算するやつを書き直してみました

今度は行列式や逆行列をちょっとは求められるようになりました.

ただ、特殊なアルゴリズムは全く使わずリストの中身をいじくりまわして計算してるだけなので

非常に遅いです。行列式を計算するとこなんて、ちょっと次数の高い行列が与えられたらまともに計算できないと思います

計算量を多項式時間?に表す方法がいまいちわかんないんですが、多分計算量は階乗で増えてくと思います

ま、いちおうコードを.

#!/usr/bin/env python
#coding:utf-8

import math

class Matrix:

    #if flag is True , make elementary matrix in the [instance].e
    def __init__ ( self , matrixFactor , flag = True ):
        if ( isinstance( matrixFactor , str ) ): matrixFactor = self.transForm( matrixFactor )
        self.gyou = len( matrixFactor )
        self.retu = len( matrixFactor[ 0 ] )
        self.e = None
        for eachLine in matrixFactor:
            if ( self.retu != len( eachLine ) ): raise IOError
        self.matrix = matrixFactor
        if (( self.retu == self.gyou ) and ( flag == True )) :
            elementary_factor = []
            each_factor = []
            counter = 0
            for dummy in xrange( self.gyou ):
                for dummy2 in xrange( self.retu ):
                    if ( dummy2 == counter ) :
                        each_factor.append( 1 )
                    else:
                        each_factor.append( 0 )
                counter += 1
                elementary_factor.append( each_factor )
                each_factor = []
            self.e = Matrix( elementary_factor , False )


    def transForm( self , strdata ):
        result = []
        proc = []
        for eachRow in strdata.split( ";" ):
            for eachFactor in eachRow.split( "," ):
                proc.append( float( eachFactor ) )
            result.append( proc )
            proc = []
        return result

    #show format
    def printFormat( self ):
        print "%s Rows %s Columns  matrix" %( self.gyou , self.retu )


    #show matrix gui
    def printMatrix( self ):
        for each in self.matrix:
            for number in each:
                print str( number ) + "\t",
            print ""



    def getFactor( self , gyou , retu ):
        return self.matrix[ gyou - 1 ][ retu - 1 ]



    def getRow( self , row ):
        return self.matrix[ row - 1 ]


    def getColumn( self , column ):
        result = []
        for each in self.matrix : result.append( each[ column - 1 ] )
        return result


    def powMatrix( self , number):
        ins = Matrix( self.matrix )
        result = ins
        for dummy in xrange( number - 1 ):
            result = result.mult( ins )
        return result


    def timesMatrix( self , number ):
        result = []
        proc = []
        for each in self.matrix:
            for n in each:
                proc.append( n * number )
            result.append( proc )
            proc = []
        return Matrix(result)


    def multMatrix( self , matrix ):
        if ( self.retu != matrix.gyou ): raise IOError
        result =[]
        proc = []
        tmp = 0
        for each in self.matrix:
            for counter2 in xrange( matrix.retu ):
                r = matrix.getColumn( counter2 + 1 )
                for counter in xrange( self.retu ):
                    tmp += each[ counter ] * r[ counter ]
                proc.append( tmp )
                tmp = 0
            result.append( proc )
            proc = []
        return Matrix( result )

    #addMatrix
    def addMatrix( self , matrix  , flag = True):
        if ( ( self.gyou != matrix.gyou ) or ( self.retu != matrix.retu ) ): raise IOError
        new_matrix = []
        counter = 0
        for each in self.matrix:
            new_matrix.append( self.addList( each , matrix.matrix[ counter ] , flag ) )
            counter += 1
        return Matrix( new_matrix )


    #SubstractionMatrix
    def subsMatrix( self , matrix ):
        return self.addMatrix( matrix , flag = False )


    def compare( self , matrix ):
        if ( ( self.gyou != matrix.gyou ) or ( self.retu != matrix.retu ) ): return False
        counter = 0
        for each in self.matrix:
            target = matrix.matrix[ counter ]
            counter2 = 0
            for each2 in each:
                if ( each2 != target[ counter2 ] ) : return False
                counter2 += 1
            counter += 1
        return True

    def getRotatedPosition(self , angle):
        if ((self.gyou != 2) or (self.retu != 1)) : raise IOError
        rotatemat = Matrix([[math.cos(angle) , -math.sin(angle)] , [math.sin(angle) , math.cos(angle)]])
        return rotatemat.multMatrix(self)
		
    #get determinant
    def getDet( self ):
        if (self.retu != self.gyou) : raise IOError
        if (self.gyou == 1 and self.retu == 1) : return self.matrix[0][0]
        factorline = []
        signature = 1
        counter = 0
        dummy = ""
        for d in range(self.gyou-1):
		    for dd in range(self.gyou-1):dummy += "0,"
		    dummy = dummy.strip(",")
		    dummy += ";"
        dummy = dummy.strip(";")
        result = Matrix(dummy)
        result2 = 0
        for row1each in self.matrix[0]:
            for rowline in range(2 , self.gyou+1):
                tmp = self.matrix[rowline - 1]
                cp = tmp[:]
                del cp[counter]
                if rowline == 2:
					for suffix in range(len(cp)):
						cp[suffix] = cp[suffix] * signature * row1each
                factorline.append(cp)
            i = Matrix(factorline)
            factorline = []
            counter += 1
            signature *= -1
            if ((i.gyou != 1) and (i.retu != 1)):
                 result2 += i.getDet()
            else:
                 result2 += i.matrix[0][0]
        return result2
        
    def getTransposeMatrix(self):
        result = []
        for suffix in xrange(self.retu):
            result.append(self.getColumn(suffix+1))
        return Matrix(result)
        
    
	
    #this method is private. DON'T CALL WITH INSTANCE
    def addList( self , list1 , list2 , flag):
        result = []
        counter = 0
        for each in list1:
            if ( flag ):
                result.append( each + list2[ counter ] )
            else:
                result.append( each - list2[ counter ] )
            counter += 1
        return result

    
    def getCofactorMatrix(self , row , column):
        factor = []
        counter = 1
        for eachrow in self.matrix:
            if counter != row:
                cp = eachrow[:]  
                del cp[column-1]
                factor.append(cp)
            counter += 1
        return Matrix(factor)
        
    
    def getInverseMatrix(self):
        r = 1
        c = 1
        result = []
        tmp = []
        det = self.getDet()
        if det == 0 : raise IOError
        for d in self.matrix:
            if r % 2 == 0 :
                signature = -1
            else:
                signature = 1
            for dd in d:
                tmp.append(signature * (self.getCofactorMatrix(r , c).getDet()))
                c += 1
                signature *= -1
            result.append(tmp)
            tmp = []
            r +=1
            c = 1
        return Matrix(result).timesMatrix(1.0/det).getTransposeMatrix()


これを使って以下のような4元連立1次方程式を解いてみます

4eq.png

クラメールとかは使わないで、普通に逆行列を掛けました

#!/usr/bin/env python
#coding:utf-8

import Matrix



def main():
    #係数行列
    coefficient = [ [1,3,2,1] , [1,1,1,1] , [4,1,1,2] ,[1,2,-3,-1]]
    #定数行列
    const = [[30],[14],[21],[5]]
    #其々クラスからインスタンス作成
    i1 = Matrix.Matrix(coefficient)
    i2 = Matrix.Matrix(const)
    #係数行列の逆行列を求めて定数行列と掛け算。結果を表示
    i1.getInverseMatrix().multMatrix(i2).printMatrix()


if (__name__ == "__main__"): main()


結果: w = 1,x=7,y=2,z=4になってくれるかな
スポンサーサイト

comment 0 trackback 0
トラックバックURL
http://telracsmoratori.blog.fc2.com/tb.php/119-4ace29ce
トラックバック
コメント
管理者にだけ表示を許可する
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。