ゆるゆるプログラミング

・ニュートン法で平方根

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

ニュートン法 漸化式

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

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

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

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

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

NewtonsMethod1.java
001:    public class NewtonsMethod1 {
002:    	// f(x)=x^2-a
003:    	static double f( double x, double a )
004:    	{
005:    		return x * x - a;
006:    	}
007:    
008:    
009:    	// f(x)の微分f'(x) - 接線の傾き
010:    	static double df( double x )
011:    	{
012:    		return 2 * x;
013:    	}
014:    
015:    
016:    	// ニュートン法 漸化式
017:    	static double newtons( double x, double a )
018:    	{
019:    		return x - f( x, a ) / df( x );
020:    	}
021:    
022:    
023:    	// メイン
024:    	public static void main(String[] args) {
025:    		// 変数の宣言
026:    		double e = 0.000001;	// 収束の判定値
027:    		double x;		// 計算値を格納
028:    		double x_ans;		// 1つ前の計算値
029:    		double a;		// 平行根を求める値
030:    
031:    		// 平行根を求める値
032:    		a = 169.0;	// 13×13
033:    
034:    		// 初期値を代入
035:    		x_ans = 10000.0;
036:    
037:    		// 無限ループ
038:    		for ( int i = 1; ; ++ i ) {
039:    			// ニュートン法で計算
040:    			x = newtons( x_ans, a );
041:    
042:    			// 収束の判定
043:    			if ( e > Math.abs( x - x_ans ) ) break;
044:    
045:    			// 最新の計算結果を次の計算結果に代入
046:    			x_ans = x;
047:    
048:    			// 途中経過の表示
049:    			System.out.println( "回数:" + i + "  計算結果: " + x_ans );
050:    		}
051:    
052:    		// 改行
053:    		System.out.println();
054:    
055:    		// 結果の表示
056:    		System.out.println( "計算結果: " + x_ans );
057:    
058:    		// 結果の絶対値
059:    		x_ans = Math.abs( x_ans );
060:    		System.out.println( a + "の絶対値: " + x_ans );
061:    
062:    		// f(x)=0になるかを確認
063:    		System.out.println( "f(" + x_ans + ")=" + f( x_ans, a ) );
064:    	}
065:    }

NewtonsMethod1を実行

C:\talavax\javasample>java NewtonsMethod1

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

NewtonsMethod1.javaの出力結果

回数: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

001:    public class NewtonsMethod1 {

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

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

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

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

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

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

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

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

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

025:    		// 変数の宣言
026:    		double e = 0.000001;	// 収束の判定値
027:    		double x;		// 計算値を格納
028:    		double x_ans;		// 1つ前の計算値
029:    		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:    		System.out.println();
054:    
055:    		// 結果の表示
056:    		System.out.println( "計算結果: " + x_ans );

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

058:    		// 結果の絶対値
059:    		x_ans = Math.abs( x_ans );
060:    		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:    		// f(x)=0になるかを確認
063:    		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の平方根であることが確認できます。

数値微分を使ったニュートン法のJavaソースコードはこちらを参照してください。「ニュートン法で平方根 その2」

ニュートン法での平方根計算をメソッド化したJavaソースコードはこちらを参照してください。「ニュートン法で平方根 その3」

■関連コンテンツ

ニュートン法 ニュートン法について
ニュートン法で平方根 その2 ニュートン法で平方根(数値微分)
ニュートン法で平方根 その3 ニュートン法で平方根(メソッド化)

■新着情報

2019.06.14 円模様1 円の縦横整列模様の画像作成方法を紹介
2019.05.24 ニュートン法で平方根 その3 ニュートン法で平方根(メソッド化)
2019.05.23 ニュートン法で平方根 その2 ニュートン法で平方根(数値微分)
2019.05.22 ニュートン法 ニュートン法について
2019.05.22 ニュートン法で平方根 ニュートン法で平方根を計算

■広告

法人向けのETC専用カード

~約8,000名の受講生と80社以上の導入実績~ 企業向けプログラミング研修ならCodeCamp

日本最大級ショッピングサイト!お買い物なら楽天市場

 

 

 

 

 

 

 

Topへ