【Python】2次元の逆行列を計算する

■逆行列

以下のような正方行列Aの逆行列A-1ad - bc ≠ 0のとき存在し、次の計算式で求めることができる。



`A^-1 = 1 / (ad – bc) [[d, -b], [-c, a]]`…
Text is not SVG – cannot display

■例題

以下の行列に関して、Pythonにて、逆行列が存在する場合は、逆行列を算出し、逆行列が存在しない場合は、その理由を出力する。

問1:

問2:

問3:

問4:
問1:`[[2, 6], [1, 3]]`…
Text is not SVG – cannot display

■前提および実装概要

  • numpy標準の以下のライブラリは使用しない。
    • np.linagle.det(A): 行列式を算出可能
    • np.linagle.inv(A): 逆関数を算出可能
  • 2次元の正方行列のみ対象とする。
  • 正方行列ではない、または、逆行列が存在しない場合のみエラーとする。

■フローチャート

以下に実装するフローチャートを示す。

・メイン処理

コンソール
コンソール
開始
開始
問題の行列をセット
問題の行列をセット
問題の行列数分繰り返し
問題の行列数分繰り返し
区切り文字
区切り文字
出力用区切り文字出力
出力用区切り文字出力
try
try
逆表列算出処理
逆表列算出処理
元の行列出力
元の行列出力
逆行列出力
逆行列出力
元の行列
元の行列
逆行列
逆行列
except ValueError
except ValueError
エラー出力
エラー出力
終了
終了
エラー
エラー
Text is not SVG – cannot display

・逆行列算出処理

開始
開始
正方行列
正方行列
 Yes
 Yes
No
No
行列式
行列式
行列式を計算
行列式を計算
≠ 0
≠ 0
= 0
= 0
逆行列配列を0埋めで作成
逆行列配列を0埋めで作成
逆行列配列に値を配置
逆行列配列に値を配置
逆行列を計算
逆行列を計算
return 逆行列
return 逆行列
終了
終了
例外:ValueError
例外:ValueError
例外:ValueError
例外:ValueError
Text is not SVG – cannot display

■サンプルコード

from fractions import Fraction
import numpy as np

# 逆行列算出力
def inverse_matrix_manual(matrix):
    # 行列が正方行列であることを確認
    if matrix.shape[0] != matrix.shape[1]:
        raise ValueError("逆行列を求めるには正方行列である必要があります。")
    
    # 行列式を計算
    det = matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0]
    if det == 0:
        raise ValueError("逆行列は存在しません。")
       
    # 逆行列配列:float型で0埋め正方配列を作成
    cofactor_matrix = np.zeros_like(matrix, dtype=float)
    
    # 逆行列配列に値を配置
    cofactor_matrix[0][0] = matrix[1][1]
    cofactor_matrix[0][1] = -1 * matrix[0][1]
    cofactor_matrix[1][0] = -1 * matrix[1][0]
    cofactor_matrix[1][1] = matrix[0][0]
        
    # 逆行列を計算
    inverse = cofactor_matrix / det

    return inverse


# メイン処理
if __name__ == '__main__':

    # 問題の行列
    matrix_1 = np.array([[2, 6], [1, 3]])
    matrix_2 = np.array([[-3, 4], [2, -3]])
    matrix_3 = np.array([[5, 2], [1, 0]])
    matrix_4 = np.arange(8).reshape(2,4)

    matrix_list = [
        matrix_1
        , matrix_2
        , matrix_3
        , matrix_4
    ]

for matrix in matrix_list:
    print("-------------------------------")
    try:
        result = inverse_matrix_manual(matrix)
        print("元の行列:")
        # 少数の場合は分数表記
        print(np.vectorize(lambda x: str(Fraction(x).limit_denominator()))(matrix))
        print("\n逆行列:")
        # 少数の場合は分数表記
        print(np.vectorize(lambda x: str(Fraction(x).limit_denominator()))(result))
    except ValueError as e:
        print(e)

■実行結果

-------------------------------
逆行列は存在しません。
-------------------------------
元の行列:
[['-3' '4']
 ['2' '-3']]

逆行列:
[['-3' '-4']
 ['-2' '-3']]
-------------------------------
元の行列:
[['5' '2']
 ['1' '0']]

逆行列:
[['0' '1']
 ['1/2' '-5/2']]
-------------------------------
逆行列を求めるには正方行列である必要があります。

コメント