Hatena::ブログ(Diary)

kobakoba0723の日記

2011-07-11

Pythonクックブック(4章)

リストで行列を表現

リストの要素を行列の列に見立てると以下のように足す、引く、掛けるの演算が出来る。

割るは、逆行列のかけ算と定義すれば良いが、逆行列の算出方法自体を忘れてしまったので今回はパス。

[kobakoba0723@fedora13-intel64 ~]$ cat calc_matrix.py
def add(matrix1, matrix2):
    added = []
    for (row1, row2) in zip(matrix1, matrix2):
        add_row = []
        for (element1, element2) in zip(row1, row2):
            add_row.append(element1 + element2)
        added.append(add_row)
    return added


def subtract(matrix1, matrix2):
    subtracted = []
    for (row1, row2) in zip(matrix1, matrix2):
        subtracted_row = []
        for (element1, element2) in zip(row1, row2):
            subtracted_row.append(element1 - element2)
        subtracted.append(subtracted_row)
    return subtracted


def multiply(matrix1, matrix2):
    transposition_multiplied = []
    for i in range(len(matrix1[0])):
        matrix1_column = [row[i] for row in matrix1]
        multiplied_row = []
        for j in range(len(matrix2)):
            multiplied_row_element = 0
            for (element1, element2) in zip(matrix1_column, matrix2[j]):
                multiplied_row_element += element1 * element2
            multiplied_row.append(multiplied_row_element)
        transposition_multiplied.append(multiplied_row)
    # リストの各要素は、行列の"列"を表すので転置が必要
    return  [[row[i] for row in transposition_multiplied]
               for i in range(len(transposition_multiplied[0]))]

if __name__ == '__main__':
    matrix1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
    matrix2 = [[2, 3, 4, 5], [6, 7, 8, 9], [10, 11, 12, 13]]

    print 'matrix1:', matrix1
    print 'matrix2:', matrix2
    print 'matrix1 + matrix2 =', add(matrix1, matrix2)
    print 'matrix1 - matrix2 =', subtract(matrix1, matrix2)
    # 4*3行列とのかけ算なので、3*4行列が必要
    transposition_matrix2 = [[row[i] for row in matrix2]
                               for i in range(len(matrix2[0]))]
    print 'matrix1 * trans_matrix2 =', multiply(matrix1, transposition_matrix2)

    print

    matrix1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    matrix2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    print 'matrix1:', matrix1
    print 'matrix2:', matrix2
    print 'matrix1 + matrxi2 =', add(matrix1, matrix2)
    print 'matrix1 - matrxi2 =', subtract(matrix1, matrix2)
    print 'matrix1 * matrxi2 = ', multiply(matrix1, matrix2)
[kobakoba0723@fedora13-intel64 ~]$ python calc_matrix.py
matrix1: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
matrix2: [[2, 3, 4, 5], [6, 7, 8, 9], [10, 11, 12, 13]]
matrix1 + matrix2 = [[3, 5, 7, 9], [11, 13, 15, 17], [19, 21, 23, 25]]
matrix1 - matrix2 = [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]]
matrix1 * trans_matrix2 = [[122, 140, 158, 176], [137, 158, 179, 200], [152, 176, 200, 224], [167, 194, 221, 248]]

matrix1: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix2: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix1 + matrxi2 = [[2, 4, 6], [8, 10, 12], [14, 16, 18]]
matrix1 - matrxi2 = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
matrix1 * matrxi2 =  [[30, 36, 42], [66, 81, 96], [102, 126, 150]]
[kobakoba0723@fedora13-intel64 ~]$ 

行列演算などの数値演算用に、サードパーティーのNumpyモジュールがあるが、

今まで行列演算を実装したことがなかったので、折角の機会ということで実装。

参考サイト

組込み関数@標準ライブラリ