mk-mode BLOG

このブログは自作の自宅サーバに構築した Debian GNU/Linux で運用しています。
PC・サーバ構築等の話題を中心に公開しております。(クローンサイト: GitHub Pages

ブログ開設日2009-01-05
サーバ連続稼働時間
Reading...
Page View 合計
Reading...
今日
Reading...
昨日
Reading...

Ruby - フーリエ級数展開!

[ プログラミング, 数学 ] [ Ruby ]

こんばんは。

前回は、「フーリエ級数展開」を C++ で実装してみました。

今回は、同じことを Ruby で実装してみました。実際、ほとんど同じです。「フーリエ級数展開」についての詳細は上記の前回記事を参照ください。

0. 前提条件

  • Linux Mint 14 Nadia (64bit) での作業を想定。
  • Ruby 2.0.0-p0 を使用。

1. Ruby スクリプト作成

例として、以下のようにスクリプトを作成した。

fourier_series_expansion.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#*********************************************
# フーリエ級数展開
#   f(t) = -1 (-pi < t <= 0 )
#           1 (  0 < t <= pi)
#*********************************************
#
N = 3  # 計算項数

# 計算クラス
class FourierSeriesExpansion
  # フーリエ級数展開
  def expand_fourier_series
    # 出力ファイルOPEN
    out_file = open("FourierSeriesExpansion.csv", "w")

    # ヘッダ出力
    out_file.puts "t,f(t)"

    # 1 / 1000 刻みで計算
    y = 0
    ((Math::PI * -1 * 1000).truncate).upto(Math::PI * 1000) do |t|
      1.upto(N) {|i| y += calc_term(i, t / 1000.0)}
      out_file.printf("%.3f,%.6f\n", t / 1000.0, 4 / Math::PI * y)
      y = 0
    end

    # 出力ファイルCLOSE
    out_file.close
  end
end

# 各項計算
def calc_term(n, t)
  return Math::sin((2 * n - 1) * t) / (2 * n - 1)
end

# メイン処理
begin
  # 計算クラスインスタンス化
  obj_calc = FourierSeriesExpansion.new

  # フーリエ級数展開
  obj_calc.expand_fourier_series
rescue => e
  # エラーメッセージ
  puts "[例外発生] #{e}"
end

2. 実行

実際に実行して検証してみる。

1
$ ruby fourier_series_expansion.rb

コンソールには特に何も表示しない。
アプリと同じディレクトリに FourierSeriesExpansion.csv という CSV ファイルが作成される。
内容は以下のようになっているはず。

FourierSeriesExpansion.csv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
t,f(t)
-3.141,-0.002264
-3.140,-0.006083
-3.139,-0.009903
-3.138,-0.013723
-3.137,-0.017542
-3.136,-0.021361
-3.135,-0.025180
-3.134,-0.028999
-3.133,-0.032817
-3.132,-0.036635
-3.131,-0.040452
-3.130,-0.044269
-3.129,-0.048086
-3.128,-0.051901
-3.127,-0.055717
-3.126,-0.059531
-3.125,-0.063345
-3.124,-0.067159
-3.123,-0.070971
         :
====< 途中省略 >====
         :
3.122,0.074783
3.123,0.070971
3.124,0.067159
3.125,0.063345
3.126,0.059531
3.127,0.055717
3.128,0.051901
3.129,0.048086
3.130,0.044269
3.131,0.040452
3.132,0.036635
3.133,0.032817
3.134,0.028999
3.135,0.025180
3.136,0.021361
3.137,0.017542
3.138,0.013723
3.139,0.009903
3.140,0.006083
3.141,0.002264

3. グラフ化

数字だけを眺めてもよく分からないので、R でグラフ化(プロット)してみた。

【元の関数グラフ】

r_fourier_series_0

以下、計算項数を 1, 2, 3, 5, 10, 20, 50, 100, 200, 500, 1000, 10000, 100000 個として計算した結果をグラフ化したもの。

r_fourier_series_1 r_fourier_series_2 r_fourier_series_3 r_fourier_series_5 r_fourier_series_10 r_fourier_series_20 r_fourier_series_50 r_fourier_series_100 r_fourier_series_200 r_fourier_series_500 r_fourier_series_1000 r_fourier_series_10000 r_fourier_series_100000

項数を増やすにつれて元の関数のグラフに近付いていくのがよく分かる。


電気工学、音響学、振動、光学等でよく使用する重要な概念です。応用範囲は広いので他にも利用できるかと思います。

以上。

Comments