数値計算の結果をプロットする(2)
のこぎり波は次のような形状をしています。

この周期波形のフーリエ級数を求めると,

となります。なお,

であり,f0を基本周波数と呼びます。 ここで,tが変数で,A, f0が定数になります。 また,計算を有限時間で終了させるために,第n次高調波(第n項のsinの値)まで求めることにし, nを定数として宣言しておくことにします。
ここでは A = 1, f0 = 1[kHz], -2[ms] <= t <= 2[ms], dt = 0.01[ms] としてプログラムを書いてみましょう。
以下がそのプログラムです。
/* Numeral Computing with gnuplot: 2 */
#include <stdio.h>
#include <math.h>
#define N        10     /* 第N高調波までを計算 */
#define A        1.0    /* 振幅 */
#define F        1e3    /* 基本周波数 f0 [Hz] */
#define T_DIV    100e3  /* サンプリング周波数(1秒間当たりのtの分割数) [Hz] */
#define T_START  -2e-3  /* tの最小値 [s] */
#define T_END    2e-3   /* tの最大値 [s] */
int main(void);
int main(void) {
  int i;            /* ステップ数 */
  int j;            /* 高調波を求めるループの制御変数 */
  double t;         /* ステップiにおける時刻t */
  double y;         /* f(t) */
  int sign;         /* 各項の符号 */
  double k, omega;  /* 計算量を減らすために,定数項をあらかじめ計算しておく */
  double pi;        /* π (= 3.14...) */
  pi = 4 * atan(1.0);
  k = 2 * A / pi;
  omega = 2 * pi * F;
  for (i=T_START*T_DIV; i<=T_END*T_DIV; i++) {
    t = (double)i / T_DIV;
    y = 0;
    sign = 1;
    for (j=1; j<=N; j++) {
      y += sign * sin(j * omega * t) / j;
      sign *= -1;  /* 符号を反転 */
    }
    y = k * y;
    printf("%f %f\n", t, y);
  }
  return 0;
}
このCソースコードをコンパイルして,実行結果をnc2.pltに出力します。 なお,math.hをインクルードしているのでコンパイル時には-lmオプションをつける必要があります。
% gcc -o nc2 nc2.c -lm % ./nc2 > nc2.plt
そしてgnuplotでプロットします。
# 結果 gnuplot> plot 'nc2.plt' w l
Nの値を変更して,実行結果のグラフがどう変化するかを調べてみてください。
$Id: numeric_computing2.shtml 1289 2007-02-04 13:22:39Z SYSTEM $