行列式の定義は置換を用いた総和の形ですが、実際の計算では 余因子展開(cofactor expansion, またはラプラス展開)が最も基本的な手法です。余因子展開は、$n \times n$ 行列式を $(n-1) \times (n-1)$ 行列式の組み合わせに帰着させる再帰的な方法であり、手計算でも計算機でも広く用いられます。
さらに、余因子を用いると逆行列を明示的な公式で表現できます。これは理論的にも重要で、行列式・逆行列・連立方程式の解の間のつながりを明確にします。
本記事の内容
- 小行列式(minor)の定義
- 余因子(cofactor)の定義
- 余因子展開の定理と証明の概略
- 余因子行列と逆行列の公式
- 具体的な計算例
- Pythonでの実装
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
小行列式とは
定義
$n \times n$ 行列 $\bm{A} = (a_{ij})$ に対して、第 $i$ 行と第 $j$ 列を取り除いた $(n-1) \times (n-1)$ 行列の行列式を $(i, j)$ 小行列式(minor)と呼び、$M_{ij}$ と書きます。
$$ \begin{equation} M_{ij} = \det(\text{$\bm{A}$ の第 $i$ 行と第 $j$ 列を除いた行列}) \end{equation} $$
具体例
$\bm{A} = \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{pmatrix}$ に対して:
$$ M_{11} = \det \begin{pmatrix} 5 & 6 \\ 8 & 9 \end{pmatrix} = 5 \cdot 9 – 6 \cdot 8 = 45 – 48 = -3 $$
$$ M_{12} = \det \begin{pmatrix} 4 & 6 \\ 7 & 9 \end{pmatrix} = 4 \cdot 9 – 6 \cdot 7 = 36 – 42 = -6 $$
$$ M_{13} = \det \begin{pmatrix} 4 & 5 \\ 7 & 8 \end{pmatrix} = 4 \cdot 8 – 5 \cdot 7 = 32 – 35 = -3 $$
余因子とは
定義
$(i, j)$ 余因子(cofactor)$C_{ij}$ は、小行列式 $M_{ij}$ に符号 $(-1)^{i+j}$ をつけたものです。
$$ \begin{equation} C_{ij} = (-1)^{i+j} M_{ij} \end{equation} $$
符号 $(-1)^{i+j}$ は次のチェッカーボードパターンに従います。
$$ \begin{pmatrix} + & – & + & – & \cdots \\ – & + & – & + & \cdots \\ + & – & + & – & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{pmatrix} $$
具体例(続き)
先ほどの $\bm{A}$ に対して:
$$ \begin{align} C_{11} &= (-1)^{1+1} M_{11} = +(-3) = -3 \\ C_{12} &= (-1)^{1+2} M_{12} = -(-6) = 6 \\ C_{13} &= (-1)^{1+3} M_{13} = +(-3) = -3 \end{align} $$
余因子展開の定理
定理(行に沿った余因子展開)
$n \times n$ 行列 $\bm{A}$ の行列式は、任意の行 $i$ に沿って次のように展開できます。
$$ \begin{equation} \det(\bm{A}) = \sum_{j=1}^{n} a_{ij} C_{ij} = \sum_{j=1}^{n} (-1)^{i+j} a_{ij} M_{ij} \end{equation} $$
定理(列に沿った余因子展開)
同様に、任意の列 $j$ に沿って:
$$ \begin{equation} \det(\bm{A}) = \sum_{i=1}^{n} a_{ij} C_{ij} = \sum_{i=1}^{n} (-1)^{i+j} a_{ij} M_{ij} \end{equation} $$
証明の概略
行列式の置換を用いた定義 $\det(\bm{A}) = \sum_{\sigma \in S_n} \mathrm{sgn}(\sigma) \prod_{k=1}^{n} a_{k,\sigma(k)}$ において、$a_{i,j}$ が現れる項(すなわち $\sigma(i) = j$ となる置換)を集めます。
$\sigma(i) = j$ を固定すると、残りの添字 $\{1, \ldots, n\} \setminus \{i\}$ から $\{1, \ldots, n\} \setminus \{j\}$ への置換を考えることになります。この部分の寄与が $(-1)^{i+j} M_{ij}$ に等しいことが示せます。
すべての $j$ について足し合わせると:
$$ \begin{align} \det(\bm{A}) &= \sum_{j=1}^{n} a_{ij} \cdot (-1)^{i+j} M_{ij} \\ &= \sum_{j=1}^{n} a_{ij} C_{ij} \end{align} $$
重要な性質: 異なる行の余因子との積
行列式の展開で重要な補足として、異なる行の成分と余因子の積の和は $0$ になります。
$$ \sum_{j=1}^{n} a_{kj} C_{ij} = 0 \quad (k \neq i) $$
これは、$\bm{A}$ の第 $i$ 行を第 $k$ 行に置き換えた行列の行列式を考えると、2つの同じ行を持つので行列式が $0$ になることから従います。
まとめると:
$$ \sum_{j=1}^{n} a_{kj} C_{ij} = \delta_{ki} \det(\bm{A}) $$
ここで $\delta_{ki}$ はクロネッカーのデルタです。
余因子行列と逆行列
余因子行列
余因子 $C_{ij}$ を $(i, j)$ 成分に持つ行列を 余因子行列 と呼びますが、逆行列の公式では 転置 した行列を使います。
$$ \begin{equation} \widetilde{\bm{A}} = (C_{ji}) = \begin{pmatrix} C_{11} & C_{21} & \cdots & C_{n1} \\ C_{12} & C_{22} & \cdots & C_{n2} \\ \vdots & \vdots & \ddots & \vdots \\ C_{1n} & C_{2n} & \cdots & C_{nn} \end{pmatrix} \end{equation} $$
$\widetilde{\bm{A}}$ を 随伴行列(adjugate matrix)と呼び、$\mathrm{adj}(\bm{A})$ とも書きます。
逆行列の公式
$\det(\bm{A}) \neq 0$ のとき:
$$ \begin{equation} \bm{A}^{-1} = \frac{1}{\det(\bm{A})} \widetilde{\bm{A}} = \frac{1}{\det(\bm{A})} \mathrm{adj}(\bm{A}) \end{equation} $$
証明:
$\bm{A} \widetilde{\bm{A}}$ の $(i, k)$ 成分を計算します。
$$ (\bm{A} \widetilde{\bm{A}})_{ik} = \sum_{j=1}^{n} a_{ij} (\widetilde{\bm{A}})_{jk} = \sum_{j=1}^{n} a_{ij} C_{kj} $$
先ほどの性質より $\sum_{j=1}^{n} a_{ij} C_{kj} = \delta_{ik} \det(\bm{A})$ なので:
$$ \bm{A} \widetilde{\bm{A}} = \det(\bm{A}) \bm{I} $$
したがって $\bm{A}^{-1} = \frac{1}{\det(\bm{A})} \widetilde{\bm{A}}$ です。$\square$
具体例
3×3 行列の余因子展開
$$ \bm{A} = \begin{pmatrix} 2 & 1 & 3 \\ 0 & -1 & 2 \\ 1 & 4 & -1 \end{pmatrix} $$
第1行に沿って展開します。
$$ \begin{align} \det(\bm{A}) &= a_{11}C_{11} + a_{12}C_{12} + a_{13}C_{13} \\ &= 2 \cdot (-1)^{1+1} \det \begin{pmatrix} -1 & 2 \\ 4 & -1 \end{pmatrix} + 1 \cdot (-1)^{1+2} \det \begin{pmatrix} 0 & 2 \\ 1 & -1 \end{pmatrix} + 3 \cdot (-1)^{1+3} \det \begin{pmatrix} 0 & -1 \\ 1 & 4 \end{pmatrix} \end{align} $$
各小行列式を計算します。
$$ \begin{align} M_{11} &= (-1)(-1) – (2)(4) = 1 – 8 = -7 \\ M_{12} &= (0)(-1) – (2)(1) = 0 – 2 = -2 \\ M_{13} &= (0)(4) – (-1)(1) = 0 + 1 = 1 \end{align} $$
したがって:
$$ \begin{align} \det(\bm{A}) &= 2 \cdot (+1)(-7) + 1 \cdot (-1)(-2) + 3 \cdot (+1)(1) \\ &= 2(-7) + 1(2) + 3(1) \\ &= -14 + 2 + 3 \\ &= -9 \end{align} $$
$0$ の多い行を選ぶ工夫
第2行には $a_{21} = 0$ があるので、第2行に沿って展開すると計算量が減ります。
$$ \begin{align} \det(\bm{A}) &= 0 \cdot C_{21} + (-1) \cdot C_{22} + 2 \cdot C_{23} \\ &= (-1) \cdot (-1)^{2+2} \det \begin{pmatrix} 2 & 3 \\ 1 & -1 \end{pmatrix} + 2 \cdot (-1)^{2+3} \det \begin{pmatrix} 2 & 1 \\ 1 & 4 \end{pmatrix} \\ &= (-1)(+1)(-2 – 3) + 2(-1)(8 – 1) \\ &= (-1)(-5) + 2(-1)(7) \\ &= 5 – 14 \\ &= -9 \end{align} $$
どちらの行で展開しても同じ結果になります。
逆行列の計算
$\det(\bm{A}) = -9 \neq 0$ なので逆行列が存在します。すべての余因子を計算します。
$$ \begin{align} C_{11} &= +M_{11} = -7, \quad C_{12} = -M_{12} = 2, \quad C_{13} = +M_{13} = 1 \\ C_{21} &= -\det\begin{pmatrix} 1 & 3 \\ 4 & -1 \end{pmatrix} = -(-1-12) = 13 \\ C_{22} &= +\det\begin{pmatrix} 2 & 3 \\ 1 & -1 \end{pmatrix} = +(-2-3) = -5 \\ C_{23} &= -\det\begin{pmatrix} 2 & 1 \\ 1 & 4 \end{pmatrix} = -(8-1) = -7 \\ C_{31} &= +\det\begin{pmatrix} 1 & 3 \\ -1 & 2 \end{pmatrix} = +(2+3) = 5 \\ C_{32} &= -\det\begin{pmatrix} 2 & 3 \\ 0 & 2 \end{pmatrix} = -(4-0) = -4 \\ C_{33} &= +\det\begin{pmatrix} 2 & 1 \\ 0 & -1 \end{pmatrix} = +(-2-0) = -2 \end{align} $$
随伴行列(余因子行列の転置):
$$ \widetilde{\bm{A}} = \begin{pmatrix} -7 & 13 & 5 \\ 2 & -5 & -4 \\ 1 & -7 & -2 \end{pmatrix} $$
逆行列:
$$ \bm{A}^{-1} = \frac{1}{-9} \begin{pmatrix} -7 & 13 & 5 \\ 2 & -5 & -4 \\ 1 & -7 & -2 \end{pmatrix} = \begin{pmatrix} 7/9 & -13/9 & -5/9 \\ -2/9 & 5/9 & 4/9 \\ -1/9 & 7/9 & 2/9 \end{pmatrix} $$
Pythonでの実装
余因子展開の再帰的実装
import numpy as np
def minor(A, i, j):
"""
行列 A の (i, j) 小行列(第i行・第j列を除いた行列)を返す
Parameters
----------
A : ndarray, shape (n, n)
i, j : int (0-indexed)
Returns
-------
ndarray, shape (n-1, n-1)
"""
return np.delete(np.delete(A, i, axis=0), j, axis=1)
def cofactor(A, i, j):
"""(i, j) 余因子を計算する"""
return (-1)**(i + j) * det_cofactor(minor(A, i, j))
def det_cofactor(A):
"""
余因子展開で行列式を計算する(再帰的実装)
Parameters
----------
A : ndarray, shape (n, n)
Returns
-------
float
"""
n = A.shape[0]
# 基底ケース
if n == 1:
return A[0, 0]
if n == 2:
return A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
# 第1行に沿って展開
det_val = 0.0
for j in range(n):
det_val += A[0, j] * cofactor(A, 0, j)
return det_val
# テスト
A = np.array([[2, 1, 3],
[0, -1, 2],
[1, 4, -1]], dtype=float)
det_custom = det_cofactor(A)
det_numpy = np.linalg.det(A)
print(f"余因子展開による行列式: {det_custom:.4f}")
print(f"NumPy による行列式: {det_numpy:.4f}")
print(f"一致: {np.isclose(det_custom, det_numpy)}")
余因子行列と逆行列の実装
import numpy as np
def adjugate(A):
"""
随伴行列(余因子行列の転置)を計算する
Parameters
----------
A : ndarray, shape (n, n)
Returns
-------
ndarray, shape (n, n)
"""
n = A.shape[0]
adj = np.zeros((n, n))
for i in range(n):
for j in range(n):
# 随伴行列は余因子行列の転置なので (j, i) に配置
adj[j, i] = cofactor(A, i, j)
return adj
def inverse_cofactor(A):
"""
余因子展開を用いて逆行列を計算する
Parameters
----------
A : ndarray, shape (n, n)
Returns
-------
ndarray, shape (n, n)
"""
det_A = det_cofactor(A)
if abs(det_A) < 1e-12:
raise ValueError("行列式が0です。逆行列は存在しません。")
return adjugate(A) / det_A
# テスト
A = np.array([[2, 1, 3],
[0, -1, 2],
[1, 4, -1]], dtype=float)
inv_custom = inverse_cofactor(A)
inv_numpy = np.linalg.inv(A)
print("=== 余因子展開による逆行列 ===")
print(inv_custom)
print("\n=== NumPy による逆行列 ===")
print(inv_numpy)
print(f"\n一致: {np.allclose(inv_custom, inv_numpy)}")
# 検算: A @ A^{-1} = I
print(f"\nA @ A^(-1) ≈ I: {np.allclose(A @ inv_custom, np.eye(3))}")
余因子展開の可視化
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
A = np.array([[2, 1, 3],
[0, -1, 2],
[1, 4, -1]])
# 元の行列を表示
ax = axes[0]
ax.set_xlim(-0.5, 2.5)
ax.set_ylim(-0.5, 2.5)
for i in range(3):
for j in range(3):
color = 'lightyellow'
if i == 0:
color = 'lightcoral'
ax.add_patch(plt.Rectangle((j-0.4, 2-i-0.4), 0.8, 0.8,
facecolor=color, edgecolor='black', linewidth=1.5))
ax.text(j, 2-i, f'{A[i,j]}', ha='center', va='center', fontsize=14, fontweight='bold')
ax.set_aspect('equal')
ax.set_title('Matrix $A$\n(Row 1 highlighted)', fontsize=11)
ax.axis('off')
# 3つの小行列式
for idx in range(3):
ax = axes[idx + 1]
M = np.delete(np.delete(A, 0, axis=0), idx, axis=1)
sign = (-1)**(0 + idx)
sign_str = '+' if sign > 0 else '-'
det_M = M[0, 0] * M[1, 1] - M[0, 1] * M[1, 0]
ax.set_xlim(-0.5, 1.5)
ax.set_ylim(-0.5, 1.5)
for i in range(2):
for j in range(2):
ax.add_patch(plt.Rectangle((j-0.4, 1-i-0.4), 0.8, 0.8,
facecolor='lightblue', edgecolor='black', linewidth=1.5))
ax.text(j, 1-i, f'{M[i,j]}', ha='center', va='center', fontsize=14, fontweight='bold')
ax.set_aspect('equal')
coef = A[0, idx]
ax.set_title(f'${sign_str}{abs(coef)} \\cdot M_{{1{idx+1}}}$\n$= {sign_str}{abs(coef)} \\times ({det_M})$',
fontsize=11)
ax.axis('off')
plt.suptitle(f'Cofactor Expansion along Row 1: det(A) = {int(det_cofactor(A))}', fontsize=13, y=1.02)
plt.tight_layout()
plt.savefig("cofactor_expansion.png", dpi=150, bbox_inches='tight')
plt.show()
まとめ
本記事では、余因子展開による行列式の計算法を解説しました。
- 小行列式 $M_{ij}$ は、第 $i$ 行・第 $j$ 列を除いた $(n-1) \times (n-1)$ 行列式である
- 余因子 $C_{ij} = (-1)^{i+j} M_{ij}$ は小行列式に符号をつけたものである
- 余因子展開: 任意の行(列)に沿って $\det(\bm{A}) = \sum_j a_{ij} C_{ij}$ で計算できる
- $0$ の多い行や列に沿って展開すると計算が効率的になる
- 逆行列の公式: $\bm{A}^{-1} = \frac{1}{\det(\bm{A})} \mathrm{adj}(\bm{A})$
次のステップとして、以下の記事も参考にしてください。