フーリエ級数展開の定義と係数の計算を解説

フーリエ級数は、周期関数を三角関数($\sin$ と $\cos$)の無限和で表す手法です。1807年にジョセフ・フーリエが熱伝導方程式の研究で提案したこの手法は、信号処理、音響学、画像処理、偏微分方程式の解法など、工学と物理学の広範な分野で応用されています。

「任意の周期関数がsin波とcos波の重ね合わせで表せる」というフーリエの発見は、数学史上最も重要なアイデアの1つです。

本記事の内容

  • 三角関数系の直交性
  • フーリエ級数の定義とフーリエ係数の導出
  • 具体的な関数のフーリエ展開
  • Pythonでの実装と可視化

前提知識

この記事を読む前に、以下の概念を理解しておくと理解が深まります。

  • 三角関数の基本的な性質
  • 積分の基本(定積分)

三角関数系の直交性

フーリエ級数の理論的基盤は、三角関数系の直交性です。

関数の内積を次のように定義します。区間 $[-\pi, \pi]$ 上の2つの関数 $f(x)$ と $g(x)$ の内積は、

$$ \langle f, g \rangle = \int_{-\pi}^{\pi} f(x) g(x) \, dx $$

です。

この内積に関して、三角関数系 $\{1, \cos x, \sin x, \cos 2x, \sin 2x, \dots\}$ は直交系をなします。具体的には、

$$ \int_{-\pi}^{\pi} \cos mx \cos nx \, dx = \begin{cases} 0 & (m \neq n) \\ \pi & (m = n \neq 0) \\ 2\pi & (m = n = 0) \end{cases} $$

$$ \int_{-\pi}^{\pi} \sin mx \sin nx \, dx = \begin{cases} 0 & (m \neq n) \\ \pi & (m = n \neq 0) \end{cases} $$

$$ \int_{-\pi}^{\pi} \cos mx \sin nx \, dx = 0 \quad (\forall m, n) $$

直交性の導出

$\cos mx \cos nx$ の直交性は、積和公式を使って示せます。

$$ \cos mx \cos nx = \frac{1}{2}[\cos(m-n)x + \cos(m+n)x] $$

$m \neq n$ のとき、

$$ \begin{align} \int_{-\pi}^{\pi} \cos mx \cos nx \, dx &= \frac{1}{2}\left[\frac{\sin(m-n)x}{m-n} + \frac{\sin(m+n)x}{m+n}\right]_{-\pi}^{\pi} \\ &= 0 \end{align} $$

$\sin$ の周期性から各項が0になります。

フーリエ級数の定義

定義

周期 $2\pi$ の関数 $f(x)$ のフーリエ級数は、

$$ f(x) = \frac{a_0}{2} + \sum_{n=1}^{\infty} \left( a_n \cos nx + b_n \sin nx \right) $$

です。ここで $a_0, a_n, b_n$ をフーリエ係数と呼びます。

フーリエ係数の導出

フーリエ係数は、三角関数の直交性を利用して求めます。

$a_0$ の導出: フーリエ級数の両辺を $[-\pi, \pi]$ で積分します。

$$ \int_{-\pi}^{\pi} f(x) \, dx = \int_{-\pi}^{\pi} \frac{a_0}{2} \, dx + \sum_{n=1}^{\infty} \left( a_n \underbrace{\int_{-\pi}^{\pi} \cos nx \, dx}_{= 0} + b_n \underbrace{\int_{-\pi}^{\pi} \sin nx \, dx}_{= 0} \right) $$

$$ \int_{-\pi}^{\pi} f(x) \, dx = \pi a_0 $$

$$ \boxed{a_0 = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \, dx} $$

$a_n$ の導出: 両辺に $\cos mx$ をかけて積分します。

$$ \int_{-\pi}^{\pi} f(x) \cos mx \, dx = \frac{a_0}{2} \underbrace{\int_{-\pi}^{\pi} \cos mx \, dx}_{= 0} + \sum_{n=1}^{\infty} a_n \underbrace{\int_{-\pi}^{\pi} \cos nx \cos mx \, dx}_{= \pi \delta_{mn}} + \cdots $$

