/********************************/ /* ニュートン法 */ /* (exp(x)-3.0*x=0の根) */ /* coded by Y.Suganuma */ /********************************/ import java.io.*; class Test { 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 kn1 = new Kansu(0); Kansu kn2 = new Kansu(1); // ニュートン法の実行 x = App.newton(x0, eps1, eps2, max, ind, kn1, kn2); // 出力 System.out.println("ind=" + ind[0] + " x=" + x + " f=" + kn1.snx(x) + " df=" + kn2.snx(x)); } } /**********************************/ /* 関数値およびその微分の計算 */ /**********************************/ class Kansu { private int sw; // コンストラクタ Kansu (int s) {sw = s;} // double型関数 double snx(double x) { double y = 0.0; switch (sw) { // 関数値(f(x))の計算 case 0: y = Math.exp(x) - 3.0 * x; break; // 関数の微分の計算 case 1: y = Math.exp(x) - 3.0; break; } return y; } } /**************************** /* 科学技術系算用の手法 */ /****************************/ class App { /*********************************************************/ /* Newton法による非線形方程式(f(x)=0)の解 */ /* x1 : 初期値 */ /* eps1 : 終了条件1(|x(k+1)-x(k)|<eps1) */ /* eps2 : 終了条件2(|f(x(k))|<eps2) */ /* max : 最大試行回数 */ /* ind : 実際の試行回数 */ /* (負の時は解を得ることができなかった) */ /* kn1 : 関数を計算するクラスオブジェクト */ /* kn2 : 関数の微分を計算するクラスオブジェクト */ /* return : 解 */ /*********************************************************/ static double newton(double x1, double eps1, double eps2, int max, int ind[], Kansu kn1, Kansu kn2) { double g, dg, x; int sw; x = x1; ind[0] = 0; sw = 0; while (sw == 0 && ind[0] >= 0) { ind[0]++; sw = 1; g = kn1.snx(x1); if (Math.abs(g) > eps2) { if (ind[0] <= max) { dg = kn2.snx(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; } }