ベクトル空間の定義と公理をわかりやすく解説

「ベクトル」と聞くと、多くの方は矢印を思い浮かべるでしょう。高校では平面や空間の中で、大きさと方向を持つ量としてベクトルを学びます。しかし線形代数では、ベクトルの概念を大幅に拡張し、足し算とスカラー倍ができるものをすべて「ベクトル」として扱います。この抽象的な枠組みを定めるのが ベクトル空間 の公理です。

ベクトル空間の理論は、線形代数のほぼすべての議論の出発点です。固有値・固有ベクトル、線形写像、内積空間といった発展的なトピックは、すべてベクトル空間の上に構築されます。物理学では状態空間、機械学習では特徴量空間、信号処理では関数空間など、理工学の至るところでベクトル空間の考え方が活用されています。

本記事の内容

  • ベクトル空間の直感的な理解(矢印から抽象化へ)
  • 8つの公理の意味と役割
  • 部分空間の定義と判定法
  • 関数空間・多項式空間など具体例
  • Pythonでのベクトル空間の操作と可視化

前提知識

この記事を読む前に、以下の知識があると理解が深まります。

  • 高校レベルのベクトルの加法・スカラー倍
  • 行列の基本的な演算

ベクトル空間とは

矢印のベクトルから抽象ベクトルへ

高校で学ぶベクトルは、平面上や空間上の「矢印」として表現されます。たとえば $\bm{a} = (2, 3)$ は、原点から点 $(2, 3)$ へ向かう矢印です。この矢印に対して、加法(2つの矢印をつなぐ)とスカラー倍(矢印を伸び縮みさせる)が自然に定義できます。

しかし、次のようなものも「足し算とスカラー倍」ができます。

  • 多項式: $f(x) = 2x^2 + 3x + 1$ と $g(x) = x^2 – x + 4$ を足せる
  • 関数: $f(x) = \sin x$ と $g(x) = \cos x$ を足せる
  • 行列: 同じサイズの行列は足し算とスカラー倍ができる

これらはすべて「矢印」ではありませんが、足し算とスカラー倍の性質をきちんと満たしています。そこで、共通の性質を公理として抽出し、それを満たすものをすべて「ベクトル空間」と呼ぶことで、統一的に扱えるようにするのです。

ベクトル空間の大まかなイメージ

ベクトル空間とは、大雑把に言えば「足し算とスカラー倍が自由にできて、その結果がまた同じ集合の中に収まる」という性質を持つ集合のことです。これを数学的に厳密にするために、8つの公理を定めます。

ベクトル空間の数学的定義

定義

体 $\mathbb{F}$(通常は実数体 $\mathbb{R}$ または複素数体 $\mathbb{C}$)上の ベクトル空間 とは、集合 $V$ に対して次の2つの演算が定義されており、以下の8つの公理を満たすものです。

演算1: ベクトルの加法 $+: V \times V \to V$

$$ \bm{u}, \bm{v} \in V \implies \bm{u} + \bm{v} \in V $$

演算2: スカラー倍 $\cdot: \mathbb{F} \times V \to V$

$$ c \in \mathbb{F}, \bm{v} \in V \implies c\bm{v} \in V $$

8つの公理

任意の $\bm{u}, \bm{v}, \bm{w} \in V$ と $c, d \in \mathbb{F}$ に対して:

加法に関する4つの公理:

(A1) 加法の結合律:

$$ (\bm{u} + \bm{v}) + \bm{w} = \bm{u} + (\bm{v} + \bm{w}) $$

(A2) 加法の交換律:

$$ \bm{u} + \bm{v} = \bm{v} + \bm{u} $$

(A3) 零ベクトルの存在: すべての $\bm{v} \in V$ に対して

$$ \bm{v} + \bm{0} = \bm{v} $$

を満たす元 $\bm{0} \in V$ が存在する。

(A4) 逆元の存在: すべての $\bm{v} \in V$ に対して

$$ \bm{v} + (-\bm{v}) = \bm{0} $$

を満たす元 $-\bm{v} \in V$ が存在する。

スカラー倍に関する4つの公理:

(S1) スカラー倍の結合律:

