1 핵심 질문
열 공간 \(C(\mathbf{A})\) 는 행렬의 “열들이 만드는 공간”이었다. 영공간은 반대 방향에서 행렬을 바라본다.
\(\mathbf{A}\mathbf{x} = \mathbf{0}\) 을 만족하는 벡터 \(\mathbf{x}\) 들은 어디에 있는가?
이 질문의 답이 영공간(nullspace) 이다. 영공간을 이해하면 왜 어떤 방정식은 해가 하나뿐이고, 왜 어떤 방정식은 무수히 많은지 구조적으로 파악할 수 있다.
2 영공간의 정의
\(m \times n\) 행렬 \(\mathbf{A}\) 의 영공간 \(N(\mathbf{A})\) 는 방정식
\[\mathbf{A}\mathbf{x} = \mathbf{0}\]
의 모든 해 벡터 \(\mathbf{x}\) 의 집합이다.
\[N(\mathbf{A}) = \{ \mathbf{x} \in \mathbb{R}^n \mid \mathbf{A}\mathbf{x} = \mathbf{0} \}\]
\(\mathbf{x}\) 는 \(n\)-성분 벡터이므로 \(N(\mathbf{A}) \subseteq \mathbb{R}^n\) 이다.
\(\mathbf{A}\) 가 \(m \times n\) 이면, 열 공간 \(C(\mathbf{A})\) 는 \(\mathbb{R}^m\) 의 부분공간이고, 영공간 \(N(\mathbf{A})\) 는 \(\mathbb{R}^n\) 의 부분공간이다. 두 공간은 서로 다른 차원에 산다는 점에 유의한다.
3 영공간은 부분공간이다
가장 먼저 확인해야 할 것은 \(N(\mathbf{A})\) 가 진짜 부분공간인지 여부다. 부분공간의 두 조건(덧셈 닫힘, 스칼라 곱 닫힘)을 확인한다.
\(\mathbf{x}\), \(\mathbf{y}\) 가 모두 영공간에 속한다고 가정한다. 즉 \(\mathbf{A}\mathbf{x} = \mathbf{0}\), \(\mathbf{A}\mathbf{y} = \mathbf{0}\).
덧셈 닫힘:
\[\mathbf{A}(\mathbf{x} + \mathbf{y}) = \mathbf{A}\mathbf{x} + \mathbf{A}\mathbf{y} = \mathbf{0} + \mathbf{0} = \mathbf{0}\]
따라서 \(\mathbf{x} + \mathbf{y} \in N(\mathbf{A})\).
스칼라 곱 닫힘:
\[\mathbf{A}(c\mathbf{x}) = c\mathbf{A}\mathbf{x} = c \cdot \mathbf{0} = \mathbf{0}\]
따라서 \(c\mathbf{x} \in N(\mathbf{A})\).
두 조건이 모두 성립하므로 \(N(\mathbf{A})\) 는 부분공간이다. (Strang, 2016, Ch.3)
증명은 행렬 곱셈의 선형성만 사용한다. 이것이 핵심이다.
4 Ax = b (b ≠ 0)의 해는 부분공간이 아니다
비교를 위해 \(\mathbf{A}\mathbf{x} = \mathbf{b}\) (\(\mathbf{b} \neq \mathbf{0}\)) 의 해 집합을 생각해본다.
이 경우, \(\mathbf{x} = \mathbf{0}\) 은 절대 해가 될 수 없다 (\(\mathbf{A}\mathbf{0} = \mathbf{0} \neq \mathbf{b}\)). 부분공간은 반드시 원점 \(\mathbf{0}\) 을 포함해야 하므로, \(\mathbf{A}\mathbf{x} = \mathbf{b}\) 의 해 집합은 부분공간이 아니다.
이 해 집합은 원점에서 이동(shift)된 평면/초평면이다. §3.4에서 완전해(complete solution)를 다룰 때 “특정해(particular solution) + 영공간” 구조로 다시 등장한다.
5 예시 1: 1×3 행렬의 영공간 (평면)
\[\mathbf{A} = \begin{bmatrix} 1 & 2 & 3 \end{bmatrix}\]
\(\mathbf{A}\mathbf{x} = 0\) 은 단 하나의 방정식이다:
\[x_1 + 2x_2 + 3x_3 = 0\]
이 방정식의 해는 \(\mathbb{R}^3\) 에서 원점을 지나는 평면이다. 이 평면이 \(N(\mathbf{A})\) 다.
피벗은 \(x_1\) 에만 있고, \(x_2\) 와 \(x_3\) 는 자유 변수(free variable)다. 자유 변수에 \((1, 0)\), \((0, 1)\) 을 대입하면 두 특수해(special solutions)를 얻는다:
\[\mathbf{s}_1 = \begin{bmatrix} -2 \\ 1 \\ 0 \end{bmatrix}, \quad \mathbf{s}_2 = \begin{bmatrix} -3 \\ 0 \\ 1 \end{bmatrix}\]
모든 해는 \(\mathbf{x} = x_2 \mathbf{s}_1 + x_3 \mathbf{s}_2\) 로 표현된다. 두 특수해의 선형결합이 평면 전체를 채운다.
6 예시 2: 특이 행렬의 영공간 (직선)
\[\mathbf{A} = \begin{bmatrix} 1 & 2 \\ 3 & 6 \end{bmatrix}\]
소거하면 두 번째 행이 \(0 = 0\) 이 된다. 실질적으로 방정식은 하나다:
\[x_1 + 2x_2 = 0\]
자유 변수 \(x_2 = 1\) 로 설정하면 \(x_1 = -2\). 특수해:
\[\mathbf{s} = \begin{bmatrix} -2 \\ 1 \end{bmatrix}\]
\(N(\mathbf{A})\) 는 \(\mathbb{R}^2\) 에서 이 벡터를 따라 뻗는 직선이다. 해는 \(\mathbf{x} = c\mathbf{s}\).
7 Ax = 0의 소거법: 피벗 변수 vs 자유 변수
\(\mathbf{A}\) 가 정사각이 아닌 경우에도 소거법은 동일하게 동작한다. 달라지는 점은 어떤 열에 피벗이 없을 수 있다는 것이다. 이것이 자유 열(free column) 이다.
핵심 개념 구분:
| 구분 | 정의 | 역할 |
|---|---|---|
| 피벗 변수 (pivot variable) | 피벗이 있는 열에 대응하는 \(x_i\) | 자유 변수가 결정되면 역대입으로 값이 정해진다 |
| 자유 변수 (free variable) | 피벗이 없는 열에 대응하는 \(x_i\) | 임의의 값을 가질 수 있다 |
자유 변수의 개수 = 특수해의 개수 = \(n - r\) (\(r\): 피벗의 수, 즉 행렬의 랭크)
8 주요 예시: 3×4 행렬
다음 \(3 \times 4\) 행렬 \(\mathbf{A}\) 로 소거법 전 과정을 보인다.
\[\mathbf{A} = \begin{bmatrix} 1 & 1 & 2 & 3 \\ 2 & 2 & 8 & 10 \\ 3 & 3 & 10 & 13 \end{bmatrix}\]
8.1 소거: A → U (상삼각 사다리꼴)
\(a_{11} = 1\) 이 첫 번째 피벗이다. 1열 아래를 0으로 만든다:
\[\text{(row2} - 2 \times \text{row1,} \quad \text{row3} - 3 \times \text{row1)} \rightarrow \begin{bmatrix} 1 & 1 & 2 & 3 \\ 0 & 0 & 4 & 4 \\ 0 & 0 & 4 & 4 \end{bmatrix}\]
2열의 피벗 위치가 0이다. 아래도 0이므로 교환 불가 — 2열은 자유 열이다. 3열로 넘어간다.
3열의 피벗은 4다. row3 \(-\) row2 로 아래를 제거하면:
\[\mathbf{U} = \begin{bmatrix} 1 & 1 & 2 & 3 \\ 0 & 0 & 4 & 4 \\ 0 & 0 & 0 & 0 \end{bmatrix}\]
세 번째 방정식은 \(0 = 0\) 이 된다. 첫 번째와 두 번째 방정식의 합이었기 때문이다.
결과:
- 피벗 열: 1열, 3열 → 피벗 변수 \(x_1\), \(x_3\)
- 자유 열: 2열, 4열 → 자유 변수 \(x_2\), \(x_4\)
8.2 특수해 계산
\(\mathbf{U}\mathbf{x} = \mathbf{0}\) 을 역대입으로 풀 때, 자유 변수에 \((1, 0)\) 과 \((0, 1)\) 을 각각 대입한다.
특수해 \(\mathbf{s}_1\): \(x_2 = 1\), \(x_4 = 0\)
두 번째 방정식 \(4x_3 + 4x_4 = 0\) 에서 \(x_3 = 0\). 첫 번째 방정식 \(x_1 + x_2 + 2x_3 + 3x_4 = 0\) 에서 \(x_1 = -1\).
\[\mathbf{s}_1 = \begin{bmatrix} -1 \\ 1 \\ 0 \\ 0 \end{bmatrix}\]
특수해 \(\mathbf{s}_2\): \(x_2 = 0\), \(x_4 = 1\)
두 번째 방정식 \(4x_3 + 4(1) = 0\) 에서 \(x_3 = -1\). 첫 번째 방정식 \(x_1 + 0 + 2(-1) + 3(1) = 0\) 에서 \(x_1 = -1\).
\[\mathbf{s}_2 = \begin{bmatrix} -1 \\ 0 \\ -1 \\ 1 \end{bmatrix}\]
8.3 완전해 (Complete Solution to Ax = 0)
\[\mathbf{x} = x_2 \mathbf{s}_1 + x_4 \mathbf{s}_2 = x_2 \begin{bmatrix} -1 \\ 1 \\ 0 \\ 0 \end{bmatrix} + x_4 \begin{bmatrix} -1 \\ 0 \\ -1 \\ 1 \end{bmatrix}\]
\(x_2\) 와 \(x_4\) 는 임의의 실수. 두 특수해의 선형결합이 \(N(\mathbf{A})\) 전체를 채운다.
9 기약 행 사다리꼴 (RREF)
소거는 \(\mathbf{U}\) 에서 멈추지 않아도 된다. 두 가지 추가 연산을 더 하면 기약 행 사다리꼴(Reduced Row Echelon Form, RREF) \(\mathbf{R}\) 에 도달한다.
- 피벗을 1로 만들기 (행 전체를 피벗으로 나누기)
- 피벗 위쪽도 0으로 만들기 (위쪽 방향 소거)
위 예시의 \(\mathbf{U}\) 에 적용한다.
\(\mathbf{U}\) 의 2행을 4로 나누면 \([0\ 0\ 1\ 1]\). 이것으로 1행의 \(2x_3\) 항을 제거하면:
\[\mathbf{R} = \text{rref}(\mathbf{A}) = \begin{bmatrix} 1 & 1 & 0 & 1 \\ 0 & 0 & 1 & 1 \\ 0 & 0 & 0 & 0 \end{bmatrix}\]
\(\mathbf{R}\) 에서는 피벗 열이 단위행렬 \(I\) 처럼 보인다. 특수해를 읽는 것이 훨씬 쉬워진다.
RREF에서 특수해를 바로 읽는 규칙:
자유 열의 항목에 부호를 반전하면 피벗 변수의 값이다.
- 2열 (자유 열): \([1,\ 0]^\top\) → 피벗 변수들은 \((-1,\ 0)\) → \(\mathbf{s}_1 = (-1, 1, 0, 0)\)
- 4열 (자유 열): \([1,\ 1]^\top\) → 피벗 변수들은 \((-1,\ -1)\) → \(\mathbf{s}_2 = (-1, 0, -1, 1)\)
결론적으로 \(N(\mathbf{A}) = N(\mathbf{U}) = N(\mathbf{R})\) 이다. 행 연산은 영공간을 바꾸지 않는다.
10 RREF의 구조: I와 F 블록
일반적인 \(m \times n\) 행렬에서 피벗 열과 자유 열을 재배열하면 \(\mathbf{R}\) 은 다음 블록 구조가 된다:
\[\mathbf{R} = \begin{bmatrix} \mathbf{I} & \mathbf{F} \\ \mathbf{0} & \mathbf{0} \end{bmatrix}\]
여기서 \(\mathbf{I}\) 는 \(r \times r\) 단위행렬 (피벗 블록), \(\mathbf{F}\) 는 \(r \times (n-r)\) 자유 블록이다.
영공간 행렬 \(\mathbf{N}\) (특수해들을 열로 나열한 행렬)은:
\[\mathbf{N} = \begin{bmatrix} -\mathbf{F} \\ \mathbf{I} \end{bmatrix}\]
\(\mathbf{R}\mathbf{N} = \mathbf{0}\) 을 바로 확인할 수 있다. 피벗 행에서: \(\mathbf{I} \cdot (-\mathbf{F}) + \mathbf{F} \cdot \mathbf{I} = \mathbf{0}\).
11 영공간이 {0}인 경우: 열 독립
영공간이 영벡터 하나만 포함하는 경우(\(N(\mathbf{A}) = \{\mathbf{0}\}\), 즉 \(Z\))는 중요한 특별 케이스다.
\[N(\mathbf{A}) = Z \iff \text{모든 열에 피벗 존재} \iff \text{열들이 선형 독립}\]
직관: \(\mathbf{A}\mathbf{x} = \mathbf{0}\) 은 “\(\mathbf{A}\) 의 열들의 선형결합이 \(\mathbf{0}\) 이 된다”는 의미다. \(N(\mathbf{A}) = Z\) 라는 것은, 계수가 모두 0인 자명한 결합(trivial combination) 외에는 열들을 결합해 영벡터를 만들 수 없다는 뜻이다. 이것이 바로 선형 독립의 정의다.
| \(N(\mathbf{A})\) | 피벗 수 \(r\) | 해의 구조 |
|---|---|---|
| \(Z\) (영벡터만) | \(r = n\) (모든 열이 피벗 열) | 해 없음 또는 유일해 |
| 직선 (1차원) | \(r = n - 1\) (자유 변수 1개) | 특수해 1개, 무수한 해 |
| 평면 (2차원) | \(r = n - 2\) (자유 변수 2개) | 특수해 2개, 무수한 해 |
12 n > m 이면 비자명해가 항상 존재한다
\(n > m\) (열 수가 행 수보다 많은) 행렬 \(\mathbf{A}\) 에서 \(\mathbf{A}\mathbf{x} = \mathbf{0}\) 은 반드시 \(\mathbf{x} = \mathbf{0}\) 이 아닌 해를 가진다.
이유: 피벗의 수는 최대 \(m\) (행 수)이다. \(n > m\) 이면 \(n - r \geq n - m \geq 1\), 즉 자유 변수가 최소 1개 존재한다. 자유 변수를 1로 설정하면 비자명 특수해가 생긴다.
해석: 미지수보다 방정식이 적으면 방정식을 “넘어서는” 자유도가 남는다. 이 자유도가 영공간에 방향(직선, 평면 등)을 부여한다.
13 왜 영공간이 중요한가
영공간은 선형대수 전체를 관통하는 핵심 구조다.
직관적 의미: 행렬 \(\mathbf{A}\) 가 “무시하는” 벡터들의 공간. \(\mathbf{x} \in N(\mathbf{A})\) 라는 것은 \(\mathbf{A}\) 가 \(\mathbf{x}\) 를 완전히 납작하게 만들어 버린다는 뜻이다.
후속 개념과의 연결:
- 완전해 구조 (§3.4): \(\mathbf{A}\mathbf{x} = \mathbf{b}\) 의 완전해 = 특정해 \(\mathbf{x}_p\) + 영공간 \(N(\mathbf{A})\)
- 랭크-무효 정리 (§3.5): \(\dim C(\mathbf{A}) + \dim N(\mathbf{A}) = n\) (차원 방정식)
- 최소제곱법 (§4.3): \(\mathbf{A}^\top \mathbf{A} \mathbf{x} = \mathbf{A}^\top \mathbf{b}\) 의 해의 유일성이 \(N(\mathbf{A})\) 에 달려 있다
- 특잇값 분해 (SVD): 영공간 = \(\mathbf{V}\) 의 마지막 열들 (대응하는 특잇값 = 0)
14 응용 분야
| 분야 | 활용 | 의미 |
|---|---|---|
| 머신러닝 | 과소결정 시스템 (underdetermined system) | \(n > m\) 이면 무수한 해 → 정규화(regularization)로 하나 선택 |
| 딥러닝 | 행렬 랭크 결핍 (rank deficiency) | 가중치 행렬의 영공간 = 모델이 무시하는 방향 |
| 제어 이론 | 상태 방정식 \(\dot{\mathbf{x}} = \mathbf{A}\mathbf{x}\) | \(N(\mathbf{A})\) 는 제어 불가 상태 방향 |
| 컴퓨터 그래픽 | 변환 행렬의 영공간 | 투영에서 사라지는 방향 = 영공간 |
| 데이터 압축 | PCA의 공분산 행렬 | 분산이 0인 방향들 = 영공간 |
15 코드 예시
15.0.1 Step 1: 순수 Python으로 소거 및 특수해 계산 (원리 확인)
import numpy as np
def rref_and_nullspace(A):
"""
행렬 A에 대해 RREF를 계산하고 특수해(nullspace basis)를 반환한다.
교육용 단순 구현 — 수치 안정성보다 명확성 우선.
"""
A = A.astype(float).copy()
m, n = A.shape
pivot_cols = []
row = 0
for col in range(n):
# 피벗 탐색
pivot = None
for r in range(row, m):
if abs(A[r, col]) > 1e-10:
pivot = r
break
if pivot is None:
continue # 자유 열 — 다음 열로
# 행 교환
A[[row, pivot]] = A[[pivot, row]]
# 피벗을 1로 정규화
A[row] /= A[row, col]
# 위아래 모두 소거 (RREF)
for r in range(m):
if r != row and abs(A[r, col]) > 1e-10:
A[r] -= A[r, col] * A[row]
pivot_cols.append(col)
row += 1
# 자유 열 식별
free_cols = [c for c in range(n) if c not in pivot_cols]
# 특수해 생성: 자유 변수 = 1, 나머지 자유 변수 = 0, 피벗 변수 = -F 항목
special_solutions = []
for fc in free_cols:
s = np.zeros(n)
s[fc] = 1.0
for i, pc in enumerate(pivot_cols):
s[pc] = -A[i, fc]
special_solutions.append(s)
return A, pivot_cols, free_cols, special_solutions
# 3×4 예시 행렬
A = np.array([
[1, 1, 2, 3],
[2, 2, 8, 10],
[3, 3, 10, 13]
], dtype=float)
R, pcols, fcols, specials = rref_and_nullspace(A)
print("RREF R:")
print(R)
print(f"\n피벗 열: {pcols}")
print(f"자유 열: {fcols}")
print("\n특수해:")
for i, s in enumerate(specials):
print(f" s{i+1} = {s}")
print(f" A @ s{i+1} = {A @ s} (0이어야 함)")15.0.2 Step 2: NumPy / SciPy로 영공간 계산 (실무 활용)
import numpy as np
from scipy.linalg import null_space
A = np.array([
[1, 1, 2, 3],
[2, 2, 8, 10],
[3, 3, 10, 13]
], dtype=float)
# scipy의 null_space는 SVD 기반으로 수치적으로 안정적인 영공간 기저를 반환한다
N = null_space(A) # 열이 영공간의 정규직교 기저
print("영공간 기저 (정규직교화된 버전):")
print(N)
print(f"\n영공간 차원: {N.shape[1]}")
print(f"검증 A @ N (0에 가까워야 함):")
print(np.round(A @ N, decimals=10))
# 랭크와 영공간 차원 확인
r = np.linalg.matrix_rank(A)
n = A.shape[1]
print(f"\n랭크 r = {r}, 변수 수 n = {n}, 영공간 차원 = n - r = {n - r}")15.0.3 Step 3: 시각화 — 1×3 행렬의 영공간 (평면)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# A = [1 2 3], Ax=0 → x1 + 2x2 + 3x3 = 0
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
x2_grid, x3_grid = np.meshgrid(np.linspace(-2, 2, 20), np.linspace(-2, 2, 20))
x1_grid = -2 * x2_grid - 3 * x3_grid
ax.plot_surface(x1_grid, x2_grid, x3_grid, alpha=0.3, color='steelblue')
s1 = np.array([-2, 1, 0])
s2 = np.array([-3, 0, 1])
ax.quiver(0, 0, 0, *s1, color='red', linewidth=2, label='s1 = (-2, 1, 0)')
ax.quiver(0, 0, 0, *s2, color='green', linewidth=2, label='s2 = (-3, 0, 1)')
ax.scatter([0], [0], [0], color='black', s=50, zorder=5)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_zlabel('x3')
ax.set_title('N(A) for A = [1 2 3]\n원점을 지나는 평면, 특수해 s1, s2가 기저')
ax.legend()
plt.tight_layout()
plt.show()16 핵심 정리
| 개념 | 내용 |
|---|---|
| \(N(\mathbf{A})\) 정의 | \(\mathbf{A}\mathbf{x} = \mathbf{0}\) 의 모든 해, \(\mathbb{R}^n\) 의 부분공간 |
| 왜 부분공간인가 | 행렬 곱의 선형성: \(\mathbf{A}(\mathbf{x}+\mathbf{y}) = \mathbf{0}\), \(\mathbf{A}(c\mathbf{x}) = \mathbf{0}\) |
| 자유 변수 | 피벗 없는 열에 대응 — 임의의 값 가능 |
| 특수해 | 자유 변수 = 1, 나머지 자유 변수 = 0, 역대입으로 피벗 변수 결정 |
| RREF \(\mathbf{R}\) | 피벗 = 1, 피벗 열 위아래 모두 0, 특수해를 직접 읽을 수 있음 |
| 영공간 차원 | \(n - r\) (자유 변수의 수, \(r\) = 피벗 수 = 랭크) |
| \(N(\mathbf{A}) = Z\) | 모든 열이 피벗 열 \(\Leftrightarrow\) 열 독립 \(\Leftrightarrow\) 유일해 |
| \(n > m\) | 자유 변수 항상 존재 → 비자명해 항상 존재 |
17 관련 주제
선행 지식
- Ch.3 §3.1 — Spaces of Vectors and Subspaces
- Ch.2 §2.2 — The Idea of Elimination
- Ch.2 §2.3 — Elimination Using Matrices
후속 주제
- Ch.3 §3.3 — The Rank and the Row Reduced Form — 랭크와 RREF 심화
- Ch.3 §3.4 — The Complete Solution to Ax = b — 특정해 + 영공간
- Ch.3 §3.5 — Independence, Basis, Dimension — 차원 방정식 \(r + (n-r) = n\)
다른 카테고리 연결
- 투영과 최소자승법 — 영공간 구조가 해의 유일성을 결정