Ruby - 非線形方程式の解法(2分法)!
Updated:
先日は、\(f(x)=0\) の解を2分法により求める C++ によるアルゴリズムを紹介しました。
今日は、同じアルゴリズムを Ruby で実現してみました。
アルゴリズムについては、上記リンクの記事を参照してください。
実際、ほとんど同じです。
以下、Ruby によるサンプルスクリプトです。
0. 前提条件
- Linux Mint 13 Maya (64bit) での作業を想定。
- Ruby 1.9.3-p194
1. Ruby スクリプト作成
今回作成した Ruby ソースは以下のとおり。
- 収束しない場合は最大50回ループするようにしている。
- f(a) < 0, f(b) > 0 となる方程式を想定。
f(a) > 0, f(b) < 0 となる方程式の場合は判定部分を修正する必要がある。
File: nonlinear_equation.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
#! /usr/local/bin/ruby
#*********************************************
# 非線形方程式の解法 ( 2分法 )
#*********************************************
class NonlinearEquation
# 各種定数
EPS = 1e-08 # 打ち切り精度
LIMIT = 50 # 打ち切り回数
def initialize
# 関数定義
@f = lambda { |x| x**3 - x + 1 }
end
# 非線形方程式を解く(2分法)
def calc_nonlinear_equation
# Low, High 初期値設定
low, high = -2.0, 2.0
# 打ち切り回数 or 打ち切り誤差になるまで LOOP
@cnt_loop = 0
1.upto(LIMIT) do |k|
@cnt_loop = k
x = (low + high) / 2
if @f.call(x) > 0
high = x
else
low = x
end
if @f.call(x) == 0 || (high - low).abs / low.abs < EPS
printf("x = %f\n", x)
break
end
end
# 収束しなかった場合
puts "収束しない" if @cnt_loop == LIMIT
end
end
if __FILE__ == $0
begin
# 計算クラスインスタンス化
obj = NonlinearEquation.new
# 非線形方程式を解く(2分法)
obj.calc_nonlinear_equation
rescue => e
$stderr.puts "[例外発生] #{e}"
end
end
2. 実行
まず、実行権限を付与。
$ chmod +x nonlinear_equation.rb
そして、実行。
$ ./nonlinear_equation.rb
x = -1.324718
C++ 版と同じ結果が得られました。
以上。
Comments