2019.05.22

ニュートン法で平方根

はじめに

ニュートン法は、関数f(x)が与えられたときf(x)=0となるxを数値計算の反復によって求めるアルゴリズムの1つです。その計算式は以下です。

ニュートン法 漸化式

ここでは、ニュートン法を使って平方根を計算するプログラムを紹介します。

関数をf(x)=x2-aとし、f(x)=0となるxを求めることで、aの平方根を計算します。

この式は、以下の手順で導いています。

ニュートン法 平方根を求める元の式

Javaソースコード

以下がそのJavaソースコードです。

NewtonsMethod1.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
public class NewtonsMethod1 {
	// f(x)=x^2-a
	static double f( double x, double a )
	{
		return x * x - a;
	}


	// f(x)の微分f'(x) - 接線の傾き
	static double df( double x )
	{
		return 2 * x;
	}


	// ニュートン法 漸化式
	static double newtons( double x, double a )
	{
		return x - f( x, a ) / df( x );
	}


	// メイン
	public static void main(String[] args) {
		// 変数の宣言
		double e = 0.000001;	// 収束の判定値
		double x;		// 計算値を格納
		double x_ans;		// 1つ前の計算値
		double a;		// 平行根を求める値

		// 平行根を求める値
		a = 169.0;	// 13×13

		// 初期値を代入
		x_ans = 10000.0;

		// 無限ループ
		for ( int i = 1; ; ++ i ) {
			// ニュートン法で計算
			x = newtons( x_ans, a );

			// 収束の判定
			if ( e > Math.abs( x - x_ans ) ) break;

			// 最新の計算結果を次の計算結果に代入
			x_ans = x;

			// 途中経過の表示
			System.out.println( "回数:" + i + "  計算結果: " + x_ans );
		}

		// 改行
		System.out.println();

		// 結果の表示
		System.out.println( "計算結果: " + x_ans );

		// 結果の絶対値
		x_ans = Math.abs( x_ans );
		System.out.println( a + "の絶対値: " + x_ans );

		// f(x)=0になるかを確認
		System.out.println( "f(" + x_ans + ")=" + f( x_ans, a ) );
	}
}

コンパイル ソースコードが「ANSI」の場合

C:\talavax\javasample>javac -encoding sjis NewtonsMethod1.java

コンパイル ソースコードが「UTF-8」の場合

C:\talavax\javasample>javac NewtonsMethod1.java

実行

C:\talavax\javasample>java NewtonsMethod1

169の平方根ニュートン法で計算してます。計算の途中経過と結果を表示しています。

出力結果

回数:1  計算結果: 5000.00845
回数:2  計算結果: 2500.021124971439
回数:3  計算結果: 1250.0443622001121
回数:4  計算結果: 625.0897787010334
回数:5  計算結果: 312.6800699323774
回数:6  計算結果: 156.61027924500786
回数:7  計算結果: 78.84469552143572
回数:8  計算結果: 40.494074900269396
回数:9  計算結果: 22.33376248850415
回数:10  計算結果: 14.950390630254306
回数:11  計算結果: 13.127221545732919
回数:12  計算結果: 13.00061647933808
回数:13  計算結果: 13.00000001461649

計算結果: 13.00000001461649
169.0の絶対値: 13.00000001461649
f(13.00000001461649)=3.8002872315701097E-7

Javaソースコードの解説

