非線形方程式(ニュートン法)

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