############################################
# ニュートン法
# (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")