フーリエ級数1

周期関数を三角関数の足し合わせで表すものを,フーリエ級数 (級数とは数列の和.単に級数といった場合,無限級数を表すことが多い.フーリエ級数も無限級数)といいます. 三角関数とは \cos 関数や \sin 関数のことです. これらは周期 2\pi の周期関数で,下図のような形をしています.

fig1 sin関数

fig2 cos関数

これは高校の数学で習いますね.

フーリエ級数でできること

この一見単純な関数を足し合わせる(重ね合わせる)ことで,周期関数であればどんな形の関数でも表せる, というのがフーリエ級数です.本当でしょうか.

足し合わせてみる

フーリエ級数をちょっと試してみましょう.つくりたい周期関数は

fig3

というものです.周期は 2\pi です.これは式で表すと

f(x) = \begin{cases}-1 & (-\pi<x<0)\\ 1 & (0<x<\pi) \end{cases}, \qquad f(x+2\pi) = f(x)

となります.この式と周期を元にどういうふうに三角関数を足せばいいか (すなわちフーリエ級数)がわかるのですが,その計算はまた後ほど.とりあえずフーリエ級数は

f(x) &= \frac{4}{\pi}\left(\sin x + \frac{1}{3}\sin 3x + \frac{1}{5}\sin 5x + \frac{1}{7}\sin 7x + \cdots \right)\\     & = \frac{4}{\pi}\sum_{n=1}^{\infty}\frac{\sin\{(2n-1)x\}}{2n-1}

であると分かったものとします.これをグラフにしていきましょう.

fig4 n=1

fig5 n=2

fig6 n=3

ここで n とは,足し合わせる三角関数の数です. うーん,近づいてはいますがまだまだ足さないといけないようです. gnuplotで直接グラフを書くのはしんどいので,つぎのCプログラムを使います.

#include <stdio.h>
#include <math.h>

#define N 10  /* この値を変更 */

double term(int n, double x){
  return sin((2*n-1)*x)/(2*n-1);
}

int main(void){
  int i;
  double x, y=0;
  FILE *fp;
  fp = fopen("fourier.dat", "w");

  for (x=-M_PI; x<M_PI; x+=0.001) {
    for (i=1; i<=N; i++) {
      y += term(i,x);
    }
    fprintf(fp, "%lf %lf\n", x, 4/M_PI*y);
    y=0;
  } 

  fclose(fp);
  return 0;
}

いま問題にしている関数のフーリエ級数を数値計算し,できたデータをプロットします. n の値(プログラム中では定数 N )を変えながら,いくつか計算してみました.

fig7 n=10

fig8 n=20

fig9 n=50

fig10 n=100

だいぶそれらしくなってきました.もっと足します.

fig11 n=200

fig12 n=500

fig13 n=1000

x = -\pi, 0, \pi の部分でうまく収束しません.これはギブスの現象と呼ばれます. 最後に,十万番目の項まで足したものを.

fig14 n=100000

ほぼ完璧に見えますが,実際にはやはり x = -\pi, 0, \pi の部分がうまく収束していないハズです. 一般に有限個のフーリエ級数の和では完璧に周期関数を再現することはできません. しかしたくさん足し合わせれば,完璧に近くなります. (ちなみにこの計算には Pentium III 750MHz で2分くらいかかりました). というわけで,周期関数は三角関数の足し合わせで再現できそうだということが分かりました.