行列計算の Python 実現ガイド

【概要】行列計算の基礎と実装について、NumPyライブラリを中心に解説する。行列の積、LU分解、逆行列、行列式、畳み込みなどの基本的な行列演算について説明し、Pythonによる実装例を示す。

【サイト内のPython関連主要ページ】

【外部リソース】

用語リスト

基礎概念

評価指標

PythonのNumPyライブラリを使用することで、効率的な行列計算を実行できる。

2. 行列の積

NumPyでは@演算子またはnp.dot()関数を使用する。内部では高度に最適化されたBLAS(Basic Linear Algebra Subprograms:基本線形代数サブプログラム)が使用され、高速な演算が実現される。

import numpy as np

A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = A @ B  # または C = np.dot(A, B)
print("行列A:\n", A)
print("行列B:\n", B)
print("A×B:\n", C)

3. LU分解と計算精度の評価

LU分解は行列Aを下三角行列(L)と上三角行列(U)の積に分解する数値計算手法である。実装では、数値安定性を高めるため、置換行列(P)も含めてPA = LUの形で分解される。

LU分解が連立方程式Ax = bを解くのに有用な理由は以下の通りである。

scipy.linalgモジュールのlu()関数を使用することで、LU分解を数値的に安定かつ効率的に計算できる。

以下のコードでは、LU分解の実行に加えて、誤差、残差、行列の階数を計算し、計算精度を評価する。

import numpy as np
from scipy import linalg

# 3×3の行列を作成
A = np.array([[2, -1, 1],
              [4, 1, -1],
              [1, 1, 1]])

# LU分解
P, L, U = linalg.lu(A)
print("元の行列A:\n", A)
print("置換行列P:\n", P)
print("下三角行列L:\n", L)
print("上三角行列U:\n", U)

# LU分解の検証(誤差の測定)
print("\nP×L×U:\n", P @ (L @ U))
error_lu = np.max(np.abs(A - P @ (L @ U)))
print("元の行列との誤差:", error_lu)

# LU分解を使用した連立方程式の解法(残差の測定)
b = np.array([1, 2, 3])
x = linalg.lu_solve(linalg.lu_factor(A), b)
print("\n連立方程式Ax = bの解:", x)
residual = np.linalg.norm(A @ x - b)
print("残差 ||Ax - b||:", residual)

# 行列の階数
rank_A = np.linalg.matrix_rank(A)
print("行列Aの階数:", rank_A)

4. 逆行列と行列式

逆行列A⁻¹は、元の行列との積が単位行列となる行列である。線形変換の逆変換を表現する重要な概念である。

逆行列は行列式が0でない場合(正則行列の場合)にのみ存在する。実用的な計算では、数値安定性を考慮して逆行列の直接計算を避けることが推奨される。

行列式には以下の重要な用途がある。

以下のコードでは、逆行列と行列式を計算し、A×A⁻¹ = Iが成り立つことを誤差の測定によって確認する。

import numpy as np

A = np.array([[4, 7], [2, 6]])

# 行列式
det_A = np.linalg.det(A)
print("行列A:\n", A)
print("行列式:", det_A)

# 逆行列
A_inv = np.linalg.inv(A)
print("\n逆行列:\n", A_inv)

# 検証: A×A^(-1) = I(誤差の測定)
print("A×A^(-1):\n", A @ A_inv)
error_inv = np.max(np.abs(A @ A_inv - np.eye(2)))
print("逆行列の精度(誤差):", error_inv)

5. 畳み込み

畳み込みは、信号処理や画像処理において基礎となる演算である。特徴抽出やフィルタリングに広く活用される。

scipy.signal.convolve2d()関数modeパラメータには以下の選択肢があり、用途に応じて適切に選択する。

import numpy as np
from scipy import signal

# 2D配列(画像を想定)
image = np.array([[1, 2, 3, 4],
                  [5, 6, 7, 8],
                  [9, 10, 11, 12],
                  [13, 14, 15, 16]])

# カーネル(エッジ検出フィルタ)
kernel = np.array([[-1, -1, -1],
                  [-1,  8, -1],
                  [-1, -1, -1]])

print("入力画像:\n", image)
print("\nカーネル(エッジ検出フィルタ):\n", kernel)

# 異なるモードでの畳み込み演算
modes = ['full', 'same', 'valid']
for mode in modes:
    conv_result = signal.convolve2d(image, kernel, mode=mode)
    print(f"\n畳み込み結果(mode='{mode}'):\n", conv_result)
    print(f"出力サイズ: {conv_result.shape}")

これらのコードを実行するには、次のコマンドで必要なライブラリをインストールする。

pip install numpy scipy