フーリエ係数の計算方法と物理的意味を解説

フーリエ級数展開において、各三角関数成分の振幅を決めるのが フーリエ係数 です。フーリエ係数を正しく計算し、その物理的意味を理解することは、信号のスペクトル解析や周波数フィルタリングの基礎となります。

フーリエ係数は、ある関数が「どの周波数の成分をどれだけ含んでいるか」を定量的に示す量です。音でたとえれば、複雑な音色がどのような純音の組み合わせで構成されているかを示す「レシピ」に相当します。本記事では、フーリエ係数の計算方法を偶関数・奇関数の対称性を利用して効率化し、パーセバルの等式でエネルギー保存の観点を学び、具体的な波形で手を動かして計算します。

本記事の内容

  • フーリエ係数の公式と物理的意味
  • 偶関数・奇関数による計算の簡略化
  • パーセバルの等式(エネルギー保存)
  • 鋸歯波・三角波のフーリエ係数の計算
  • Pythonによるスペクトル表示

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

フーリエ係数とは

フーリエ級数展開において、周期 $2L$ の関数 $f(x)$ は次のように表されます。

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

ここで $a_0, a_n, b_n$ がフーリエ係数であり、それぞれ以下の意味を持ちます。

係数 公式 物理的意味
$a_0 / 2$ $\frac{1}{2L}\int_{-L}^{L} f(x) \, dx$ 関数の 直流成分(平均値)
$a_n$ $\frac{1}{L}\int_{-L}^{L} f(x) \cos\frac{n\pi x}{L} \, dx$ 周波数 $n/(2L)$ の 余弦成分 の振幅
$b_n$ $\frac{1}{L}\int_{-L}^{L} f(x) \sin\frac{n\pi x}{L} \, dx$ 周波数 $n/(2L)$ の 正弦成分 の振幅

$n$ を大きくすると高い周波数の成分を表し、$n = 1$ は 基本周波数(基本波)、$n \geq 2$ は 高調波 と呼ばれます。

数学的定義: 振幅スペクトルと位相スペクトル

$a_n$ と $b_n$ を組み合わせることで、各周波数の 振幅 $c_n$ と 位相 $\phi_n$ を定義できます。

$$ \begin{equation} c_n = \sqrt{a_n^2 + b_n^2} \end{equation} $$

$$ \begin{equation} \phi_n = \arctan\left(-\frac{b_n}{a_n}\right) \end{equation} $$

このとき、フーリエ級数は次のように書き換えられます。

$$ f(x) = \frac{a_0}{2} + \sum_{n=1}^{\infty} c_n \cos\left(\frac{n\pi x}{L} + \phi_n\right) $$

$c_n$ を周波数 $n$ に対してプロットしたものが 振幅スペクトル、$\phi_n$ をプロットしたものが 位相スペクトル です。

偶関数・奇関数による簡略化

関数の対称性を利用すると、フーリエ係数の計算を大幅に簡略化できます。

偶関数の場合

$f(-x) = f(x)$ のとき、$f(x)$ は偶関数です。偶関数と奇関数の積は奇関数であり、対称区間上での奇関数の積分は $0$ になるため、

$$ b_n = 0 \quad (\text{すべての } n) $$

が成り立ちます。つまり、偶関数のフーリエ級数は 余弦級数(cos のみ)になります。

$$ f(x) = \frac{a_0}{2} + \sum_{n=1}^{\infty} a_n \cos\frac{n\pi x}{L} $$

このとき $a_n$ は偶関数の対称性を利用して、

$$ a_n = \frac{2}{L} \int_{0}^{L} f(x) \cos\frac{n\pi x}{L} \, dx $$

と、$[0, L]$ の積分の2倍で計算できます。

奇関数の場合

$f(-x) = -f(x)$ のとき、$f(x)$ は奇関数です。同様の議論により、

$$ a_n = 0 \quad (\text{すべての } n, \; a_0 \text{ を含む}) $$

が成り立ちます。奇関数のフーリエ級数は 正弦級数(sin のみ)になります。

$$ f(x) = \sum_{n=1}^{\infty} b_n \sin\frac{n\pi x}{L} $$

このとき、

$$ b_n = \frac{2}{L} \int_{0}^{L} f(x) \sin\frac{n\pi x}{L} \, dx $$

半波対称性

$f(x + L) = -f(x)$ を満たす関数(半周期ずらすと符号が反転する)では、偶数次の高調波が消えます。

