Ruby - テイラー展開 [ exp(x) ]!
Updated:
先日は、\(e ^ x\) をテイラー展開で計算する C++ によるアルゴリズムを紹介しました。
今日は、同じアルゴリズムを Ruby で実現してみました。
アルゴリズムについては、上記リンクの記事を参照してください。
実際、ほとんど同じです。
以下、Ruby によるサンプルスクリプトです。
0. 前提条件
- Scientific Linux 6.3 (64bit) での作業を想定。
- Ruby 1.9.3-p194
1. Ruby スクリプト作成
今回作成した Ruby ソースは以下のとおり。
- 収束しない場合は最大200項計算するようにしている。
- 今回計算した値と比較するため、Ruby 標準の関数の値も出力している。
- \(x=-50,\cdots,50\)を10刻みで計算している。
- x < 0 の場合は、\(e ^ {-x}=1/e ^ x\)として計算。
File: taylor_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
#! /usr/local/bin/ruby
#*********************************************
# テイラー展開 [ exp(x) ]
#*********************************************
class TaylorExpansion
# 各種定数
EPS = 1e-08 # 精度
# テイラー展開
def calc_taylor
# x = -50 から 50 を 10 刻みで計算
puts " x myexp(x) exp(x)"
-50.step(50, 10) do |x|
printf("%5.1f%14.6g%14g\n", x, calc_exp(x), Math.exp(x))
end
end
# Exp 計算
def calc_exp(x)
# 変数初期化
d = s = e = 1.0
# 最大200回ループ処理
1.upto(200) do |k|
d = s # d 和
e = e * x.abs / k # e 値
s += e # s 和
# 打ち切り誤差
return x > 0 ? s : 1.0 / s if (s - d).abs / d.abs < EPS
end
# 収束しない時
return 0.0
end
end
if __FILE__ == $0
begin
# 計算クラスインスタンス化
obj = TaylorExpansion.new
# テイラー展開
obj.calc_taylor
rescue => e
$stderr.puts "[例外発生] #{e}"
end
end
2. 実行
まず、実行権限を付与。
$ chmod +x taylor_expansion.rb
そして、実行。
$ ./taylor_expansion.rb
x myexp(x) exp(x)
-50.0 1.92875e-22 1.92875e-22
-40.0 4.24835e-18 4.24835e-18
-30.0 9.35762e-14 9.35762e-14
-20.0 2.06115e-09 2.06115e-09
-10.0 4.53999e-05 4.53999e-05
0.0 1 1
10.0 22026.5 22026.5
20.0 4.85165e+08 4.85165e+08
30.0 1.06865e+13 1.06865e+13
40.0 2.35385e+17 2.35385e+17
50.0 5.18471e+21 5.18471e+21
C++ 版と同じ結果が得られました。
以上。
Comments