次回記事では連立一次方程式を解くための一般的な手順を考えます。その準備として、今回は単位行列と逆行列を定義して、その基本的な性質と Python で実装する方法を学びます。
単位行列の定義と性質
行列 $A$ に左右どちらから掛けても $A$ となるような行列を単位行列 (identity matrix) とよびます。$2\times 2$ の単位行列は
\[I=\begin{bmatrix}1&0\\0&1\end{bmatrix}\tag{1}\]
で表されます。たとえば、$A$ に $I$ を左から掛けると
\[IA=\begin{bmatrix}1&0\\0&1\end{bmatrix}\begin{bmatrix}a&b\\c&d\end{bmatrix}=\begin{bmatrix}a&b\\c&d\end{bmatrix}\]
となって $A$ は変化しません。同様にして $AI=A$ も確かめられます。もちろん任意のベクトルも単位行列によって変化しません。
\[\begin{bmatrix}1&0\\0&1\end{bmatrix}\begin{bmatrix}a\\b\end{bmatrix}=\begin{bmatrix}a\\b\end{bmatrix}\]
このように、行列やベクトルに対して恒等変換を施すことから、単位行列はスカラーの $1$ に相当します。一般に $n\times n$ の単位行列は、主対角線上の成分 (左上から右下に並ぶ要素) が $1$、他はすべて $0$ の行列として表されます:
\[I=\begin{bmatrix}1&0 &\cdots &0\\0&1 &\cdots &0\\\vdots & \vdots &\ddots &\vdots\\0&0 &\cdots &1\end{bmatrix}\tag{2}\]
Python で単位行列の性質を確認してみましょう。NumPy をインポートして、 numpy.identity() 関数を使って $3\times{3}$ の単位行列を生成します。行列の各要素を整数型にしたいので、データ型 (dtype) に np.int8 を指定しておきます。
# python_identity_matrix
# In[1]
import numpy as np
# 3×3の単位行列を生成
I = np.identity(3, dtype = np.int8)
print(I)
[[1 0 0] [0 1 0] [0 0 1]]
次に同サイズの行列 $A$ を作っておきます。
# In[2]
# 行列Aを定義
A = np.arange(9).reshape(3, 3)
print(A)
[[0 1 2] [3 4 5] [6 7 8]]
単位行列 $I$ を $A$ の左側から掛けてみます。
# In[3]
# 行列積IAを計算
print(I@A)
[[0 1 2] [3 4 5] [6 7 8]]
行列 $A$ と一致していますね。今度は単位行列 $I$ を $A$ の右側から掛けます。
# In[4]
# 行列積AIを計算
print(A@I)
[[0 1 2] [3 4 5] [6 7 8]]
やはり、恒等変換となっていることが確認できました。
関連記事:numpy.identity()
逆行列と正則行列
行列 $A$ に左右どちらから掛けても単位行列となるような行列、すなわち
\[A^{-1}A=AA^{-1}=I\tag{3}\]
を満たすような行列 $A^{-1}$ が存在すれば、$A^{-1}$ を $A$ の 逆行列 (invertible matrix) とよびます。また、自身の逆行列をもつ行列を 正則行列 (regular matrix) とよびます。
ある行列について、逆行列は存在したとしても 1 個だけです。実際、$A$ に互いに相異なる逆行列 $B$ と $C$ が存在したとすると、
\[BA=AC=I\tag{4}\]
が成り立ちます。一方で結合法則により
\[B(AC)=(BA)C\tag{5}\]
が成り立ちますが、(4) より
\[BI=IC\tag{6}\]
となります。すなわち $B=C$ であり、$A$ の逆行列は唯一つであることがわかります。
行列 $A=\begin{bmatrix}a&b\\c&d\end{bmatrix}$ の逆行列は
\[A^{-1}=\frac{1}{ad-bc}\begin{bmatrix}d&-b\\-c&a\end{bmatrix}\tag{7}\]
で与えられます(実際に $A^{-1}A$ と $AA^{-1}$ を計算して $I$ になることが確かめられます)。ただし、$ad-bc=0$ のときは分母が $0$ になってしまうので逆行列は存在しません。
$ad-bc$ は $A$ の行列式 $\det A$ なので、(4) は
\[A^{-1}=\frac{1}{\det A}\begin{bmatrix}d&-b\\-c&a\end{bmatrix}\tag{8}\]
と表すこともできます。
行列積 $AB$ の逆行列は
\[(AB)^{-1}=B^{-1}A^{-1}\tag{9}\]
で与えられます。実際に $AB$ に左から掛けてみると
\[B^{-1}A^{-1}AB=B^{-1}IB=B^{-1}B=I\]
となって確かに単位行列になります。同じように右から掛けても単位行列になります。
Python で逆行列の性質を確認してみましょう。まず、3 行 3 列の適当な行列 A を生成します。
# python_invertible_matrix
# In[1]
import numpy as np
np.set_printoptions(precision=3)
# 乱数のseedを設定
np.random.seed(5)
# 3×3配列をランダムに生成
A = np.random.randint(0, 9, (3, 3))
print(A)
[[3 6 6] [0 8 4] [7 0 0]]
念のために A の 行列式 の値が 0 ではないことを確認しておきます。
# In[2]
from scipy.linalg import det
# Aの行列式を求める
print(det(A))
-168.0
逆行列は NumPy の linalg.inv() 関数を使って求められます。
# In[3]
# Aの逆行列
A_inv = np.linalg.inv(A)
print(A_inv)
[[ 0. 0. 0.143] [-0.167 0.25 0.071] [ 0.333 -0.25 -0.143]]
A に A の逆行列を左から掛けて単位行列になることを確認してみます。
# In[4]
# AにAの逆行列を左から掛ける
print(A_inv @ A)
[[ 1.000e+00 0.000e+00 0.000e+00] [-2.776e-17 1.000e+00 0.000e+00] [ 5.551e-17 0.000e+00 1.000e+00]]
同様に A に A の逆行列を右から掛けて単位行列になることを確めます。
# In[5]
# AにAの逆行列を右から掛ける
print(A @ A_inv)
[[1. 0. 0.] [0. 1. 0.] [0. 0. 1.]]
numpy.linalg.inv()
numpy.linalg.inv() は配列 a を受け取って、a の逆行列を返します。
# numpy_invertible_matrix
# In[1]
import numpy as np
# 行列aを定義
a = np.array([[1, 2],
[3, 4]])
# aの逆行列ainv
ainv = np.linalg.inv(a)
# aとainvの積bを計算
b = np.dot(a, ainv)
print("aの逆行列\n{}\n".format(ainv))
print("aとaの逆行列の積\n{}".format(b))
aの逆行列 [[-2. 1. ] [ 1.5 -0.5]] aとaの逆行列の積 [[1.00000000e+00 1.11022302e-16] [0.00000000e+00 1.00000000e+00]]
scipy.linalg.inv()
scipy.linalg.inv() は配列 a を受け取って、a の逆行列を返します。
# scipy_invertible_matrix
# In[1]
import numpy as np
from scipy import linalg
# 行列aを定義
a = np.array([[7, -2],
[5, 1]])
# aの逆行列ainv
ainv = linalg.inv(a)
# aとainvの積bを計算
b = np.dot(a, ainv)
print("aの逆行列\n{}\n".format(ainv))
print("aとaの逆行列の積\n{}".format(b))
aの逆行列 [[ 0.05882353 0.11764706] [-0.29411765 0.41176471]] aとaの逆行列の積 [[ 1.00000000e+00 -1.11022302e-16] [ 0.00000000e+00 1.00000000e+00]]
逆行列との積が単位行列にならないのはなぜでしょうか??
浮動小数点の演算では、原理的に丸め誤差が避けられません。たとえば、10 進数の 0.2 は 2 進数で表すと本来は無限級数になります。しかし、コンピュータは限られたビット数で数値を扱わなければならないので、有限桁数で打ち切る必要があります。単純な引き算でさえ誤差が生じ得ます。次の例を見てください。
計算結果が 0 になるべきところで、僅かな誤差が生じています。これは 0.2 と 0.9 – 0.7 が、コンピュータ内部では異なる値であることを示しています。0.2 と 0.9 – 0.7 をそれぞれ 40 桁まで正確に表示させて、比較すると、0.2 のほうが僅かに小さいことがわかります。
上の例のように、同程度の数の引き算で有効桁数が減少することを「桁落ち」といいます。特に行列と逆行列の積の計算では、対角成分の要素を計算するときに (原理的には) 結果が 0 になるような引き算が内部で実行されるので、この「桁落ち」が生じやすいといえます。
下記は誤植と思われますので、ご確認ください。
#In[5]の上の文章で、左から → 右から
細かい所までみてくださって、本当にありがとうございます。
直しておきました。
人工知能が単位行列と逆行列について語ります
[ChatGPT] 単位行列(Identity Matrix)は、正方行列の中で特別な性質を持つ行列です。単位行列は、対角線上の要素が全て1で、それ以外の要素が全て0で構成されています。通常、IまたはI_nと表記されます。ここで、nは行列の次元を表します。単位行列は、行列の掛け算において特別な役割を果たします。任意の正方行列Aと単位行列I_nを掛けると、A自体が結果として得られます。つまり、A・I_n = Aです。単位行列は、行列の「恒等写像」とも考えることができます。行列の掛け算では、行列Aを別の行列Bに変換する操作が行われますが、単位行列を掛けることで元の行列Aを変化させずに変換します。これは、単位行列が行列空間における基底の役割を果たしていることを意味します。
[ChatGPT] 逆行列は、行列の特別な性質です。行列は、数値の集合を表すために使用される2次元の配列です。逆行列は、与えられた行列と積をとった場合に単位行列(すべての対角成分が1でそれ以外の成分が0の行列)が得られるような行列のことを指します。逆行列がなぜ重要なのかを理解するために、まず逆行列を使わずに連立方程式を解く方法を考えてみましょう。例えば、以下のような連立方程式があるとします。
2x + 3y = 8
4x – 5y = 1
これを行列の形式で表すと次のようになります。
[ 2 3 ] [ x ] = [ 8 ]
[ 4 -5 ] [ y ] [ 1 ]
行列の形式で表現すると、次のように書くことができます。
AX = B
ここで、Aは係数行列、Xは未知数の列ベクトル、Bは定数の列ベクトルです。逆行列が存在する場合、次のように連立方程式を解くことができます。
A^(-1)AX = A^(-1)B
IX = A^(-1)B
X = A^(-1)B
ここで、Iは単位行列を表します。ただし、逆行列が存在するためにはいくつかの条件が必要です。行列Aが正方行列(行と列の数が同じ)であり、かつ行列式が0でない場合に逆行列が存在します。行列式が0になる場合や正方行列でない場合、逆行列は存在しないことになります。逆行列の求め方は、行列の性質や計算方法に基づいており、手計算では煩雑な場合もあります。幸いなことに、多くの数値計算ソフトウェアや数学ライブラリが逆行列の計算をサポートしており、簡単に逆行列を求めることができます。