Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 16428] ファイルの概要

このコミットは、Go言語のドキュメント内の平方根の近似計算に関するコード例における誤植(typo)を修正するものです。具体的には、ニュートン法を用いた平方根の計算式に誤りがあったため、これを数学的に正しい形に修正しています。

コミット

commit 605da0e2a23fbaadca9bd056a3cf04ecac507add
Author: Katrina Owen <katrina.owen@gmail.com>
Date:   Wed May 29 13:49:51 2013 +1000

    doc: Fix typo in approximation of square root
    
    See https://en.wikipedia.org/wiki/Newton%27s_method#Square_root_of_a_number
    
    R=golang-dev, minux.ma, adg
    CC=golang-dev
    https://golang.org/cl/9145044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/605da0e2a23fbaadca9bd056a3cf04ecac507add

元コミット内容

doc: Fix typo in approximation of square root

See https://en.wikipedia.org/wiki/Newton%27s_method#Square_root_of_a_number

R=golang-dev, minux.ma, adg
CC=golang-dev
https://golang.org/cl/9145044

変更の背景

この変更は、Go言語の公式ドキュメント doc/code.html に含まれる平方根の近似計算のコード例に存在する誤植を修正するために行われました。このコードは、ニュートン法(Newton's method)を用いて数値の平方根を近似的に求めるものですが、その実装に数学的な誤りがありました。具体的には、ニュートン法の更新式において、分母が誤っていたため、正しい計算結果が得られない状態でした。

ドキュメント内のコード例は、Go言語の機能やプログラミングの概念を説明するために提供されるものであり、その正確性は非常に重要です。誤ったコード例は、読者に誤解を与えたり、間違った知識を伝えたりする可能性があるため、発見され次第速やかに修正される必要があります。このコミットは、そのようなドキュメントの品質と正確性を保つためのメンテナンスの一環として実施されました。

前提知識の解説

ニュートン法(Newton's Method)

ニュートン法(またはニュートン・ラフソン法)は、関数 $f(x) = 0$ の根(ゼロ点)を数値的に見つけるための反復法です。この方法は、初期値 $x_0$ から始めて、接線を用いてより良い近似値 $x_{n+1}$ を見つけることを繰り返します。

更新式は以下の通りです。 $x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$ ここで、$f'(x_n)$ は $f(x)$ の導関数です。

ニュートン法による平方根の計算

ある数 $S$ の平方根 $\sqrt{S}$ を求める場合、これは $x^2 = S$ という方程式の根を見つけることと同じです。これを $f(x) = x^2 - S = 0$ と定義できます。

この関数の導関数は $f'(x) = 2x$ です。

ニュートン法の更新式にこれらを代入すると、平方根を求めるための更新式が得られます。 $x_{n+1} = x_n - \frac{x_n^2 - S}{2x_n}$

この式を整理すると、以下のようになります。 $x_{n+1} = x_n - \left( \frac{x_n^2}{2x_n} - \frac{S}{2x_n} \right)$ $x_{n+1} = x_n - \left( \frac{x_n}{2} - \frac{S}{2x_n} \right)$ $x_{n+1} = x_n - \frac{x_n}{2} + \frac{S}{2x_n}$ $x_{n+1} = \frac{x_n}{2} + \frac{S}{2x_n}$ $x_{n+1} = \frac{1}{2} \left( x_n + \frac{S}{x_n} \right)$

この最後の式が、平方根を求めるニュートン法の一般的な更新式として知られています。

技術的詳細

コミットの変更は、doc/code.html 内のGo言語のコードスニペットにおけるニュートン法の平方根近似の実装に関するものです。元のコードは以下のようになっていました。

// Sqrt returns an approximation to the square root of x.
func Sqrt(x float64) float64 {
	z := 0.0 // 初期値
	for i := 0; i < 1000; i++ {
		z -= (z*z - x) / (2 * x) // 誤った更新式
	}
	return z
}

このコードの誤りは、更新式 z -= (z*z - x) / (2 * x) の分母に 2 * x が使われている点です。ニュートン法の更新式 $x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$ において、$f(z) = z^2 - x$ であり、$f'(z) = 2z$ です。したがって、正しい更新式は z -= (z*z - x) / (2 * z) となるべきです。

また、初期値 z := 0.0 も問題がありました。ニュートン法では、初期値が0であると分母が0になり、計算が破綻します。平方根の計算では、初期値として1.0や対象の数値自身など、0以外の適切な値を用いるのが一般的です。

このコミットでは、以下の2点が修正されました。

  1. 初期値の修正: z := 0.0 から z := 1.0 へ変更。これにより、計算の開始時に分母が0になることを防ぎ、より安定した収束を期待できます。
  2. 更新式の修正: z -= (z*z - x) / (2 * x) から z -= (z*z - x) / (2 * z) へ変更。これにより、ニュートン法の数学的に正しい更新式が適用され、正確な平方根の近似値が得られるようになります。

この修正により、ドキュメントに記載されているコード例が、数学的に正しく、かつ機能的に動作するようになりました。

コアとなるコードの変更箇所

--- a/doc/code.html
+++ b/doc/code.html
@@ -295,9 +295,9 @@ package newmath
 
 // Sqrt returns an approximation to the square root of x.
 func Sqrt(x float64) float64 {
-	z := 0.0
+	z := 1.0
 	for i := 0; i < 1000; i++ {
-		z -= (z*z - x) / (2 * x)
+		z -= (z*z - x) / (2 * z)
 	}
 	return z
 }

コアとなるコードの解説

変更されたファイルは doc/code.html です。これはGo言語の公式ドキュメントの一部であり、ウェブページとして表示されるHTMLファイルです。このファイル内には、Go言語のコードスニペットが埋め込まれており、今回の修正対象はその中の newmath パッケージの Sqrt 関数でした。

Sqrt 関数は、float64 型の引数 x を受け取り、その平方根の近似値を float64 型で返します。

変更前:

func Sqrt(x float64) float64 {
	z := 0.0 // 初期値が0
	for i := 0; i < 1000; i++ {
		z -= (z*z - x) / (2 * x) // 分母が誤っている (2 * x)
	}
	return z
}
  • z := 0.0: 初期値が0に設定されていました。ニュートン法では、初期値が0だと次の反復で分母が0になり、計算が停止するか、NaN(Not a Number)などの不正な結果を返します。
  • z -= (z*z - x) / (2 * x): ニュートン法の更新式において、分母が 2 * x となっていました。これは数学的に誤りです。正しいニュートン法の更新式では、分母は現在の近似値 z の2倍、つまり 2 * z であるべきです。

変更後:

func Sqrt(x float64) float64 {
	z := 1.0 // 初期値が1.0に修正
	for i := 0; i < 1000; i++ {
		z -= (z*z - x) / (2 * z) // 分母が正しい (2 * z) に修正
	}
	return z
}
  • z := 1.0: 初期値が 1.0 に変更されました。これにより、計算の開始時に分母が0になることを避け、ニュートン法が正しく収束するための適切な出発点となります。
  • z -= (z*z - x) / (2 * z): 更新式の分母が 2 * z に修正されました。これにより、ニュートン法の数学的に正しい反復計算が行われ、より正確な平方根の近似値が得られるようになります。

この修正は、ドキュメントのコード例の正確性を向上させ、読者が正しいニュートン法の実装を理解できるようにするために非常に重要です。

関連リンク

参考にした情報源リンク