$$ a_{2k} = 0, \quad b_{2k} = 0 \quad (k = 1, 2, 3, \dots) $$

矩形波がこの性質を持ち、奇数次の高調波のみが現れるのはこの半波対称性によるものです。

パーセバルの等式

定理

周期 $2L$ の関数 $f(x)$ に対して、以下の等式が成り立ちます。

$$ \begin{equation} \frac{1}{L} \int_{-L}^{L} |f(x)|^2 \, dx = \frac{a_0^2}{2} + \sum_{n=1}^{\infty} (a_n^2 + b_n^2) \end{equation} $$

物理的意味

左辺は関数の 平均パワー(1周期にわたるエネルギーの平均)を表し、右辺は各周波数成分のパワーの総和を表します。つまり、パーセバルの等式は 時間領域と周波数領域でエネルギーが保存される ことを意味しています。

導出

フーリエ級数の展開式を $|f(x)|^2 = f(x) \cdot f(x)$ に代入します。

$$ \begin{align} \frac{1}{L} \int_{-L}^{L} |f(x)|^2 \, dx &= \frac{1}{L} \int_{-L}^{L} f(x) \left[ \frac{a_0}{2} + \sum_{n=1}^{\infty} \left( a_n \cos\frac{n\pi x}{L} + b_n \sin\frac{n\pi x}{L} \right) \right] dx \\ &= \frac{a_0}{2} \cdot \frac{1}{L} \int_{-L}^{L} f(x) \, dx + \sum_{n=1}^{\infty} a_n \cdot \frac{1}{L} \int_{-L}^{L} f(x) \cos\frac{n\pi x}{L} \, dx \\ &\quad + \sum_{n=1}^{\infty} b_n \cdot \frac{1}{L} \int_{-L}^{L} f(x) \sin\frac{n\pi x}{L} \, dx \end{align} $$

フーリエ係数の定義式を適用すると、

$$ \begin{align} &= \frac{a_0}{2} \cdot a_0 + \sum_{n=1}^{\infty} a_n \cdot a_n + \sum_{n=1}^{\infty} b_n \cdot b_n \\ &= \frac{a_0^2}{2} + \sum_{n=1}^{\infty} (a_n^2 + b_n^2) \end{align} $$

これでパーセバルの等式が証明されました。

パーセバルの等式の応用

パーセバルの等式を利用すると、級数の値を求めることができます。たとえば、矩形波のフーリエ係数は $b_n = 4/(n\pi)$($n$ が奇数)であったことを使うと、

$$ \frac{1}{\pi} \int_{-\pi}^{\pi} 1^2 \, dx = \sum_{k=0}^{\infty} \left(\frac{4}{(2k+1)\pi}\right)^2 $$

$$ 2 = \frac{16}{\pi^2} \sum_{k=0}^{\infty} \frac{1}{(2k+1)^2} $$

$$ \sum_{k=0}^{\infty} \frac{1}{(2k+1)^2} = 1 + \frac{1}{9} + \frac{1}{25} + \cdots = \frac{\pi^2}{8} $$

このように、フーリエ解析を通じて級数の厳密値を求めるというエレガントな応用もあります。

具体例1: 鋸歯波のフーリエ係数

周期 $2\pi$ の鋸歯波を考えます。

$$ f(x) = x \quad (-\pi < x < \pi) $$

この関数は奇関数なので $a_n = 0$ です。$b_n$ を計算します。

$$ \begin{align} b_n &= \frac{1}{\pi} \int_{-\pi}^{\pi} x \sin(nx) \, dx \\ &= \frac{2}{\pi} \int_{0}^{\pi} x \sin(nx) \, dx \quad (\because x\sin(nx) \text{ は偶関数}) \\ &= \frac{2}{\pi} \left[ -\frac{x}{n} \cos(nx) + \frac{1}{n^2} \sin(nx) \right]_{0}^{\pi} \quad (\text{部分積分}) \\ &= \frac{2}{\pi} \left( -\frac{\pi}{n} \cos(n\pi) + 0 \right) \\ &= -\frac{2}{n} \cos(n\pi) \\ &= -\frac{2}{n} (-1)^n = \frac{2(-1)^{n+1}}{n} \end{align} $$

したがって、鋸歯波のフーリエ級数は、

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

矩形波とは異なり、偶数次の高調波も現れます。これは鋸歯波が半波対称性を持たないためです。

具体例2: 三角波のフーリエ係数