直交性より $n = m$ の項だけが残り、

$$ \boxed{a_n = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \cos nx \, dx} $$

$b_n$ の導出: 同様に $\sin mx$ をかけて、

$$ \boxed{b_n = \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \sin nx \, dx} $$

一般の周期 $2L$ の場合

周期 $2L$ の関数に対しては、変数変換 $t = \pi x / L$ を行うと、

$$ a_n = \frac{1}{L} \int_{-L}^{L} f(x) \cos \frac{n\pi x}{L} \, dx, \quad b_n = \frac{1}{L} \int_{-L}^{L} f(x) \sin \frac{n\pi x}{L} \, dx $$

具体例1: 方形波のフーリエ展開

方形波 $f(x) = \begin{cases} 1 & (0 < x < \pi) \\ -1 & (-\pi < x < 0) \end{cases}$ のフーリエ級数を求めます。

$f(x)$ は奇関数なので $a_n = 0$ です($\forall n \geq 0$)。

$b_n$ を計算します。

$$ \begin{align} b_n &= \frac{1}{\pi} \int_{-\pi}^{\pi} f(x) \sin nx \, dx \\ &= \frac{2}{\pi} \int_{0}^{\pi} \sin nx \, dx \quad (\text{奇関数} \times \text{奇関数} = \text{偶関数}) \\ &= \frac{2}{\pi} \left[-\frac{\cos nx}{n}\right]_0^{\pi} \\ &= \frac{2}{n\pi}(1 – \cos n\pi) \\ &= \frac{2}{n\pi}(1 – (-1)^n) \end{align} $$

$n$ が偶数のとき $b_n = 0$、$n$ が奇数のとき $b_n = \frac{4}{n\pi}$ なので、

$$ f(x) = \frac{4}{\pi} \sum_{k=0}^{\infty} \frac{\sin(2k+1)x}{2k+1} = \frac{4}{\pi}\left(\sin x + \frac{\sin 3x}{3} + \frac{\sin 5x}{5} + \cdots\right) $$

具体例2: のこぎり波のフーリエ展開

$f(x) = x$($-\pi < x < \pi$)のフーリエ級数を求めます。

$f(x) = x$ は奇関数なので $a_n = 0$ です。

$$ \begin{align} b_n &= \frac{1}{\pi} \int_{-\pi}^{\pi} x \sin nx \, dx = \frac{2}{\pi} \int_0^{\pi} x \sin nx \, dx \end{align} $$

部分積分を適用すると、

$$ \begin{align} \int_0^{\pi} x \sin nx \, dx &= \left[-\frac{x \cos nx}{n}\right]_0^{\pi} + \frac{1}{n}\int_0^{\pi} \cos nx \, dx \\ &= -\frac{\pi \cos n\pi}{n} + 0 \\ &= \frac{(-1)^{n+1} \pi}{n} \end{align} $$

$$ b_n = \frac{2}{\pi} \cdot \frac{(-1)^{n+1} \pi}{n} = \frac{2(-1)^{n+1}}{n} $$

$$ f(x) = 2\sum_{n=1}^{\infty} \frac{(-1)^{n+1}}{n} \sin nx = 2\left(\sin x – \frac{\sin 2x}{2} + \frac{\sin 3x}{3} – \cdots\right) $$

Pythonでの実装と可視化

方形波のフーリエ級数近似

import numpy as np
import matplotlib.pyplot as plt

def square_wave(x):
    """方形波"""
    return np.sign(np.sin(x))

def fourier_square_wave(x, N):
    """方形波のフーリエ級数近似(N項まで)"""
    result = np.zeros_like(x)
    for k in range(N):
        n = 2 * k + 1  # 奇数項のみ
        result += (4 / (n * np.pi)) * np.sin(n * x)
    return result

