1 개요: 유한에서 무한으로 — 바뀌는 것과 바뀌지 않는 것
Ch.1~7에서 배운 선형대수의 핵심 도구 — 내적, 직교성, 정사영, 정규직교 기저, \(Q^\top Q = I\) — 는 \(\mathbb{R}^n\) 에서만 작동하는가? 아니다. \(n\) 을 무한대로 보내도 이 도구들은 거의 그대로 살아남는다. §8.5는 이 사실을 푸리에 급수를 통해 보여준다 (Strang, 2009, §8.5).
바뀌는 것은 단 하나 — 합이 적분으로 바뀐다. 나머지는 유한차원과 판박이다.
유한차원에서 벡터 \(\mathbf{b}\) 를 직교 기저 \(\{\mathbf{v}_1, \ldots, \mathbf{v}_n\}\) 으로 분해할 때
\[ \mathbf{b} = c_1 \mathbf{v}_1 + c_2 \mathbf{v}_2 + \cdots + c_n \mathbf{v}_n, \quad c_k = \frac{\mathbf{v}_k^\top \mathbf{b}}{\mathbf{v}_k^\top \mathbf{v}_k} \]
무한차원에서 함수 \(f(x)\) 를 직교 기저 \(\{1, \cos x, \sin x, \cos 2x, \sin 2x, \ldots\}\) 으로 분해할 때
\[ f(x) = a_0 + \sum_{k=1}^{\infty}(a_k \cos kx + b_k \sin kx), \quad a_k = \frac{\int f(x) \cos kx \, dx}{\int \cos^2 kx \, dx} \]
구조가 동일하다. 분자는 내적, 분모는 길이의 제곱이다.
2 무한차원 벡터: 두 가지 관점
무한 개의 성분을 가진 벡터는 두 가지 형태로 나타난다 (Strang, 2009, §8.5).
관점 1: 무한 수열
\[ \mathbf{v} = (v_1, v_2, v_3, \ldots) \]
예를 들어 \(\mathbf{v} = (1, \tfrac{1}{2}, \tfrac{1}{4}, \ldots)\) 은 성분이 무한히 이어지는 벡터다.
관점 2: 함수
\[ f(x) \quad \text{(예: } f(x) = \sin x\text{)} \]
함수 \(f(x)\) 는 각 \(x\) 값에 대해 하나의 “성분”을 주므로, 연속적으로 무한 개의 성분을 가진 벡터로 볼 수 있다. 푸리에 급수가 이 두 관점을 연결한다 — 함수 \(f(x)\) 와 그 푸리에 계수 벡터 \((a_0, a_1, b_1, a_2, b_2, \ldots)\) 가 일대일 대응한다.
3 무한차원의 내적과 길이
3.1 수열 벡터의 경우
유한차원에서 \(\mathbf{v} \cdot \mathbf{w} = v_1 w_1 + v_2 w_2 + \cdots + v_n w_n\) 이었다. 무한차원에서는 합이 무한급수가 된다.
\[ \mathbf{v} \cdot \mathbf{w} = v_1 w_1 + v_2 w_2 + v_3 w_3 + \cdots \]
유한차원에서는 없던 문제가 등장한다 — 이 무한 합이 수렴하는가? \(\mathbf{v} = \mathbf{w} = (1, 1, 1, \ldots)\) 이면 \(\mathbf{v} \cdot \mathbf{v} = 1 + 1 + 1 + \cdots = \infty\) 다. 이 벡터는 “길이가 무한”하므로 사용할 수 없다.
무한 수열 벡터 \(\mathbf{v} = (v_1, v_2, \ldots)\) 가 힐베르트 공간에 속하려면, 그 길이가 유한해야 한다.
\[ \|\mathbf{v}\|^2 = v_1^2 + v_2^2 + v_3^2 + \cdots < \infty \]
이 조건을 만족하는 수열들의 집합을 \(\ell^2\) 라고 쓴다.
예를 들어 \(\mathbf{v} = (1, \tfrac{1}{2}, \tfrac{1}{4}, \ldots)\) 의 길이의 제곱은 등비급수다.
\[ \|\mathbf{v}\|^2 = 1 + \frac{1}{4} + \frac{1}{16} + \cdots = \frac{1}{1 - 1/4} = \frac{4}{3} \]
이 벡터는 길이가 \(2/\sqrt{3}\) 으로 유한하므로 힐베르트 공간에 속한다. 반면 \((1, 1, 1, \ldots)\) 은 길이가 무한하므로 힐베르트 공간에서 추방된다.
Strang의 핵심 관찰: 유한 길이의 벡터 두 개의 내적은 반드시 유한하다. 코시-슈바르츠 부등식이 무한차원에서도 성립한다.
\[ |\mathbf{v} \cdot \mathbf{w}| \leq \|\mathbf{v}\| \cdot \|\mathbf{w}\| \]
3.2 함수의 경우: 합을 적분으로
함수 공간에서는 합이 적분으로 바뀐다. 두 함수 \(f(x)\) 와 \(g(x)\) 의 내적과 길이를 다음과 같이 정의한다.
\([0, 2\pi]\) 에서 정의된 함수에 대해:
\[ (f, g) = \int_0^{2\pi} f(x) g(x) \, dx \quad \text{(내적)} \]
\[ \|f\|^2 = \int_0^{2\pi} [f(x)]^2 \, dx \quad \text{(길이의 제곱)} \]
구간 \([0, 2\pi]\) 을 선택한 이유는 \(\sin x\) 와 \(\cos x\) 의 주기가 \(2\pi\) 이기 때문이다. 다른 구간(예: \([0, 1]\) 이나 \((-\infty, \infty)\))을 쓸 수도 있다.
3.3 유한차원-무한차원 대응표
이 대응은 §8.5의 골격이다. 왼쪽의 모든 정리가 오른쪽에서도 성립한다.
| 유한차원 \(\mathbb{R}^n\) | 무한차원 함수 공간 \(L^2[0, 2\pi]\) |
|---|---|
| 벡터 \(\mathbf{v} = (v_1, \ldots, v_n)\) | 함수 \(f(x)\) |
| 내적 \(\mathbf{v}^\top \mathbf{w} = \sum_{i=1}^n v_i w_i\) | \((f, g) = \int_0^{2\pi} f(x) g(x) \, dx\) |
| 길이 \(\|\mathbf{v}\|^2 = \sum v_i^2\) | \(\|f\|^2 = \int [f(x)]^2 \, dx\) |
| 직교 \(\mathbf{v}^\top \mathbf{w} = 0\) | \(\int f(x) g(x) \, dx = 0\) |
| 정규직교 기저 \(Q\), \(Q^\top Q = I\) | \(\{1, \cos x, \sin x, \cos 2x, \sin 2x, \ldots\}\) (정규화 후) |
| 좌표 \(c_k = \mathbf{v}_k^\top \mathbf{b} / \mathbf{v}_k^\top \mathbf{v}_k\) | 푸리에 계수 \(a_k = \frac{1}{\pi}\int f(x)\cos kx \, dx\) |
| 길이 보존 \(\|\mathbf{b}\|^2 = \sum c_k^2 \|\mathbf{v}_k\|^2\) | Parseval: \(\|f\|^2 = 2\pi a_0^2 + \pi \sum(a_k^2 + b_k^2)\) |
이 표를 통째로 외우면 푸리에 급수의 모든 공식이 “당연한” 것이 된다.
4 sin과 cos의 직교성: 왜 이 기저가 특별한가
4.1 직교성 증명
\(\sin nx\) 와 \(\cos mx\) 는 \([0, 2\pi]\) 에서 서로 직교한다. 이것은 삼각함수의 곱-합 공식(product-to-sum identity)에서 바로 나온다.
\[ 2\cos jx \cos kx = \cos(j+k)x + \cos(j-k)x \]
양변을 \([0, 2\pi]\) 에서 적분하면, \(j \neq k\) 일 때 오른쪽의 두 항 모두 완전한 주기의 적분이므로 0이 된다.
\[ \int_0^{2\pi} \cos jx \cos kx \, dx = 0 \quad (j \neq k) \]
같은 논리로 다음이 모두 성립한다.
\[ \int_0^{2\pi} \sin jx \sin kx \, dx = 0 \quad (j \neq k) \]
\[ \int_0^{2\pi} \sin jx \cos kx \, dx = 0 \quad (\text{모든 } j, k) \]
왜 sin-cos 내적은 \(j = k\) 일 때도 0인가? \(\sin jx \cos jx = \frac{1}{2}\sin 2jx\) 이고, 이것의 \([0, 2\pi]\) 적분은 완전한 주기이므로 역시 0이다.
4.2 각 기저 함수의 길이
| 기저 함수 | \(\int_0^{2\pi} [\cdot]^2 \, dx\) | 길이 |
|---|---|---|
| \(1\) (상수 함수) | \(2\pi\) | \(\sqrt{2\pi}\) |
| \(\cos kx\) (\(k \geq 1\)) | \(\pi\) | \(\sqrt{\pi}\) |
| \(\sin kx\) (\(k \geq 1\)) | \(\pi\) | \(\sqrt{\pi}\) |
\(\sin^2 kx\) 의 적분이 \(\pi\) 인 이유: \(\sin^2 kx = \frac{1}{2} - \frac{1}{2}\cos 2kx\) 이므로 \(\int_0^{2\pi} \sin^2 kx \, dx = \frac{1}{2} \cdot 2\pi - 0 = \pi\) 다.
4.3 정규직교 기저
길이로 나누면 정규직교(orthonormal) 기저가 된다.
\[ \frac{1}{\sqrt{2\pi}}, \quad \frac{\cos x}{\sqrt{\pi}}, \quad \frac{\sin x}{\sqrt{\pi}}, \quad \frac{\cos 2x}{\sqrt{\pi}}, \quad \frac{\sin 2x}{\sqrt{\pi}}, \quad \ldots \]
이것은 \(\mathbb{R}^n\) 의 정규직교 행렬 \(Q\) (\(Q^\top Q = I\))의 무한차원 버전이다. “무한 개의 열을 가진 직교 행렬”이라고 생각하면 된다. 그 역행렬은 전치이고, 직교성이 전체 급수를 각각의 한 항으로 환원시킨다.
4.4 왜 sin/cos인가 — 미분 연산자의 고유벡터
\(\sin kx\) 와 \(\cos kx\) 가 특별한 이유는 이들이 이계 미분 연산자 \(-d^2/dx^2\) 의 고유함수(eigenvector)이기 때문이다.
\[ -\frac{d^2}{dx^2}(\sin kx) = k^2 \sin kx, \quad -\frac{d^2}{dx^2}(\cos kx) = k^2 \cos kx \]
고유값은 \(k^2\) 이다. 유한차원에서 대칭 행렬의 고유벡터가 직교한다는 스펙트럼 정리(Ch.6 §6.4)가, 무한차원에서 대칭 연산자의 고유함수가 직교한다는 것으로 확장된다. 물리학에서 진동하는 현(string)의 고유 모드가 \(\sin kx\) 인 것은 이 때문이다 — 경계 조건과 미분 방정식이 직교 기저를 결정한다.
5 푸리에 급수와 계수: 직교성이 일을 쉽게 만든다
5.1 급수 전개
\([0, 2\pi]\) 에서 주기적인 함수 \(f(x)\) 를 직교 기저로 분해한다.
\[ f(x) = a_0 + a_1 \cos x + b_1 \sin x + a_2 \cos 2x + b_2 \sin 2x + \cdots \]
\[ = a_0 + \sum_{k=1}^{\infty} (a_k \cos kx + b_k \sin kx) \]
이것이 푸리에 급수(Fourier series) 다. 유한차원에서 \(\mathbf{b} = c_1 \mathbf{v}_1 + \cdots + c_n \mathbf{v}_n\) 과 완전히 같은 구조이되, 기저가 무한 개다.
5.2 계수 계산: 내적으로
\(a_k\) 를 구하려면 양변에 \(\cos kx\) 를 곱하고 \([0, 2\pi]\) 에서 적분한다. 직교성 덕분에 오른쪽에서 \(\cos kx\) 항만 살아남는다.
\[ \int_0^{2\pi} f(x) \cos kx \, dx = a_k \int_0^{2\pi} \cos^2 kx \, dx = \pi a_k \]
따라서:
\[ a_k = \frac{1}{\pi} \int_0^{2\pi} f(x) \cos kx \, dx \quad (k \geq 1) \]
\[ b_k = \frac{1}{\pi} \int_0^{2\pi} f(x) \sin kx \, dx \quad (k \geq 1) \]
\(a_0\) 은 예외다. 상수 함수 1의 길이의 제곱이 \(2\pi\) 이므로:
\[ a_0 = \frac{1}{2\pi} \int_0^{2\pi} f(x) \, dx = \text{(함수의 평균값)} \]
이 공식들은 유한차원의 좌표 공식 \(c_k = \mathbf{v}_k^\top \mathbf{b} / \mathbf{v}_k^\top \mathbf{v}_k\) 의 정확한 무한차원 대응물이다.
- 분자: 함수 \(f\) 와 기저 함수 \(\cos kx\) 의 내적 \(\int f(x) \cos kx \, dx\)
- 분모: 기저 함수의 길이의 제곱 \(\int \cos^2 kx \, dx = \pi\)
직교성이 계산을 극적으로 단순화한다. 직교가 아닌 기저로 분해하려면 연립방정식(무한 개!)을 풀어야 하지만, 직교 기저에서는 각 계수를 독립적으로 내적 한 번으로 구한다. 이것이 Ch.4 §4.4의 Gram-Schmidt와 정규직교 기저가 중요한 근본적 이유다.
6 사각파 예제: 불연속 함수도 분해된다
6.1 푸리에 급수 계산
사각파(square wave) \(f(x)\) 를 다음과 같이 정의한다.
\[ f(x) = \begin{cases} +1 & 0 \leq x < \pi \\ -1 & \pi \leq x < 2\pi \end{cases} \]
이 함수는 불연속이다. 그런데도 푸리에 급수로 분해할 수 있을까? 된다.
\(f(x)\) 는 홀함수(odd function)이다: \(f(-x) = -f(x)\). 홀함수의 푸리에 급수에는 \(\cos\) 항이 없다. 왜냐하면 \(\cos kx\) 는 짝함수이고, 홀함수와 짝함수의 내적(적분)은 0이기 때문이다.
\(b_k\) 를 계산한다.
\[ b_k = \frac{1}{\pi} \int_0^{2\pi} f(x) \sin kx \, dx = \frac{1}{\pi}\left[\int_0^{\pi} \sin kx \, dx - \int_{\pi}^{2\pi} \sin kx \, dx\right] \]
\(k\) 가 짝수이면 두 적분이 상쇄되어 \(b_k = 0\) 이다. \(k\) 가 홀수이면:
\[ b_k = \frac{4}{\pi k} \quad (k = 1, 3, 5, \ldots) \]
따라서 사각파의 푸리에 급수는:
\[ f(x) = \frac{4}{\pi}\left[\frac{\sin x}{1} + \frac{\sin 3x}{3} + \frac{\sin 5x}{5} + \frac{\sin 7x}{7} + \cdots\right] \]
홀수 사인만 등장한다. 이것은 “사각파 = 기본 진동 + 홀수 배음(odd harmonics)의 합”이라는 물리적 의미를 갖는다. 음향학에서 클라리넷 소리가 사각파에 가깝고 홀수 배음이 강한 이유가 바로 이것이다.
6.2 라이프니츠 급수: 직교성의 부산물
사각파의 푸리에 급수에 \(x = \pi/2\) 를 대입하면 놀라운 일이 벌어진다.
\(x = \pi/2\) 에서 \(\sin(\pi/2) = 1\), \(\sin(3\pi/2) = -1\), \(\sin(5\pi/2) = 1\), \(\sin(7\pi/2) = -1\), … 이고 \(f(\pi/2) = 1\) 이다.
\[ 1 = \frac{4}{\pi}\left(1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \cdots\right) \]
\[ \frac{\pi}{4} = 1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \cdots \]
이것이 유명한 라이프니츠 급수(Leibniz series) 다. 원주율 \(\pi\) 가 홀수의 역수를 번갈아 더하고 빼는 것으로 표현된다. 이 결과는 삼각함수의 직교성이 만들어낸 아름다운 부산물이다 — 순수하게 대수적인 사실(\(\pi\) 의 값)이 기하학적 직교성에서 나온다.
6.3 깁스 현상: 불연속점에서의 오버슈트
사각파의 푸리에 급수는 불연속점 \(x = 0, \pi\) 에서 중간값 0을 준다 — \(+1\) 에서 \(-1\) 로의 점프의 중간이다. 그런데 유한 개의 항만 합하면, 불연속점 근처에서 약 9%의 오버슈트(overshoot) 가 발생한다. 이것이 깁스 현상(Gibbs phenomenon)이다.
항의 개수를 \(N\) 으로 늘려도 오버슈트의 비율은 줄지 않고, 오버슈트가 일어나는 폭만 좁아진다. 즉 \(N \to \infty\) 에서 “뾰족한 돌출”이 사라지지 않고 불연속점으로 쫓겨갈 뿐이다. 이것은 유한차원에서는 볼 수 없는 무한차원 특유의 현상이다.
7 Parseval 정리: 함수의 길이 = 계수의 길이
7.1 정리 서술
\[ \|f\|^2 = \int_0^{2\pi} [f(x)]^2 \, dx = 2\pi a_0^2 + \pi \sum_{k=1}^{\infty} (a_k^2 + b_k^2) \]
7.2 왜 성립하는가 — 직교성
증명은 놀랍도록 짧다. \(f(x)\) 를 푸리에 급수로 대입하고 제곱하여 적분하면, 직교성 덕분에 교차항(예: \(\cos x \cdot \cos 2x\))의 적분이 모두 0이 된다. 제곱항만 남는다.
\[ \int_0^{2\pi} f^2 \, dx = a_0^2 \cdot 2\pi + a_1^2 \cdot \pi + b_1^2 \cdot \pi + a_2^2 \cdot \pi + \cdots \]
이것은 유한차원에서 정규직교 행렬 \(Q\) 에 대해 \(\|Q\mathbf{c}\| = \|\mathbf{c}\|\) 인 것의 정확한 무한차원 대응물이다.
7.3 직관적 의미
Parseval 정리는 “에너지 보존 법칙”이다.
- 왼쪽 \(\|f\|^2\) 은 함수의 시간 영역(time domain) 에너지 — 함수를 시간(또는 공간)으로 본 것이다.
- 오른쪽 \(\sum (a_k^2 + b_k^2)\) 은 주파수 영역(frequency domain) 에너지 — 함수를 주파수 성분으로 분해한 것이다.
어떤 관점에서 보든 에너지의 총합은 같다. 이것은 물리학에서 기본적인 보존 법칙이며, 수학적으로는 함수 공간 \(L^2\) 와 좌표 공간 \(\ell^2\) 가 등거리(isometric) 대응한다는 의미다.
7.4 사각파에 적용
사각파의 \(\|f\|^2 = \int_0^{2\pi} 1 \, dx = 2\pi\) 이다 (함수값이 \(\pm 1\) 이므로 제곱은 항상 1).
Parseval 정리를 적용하면 (\(a_0 = 0\), \(a_k = 0\), \(b_k = 4/(\pi k)\) for 홀수 \(k\)):
\[ 2\pi = \pi \sum_{k \text{ odd}} \left(\frac{4}{\pi k}\right)^2 = \frac{16}{\pi} \sum_{k \text{ odd}} \frac{1}{k^2} \]
정리하면:
\[ \sum_{k \text{ odd}} \frac{1}{k^2} = 1 + \frac{1}{9} + \frac{1}{25} + \frac{1}{49} + \cdots = \frac{\pi^2}{8} \]
이로부터 바젤 문제(Basel problem)의 해 \(\sum_{k=1}^{\infty} 1/k^2 = \pi^2/6\) 도 유도할 수 있다. 직교성이라는 하나의 원리에서 \(\pi\) 에 관한 심원한 등식들이 줄줄이 떨어진다.
8 왜 필요한가: 데이터 사이언스와 공학에서의 응용
| 분야 | 푸리에 급수와의 연결 | 구체적 예시 |
|---|---|---|
| 신호처리 | 시간 영역 신호를 주파수 성분으로 분해 | 음성 인식, 노이즈 필터링, 스펙트럼 분석 |
| 이미지 압축 | DCT(Discrete Cosine Transform)는 푸리에의 사촌 | JPEG 압축: 이미지를 cos 기저로 분해, 작은 계수를 버림 |
| 딥러닝 | sin/cos 기반 위치 인코딩 | Transformer의 positional encoding: \(PE(pos, 2i) = \sin(pos/10000^{2i/d})\) |
| PDE 풀이 | 열방정식, 파동방정식의 일반해 | 초기 조건을 푸리에 급수로 분해 \(\to\) 각 모드가 독립적으로 진화 |
| 시계열 분석 | 주기적 패턴 검출 | 매출 데이터에서 주간/월간/연간 주기를 주파수 성분으로 분리 |
| 양자역학 | 위치-운동량의 푸리에 쌍대성 | 파동함수의 운동량 표현 = 위치 표현의 푸리에 변환 |
| Neural ODE / FNO | 함수 공간에서의 학습 | Fourier Neural Operator: 주파수 영역에서 커널을 학습하여 PDE를 풂 |
JPEG 압축은 본질적으로 “이미지에 대한 푸리에 분해”다. 8x8 블록의 이미지를 DCT로 변환하면 대부분의 에너지가 소수의 저주파 계수에 집중된다. 고주파 계수(디테일)를 버려도 눈으로 보기에 큰 차이가 없다 — Parseval 정리에 의해 버린 계수의 에너지 합이 작기 때문이다. 압축률과 화질의 트레이드오프는 “몇 개의 푸리에 계수를 유지할 것인가”의 문제다.
9 코드 예시
9.1 Step 1: Low-level 구현 (원리 이해)
import numpy as np
def fourier_coefficients(f_values, x_values, K):
"""
수치적으로 푸리에 계수를 계산한다.
직교성 원리를 직접 구현 — 각 계수는 함수와 기저의 내적/기저의 길이^2.
f_values: f(x)의 값들 (1D array)
x_values: x 좌표들 (1D array, [0, 2pi] 구간)
K: 계산할 최대 주파수
"""
dx = x_values[1] - x_values[0] # 적분을 리만합으로 근사
# a0 = (1/2pi) * integral of f(x) dx = 평균값
a0 = np.sum(f_values) * dx / (2 * np.pi)
a_k = []
b_k = []
for k in range(1, K + 1):
# a_k = (1/pi) * integral of f(x) * cos(kx) dx -- 내적 / 길이^2
ak = np.sum(f_values * np.cos(k * x_values)) * dx / np.pi
# b_k = (1/pi) * integral of f(x) * sin(kx) dx
bk = np.sum(f_values * np.sin(k * x_values)) * dx / np.pi
a_k.append(ak)
b_k.append(bk)
return a0, np.array(a_k), np.array(b_k)
def fourier_reconstruct(a0, a_k, b_k, x_values):
"""푸리에 계수로부터 함수를 복원한다."""
result = np.full_like(x_values, a0, dtype=float)
for k in range(len(a_k)):
result += a_k[k] * np.cos((k + 1) * x_values)
result += b_k[k] * np.sin((k + 1) * x_values)
return result
# 사각파 정의
N = 10000
x = np.linspace(0, 2 * np.pi, N, endpoint=False)
f_square = np.where(x < np.pi, 1.0, -1.0)
# 푸리에 계수 계산
K = 10
a0, a_k, b_k = fourier_coefficients(f_square, x, K)
print(f"a0 = {a0:.6f} (이론값: 0)")
print(f"\n코사인 계수 (모두 ~0이어야 함, 홀함수이므로):")
for k, ak in enumerate(a_k, 1):
if abs(ak) > 1e-10:
print(f" a_{k} = {ak:.6f}")
print(f"\n사인 계수:")
for k, bk in enumerate(b_k, 1):
theoretical = 4 / (np.pi * k) if k % 2 == 1 else 0
print(f" b_{k} = {bk:.6f} (이론값: {theoretical:.6f})")
# Parseval 정리 검증
energy_time = np.sum(f_square**2) * (2 * np.pi / N) # ||f||^2
energy_freq = 2 * np.pi * a0**2 + np.pi * (np.sum(a_k**2) + np.sum(b_k**2))
print(f"\n== Parseval 정리 검증 ==")
print(f"시간 영역 에너지: {energy_time:.4f}")
print(f"주파수 영역 에너지 (K={K}): {energy_freq:.4f}")
print(f"이론값: {2 * np.pi:.4f}")
# K를 키울수록 주파수 영역 에너지가 2*pi에 수렴한다9.2 Step 2: NumPy/Matplotlib 실무 코드
import numpy as np
import matplotlib.pyplot as plt
# 사각파와 푸리에 근사 시각화
N_points = 1000
x = np.linspace(0, 2 * np.pi, N_points, endpoint=False)
f_square = np.where(x < np.pi, 1.0, -1.0)
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
for idx, K in enumerate([1, 3, 10, 50]):
ax = axes[idx // 2][idx % 2]
# 해석적 푸리에 급수 (사각파: 홀수 사인만)
approx = np.zeros_like(x)
for k in range(1, K + 1):
if k % 2 == 1: # 홀수만
approx += (4 / (np.pi * k)) * np.sin(k * x)
ax.plot(x, f_square, 'k--', alpha=0.5, label='사각파')
ax.plot(x, approx, 'b-', linewidth=1.5, label=f'{K}항 근사')
ax.set_title(f'K = {K}', fontsize=12)
ax.set_xlim(0, 2 * np.pi)
ax.set_ylim(-1.5, 1.5)
ax.legend()
ax.grid(True, alpha=0.3)
plt.suptitle('사각파의 푸리에 급수 근사 (깁스 현상 관찰)', fontsize=14)
plt.tight_layout()
plt.savefig('fourier_gibbs.png', dpi=150)
plt.show()# Parseval 정리: 에너지 수렴 시각화
K_max = 100
K_values = range(1, K_max + 1)
cumulative_energy = []
running = 0
for k in K_values:
if k % 2 == 1:
running += np.pi * (4 / (np.pi * k))**2
cumulative_energy.append(running)
total_energy = 2 * np.pi # ||f||^2
plt.figure(figsize=(8, 5))
plt.plot(K_values, cumulative_energy, 'b-', linewidth=2, label='주파수 영역 누적 에너지')
plt.axhline(y=total_energy, color='r', linestyle='--', label=f'시간 영역 에너지 = 2pi = {total_energy:.2f}')
plt.xlabel('주파수 성분 수 K')
plt.ylabel('에너지')
plt.title('Parseval 정리: 에너지 보존')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('parseval_convergence.png', dpi=150)
plt.show()9.3 Step 3: FFT를 이용한 실무 코드
import numpy as np
# 실무에서는 적분 대신 FFT(Fast Fourier Transform)를 사용한다.
# FFT는 이산 푸리에 변환(DFT)을 O(N log N)으로 계산하는 알고리즘이다.
N = 1024
x = np.linspace(0, 2 * np.pi, N, endpoint=False)
f = np.where(x < np.pi, 1.0, -1.0)
# FFT 계산
F = np.fft.rfft(f) # 실수 입력 -> 양의 주파수만
# FFT 결과에서 푸리에 계수 추출
a0_fft = F[0].real / N
a_k_fft = 2 * F[1:].real / N
b_k_fft = -2 * F[1:].imag / N
print("FFT로 구한 사인 계수 (처음 10개):")
for k in range(10):
print(f" b_{k+1} = {b_k_fft[k]:.6f}", end="")
theoretical = 4 / (np.pi * (k + 1)) if (k + 1) % 2 == 1 else 0
print(f" (이론값: {theoretical:.6f})")
# Parseval 정리: FFT 버전
energy_time = np.sum(f**2) / N
energy_freq = np.sum(np.abs(F)**2) / N**2 # 정규화
print(f"\nParseval (FFT): 시간={energy_time:.4f}, 주파수={energy_freq:.4f}")10 요약: 푸리에 급수가 말하는 것
| 핵심 아이디어 | 유한차원 대응물 | 무한차원 표현 |
|---|---|---|
| 직교 기저 | \(Q^\top Q = I\) | \(\int \sin jx \cos kx \, dx = 0\) |
| 좌표 = 내적 | \(c_k = \mathbf{v}_k^\top \mathbf{b} / \mathbf{v}_k^\top \mathbf{v}_k\) | \(a_k = \frac{1}{\pi}\int f(x)\cos kx \, dx\) |
| 길이 보존 | \(\|\mathbf{b}\|^2 = \sum c_k^2 \|\mathbf{v}_k\|^2\) | \(\|f\|^2 = 2\pi a_0^2 + \pi\sum(a_k^2 + b_k^2)\) |
| 분해의 유일성 | 기저가 공간을 span | 함수 공간 \(L^2\) 의 완비 기저 |
푸리에 급수의 모든 공식은 Ch.4의 직교성과 정사영에서 나온다. 바뀐 것은 합이 적분이 된 것뿐이다. 함수해석학(functional analysis)의 출발점이 바로 이 관찰이다 — 선형대수의 유한차원 정리들이 적절한 조건(완비성, 가분성) 아래서 무한차원에서도 살아남는다는 것.
11 관련 주제
선행 지식
- Ch.4 §4.2 — Projections (투영) — 직교 정사영 공식의 유한차원 버전
- Ch.4 §4.4 — Orthogonal Bases and Gram-Schmidt — 정규직교 기저와 좌표 계산
- Ch.6 §6.4 — 대칭 행렬과 스펙트럼 정리 — 고유벡터의 직교성
후속 주제
- Ch.8 Applications 종합 개요 — 푸리에를 포함한 7가지 응용의 조감도
- 이산 푸리에 변환과 FFT — 연속에서 이산으로, 그리고 \(O(N\log N)\) 알고리즘
- Wavelet 변환 — 시간-주파수 동시 해상도
다른 카테고리 연결
- 시계열 분석 기초 — 주파수 영역 분석의 통계적 응용
- Transformer 위치 인코딩 — sin/cos 기저의 딥러닝 응용