Ruby - 非線形方程式の解法(ニュートン法)!

Updated:


先日は、\(f(x)=0\) の解をニュートン法により求める C++ によるアルゴリズムを紹介しました。

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

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

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

0. 前提条件

  • Linux Mint 13 Maya (64bit) での作業を想定。
  • Ruby 1.9.3-p194

1. Ruby スクリプト作成

今回作成した Ruby ソースは以下の通りです。

  • 収束しない場合は最大50回ループするようにしている。

File: nonlinear_equation_newtown.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
#! /usr/local/bin/ruby
#*********************************************
# 非線形方程式の解法 ( ニュートン法 )
#*********************************************
class NonlinearEquationNewton
  # 各種定数
  EPS = 1e-08  # 打ち切り精度
  LIMIT = 50   # 打ち切り回数

  def initialize
    # 関数定義
    @f = lambda { |x| x**3 - x + 1 }
    # f(x) の x における傾き ( f(x) を1回微分 )
    @g = lambda { |x| 3 * x**2 - 1 }
  end

  # 非線形方程式を解く(ニュートン法)
  def calc_nonlinear_equation
    # x 初期値設定
    x = -2.0
    # 打ち切り回数 or 打ち切り誤差になるまで LOOP
    cnt_loop = 0
    1.upto(LIMIT) do |k|
      cnt_loop = k
      dx = x
      x -= @f.call(x) / @g.call(x)
      if (x - dx).abs / dx.abs < EPS
        printf("x = %f\n", x)
        break
      end
    end
    # 収束しなかった場合
    puts "収束しない" if cnt_loop == LIMIT
  end
end

if __FILE__ == $0
  begin
    # 計算クラスインスタンス化
    obj = NonlinearEquationNewton.new
    # 非線形方程式を解く(ニュートン法)
    obj.calc_nonlinear_equation
  rescue => e
    $stderr.puts "[例外発生] #{e}"
  end
end

2. 実行

まず、実行権限を付与。

$ chmod +x nonlinear_equation_newtown.rb

そして、実行。

$ ./nonlinear_equation_newtown.rb
x=-1.324718

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

以上。





 

Sponsored Link

 

Comments