001
public class NewtonsMethod1 {

クラス名を、NewtonsMethod1としています。

002
003
004
005
006
	// f(x)=x^2-a
	static double f( double x, double a )
	{
		return x * x - a;
	}

ニュートン法でf(x)=0を求めたい関数です。ここでは、f(x)=x2-aという関数を記述しています。平方根の元の値をaに代入します。

009
010
011
012
013
	// f(x)の微分f'(x) - 接線の傾き
	static double df( double x )
	{
		return 2 * x;
	}

f(x)の微分式f'(x)を記述しています。f(x)=x2-aなので、f'(x)=2xになります。

016
017
018
019
020
	// ニュートン法 漸化式
	static double newtons( double x, double a )
	{
		return x - f( x, a ) / df( x );
	}

ニュートン法の漸化式のメソッドです。

023
024
	// メイン
	public static void main(String[] args) {

このmainメソッドからプログラムを実行します。

025
026
027
028
029
		// 変数の宣言
		double e = 0.000001;	// 収束の判定値
		double x;		// 計算値を格納
		double x_ans;		// 1つ前の計算値
		double a;		// 平行根を求める値

このプログラムで使う変数を宣言しています。double型変数eは、漸化式を終了させるための値で、計算したxn+1とxn絶対値の差がe未満になったときに計算を終了させます。

031
032
		// 平行根を求める値
		a = 169.0;	// 13×13

平方根を求める値をdouble型変数aに代入しています。

ここでは169.0を変数aに代入しています。これにより、ニュートン法で収束させた値が169.0の平方根である13.0になることが期待できます。

034
035
		// 初期値を代入
		x_ans = 10000.0;

計算の初期値に10000.0を代入しています。この値は任意です。

037
038
		// 無限ループ
		for ( int i = 1; ; ++ i ) {

for文無限ループを作っています。int型変数iを1からインクリメント(1を足す)しています、終了条件を記述していないので無限ループになります。

039
040
			// ニュートン法で計算
			x = newtons( x_ans, a );

ニュートン法の漸化式にx_ansとaを渡して、次のxの値を取得しています。

042
043
			// 収束の判定
			if ( e > Math.abs( x - x_ans ) ) break;

計算した値xと、計算に使った値x_ansの差の絶対値を計算し、その値がeより小さければ計算が収束したと判断し、break文for文を抜けます。

045
046
			// 最新の計算結果を次の計算結果に代入
			x_ans = x;

x_ansにxを代入しています。

052
053
054
055
056
		// 改行
		System.out.println();

		// 結果の表示
		System.out.println( "計算結果: " + x_ans );

ニュートン法で求めた結果x_ansをコンソールに出力しています。

058
059
060
		// 結果の絶対値
		x_ans = Math.abs( x_ans );
		System.out.println( a + "の絶対値: " + x_ans );

計算結果x_ansの絶対値をとった値をコンソールに出力しています。これが、実際に求めたい平方根の値になります。このプログラムの場合、f(x)=x2-169.0を0.0にするxを求めるようにしてるため、xの値が13.0と-13.0の2つの値のどちらでもf(x)=0を満たすことが出来ます。これは初期値によりプラスとマイナスのどちらかの値をとります。例えば初期値を-10000.0にするとx_ans=-13になります。

062
063
		// f(x)=0になるかを確認
		System.out.println( "f(" + x_ans + ")=" + f( x_ans, a ) );

計算結果x_ansをメソッドfに代入して、その結果が0になっているか確認するための出力です。この例では、結果の表示が指数表記になっていて、数値の後に'E-7'が付いています。これは10の-7乗を意味しています。この結果から求めたx_ansでメソッドfが戻す値は0に近く、x_ansはaの平方根であることが確認できます。

以上です。

関連コンテンツ

反復によって数値計算を行うアルゴリズム、ニュートン法を解説しています。興味がある方は、記事をご覧ください。

2019.05.22

数値微分を使ったニュートン法で平方根を計算する方法を紹介しています。興味のあるかたは是非ご覧ください。

2019.05.23

反復計算の回数の上限があるニュートン法の解法ソースコードを紹介しています。

2019.05.24

処理を繰り返すために使用するfor文について解説しています。

2020.03.23

基本的な計算である足し算(加法)/引き算(減法)/掛け算(乗法)/割り算(除法)を行うプログラム作成。

2020.03.23

メソッドを抜けるときに使用するreturn文について説明しています。

2020.03.20

Javaのmainメソッドで受け取るパラメータについて解説しています。

2017.09.26

mainメソッドで受け取るパラメータの数の取得の仕方について解説しています。

2019.05.14

条件式を判断して処理を分岐する方法を詳しく説明しています。

2023.03.20

繰り返し処理(ループ)から強制的に抜けかたについて解説しています。

2017.07.14

変数やクラスに格納されている値をコンソール出力する方法は?

2020.03.23

プログラムの最初に実行されるメソッドは?

2022.12.13

プログラミングで使う変数って何?

2020.03.23

Javaのプログラムを書いてみませんか?プログラムの書き方をくわしく説明しています。

2020.03.23

「Javaソースコード」から実行可能な「オブジェクトコード」に変換する方法をくわしく説明しています。

2020.03.23

Javaのプログラムを作ってみませんか?プログラミングに必要なものの用意から実行までを説明しています。

2020.03.23

Javaの学習に役立つソースコードを多数紹介しています。是非、ご覧ください。

2022.09.10

Swingパッケージを使ってグラフィック表示を行う方法を解説しています。

2020.03.23

画像フォーマット形式・色・大きさ・傾きなどの変更、特定の図形(文字・記号など)を見つけたり、取り出したりする画像処理について詳しく解説。

2015.11.29

繰り返し処理を使ったJavaのソースコードサンプルを紹介しています。

2020.03.23

配列を使うJavaソースコードを多数紹介しています。

2021.05.18

数学に関係するJavaのメソッドやソースコードなどを紹介しています。

2022.10.25

三角形、台形、円などいろいろな図形の面積を計算するプログラムを紹介しています。詳しくは、記事をご覧ください。

2021.05.18

StringクラスとStringBuilderクラスを利用したプログラミングの仕方を紹介しています。

2016.12.16

Javaを使った簡単な応用プログラム(生年月日から年齢を計算プログラムなど)を紹介しています。

2022.07.07

プログラミング、ITに関する用語をまとめています。

2022.10.17

日本で使われてきた伝統文様「和柄」について解説しています。

2022.07.27

アルゴリズムって何?

2022.12.29

平方根の意味と、Math.sqrtメソッドの使い方をソースコードを使って詳しく解説しています。

2020.03.23

プログラミング言語とは?種類や特徴について説明しています。

2022.08.03

Javaプログラムの構成について解説しています。詳しくは、こちらをご覧ください。

2020.03.23

メソッドの定義方法を詳しく解説しています。Javaのサンプルソースコードを使った説明もあります。

2020.03.23

絶対値の意味と、Math.absメソッドの使い方をソースコードを使って詳しく解説しています。

2020.03.23

for文で変数名iがよく使われる理由について説明しています。興味のある方は是非。

2022.08.29

繰り返し処理の作り方を解説しています。

2016.03.02

整数型の変数に1を足すインクリメント、1つ引くデクリメントについて詳しく説明しています。

2020.03.23

コンピュータを制御するために使用する入力機能と出力機能を持つ装置のことをコンソールといいます。興味のある方は、ご覧ください。

2020.08.24

指数表記は、非常に大きな数値や、0に近い小さい数値を表現するときに使われる表記方法の1つです。興味のある方は、記事をご覧ください。

2020.03.23

「ゆるゆるプログラム」のコンテンツを紹介しています。興味のある方はこの記事をご覧ください。

2020.03.23

広告