############################################ # ニュートン法 # (exp(x)-3.0*x=0の根) # coded by Y.Suganuma ############################################ ############################################ # Newton法による非線形方程式(f(x)=0)の解 # x0 : 初期値 # eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) # eps2 : 終了条件2(|f(x(k))|<eps2) # max : 最大試行回数 # ind : 実際の試行回数 # (負の時は解を得ることができなかった) # fn : f(x)とその微分を計算する関数名 # return : 解 # coded by Y.Suganuma ############################################ def newton(x0, eps1, eps2, max, ind, &fn) x1 = x0 x = x1 ind[0] = 0 sw = 0 while sw == 0 and ind[0] >= 0 sw = 1 ind[0] += 1 g = fn.call(0, x1) if g.abs() > eps2 if ind[0] <= max dg = fn.call(1, x1) if dg.abs() > eps2 x = x1 - g / dg if (x-x1).abs() > eps1 && (x-x1).abs() > eps1*x.abs() x1 = x sw = 0 end else ind[0] = -1 end else ind[0] = -1 end end end return x end ################################# # 関数値(f(x))とその微分の計算 ################################# snx = Proc.new { |sw, x| if sw == 0 Math.exp(x) - 3.0 * x else Math.exp(x) - 3.0 end } # データの設定 ind = [0] eps1 = 1.0e-7 eps2 = 1.0e-10 max = 20 x0 = 0.0 # 実行と結果 x = newton(x0, eps1, eps2, max, ind, &snx) print("ind=", ind[0], " x=", x, " f=", snx.call(0,x), " df=", snx.call(1,x), "\n")