フーリエ級数は「あらゆる関数を三角関数の和で表せる」かのように思えますが、実際には収束するための条件があります。ディリクレ条件はフーリエ級数の収束を保証する十分条件です。
本記事の内容
- ディリクレ条件
- 各点収束と一様収束
- 不連続点での収束値
- ギブズ現象
- Pythonでの可視化
前提知識
ディリクレ条件
周期関数 $f(t)$ が以下の条件を満たすとき、フーリエ級数は収束します:
- $f(t)$ は1周期内で区分的に連続
- $f(t)$ は1周期内で有限個の不連続点しか持たない
- $f(t)$ は1周期内で有限個の極値しか持たない(有界変動)
収束先
- 連続点では $f(t)$ そのものに収束
- 不連続点 $t_0$ では左極限と右極限の平均に収束:
$$ \frac{f(t_0^+) + f(t_0^-)}{2} $$
ギブズ現象
不連続点の近傍では、フーリエ級数の部分和にオーバーシュート(行き過ぎ)が生じます。これをギブズ現象と呼びます。
項数 $N$ を増やしてもオーバーシュートの割合は約 9% のまま残ります。ピークの位置は不連続点に近づきますが、振幅比は変わりません。
正確には、ジャンプ量 $d$ に対して最大オーバーシュートは約 $1.0895 \times d/2$ です。
Pythonでの可視化
import numpy as np
import matplotlib.pyplot as plt
T = 2*np.pi; omega = 2*np.pi/T
t = np.linspace(-np.pi, 3*np.pi, 2000)
def square_wave(t):
return np.where(np.sin(t) >= 0, 1.0, -1.0)
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# (1) ギブズ現象:項数による変化
for N in [3, 9, 29, 99]:
f_N = np.zeros_like(t)
for n in range(1, N+1, 2):
f_N += 4/(n*np.pi) * np.sin(n*t)
axes[0].plot(t, f_N, lw=1.2, label=f'N={N}')
axes[0].plot(t, square_wave(t), 'k--', lw=1, alpha=0.4, label='Original')
axes[0].set_xlabel('$t$'); axes[0].set_ylabel('$f(t)$')
axes[0].set_title('Gibbs phenomenon', fontsize=13)
axes[0].legend(fontsize=9); axes[0].grid(True, alpha=0.3)
axes[0].set_xlim(-0.5, 2*np.pi+0.5)
# (2) 不連続点付近の拡大
t_zoom = np.linspace(-0.3, 0.3, 1000)
for N in [9, 29, 99, 299]:
f_N = np.zeros_like(t_zoom)
for n in range(1, N+1, 2):
f_N += 4/(n*np.pi) * np.sin(n*t_zoom)
axes[1].plot(t_zoom, f_N, lw=1.5, label=f'N={N}')
axes[1].axhline(1, color='k', ls='--', alpha=0.3)
axes[1].axhline(0, color='gray', ls='-', alpha=0.3)
axes[1].set_xlabel('$t$'); axes[1].set_ylabel('$f(t)$')
axes[1].set_title('Zoom near discontinuity', fontsize=13)
axes[1].legend(); axes[1].grid(True, alpha=0.3)
# (3) 最大オーバーシュート vs N
N_range = np.arange(3, 200, 2)
max_overshoot = []
for N in N_range:
t_fine = np.linspace(0.001, 0.5, 5000)
f_N = np.zeros_like(t_fine)
for n in range(1, N+1, 2):
f_N += 4/(n*np.pi) * np.sin(n*t_fine)
max_overshoot.append(np.max(f_N))
axes[2].plot(N_range, max_overshoot, 'b-', lw=1.5)
axes[2].axhline(1.0, color='k', ls='--', alpha=0.3, label='Target = 1.0')
axes[2].axhline(1.0895*2/np.pi*2, color='r', ls=':', alpha=0.5, label='~1.089')
axes[2].set_xlabel('Number of terms $N$'); axes[2].set_ylabel('Max value near $t=0$')
axes[2].set_title('Gibbs overshoot convergence', fontsize=13)
axes[2].legend(); axes[2].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
まとめ
- ディリクレ条件: 区分的連続、有限個の不連続点、有界変動
- 連続点: フーリエ級数は $f(t)$ に収束
- 不連続点: $(f(t^+) + f(t^-))/2$ に収束
- ギブズ現象: 不連続点近傍で約9%のオーバーシュートが残る
次のステップとして、以下の記事も参考にしてください。