$$ c(d\bm{v}) = (cd)\bm{v} $$

(S2) スカラーの分配律:

$$ c(\bm{u} + \bm{v}) = c\bm{u} + c\bm{v} $$

(S3) ベクトルの分配律:

$$ (c + d)\bm{v} = c\bm{v} + d\bm{v} $$

(S4) スカラー乗法の単位元:

$$ 1 \cdot \bm{v} = \bm{v} $$

公理の意味を丁寧に理解する

閉じている(閉包性)

8つの公理以前に重要なのが、加法とスカラー倍の結果が $V$ の中に留まることです。これを 閉包性(closure)と呼びます。$\bm{u} + \bm{v} \in V$ かつ $c\bm{v} \in V$ が常に成り立たなければなりません。

零ベクトルと逆元

零ベクトル $\bm{0}$ は、「何も足さない」に対応する元です。$\mathbb{R}^n$ では成分がすべて $0$ のベクトル $(0, 0, \ldots, 0)$ です。関数空間では恒等的に $0$ の関数 $f(x) = 0$ が零ベクトルです。

逆元 $-\bm{v}$ は、$\bm{v}$ を「打ち消す」元です。$\bm{v}$ と $-\bm{v}$ を足すと零ベクトルになります。

なぜこの8つなのか

8つの公理は、線形結合 $c_1\bm{v}_1 + c_2\bm{v}_2 + \cdots + c_n\bm{v}_n$ が矛盾なく計算できるための必要十分条件です。結合律があるので括弧の付け方を気にしなくてよく、交換律があるので順序も自由です。分配律のおかげで展開・因数分解もできます。

具体例

例1: $\mathbb{R}^n$(n次元実数ベクトル空間)

最も基本的な例です。

$$ \mathbb{R}^n = \{(x_1, x_2, \ldots, x_n) \mid x_i \in \mathbb{R}\} $$

加法とスカラー倍は成分ごとに定義します。

$$ \begin{align} (x_1, \ldots, x_n) + (y_1, \ldots, y_n) &= (x_1 + y_1, \ldots, x_n + y_n) \\ c(x_1, \ldots, x_n) &= (cx_1, \ldots, cx_n) \end{align} $$

零ベクトルは $(0, 0, \ldots, 0)$、逆元は $(-x_1, -x_2, \ldots, -x_n)$ です。8つの公理はすべて実数の性質から従います。

例2: 多項式空間 $P_n$

次数が $n$ 以下の実係数多項式全体の集合を $P_n$ と書きます。

$$ P_n = \{a_0 + a_1 x + a_2 x^2 + \cdots + a_n x^n \mid a_i \in \mathbb{R}\} $$

加法は多項式の和、スカラー倍は係数をスカラー倍します。零ベクトルは零多項式 $f(x) = 0$ です。

例えば $P_2$ では:

$$ \begin{align} (2x^2 + 3x + 1) + (x^2 – x + 4) &= 3x^2 + 2x + 5 \in P_2 \\ 3(2x^2 + 3x + 1) &= 6x^2 + 9x + 3 \in P_2 \end{align} $$

結果は $P_2$ に留まるので閉包性を満たし、他の公理も容易に確認できます。

例3: 関数空間 $C[a, b]$

閉区間 $[a, b]$ 上の連続関数全体の集合 $C[a, b]$ もベクトル空間になります。

$$ C[a, b] = \{f: [a, b] \to \mathbb{R} \mid f \text{ は連続}\} $$

加法 $(f + g)(x) = f(x) + g(x)$ とスカラー倍 $(cf)(x) = c \cdot f(x)$ で定義します。連続関数の和もスカラー倍も連続なので閉包性を満たします。零ベクトルは $f(x) = 0$(零関数)です。

例4: 行列空間 $M_{m \times n}$

$m \times n$ の実数行列全体の集合 $M_{m \times n}(\mathbb{R})$ もベクトル空間です。加法は行列の和、スカラー倍は各成分のスカラー倍、零ベクトルは零行列です。

ベクトル空間でない例

$V = \{(x, y) \in \mathbb{R}^2 \mid x \geq 0, y \geq 0\}$(第一象限)はベクトル空間ではありません。なぜなら、$\bm{v} = (1, 2) \in V$ に対して $-\bm{v} = (-1, -2) \notin V$ となり、逆元が存在しないからです。