x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)

fig, axes = plt.subplots(2, 2, figsize=(12, 8))
terms_list = [1, 3, 10, 50]

for ax, N in zip(axes.flatten(), terms_list):
    ax.plot(x, square_wave(x), 'k-', linewidth=1, alpha=0.3, label='Square wave')
    ax.plot(x, fourier_square_wave(x, N), 'b-', linewidth=2, label=f'$N = {N}$ terms')
    ax.set_xlabel('$x$')
    ax.set_ylabel('$f(x)$')
    ax.set_title(f'Fourier series approximation ($N = {N}$)')
    ax.legend()
    ax.grid(True, alpha=0.3)
    ax.set_ylim(-1.5, 1.5)

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

項数を増やすにつれて、フーリエ級数が方形波に近づいていく様子が確認できます。ただし、不連続点の近傍で約9%のオーバーシュートが残ります。これはギブズ現象と呼ばれ、フーリエ級数の本質的な性質です。

のこぎり波のフーリエ級数近似

import numpy as np
import matplotlib.pyplot as plt

def sawtooth_wave(x):
    """のこぎり波(周期2πで-πからπの範囲でy=x)"""
    return (x + np.pi) % (2 * np.pi) - np.pi

def fourier_sawtooth(x, N):
    """のこぎり波のフーリエ級数近似"""
    result = np.zeros_like(x)
    for n in range(1, N + 1):
        result += 2 * (-1)**(n + 1) / n * np.sin(n * x)
    return result

x = np.linspace(-2 * np.pi, 2 * np.pi, 1000)

fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, sawtooth_wave(x), 'k-', linewidth=1, alpha=0.3, label='Sawtooth wave')

for N, color in zip([1, 3, 10, 50], ['red', 'orange', 'green', 'blue']):
    ax.plot(x, fourier_sawtooth(x, N), color=color, linewidth=1.5,
            label=f'$N = {N}$', alpha=0.8)

ax.set_xlabel('$x$')
ax.set_ylabel('$f(x)$')
ax.set_title('Fourier series of sawtooth wave')
ax.legend()
ax.grid(True, alpha=0.3)

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

フーリエ係数のスペクトル

import numpy as np
import matplotlib.pyplot as plt

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

# 方形波のフーリエ係数
ax = axes[0]
N = 20
n_values = np.arange(1, N + 1)
b_n_square = np.array([4 / (n * np.pi) if n % 2 == 1 else 0 for n in n_values])
ax.stem(n_values, b_n_square, basefmt='k-', linefmt='b-', markerfmt='bo')
ax.set_xlabel('$n$')
ax.set_ylabel('$b_n$')
ax.set_title('Fourier coefficients of square wave')
ax.grid(True, alpha=0.3)

# のこぎり波のフーリエ係数
ax = axes[1]
b_n_sawtooth = np.array([2 * (-1)**(n + 1) / n for n in n_values])
ax.stem(n_values, b_n_sawtooth, basefmt='k-', linefmt='r-', markerfmt='ro')
ax.set_xlabel('$n$')
ax.set_ylabel('$b_n$')
ax.set_title('Fourier coefficients of sawtooth wave')
ax.grid(True, alpha=0.3)

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

まとめ

本記事では、フーリエ級数展開の定義とフーリエ係数の計算方法を解説しました。

  • フーリエ級数: 周期関数を $\sin$ と $\cos$ の無限和で表す
  • 三角関数の直交性: フーリエ係数の導出の理論的基盤
  • フーリエ係数: $a_n = \frac{1}{\pi}\int f(x)\cos nx \, dx$, $b_n = \frac{1}{\pi}\int f(x)\sin nx \, dx$
  • ギブズ現象: 不連続点でのオーバーシュートはフーリエ級数の本質的な性質

次のステップとして、フーリエ変換について学びましょう。フーリエ級数が周期関数を扱うのに対し、フーリエ変換は非周期関数も扱えるように拡張したものです。