行列式の定義とサラスの方法

行列式の定義とサラスの方法

行列式の定義

 前回記事 で扱った $v_1w_2-v_2w_1$ は線型代数において重要な意味をもつ量であり、
 
\[\mathrm{det}(\boldsymbol{v},\boldsymbol{w})
=\begin{vmatrix}v_1 & w_1\\v_2 & w_2\end{vmatrix}\tag{2}\]
のように書いて 行列式 (determinant) とよびます。計算するときは対角要素の積をつくってから差をとります。大事なことなので繰り返し述べますが、$\mathrm{det}(\boldsymbol{v},\boldsymbol{w})\neq 0$ のとき、$\boldsymbol{v}$ と $\boldsymbol{w}$ は線型独立であり、この 2 つのベクトルで平面を張ることができます。

 線型独立と行列式の関係を幾何学的に考えてみます。
 $\mathrm{det}(\boldsymbol{v},\boldsymbol{w})$ は $\boldsymbol{v}$ と $\boldsymbol{w}$ を辺とする平行四辺形の面積を表すことが知られています。

 2次元行列式 determinant の幾何学的定義

 しかし、$\boldsymbol{v}$ と $\boldsymbol{w}$ が線型従属(平行)であるときは、この平行四辺形は潰れてしまって面積は $0$ になってしまいます。したがって、$\boldsymbol{v}$ と $\boldsymbol{w}$ が線型独立であることは、$\mathrm{det}(\boldsymbol{v},\boldsymbol{w})$ が $0$ 以外の値をもつことに対応します。
 

scipy.linalg.det()

 行列式は scipy.linalg.det() を使って計算できます。

# SLA_012

import numpy as np
from scipy.linalg import det

# 配列を定義
x = np.array([[ 5, 2],
              [-3, 4]])

# 行列式を計算
det_x = det(x)

print("det(x) = {}".format(det_x))
det(x) = 26.0

サラスの方法

 線型独立と行列式の関係は 3 次元ベクトルにも拡張できます。
 3 次元空間における行列式は以下の式で与えられます。
 