部分空間

定義

ベクトル空間 $V$ の部分集合 $W \subseteq V$ が 部分空間 であるとは、$W$ 自体が $V$ と同じ演算のもとでベクトル空間になることです。

部分空間の判定条件

8つの公理をすべて確認する必要はありません。$V$ がベクトル空間であれば、$W$ が部分空間であるための必要十分条件は次の3条件です。

(1) 空でない: $\bm{0} \in W$(あるいは $W \neq \emptyset$)

(2) 加法で閉じている: $\bm{u}, \bm{v} \in W \implies \bm{u} + \bm{v} \in W$

(3) スカラー倍で閉じている: $c \in \mathbb{F}, \bm{v} \in W \implies c\bm{v} \in W$

条件 (2) と (3) をまとめると、1つの条件 で判定できます。

$$ \bm{u}, \bm{v} \in W, \quad c, d \in \mathbb{F} \implies c\bm{u} + d\bm{v} \in W $$

これは「線形結合で閉じている」ことを意味します。

証明(3条件で十分な理由)

公理 A1(結合律)、A2(交換律)、S1〜S4 は $V$ で成り立つ性質が $W$ でもそのまま成り立ちます($W \subseteq V$ なので)。残りの公理を確認します。

条件 (3) より、$\bm{v} \in W$ に対して $c = -1$ とすれば $(-1)\bm{v} = -\bm{v} \in W$ なので A4(逆元の存在)が成り立ちます。

条件 (2) より $\bm{v} + (-\bm{v}) = \bm{0} \in W$ なので A3(零ベクトルの存在)も成り立ちます。

したがって、3条件から8つの公理がすべて導かれます。

具体例

$\mathbb{R}^3$ の部分空間:

  • 原点を通る直線 $W = \{t\bm{a} \mid t \in \mathbb{R}\}$
  • 原点を通る平面 $W = \{s\bm{a} + t\bm{b} \mid s, t \in \mathbb{R}\}$
  • $\{\bm{0}\}$(零空間)
  • $\mathbb{R}^3$ 自身

部分空間でない例:

  • 原点を通らない直線($\bm{0} \notin W$)
  • $\{(x, y) \mid x^2 + y^2 \leq 1\}$(単位円盤。スカラー倍で閉じない)

Pythonでの実装

ベクトル空間の公理の検証

import numpy as np

# R^3 のベクトルで8つの公理を数値的に検証する
u = np.array([1.0, 2.0, 3.0])
v = np.array([4.0, -1.0, 2.0])
w = np.array([-2.0, 3.0, 1.0])
c = 3.0
d = -2.0

# (A1) 加法の結合律
print("=== 加法の公理 ===")
print(f"(A1) 結合律: {np.allclose((u + v) + w, u + (v + w))}")

# (A2) 加法の交換律
print(f"(A2) 交換律: {np.allclose(u + v, v + u)}")

# (A3) 零ベクトルの存在
zero = np.zeros(3)
print(f"(A3) 零ベクトル: {np.allclose(v + zero, v)}")

# (A4) 逆元の存在
print(f"(A4) 逆元: {np.allclose(v + (-v), zero)}")

# (S1) スカラー倍の結合律
print("\n=== スカラー倍の公理 ===")
print(f"(S1) 結合律: {np.allclose(c * (d * v), (c * d) * v)}")

# (S2) スカラーの分配律
print(f"(S2) 分配律: {np.allclose(c * (u + v), c * u + c * v)}")

# (S3) ベクトルの分配律
print(f"(S3) 分配律: {np.allclose((c + d) * v, c * v + d * v)}")

# (S4) 単位元
print(f"(S4) 単位元: {np.allclose(1.0 * v, v)}")

部分空間の可視化

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# R^3 における部分空間の可視化
fig = plt.figure(figsize=(14, 5))