周期 $2\pi$ の三角波を考えます。

$$ f(x) = |x| \quad (-\pi < x < \pi) $$

この関数は偶関数なので $b_n = 0$ です。$a_0$ と $a_n$ を計算します。

$$ \begin{align} a_0 &= \frac{1}{\pi} \int_{-\pi}^{\pi} |x| \, dx = \frac{2}{\pi} \int_{0}^{\pi} x \, dx = \frac{2}{\pi} \cdot \frac{\pi^2}{2} = \pi \end{align} $$

$$ \begin{align} a_n &= \frac{2}{\pi} \int_{0}^{\pi} x \cos(nx) \, dx \\ &= \frac{2}{\pi} \left[ \frac{x}{n} \sin(nx) + \frac{1}{n^2} \cos(nx) \right]_{0}^{\pi} \quad (\text{部分積分}) \\ &= \frac{2}{\pi} \left( \frac{\pi}{n} \sin(n\pi) + \frac{1}{n^2} \cos(n\pi) – \frac{1}{n^2} \right) \\ &= \frac{2}{\pi} \cdot \frac{(-1)^n – 1}{n^2} \\ &= \begin{cases} -\dfrac{4}{\pi n^2} & (n \text{ が奇数}) \\ 0 & (n \text{ が偶数}) \end{cases} \end{align} $$

したがって、三角波のフーリエ級数は、

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

三角波は連続関数であるため、係数が $1/n^2$ で減衰します。矩形波($1/n$ 減衰)より速い収束を示し、少ない項数でよい近似が得られます。

Pythonでの実装

鋸歯波と三角波のフーリエ級数近似

import numpy as np
import matplotlib.pyplot as plt

# 鋸歯波のフーリエ級数近似
def fourier_sawtooth(x, N):
    """鋸歯波のフーリエ級数近似(N項まで)"""
    result = np.zeros_like(x, dtype=float)
    for n in range(1, N + 1):
        result += 2 * ((-1) ** (n + 1)) / n * np.sin(n * x)
    return result

# 三角波のフーリエ級数近似
def fourier_triangle(x, N):
    """三角波のフーリエ級数近似(N項まで)"""
    result = np.pi / 2 * np.ones_like(x, dtype=float)
    for k in range(N):
        n = 2 * k + 1  # 奇数次のみ
        result -= (4 / (np.pi * n ** 2)) * np.cos(n * x)
    return result

# 元の波形
def sawtooth_wave(x):
    """周期2piの鋸歯波"""
    return ((x + np.pi) % (2 * np.pi)) - np.pi

def triangle_wave(x):
    """周期2piの三角波"""
    return np.abs(((x + np.pi) % (2 * np.pi)) - np.pi)

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

fig, axes = plt.subplots(2, 3, figsize=(15, 8))
terms_list = [1, 5, 20]

# 鋸歯波
for ax, N in zip(axes[0], terms_list):
    ax.plot(x, sawtooth_wave(x), 'k--', alpha=0.4, label='Sawtooth')
    ax.plot(x, fourier_sawtooth(x, N), 'b-', linewidth=1.5, label=f'N = {N}')
    ax.set_title(f'Sawtooth Wave (N = {N})')
    ax.set_xlim(-2 * np.pi, 2 * np.pi)
    ax.set_ylim(-4, 4)
    ax.legend()
    ax.grid(True, alpha=0.3)

# 三角波
for ax, N in zip(axes[1], terms_list):
    ax.plot(x, triangle_wave(x), 'k--', alpha=0.4, label='Triangle')
    ax.plot(x, fourier_triangle(x, N), 'r-', linewidth=1.5, label=f'N = {N}')
    ax.set_title(f'Triangle Wave (N = {N})')
    ax.set_xlim(-2 * np.pi, 2 * np.pi)
    ax.set_ylim(-0.5, 4)
    ax.legend()
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("sawtooth_triangle_fourier.png", dpi=150, bbox_inches="tight")
plt.show()

三角波は連続関数であるため $N = 5$ 程度でほぼ完全に元の波形と一致しますが、鋸歯波は不連続点を持つため $N = 20$ でもギブズ現象が見られます。

振幅スペクトルの比較

import numpy as np
import matplotlib.pyplot as plt

# 各波形のフーリエ係数を解析的に計算
N = 30

