2019/05/22 公開
・ニュートン法で平方根
ニュートン法は、関数f(x)が与えられたときf(x)=0となるxを数値計算の反復によって求めるアルゴリズムの1つです。その計算式は以下です。
ここでは、ニュートン法を使って平方根を計算するプログラムを紹介します。
関数をf(x)=x2-aとし、f(x)=0となるxを求めることで、aの平方根を計算します。
この式は、以下の手順で導いています。
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 {
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
ここでは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 | ニュートン法で平方根(メソッド化) |
■新着情報
2022.07.07 | 外部プログラムの実行 | exeファイル実行 |
2022.07.06 | 完全数 | 6=1+2+3 |
■広告