1 챕터 3 전체 로드맵
Ch.3는 선형대수의 세 번째 이해 수준으로의 도약이다.
- Ch.1: 개별 벡터 — 덧셈, 스칼라 곱, 내적
- Ch.2: 개별 방정식 — \(Ax = b\) 를 푸는 소거법, LU 분해
- Ch.3: 벡터들의 집합(공간) — 해가 이루는 구조 전체를 한꺼번에 파악
“공간 눈”을 갖게 되면 \(Ax = b\) 가 풀리는 조건, 해의 개수, 해의 구조가 모두 기하학적으로 보인다.
| 절 | 제목 | 핵심 질문 |
|---|---|---|
| §3.1 | Spaces of Vectors | 벡터 공간이란 무엇인가? |
| §3.2 | The Nullspace of A: Solving Ax = 0 | \(Ax = 0\) 의 해집합은 무엇인가? |
| §3.3 | The Rank and the Row Reduced Form | 피벗 수가 말해주는 것은? |
| §3.4 | The Complete Solution to Ax = b | \(Ax = b\) 의 완전해 구조는? |
| §3.5 | Independence, Basis and Dimension | 기저와 차원은 어떻게 정의하는가? |
| §3.6 | Dimensions of the Four Subspaces | 네 부분공간의 차원 관계는? |
2 왜 ’공간’이 필요한가
Ch.2까지는 행렬 \(A\) 와 벡터 \(\mathbf{b}\) 가 주어졌을 때 특정 해 \(\mathbf{x}\) 를 구하는 데 집중했다. 그런데 한 발 물러서면 더 근본적인 질문이 생긴다.
“\(Ax = b\) 는 어떤 \(\mathbf{b}\) 에 대해 풀리는가?”
이 질문의 답은 개별 벡터가 아니라 벡터들의 집합 — 즉 “열공간(column space)” — 이 결정한다. 열공간 안에 \(\mathbf{b}\) 가 있으면 풀리고, 없으면 풀리지 않는다.
이처럼 벡터들의 집합 전체를 하나의 객체로 다루는 개념이 벡터 공간(vector space)이다.
3 벡터 공간의 정의
3.1 \(\mathbb{R}^n\) — 가장 기본적인 벡터 공간
\(\mathbb{R}^n\) 은 \(n\) 개의 실수 성분을 가진 모든 열벡터의 집합이다.
\[\mathbb{R}^n = \left\{ \mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} \;\middle|\; v_i \in \mathbb{R} \right\}\]
- \(\mathbb{R}^2\): \(xy\)-평면의 모든 점 — “개별 화살표”가 아닌 “평면 전체”
- \(\mathbb{R}^3\): 3차원 공간 전체
- \(\mathbb{R}^5\): 다섯 개의 실수로 이루어진 모든 열벡터
직관: “\(\mathbb{R}^n\) 이 공간이다”는 말은 단순히 “벡터가 있다”는 것이 아니라, 그 안에서 덧셈과 스칼라 곱을 얼마든지 해도 결과가 여전히 그 집합 안에 있다는 뜻이다.
3.2 벡터 공간의 일반 정의와 8가지 공리
\(\mathbb{R}^n\) 이외에도 벡터 공간이 될 수 있는 집합은 많다. 그래서 더 일반적인 정의가 필요하다.
집합 \(V\) 가 벡터 덧셈 \(\mathbf{v} + \mathbf{w}\) 와 스칼라 곱 \(c\mathbf{v}\) 에 대해 다음 8가지 공리를 만족하면, \(V\) 를 벡터 공간이라 한다.
| 공리 | 내용 |
|---|---|
| (1) 교환법칙 | \(\mathbf{v} + \mathbf{w} = \mathbf{w} + \mathbf{v}\) |
| (2) 결합법칙 | \(\mathbf{u} + (\mathbf{v} + \mathbf{w}) = (\mathbf{u} + \mathbf{v}) + \mathbf{w}\) |
| (3) 영벡터 존재 | \(\mathbf{v} + \mathbf{0} = \mathbf{v}\) 를 만족하는 유일한 \(\mathbf{0}\) 이 존재한다 |
| (4) 역원 존재 | 각 \(\mathbf{v}\) 에 대해 \(\mathbf{v} + (-\mathbf{v}) = \mathbf{0}\) 을 만족하는 \(-\mathbf{v}\) 가 존재한다 |
| (5) 스칼라 1 | \(1 \cdot \mathbf{v} = \mathbf{v}\) |
| (6) 스칼라 결합 | \((c_1 c_2)\mathbf{v} = c_1(c_2 \mathbf{v})\) |
| (7) 분배법칙 1 | \(c(\mathbf{v} + \mathbf{w}) = c\mathbf{v} + c\mathbf{w}\) |
| (8) 분배법칙 2 | \((c_1 + c_2)\mathbf{v} = c_1\mathbf{v} + c_2\mathbf{v}\) |
왜 8가지인가? 이 공리들은 “선형 연산이 일관되게 작동하기 위한 최소 조건”이다. 예컨대 공리 (3)이 없으면 “더해서 제자리로 돌아오는 벡터”가 없고, 공리 (4)가 없으면 빼기가 정의되지 않는다.
3.3 \(\mathbb{R}^n\) 외의 벡터 공간
열벡터만 벡터 공간이 되는 것이 아니다. 다음 집합들도 8가지 공리를 모두 만족한다.
| 기호 | 집합 | 덧셈 | 스칼라 곱 |
|---|---|---|---|
| \(M\) | \(2 \times 2\) 실수 행렬 전체 | 행렬 덧셈 | 스칼라 × 행렬 |
| \(F\) | 실수 함수 \(f(x)\) 전체 | 함수 덧셈 \((f+g)(x) = f(x)+g(x)\) | \((cf)(x) = c \cdot f(x)\) |
| \(Z\) | 영벡터 하나만 포함한 집합 \(\{\mathbf{0}\}\) | \(\mathbf{0} + \mathbf{0} = \mathbf{0}\) | \(c\mathbf{0} = \mathbf{0}\) |
직관:
- \(M\) 에서 “벡터”는 행렬이다. 두 행렬을 더해도 행렬이고, 4배 해도 행렬이다.
- \(F\) 에서 “벡터”는 함수다. \(f(x) = x^2\) 과 \(g(x) = 5x\) 를 더하면 \(h(x) = x^2 + 5x\) 가 되고, 이것도 함수이므로 \(F\) 에 속한다.
- \(Z\) 는 차원이 0인 벡터 공간이다. 가장 작은 벡터 공간으로, 영벡터 없이는 어떤 벡터 공간도 존재할 수 없다.
공리 (5): \(1 \cdot \mathbf{v} = \mathbf{v}\) 에서 출발하면, 공리 (8)에 의해 \((1 + (-1))\mathbf{v} = \mathbf{v} + (-1)\mathbf{v} = \mathbf{0}\) 이 성립한다. 따라서 어떤 벡터 공간이든 반드시 영벡터 \(\mathbf{0}\) 을 포함한다. 이는 단순한 규칙이 아니라 벡터 공간을 구성하는 논리적 귀결이다.
4 부분공간 (Subspace)
4.1 정의
벡터 공간 전체가 아닌 그 안의 특정 닫힌 부분을 다룰 때 부분공간이 필요하다.
벡터 공간 \(V\) 의 부분집합 \(S\) 가 다음 두 조건을 만족하면 \(S\) 를 \(V\) 의 부분공간이라 한다.
- 덧셈에 닫힘: \(\mathbf{v}, \mathbf{w} \in S \implies \mathbf{v} + \mathbf{w} \in S\)
- 스칼라 곱에 닫힘: \(\mathbf{v} \in S,\; c \in \mathbb{R} \implies c\mathbf{v} \in S\)
두 조건을 합치면: \(S\) 는 모든 선형결합 \(c\mathbf{v} + d\mathbf{w}\) 에 닫혀 있다.
직관: “닫혀 있다(closed)”는 말은 부분공간 안에서 더하거나 늘리거나 줄여도 절대 밖으로 나가지 않는다는 뜻이다. 마치 수를 아무리 더하고 빼도 정수 집합을 벗어나지 않듯이.
4.2 원점을 통과해야 한다
조건 2에서 \(c = 0\) 을 대입하면 \(0 \cdot \mathbf{v} = \mathbf{0} \in S\) 이어야 한다. 따라서 원점을 통과하지 않는 집합은 부분공간이 될 수 없다.
예: \(\mathbb{R}^2\) 에서 직선 \(y = x + 1\) 은 원점을 지나지 않으므로 부분공간이 아니다. 직선 \(y = x\) 는 원점을 지나므로 부분공간이다.
4.3 \(\mathbb{R}^3\) 의 모든 부분공간
\(\mathbb{R}^3\) 에서 가능한 부분공간은 정확히 4종류이다.
| 종류 | 예시 | 차원 |
|---|---|---|
| 원점만 | \(\{(0,0,0)\}\) — 영공간 \(Z\) | 0 |
| 원점을 지나는 직선 | 방향벡터 하나로 생성 | 1 |
| 원점을 지나는 평면 | 두 벡터로 생성 | 2 |
| 공간 전체 | \(\mathbb{R}^3\) 자체 | 3 |
왜 평면은 반드시 원점을 지나야 하는가? 평면 위의 벡터 \(\mathbf{v}\) 에 \(c = 0\) 을 곱하면 \(\mathbf{0}\) 이 나온다. 이것이 평면 위에 없다면 조건 2가 깨진다. 수학적으로 이는 선택이 아니라 필연이다.
4.4 부분공간이 아닌 예시
예시 1: 1사분면 (1st quadrant)
\(\mathbb{R}^2\) 에서 \(x \geq 0,\; y \geq 0\) 인 벡터들의 집합.
- \((2, 3) \in S\) 이지만 \((-1) \cdot (2, 3) = (-2, -3) \notin S\) → 조건 2 위반
- 부분공간이 아니다.
예시 2: 1·3사분면 합집합
\(x, y\) 동부호인 벡터들의 집합.
- 조건 2는 만족 (스칼라 배해도 부호 유지)
- 그러나 \((2, 3) + (-3, -2) = (-1, 1)\) 은 4사분면 → 조건 1 위반
- 부분공간이 아니다.
교훈: 부분공간은 두 조건을 동시에 만족해야 한다. 하나만 만족해도 충분하지 않다.
5 열공간 (Column Space)
5.1 정의
행렬 \(A\) 에서 자연스럽게 등장하는 가장 중요한 부분공간이다.
\(m \times n\) 행렬 \(A\) 의 열공간(column space) \(C(A)\) 는 \(A\) 의 열벡터들의 모든 선형결합으로 이루어진 집합이다.
\[C(A) = \{ A\mathbf{x} \mid \mathbf{x} \in \mathbb{R}^n \} = \text{span}(\mathbf{a}_1, \mathbf{a}_2, \ldots, \mathbf{a}_n)\]
여기서 \(\mathbf{a}_1, \ldots, \mathbf{a}_n\) 은 \(A\) 의 열벡터이고, \(C(A)\) 는 \(\mathbb{R}^m\) 의 부분공간이다.
핵심 관계:
\[A\mathbf{x} = x_1 \mathbf{a}_1 + x_2 \mathbf{a}_2 + \cdots + x_n \mathbf{a}_n\]
\(Ax\) 는 \(A\) 의 열벡터들을 \(x_1, x_2, \ldots, x_n\) 으로 선형결합한 것이다. \(\mathbf{x}\) 를 모든 가능한 값으로 변화시키면 나오는 모든 벡터가 열공간 \(C(A)\) 를 채운다.
5.2 \(Ax = b\) 의 해 존재 조건 — 열공간 언어로
\[Ax = b \text{에 해가 존재한다} \iff \mathbf{b} \in C(A)\]
\(\mathbf{b}\) 가 \(A\) 의 열벡터들의 선형결합으로 표현될 수 있을 때, 그리고 그때만 해가 존재한다.
직관: “\(Ax = b\) 를 풀어라”는 사실 “\(\mathbf{b}\) 를 \(A\) 의 열들로 만들 수 있는 조리법 \(\mathbf{x}\) 를 찾아라”는 문제다. 가능한 모든 조리법을 시도해서 만들어지는 결과물 전체가 열공간이다. \(\mathbf{b}\) 가 그 결과물 집합에 없다면 어떤 조리법으로도 만들 수 없다.
5.3 예시
\[A = \begin{bmatrix} 1 & 0 \\ 4 & 3 \\ 2 & 3 \end{bmatrix}\]
이 \(3 \times 2\) 행렬의 두 열은 \(\mathbf{a}_1 = (1, 4, 2)^\top\), \(\mathbf{a}_2 = (0, 3, 3)^\top\) 이다.
\[C(A) = \left\{ x_1 \begin{bmatrix} 1 \\ 4 \\ 2 \end{bmatrix} + x_2 \begin{bmatrix} 0 \\ 3 \\ 3 \end{bmatrix} \;\middle|\; x_1, x_2 \in \mathbb{R} \right\}\]
두 열이 선형독립이면 이들이 생성하는 집합은 \(\mathbb{R}^3\) 안의 평면이 된다. 따라서 이 평면 위에 있는 \(\mathbf{b}\) 에 대해서만 \(A\mathbf{x} = \mathbf{b}\) 가 풀린다. \(\mathbb{R}^3\) 의 “대부분” 벡터는 이 평면 위에 없으므로, 해가 존재하지 않는 경우가 일반적이다.
5.4 열이 적을수록 열공간이 좁아진다
| 행렬 | 열공간 \(C(A)\) | 차원 |
|---|---|---|
| \(I = \begin{bmatrix}1&0\\0&1\end{bmatrix}\) | \(\mathbb{R}^2\) 전체 | 2 |
| \(A = \begin{bmatrix}1&2\\2&4\end{bmatrix}\) | \((1,2)^\top\) 방향의 직선 | 1 |
| \(B = \begin{bmatrix}1&2&3\\0&0&4\end{bmatrix}\) | \(\mathbb{R}^2\) 전체 | 2 |
\(A\) 에서 두 번째 열이 첫 번째 열의 2배이므로, 새로운 방향을 추가하지 못한다. \(B\) 는 열이 3개지만 2차원 공간에 속하므로 열공간의 차원은 여전히 2이다. 열의 수가 아닌 독립적인 열의 수가 열공간의 차원을 결정한다.
6 생성(Span)과 부분공간
벡터들의 집합 \(S = \{\mathbf{v}_1, \ldots, \mathbf{v}_k\}\) 가 있을 때, 이들의 모든 선형결합으로 이루어진 집합을 \(S\) 의 생성(span)이라 한다.
\[\text{span}(S) = \{c_1 \mathbf{v}_1 + c_2 \mathbf{v}_2 + \cdots + c_k \mathbf{v}_k \mid c_i \in \mathbb{R}\}\]
\(\text{span}(S)\) 는 항상 부분공간이 된다.
- \(S\) 에 벡터 하나 \(\mathbf{v}\) 만 있으면, \(\text{span}(\mathbf{v})\) 는 \(\mathbf{v}\) 를 지나는 직선
- 두 벡터 \(\mathbf{v}, \mathbf{w}\) 가 선형독립이면, \(\text{span}(\mathbf{v}, \mathbf{w})\) 는 평면
- 열공간 \(C(A) = \text{span}(\mathbf{a}_1, \ldots, \mathbf{a}_n)\)
7 벡터 공간의 8가지 공리 — 직관으로 이해하기
추상적인 공리를 “왜 저런 조건인가?”의 관점에서 다시 읽으면 각각의 필요성이 보인다.
| 공리 | 없으면 어떻게 되는가 |
|---|---|
| 교환법칙 | \(\mathbf{v} + \mathbf{w}\) 와 \(\mathbf{w} + \mathbf{v}\) 가 달라지므로 덧셈 순서를 매번 지정해야 한다 |
| 영벡터 존재 | “아무것도 더하지 않음”에 해당하는 기준점이 없어 차이 개념이 무너진다 |
| 역원 존재 | 빼기가 정의되지 않아 방정식 \(\mathbf{v} + \mathbf{x} = \mathbf{0}\) 을 풀 수 없다 |
| 분배법칙 1 | 스칼라 배가 덧셈을 보존하지 않아 선형결합 전체가 의미를 잃는다 |
공리 (1)~(8)은 “좋은 선형 연산”을 보장하는 최소 요건이다. 이 조건들을 모두 만족해야 벡터 공간에서 배운 모든 정리들이 그대로 적용된다.
8 응용 분야
벡터 공간과 부분공간은 수학적 추상 개념이지만, 데이터 사이언스 전반의 근간을 이룬다.
| 분야 | 활용 | 부분공간과의 연결 |
|---|---|---|
| 머신러닝 | 주성분분석(PCA) | 공분산행렬의 열공간 = 주성분들이 생성하는 공간 |
| 딥러닝 | 레이어의 표현 공간 | 각 레이어의 출력은 입력의 열공간 내 벡터 |
| 통계학 | 최소제곱 회귀 | 적합값 \(\hat{\mathbf{y}} = H\mathbf{y}\) 는 설계행렬의 열공간 위로의 정사영 |
| 신호처리 | 필터 설계 | 필터링 = 신호를 특정 부분공간으로 투영하는 연산 |
| NLP | Word Embedding | 단어 벡터들이 의미 공간(벡터 공간)을 이룬다 |
9 손계산 예시
9.1 예시 1: \(\mathbb{R}^2\) 에서 부분공간 판별
다음 집합이 \(\mathbb{R}^2\) 의 부분공간인지 판별한다.
- \(S_1 = \{(x, y) \mid y = 2x\}\)
\(\mathbf{v} = (1, 2)\), \(\mathbf{w} = (3, 6)\) 이면 \(\mathbf{v} + \mathbf{w} = (4, 8)\) 이고 \(8 = 2 \times 4\) 이므로 조건 1 만족. \(c \cdot (1, 2) = (c, 2c)\) 이고 \(2c = 2 \times c\) 이므로 조건 2 만족. \(S_1\) 은 부분공간이다 — 원점을 지나는 직선.
- \(S_2 = \{(x, y) \mid y = 2x + 1\}\)
\((0, 0)\) 을 대입하면 \(0 = 0 + 1\) 이 성립하지 않으므로 영벡터가 없다. \(S_2\) 는 부분공간이 아니다 — 원점을 지나지 않는 직선.
9.2 예시 2: \(3 \times 2\) 행렬의 열공간
\[A = \begin{bmatrix} 1 & 2 \\ 0 & 1 \\ 3 & 5 \end{bmatrix}\]
\(\mathbf{a}_1 = (1, 0, 3)^\top\), \(\mathbf{a}_2 = (2, 1, 5)^\top\).
\(\mathbf{a}_2 - 2\mathbf{a}_1 = (2-2, 1-0, 5-6)^\top = (0, 1, -1)^\top\) 이므로 두 벡터는 선형독립이다. 따라서 \(C(A)\) 는 \(\mathbb{R}^3\) 안의 2차원 평면이다.
\(\mathbf{b} = (1, 0, 3)^\top\) 은 \(\mathbf{a}_1\) 자체이므로 \(C(A) \in \mathbf{b}\) 이고, \(x_1 = 1, x_2 = 0\) 이 해다.
\(\mathbf{b} = (0, 0, 1)^\top\) 에 대해 \(A\mathbf{x} = \mathbf{b}\) 가 해를 갖는지 확인하려면 \(\mathbf{b}\) 가 \(C(A)\) 위의 평면에 속하는지 확인하면 된다. 소거법으로 풀면:
\[\begin{bmatrix} 1 & 2 & 0 \\ 0 & 1 & 0 \\ 3 & 5 & 1 \end{bmatrix} \xrightarrow{R_3 - 3R_1} \begin{bmatrix} 1 & 2 & 0 \\ 0 & 1 & 0 \\ 0 & -1 & 1 \end{bmatrix} \xrightarrow{R_3 + R_2} \begin{bmatrix} 1 & 2 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\]
3행이 \(0 = 1\) 이 되므로 해가 없다. 즉 \((0, 0, 1)^\top \notin C(A)\).
10 코드 예시
10.1 Step 1: 순수 Python — 부분공간 조건 검증
# 두 벡터의 선형결합이 주어진 집합에 속하는지 확인
def is_on_subspace(v, w, predicate, trials=100):
"""
v, w: list (벡터)
predicate: 집합 조건 (함수)
trials: 무작위 계수로 테스트 횟수
"""
import random
for _ in range(trials):
c = random.uniform(-10, 10)
d = random.uniform(-10, 10)
combo = [c * vi + d * wi for vi, wi in zip(v, w)]
if not predicate(combo):
return False # 닫혀 있지 않음
return True
# y = 2x 직선 조건
on_line = lambda v: abs(v[1] - 2 * v[0]) < 1e-9
v = [1, 2]
w = [3, 6]
print("y=2x는 부분공간?", is_on_subspace(v, w, on_line))
# True — 모든 선형결합이 y=2x 위에 있다
# y = x^2 포물선 조건 (부분공간이 아닌 예)
on_parabola = lambda v: abs(v[1] - v[0]**2) < 1e-9
v = [1, 1]
w = [2, 4]
print("y=x^2는 부분공간?", is_on_subspace(v, w, on_parabola))
# False — 선형결합이 포물선 위에 있지 않음10.2 Step 2: NumPy — 열공간 소속 판별
import numpy as np
def in_column_space(A, b, tol=1e-9):
"""
b가 A의 열공간에 속하는지 판별한다.
방법: [A | b]의 랭크가 A의 랭크와 같으면 b ∈ C(A)
"""
rank_A = np.linalg.matrix_rank(A)
rank_Ab = np.linalg.matrix_rank(np.column_stack([A, b]))
return rank_A == rank_Ab
A = np.array([[1, 0],
[4, 3],
[2, 3]], dtype=float)
b1 = np.array([1, 4, 2]) # A의 첫 번째 열
b2 = np.array([0, 0, 1]) # 열공간 밖의 벡터
print("b1 ∈ C(A)?", in_column_space(A, b1)) # True
print("b2 ∈ C(A)?", in_column_space(A, b2)) # False10.3 Step 3: 열공간 시각화 (matplotlib)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# A의 두 열벡터
a1 = np.array([1, 4, 2])
a2 = np.array([0, 3, 3])
# 열공간: a1, a2의 모든 선형결합이 이루는 평면
s = np.linspace(-1, 1, 20)
t = np.linspace(-1, 1, 20)
S, T = np.meshgrid(s, t)
X = S * a1[0] + T * a2[0]
Y = S * a1[1] + T * a2[1]
Z = S * a1[2] + T * a2[2]
ax.plot_surface(X, Y, Z, alpha=0.3, color='skyblue', label='C(A)')
# 열벡터 표시
origin = np.zeros(3)
for vec, label, color in [(a1, 'a1', 'blue'), (a2, 'a2', 'red')]:
ax.quiver(*origin, *vec, color=color, arrow_length_ratio=0.1)
ax.text(*vec, label, color=color, fontsize=12)
# 열공간 안의 벡터 b = a1 + a2
b = a1 + a2
ax.quiver(*origin, *b, color='green', arrow_length_ratio=0.1)
ax.text(*b, 'b = a1+a2\n(b ∈ C(A))', color='green', fontsize=9)
ax.set_xlabel('x'); ax.set_ylabel('y'); ax.set_zlabel('z')
ax.set_title('Column Space C(A): 열공간은 R³ 안의 평면')
plt.tight_layout()
plt.show()11 Ch.3 §3.1 핵심 요약
- \(\mathbb{R}^n\) 은 \(n\) 성분 실수 열벡터 전체의 집합이며, 덧셈과 스칼라 곱에 대해 닫혀 있다.
- 벡터 공간은 8가지 공리를 만족하는 집합이다. \(\mathbb{R}^n\), 행렬 공간 \(M\), 함수 공간 \(F\) 등이 모두 벡터 공간이다.
- 부분공간은 덧셈과 스칼라 곱에 닫혀 있어야 하며, 반드시 영벡터를 포함한다. 원점을 지나지 않으면 부분공간이 아니다.
- \(m \times n\) 행렬 \(A\) 의 열공간 \(C(A)\) 는 \(A\) 의 열벡터들의 모든 선형결합으로 이루어진 \(\mathbb{R}^m\) 의 부분공간이다.
- \(Ax = b\) 에 해가 존재하는 필요충분조건은 \(\mathbf{b} \in C(A)\) 이다.
(Strang, 2009, Ch.3)
12 관련 주제
선행 지식
- Ch.1 §1.1 — Vectors and Linear Combinations
- Ch.2 Overview — Ax=b에서 LU 분해까지
- Ch.2 §2.7 — Transposes and Permutations
후속 주제