# 矩形波: b_n = 4/(n*pi) (n: 奇数), a_n = 0
square_a = np.zeros(N + 1)
square_b = np.zeros(N + 1)
for n in range(1, N + 1):
    if n % 2 == 1:
        square_b[n] = 4 / (n * np.pi)

# 鋸歯波: b_n = 2*(-1)^(n+1)/n, a_n = 0
saw_a = np.zeros(N + 1)
saw_b = np.zeros(N + 1)
for n in range(1, N + 1):
    saw_b[n] = 2 * ((-1) ** (n + 1)) / n

# 三角波: a_0 = pi, a_n = -4/(pi*n^2) (n: 奇数), b_n = 0
tri_a = np.zeros(N + 1)
tri_b = np.zeros(N + 1)
tri_a[0] = np.pi
for n in range(1, N + 1):
    if n % 2 == 1:
        tri_a[n] = -4 / (np.pi * n ** 2)

# 振幅スペクトル c_n = sqrt(a_n^2 + b_n^2)
square_c = np.sqrt(square_a ** 2 + square_b ** 2)
saw_c = np.sqrt(saw_a ** 2 + saw_b ** 2)
tri_c = np.sqrt(tri_a ** 2 + tri_b ** 2)

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
n_vals = np.arange(N + 1)

axes[0].stem(n_vals[1:], square_c[1:], linefmt='b-', markerfmt='bo', basefmt='k-')
axes[0].set_title('Square Wave Spectrum')
axes[0].set_xlabel('Harmonic number n')
axes[0].set_ylabel('Amplitude $c_n$')
axes[0].grid(True, alpha=0.3)

axes[1].stem(n_vals[1:], saw_c[1:], linefmt='g-', markerfmt='go', basefmt='k-')
axes[1].set_title('Sawtooth Wave Spectrum')
axes[1].set_xlabel('Harmonic number n')
axes[1].set_ylabel('Amplitude $c_n$')
axes[1].grid(True, alpha=0.3)

axes[2].stem(n_vals[1:], tri_c[1:], linefmt='r-', markerfmt='ro', basefmt='k-')
axes[2].set_title('Triangle Wave Spectrum')
axes[2].set_xlabel('Harmonic number n')
axes[2].set_ylabel('Amplitude $c_n$')
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("amplitude_spectrum_comparison.png", dpi=150, bbox_inches="tight")
plt.show()

矩形波と鋸歯波の振幅は $1/n$ で減衰するのに対し、三角波は $1/n^2$ で減衰しています。これは関数の滑らかさと密接に関連しており、一般に $f(x)$ が $k$ 回連続微分可能であれば、フーリエ係数は $O(1/n^{k+1})$ で減衰します。

パーセバルの等式の数値検証

import numpy as np

# 矩形波に対するパーセバルの等式の検証
# 左辺: (1/pi) * int_{-pi}^{pi} |f(x)|^2 dx = 2 (矩形波の場合)
lhs = 2.0

# 右辺: sum of b_n^2 (a_n = 0, a_0 = 0)
N_values = [10, 100, 1000, 10000]
for N in N_values:
    rhs = sum((4 / ((2 * k + 1) * np.pi)) ** 2 for k in range(N))
    print(f"N = {N:>5d}: RHS = {rhs:.10f}, LHS = {lhs:.10f}, Error = {abs(rhs - lhs):.2e}")

# おまけ: pi^2/8の近似値
print(f"\npi^2/8 = {np.pi**2/8:.10f}")
partial_sum = sum(1 / (2 * k + 1) ** 2 for k in range(10000))
print(f"Partial sum (N=10000) = {partial_sum:.10f}")

項数を増やすにつれて右辺が左辺に近づき、パーセバルの等式が数値的にも成り立つことを確認できます。

まとめ

本記事では、フーリエ係数の計算方法と物理的意味について解説しました。

  • フーリエ係数 $a_n, b_n$ は、関数がどの周波数成分をどれだけ含むかを表す量です
  • 振幅スペクトル $c_n = \sqrt{a_n^2 + b_n^2}$ と位相スペクトル $\phi_n$ により、周波数ごとの振幅と位相がわかります
  • 偶関数のフーリエ級数は余弦級数($b_n = 0$)、奇関数のフーリエ級数は正弦級数($a_n = 0$)になります
  • パーセバルの等式は、時間領域と周波数領域でエネルギーが保存されることを意味します
  • 関数の滑らかさがフーリエ係数の減衰速度を決定します(滑らかなほど速く減衰)

次のステップとして、以下の記事も参考にしてください。