\[\begin{align*}\mathrm{det}(\boldsymbol{u},\boldsymbol{v},\boldsymbol{w})
&=\begin{vmatrix}
u_1 & v_1 & w_1\\
u_2 & v_2 & w_2\\
u_3 & v_3 & w_3\end{vmatrix}\\[6pt]
&=u_1v_2w_3+u_2v_3w_1+u_3v_1w_2-u_1v_3w_2-u_2v_1w_3-u_2v_1w_3\end{align*}\]
 こんな式を覚えられるわけないので、以下の図に示すように行列式のを二つ重ねて、対角線上の積をつくって合計します。

 Python サラスの方法 (Sarrus' rule)

 ただし、左上から右下にとる積はプラス、右上から左下にとる積はマイナスの符号をつけて計算します。この計算法を サラスの方法 (Sarrus' rule) とよびます。
 

3次元ベクトルの線形結合

 3 次元のベクトルで作られる行列式は、3 つのベクトルが作る立体の体積を表します。

 3次元行列式 determinant の幾何学的意味

 3 つのベクトルが同じ平面内にあるとき (1 次従属の関係にあるとき) には、立体は潰れてしまって体積は $0$ になります。
 $\boldsymbol{u},\ \boldsymbol{v},\ \boldsymbol{w}$ で空間を張ることができる (1 次独立の関係にある) のは、行列式の値が $0$ 以外の値をとるときです。
 

行列式の計算手順

 実際に行列式を計算するときは、サラスの方法を使う前に、明らかに行列式が $0$ にならないかを確認します。たとえば、
 
\[\mathrm{det}A=\begin{vmatrix}
2 & 4 & 5\\
1 & 2 & 5\\
4 & 8 & 3\end{vmatrix}\]
という行列式は、2 列目のベクトルが 1 列目のベクトルの 2 倍になっています。つまり平行なベクトルが含まれているので、この行列式は計算するまでもなく $\mathrm{det}A=0$ だとわかります。

 あるベクトルの成分に共通の約数があれば行列式の外に出します(詳しくは次回記事行列式の線型性で扱います)。すなわち成分の最大公約数を見つけます。たとえば、
 
\[\mathrm{det}B=\begin{vmatrix}
1 & 5 & 12\\
7 & 0 & 16\\
9 & 5 & 8\end{vmatrix}\]
の 2 列目の最大公約数は $5$, 3 列目の成分の最大公約数は $4$ なので、この行列式は
 
\[\mathrm{det}B=4\cdot 5\begin{vmatrix}
1 & 1 & 3\\
7 & 0 & 4\\
9 & 1 & 2\end{vmatrix}=20\times 39=780\]
のように計算できます。
 

Pythonからはじめる数学入門

中古価格
¥1,882から
(2019/10/27 13:03時点)

n次元ベクトルの線形結合

 2 次元と 3 次元で展開された議論はそのまま $n$ 次元空間に拡張されます。
 $n$ 組の $n$ 次元ベクトルが $n$ 次元空間を張るための条件は、互いに 1 次独立の関係にあること、すなわち、$n$ 組の $n$ 次元ベクトルから作られた行列式が $0$ 以外の値をとることです。
 次元が増えると、もはや紙の上での計算では手に負えなくなるので、コンピュータの力を借りることになります。scipy.linalg.det() を使って、10 次元の行列式の値を計算してみましょう。各成分は np.random.randint() を使って 0 ~ 9 の範囲で無作為に決定します。

# SLA_013-1

import numpy as np
from scipy.linalg import det

# 10次元の行列式を定義

# 乱数シードを設定
np.random.seed(10)

# 10次元ベクトルを10個格納した2次元配列
# [[5 0 3 3 7 9 3 5 2 4]
#  [7 6 8 8 1 6 7 7 8 1]
#  [5 9 8 9 4 3 0 3 5 0]
#  [2 3 8 1 3 3 3 7 0 1]
#  [9 9 0 4 7 3 2 7 2 0]
#  [0 4 5 5 6 8 4 1 4 9]
#  [8 1 1 7 9 9 3 6 7 2]
#  [0 3 5 9 4 4 6 4 4 3]
#  [4 4 8 4 3 7 5 5 0 1]
#  [5 9 3 0 5 0 1 2 4 2]]
x = np.random.randint(0, 10, (10, 10))

# 行列式の値を計算
det_x = det(x)

print("det(x) = {:.3e}".format(det_x))
det(x) = 5.825e+07

 $5.825\times 10^7$ という大きな桁の数が表示されました。
 言うまでもなく、上のコードで設定したベクトルは互いに 1 次独立です。
 次元が大きい場合、ランダムに成分を決めても、1 次従属なベクトルの組は滅多に出現しないようです。行列式の値はプラス側にもマイナス側にも大きく振れます。上のコードで seed を 10 に設定すると $-2.982\times 10^8$ となります。

 同じように、3 次元で 0 ~ 9 の範囲のランダム成分をもつ行列式を 10 万個つくって、そのうち何個が 0 になるか調べてみました。

# SLA_013-2

# 乱数シードを設定
np.random.seed(0)

# カウント数の初期値
ct = 0

# 無作為な3次元行列式を10万個作成して値を計算
for k in range(10**5):
    x = np.random.randint(0, 10, (3, 3))
    if det(x) == 0:
        ct += 1
        
print("行列式が0になった個数:{}".format(ct))
行列式が0になった個数:1785

 結果は 1785 個です。seed を変えて計算しても、概ね 1700 個前後でした。おおよそ 100 個のうち 2 個程度が 1 次従属の関係にあるベクトルの組となります。
 

行列式の展開

 行列式を計算する別の手段として、行展開(または列展開)があります。たとえば、3 次元行列式は以下のように展開できることが知られています。
 
\[\begin{align*}\begin{vmatrix}u_1 & v_1 & w_1\\
u_2 & v_2 & w_2\\u_3 & v_3 & w_3\end{vmatrix}
&=u_1\begin{vmatrix}v_2 & w_2 \\ v_3 & w_3\end{vmatrix}
-v_1\begin{vmatrix}u_2 & w_2 \\ u_3 & w_3\end{vmatrix}
+w_1\begin{vmatrix}u_2 & v_2 \\ u_3 & v_3\end{vmatrix}\end{align*}\]
 各項は次のような手順で作られます。

 Python 行列式の展開 (expand determinant)

 符号は +, -, + のように交互に並べます。上の例では 1 行目を使いましたが、係数はどの行または列を選んでも構いません。大きなサイズの行列式についても、同じように次元を 1 つ下げた行列式を使って展開できるので、展開を繰り返すことによって最終的には 2 次元行列式の計算に帰着できます。

 [参考文献] ゼロから学ぶ線形代数