Ruby - テイラー展開 [ cos(x) ]!

Updated:


先日は、\(\cos x\) をテイラー展開で計算する C++ によるアルゴリズムを紹介しました。

今日は、同じアルゴリズムを Ruby で実現してみました。
アルゴリズムについては、上記リンクの記事を参照してください。

実際、ほとんど同じです。

以下、Ruby によるサンプルスクリプトです。

0. 前提条件

  • Scientific Linux 6.3 (64bit) での作業を想定。
  • Ruby 1.9.3-p194

1. Ruby スクリプト作成

今回作成した Ruby ソースは以下のとおり。

  • 収束しない場合は最大200項計算するようにしている。
  • 今回計算した値と比較するため、Ruby 標準の関数の値も出力している。
  • \(x=0,\cdots,180\)を10刻みで計算している。

File: taylor_expansion_cos.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
48
49
50
#! /usr/local/bin/ruby
#*********************************************
# テイラー展開 [ cos(x) ]
#*********************************************
class TaylorExpansionCos
  # 各種定数
  EPS = 1e-08         # 精度
  PI  = 3.1415926535  # 円周率

  # テイラー展開
  def calc_taylor
    # ラジアン値計算
    rd = PI / 180
    # x = 0 から 180 を 10 刻みで計算
    puts "    x      mycos(x)        cos(x)"
    0.step(180, 10) do |x|
      printf("%5.1f%14.6f%14.6f\n", x, calc_cos(x * rd), Math.cos(x * rd))
    end
  end

  # Cos 計算
  def calc_cos(x)
    # 変数初期化
    d = s = e = 1.0
    # x の値が 0 から 2π の範囲外の場合、0 から 2π に収める
    x = x % (2 * PI)
    # 最大200回ループ処理
    # ( ただし、偶数項は 0 なので除外 )
    1.step(200, 2) do |k|
      d = s                        # d 和
      e *= -x * x / (k * (k + 1))  # 各項の値
      s += e                       # s 和
      # 打ち切り誤差
      return s if (s - d).abs / d.abs < EPS
    end
    # 収束しない時
    return 9999.0
  end
end

if __FILE__ == $0
  begin
    # 計算クラスインスタンス化
    obj = TaylorExpansionCos.new
    # テイラー展開
    obj.calc_taylor
  rescue => e
    $stderr.puts "[例外発生] #{e}"
  end
end

2. 実行

まず、実行権限を付与。

$ chmod +x taylor_expansion_cos.rb

そして、実行。

$ ./taylor_expansion_cos.rb
    x      mycos(x)        cos(x)
  0.0      1.000000      1.000000
 10.0      0.984808      0.984808
 20.0      0.939693      0.939693
 30.0      0.866025      0.866025
 40.0      0.766044      0.766044
 50.0      0.642788      0.642788
 60.0      0.500000      0.500000
 70.0      0.342020      0.342020
 80.0      0.173648      0.173648
 90.0      0.000000      0.000000
100.0     -0.173648     -0.173648
110.0     -0.342020     -0.342020
120.0     -0.500000     -0.500000
130.0     -0.642788     -0.642788
140.0     -0.766044     -0.766044
150.0     -0.866025     -0.866025
160.0     -0.939693     -0.939693
170.0     -0.984808     -0.984808
180.0     -1.000000     -1.000000

C++ 版と同じ結果が得られました。

 \(e ^ x\) や \(\cos x\) に限らず、色々と計算してみるのもよいでしょう。

以上。





 

Sponsored Link

 

Comments