/****************************/ /* ニュートン法 */ /* (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; } }