# --- 部分空間1: 原点を通る直線 ---
ax1 = fig.add_subplot(131, projection='3d')
a = np.array([1, 2, 1])
t = np.linspace(-3, 3, 100)
line = np.outer(t, a)
ax1.plot(line[:, 0], line[:, 1], line[:, 2], 'b-', linewidth=2, label='$W = \\{t\\mathbf{a}\\}$')
ax1.scatter([0], [0], [0], color='red', s=50, zorder=5, label='Origin')
ax1.set_xlabel('$x$')
ax1.set_ylabel('$y$')
ax1.set_zlabel('$z$')
ax1.set_title('Subspace: Line through origin')
ax1.legend(fontsize=8)

# --- 部分空間2: 原点を通る平面 ---
ax2 = fig.add_subplot(132, projection='3d')
a = np.array([1, 0, 1])
b = np.array([0, 1, 1])
s_vals = np.linspace(-2, 2, 20)
t_vals = np.linspace(-2, 2, 20)
S, T = np.meshgrid(s_vals, t_vals)
X = S * a[0] + T * b[0]
Y = S * a[1] + T * b[1]
Z = S * a[2] + T * b[2]
ax2.plot_surface(X, Y, Z, alpha=0.3, color='cyan')
ax2.scatter([0], [0], [0], color='red', s=50, zorder=5, label='Origin')
ax2.set_xlabel('$x$')
ax2.set_ylabel('$y$')
ax2.set_zlabel('$z$')
ax2.set_title('Subspace: Plane through origin')
ax2.legend(fontsize=8)

# --- 部分空間でない例: 原点を通らない平面 ---
ax3 = fig.add_subplot(133, projection='3d')
s_vals = np.linspace(-2, 2, 20)
t_vals = np.linspace(-2, 2, 20)
S, T = np.meshgrid(s_vals, t_vals)
X_not = S
Y_not = T
Z_not = 1 - S - T  # x + y + z = 1(原点を通らない)
ax3.plot_surface(X_not, Y_not, Z_not, alpha=0.3, color='orange')
ax3.scatter([0], [0], [0], color='red', s=50, zorder=5, label='Origin')
ax3.set_xlabel('$x$')
ax3.set_ylabel('$y$')
ax3.set_zlabel('$z$')
ax3.set_title('NOT a subspace: $x+y+z=1$')
ax3.legend(fontsize=8)

plt.tight_layout()
plt.savefig("vector_space_subspaces.png", dpi=150, bbox_inches='tight')
plt.show()

多項式空間の操作

import numpy as np
import matplotlib.pyplot as plt

# P_2(2次以下の多項式空間)の操作
# 多項式を係数配列で表現する: [a0, a1, a2] -> a0 + a1*x + a2*x^2

def poly_add(p, q):
    """多項式の加法"""
    max_len = max(len(p), len(q))
    p_pad = np.pad(p, (0, max_len - len(p)))
    q_pad = np.pad(q, (0, max_len - len(q)))
    return p_pad + q_pad

def poly_scalar_mul(c, p):
    """多項式のスカラー倍"""
    return c * np.array(p)

def poly_eval(p, x):
    """多項式の値を計算"""
    return sum(coef * x**i for i, coef in enumerate(p))

# P_2 の元
f = np.array([1.0, 3.0, 2.0])   # f(x) = 1 + 3x + 2x^2
g = np.array([4.0, -1.0, 1.0])  # g(x) = 4 - x + x^2

# 加法とスカラー倍
f_plus_g = poly_add(f, g)
scaled_f = poly_scalar_mul(2.0, f)

print(f"f(x) = {f[0]:.0f} + {f[1]:.0f}x + {f[2]:.0f}x^2")
print(f"g(x) = {g[0]:.0f} + ({g[1]:.0f})x + {g[2]:.0f}x^2")
print(f"f + g = {f_plus_g[0]:.0f} + {f_plus_g[1]:.0f}x + {f_plus_g[2]:.0f}x^2")
print(f"2f   = {scaled_f[0]:.0f} + {scaled_f[1]:.0f}x + {scaled_f[2]:.0f}x^2")

