余因子展開による行列式の計算法を完全解説

行列式の定義は置換を用いた総和の形ですが、実際の計算では 余因子展開(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})$

次のステップとして、以下の記事も参考にしてください。