逆行列の求め方 PythonとC++

統計学




逆行列とは

$$
A X = I
$$
上式を満たす、Xがあれば、Xは逆行列と呼ぶ。

Aの逆行列は、\(A-{−1}\)と表す。

$$
A A ^ { – 1 } = A ^ { – 1 } A = I
$$

逆行列は、全てに存在するとは限りません。

逆行列が存在する正方行列(n行n列行列)を、正則行列と呼びます。

存在しない正方行列を、非正則行列または、特異行列と呼びます。

逆行列をPythonで求める

逆行列をPythonで求めるには、numpyのnp.linalg.inv()を使用します。

import numpy as np

np.linalg.inv()

プログラム

import numpy as np

arr = np.array([[1, 2], [3, 4]])
print("行列A = \n", arr)
arr_inv = np.linalg.inv(arr)
print("逆行列A = \n", arr_inv)

出力値

特異値分解で逆行列を求める

$$
\Large
M = U \Sigma V ^ { * }
$$

$$
A = U \Sigma V ^ { T } \Longrightarrow A ^ { + } = V \Sigma ^ { + } U ^ { T }
$$

import numpy as np

arr = np.array([[1, 2], [3, 4]])
print("行列A = \n", arr)

U, s, V = np.linalg.svd(arr, full_matrices=True)
sp = 1/s
sp = np.diag(sp)
sp
U = np.conj(U).T
V = np.conj(V).T
arr_invs = np.dot(np.dot(V,sp), U)
print("逆行列A = \n", arr_invs)

np.dot(arr, arr_invs)

擬似逆行列をPythonで求める

wiki/擬似逆行列

import numpy as np

arr = np.array([[1, 1], [1, 1]])
print("行列A = \n", arr)
arr_pinv = np.linalg.pinv(arr)
print("逆行列A = \n", arr_pinv)

C++で掃き出し法

# C++
//単位行列を作る
for(i=0;i<n;i++){
 for(j=0;j<n;j++){
 inv_a[i][j]=(i==j)?1.0:0.0;
 }
}
//掃き出し法
for(i=0;i<n;i++){
 buf=1/a[i][i];
 for(j=0;j<n;j++){
 a[i][j]*=buf;
 inv_a[i][j]*=buf;
}
for(j=0;j<n;j++){
 if(i!=j){
  buf=a[j][i];
  for(k=0;k<n;k++){
   a[j][k]-=a[i][k]*buf;
   inv_a[j][k]-=inv_a[i][k]*buf;
  }
 }
}
}

参考

タイトルとURLをコピーしました