# 可視化
x = np.linspace(-2, 2, 200)
y_f = np.array([poly_eval(f, xi) for xi in x])
y_g = np.array([poly_eval(g, xi) for xi in x])
y_sum = np.array([poly_eval(f_plus_g, xi) for xi in x])
y_scaled = np.array([poly_eval(scaled_f, xi) for xi in x])

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# 加法の可視化
axes[0].plot(x, y_f, 'b-', linewidth=2, label='$f(x) = 1 + 3x + 2x^2$')
axes[0].plot(x, y_g, 'r-', linewidth=2, label='$g(x) = 4 - x + x^2$')
axes[0].plot(x, y_sum, 'g--', linewidth=2, label='$f + g = 5 + 2x + 3x^2$')
axes[0].axhline(y=0, color='k', linewidth=0.5)
axes[0].axvline(x=0, color='k', linewidth=0.5)
axes[0].set_xlabel('$x$')
axes[0].set_ylabel('$y$')
axes[0].set_title('Polynomial Addition in $P_2$')
axes[0].legend()
axes[0].grid(True, alpha=0.3)
axes[0].set_ylim(-10, 20)

# スカラー倍の可視化
axes[1].plot(x, y_f, 'b-', linewidth=2, label='$f(x) = 1 + 3x + 2x^2$')
axes[1].plot(x, y_scaled, 'm--', linewidth=2, label='$2f(x) = 2 + 6x + 4x^2$')
axes[1].axhline(y=0, color='k', linewidth=0.5)
axes[1].axvline(x=0, color='k', linewidth=0.5)
axes[1].set_xlabel('$x$')
axes[1].set_ylabel('$y$')
axes[1].set_title('Scalar Multiplication in $P_2$')
axes[1].legend()
axes[1].grid(True, alpha=0.3)
axes[1].set_ylim(-10, 30)

plt.tight_layout()
plt.savefig("polynomial_space.png", dpi=150, bbox_inches='tight')
plt.show()

関数空間の可視化

import numpy as np
import matplotlib.pyplot as plt

# C[0, 2π] の元として sin, cos を使ったベクトル空間の操作
x = np.linspace(0, 2 * np.pi, 300)

f = np.sin(x)          # f(x) = sin(x)
g = np.cos(x)          # g(x) = cos(x)
h = f + g              # 加法: f + g
s = 2.0 * f            # スカラー倍: 2f
lc = 3 * f - 2 * g     # 線形結合: 3f - 2g

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 加法
axes[0].plot(x, f, 'b-', linewidth=2, label='$f = \\sin x$')
axes[0].plot(x, g, 'r-', linewidth=2, label='$g = \\cos x$')
axes[0].plot(x, h, 'g--', linewidth=2, label='$f + g$')
axes[0].set_title('Addition in $C[0, 2\\pi]$')
axes[0].set_xlabel('$x$')
axes[0].legend()
axes[0].grid(True, alpha=0.3)

# スカラー倍
axes[1].plot(x, f, 'b-', linewidth=2, label='$f = \\sin x$')
axes[1].plot(x, s, 'm--', linewidth=2, label='$2f$')
axes[1].set_title('Scalar Multiplication')
axes[1].set_xlabel('$x$')
axes[1].legend()
axes[1].grid(True, alpha=0.3)

# 線形結合
axes[2].plot(x, f, 'b-', linewidth=1, alpha=0.5, label='$f = \\sin x$')
axes[2].plot(x, g, 'r-', linewidth=1, alpha=0.5, label='$g = \\cos x$')
axes[2].plot(x, lc, 'k-', linewidth=2, label='$3f - 2g$')
axes[2].set_title('Linear Combination')
axes[2].set_xlabel('$x$')
axes[2].legend()
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("function_space.png", dpi=150, bbox_inches='tight')
plt.show()

まとめ

本記事では、ベクトル空間の定義と公理について解説しました。

  • ベクトル空間は「加法」と「スカラー倍」が定義され、8つの公理を満たす集合である
  • 8つの公理は、線形結合が矛盾なく行えるための条件を保証する
  • $\mathbb{R}^n$, 多項式空間 $P_n$, 関数空間 $C[a,b]$, 行列空間 $M_{m \times n}$ などが具体例である
  • 部分空間の判定は、「空でない」「加法で閉じている」「スカラー倍で閉じている」の3条件で行える
  • 公理を抽象的に定めることで、矢印に限らないさまざまな対象を統一的に扱える

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