/****************************/
/* ニュートン法 */
/* (exp(x)-3.0*x=0の根) */
/* coded by Y.Suganuma */
/****************************/
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException
{
double eps1, eps2, x, x0;
int max, ind[] = new int [1];
eps1 = 1.0e-7;
eps2 = 1.0e-10;
max = 30;
x0 = 0.0;
// 関数値を計算するクラス
Kansu kn = new Kansu();
// ニュートン法の実行
x = kn.newton(x0, eps1, eps2, max, ind);
// 出力
System.out.println("ind=" + ind[0] + " x=" + x + " f=" + kn.snx(x) + " df=" + kn.dsnx(x));
}
}
/******************************/
/* 関数値およびその微分の計算 */
/******************************/
class Kansu extends Newton
{
// 関数値(f(x))の計算
double snx(double x)
{
double y = Math.exp(x) - 3.0 * x;
return y;
}
// 関数の微分の計算
double dsnx(double x)
{
double y = Math.exp(x) - 3.0;
return y;
}
}
abstract class Newton
{
/*****************************************************/
/* Newton法による非線形方程式(f(x)=0)の解 */
/* x1 : 初期値 */
/* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */
/* eps2 : 終了条件2(|f(x(k))|<eps2) */
/* max : 最大試行回数 */
/* ind : 実際の試行回数 */
/* (負の時は解を得ることができなかった) */
/* return : 解 */
/*****************************************************/
abstract double snx(double x);
abstract double dsnx(double x);
double newton(double x1, double eps1, double eps2, int max, int ind[])
{
double g, dg, x;
int sw;
x = x1;
ind[0] = 0;
sw = 0;
while (sw == 0 && ind[0] >= 0) {
ind[0]++;
sw = 1;
g = snx(x1);
if (Math.abs(g) > eps2) {
if (ind[0] <= max) {
dg = dsnx(x1);
if (Math.abs(dg) > eps2) {
x = x1 - g / dg;
if (Math.abs(x-x1) > eps1 && Math.abs(x-x1) > eps1*Math.abs(x)) {
x1 = x;
sw = 0;
}
}
else
ind[0] = -1;
}
else
ind[0] = -1;
}
}
return x;
}
}