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

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

このコミットは、Go言語の標準ライブラリ math/cmplx パッケージ内の Sqrt 関数、すなわち複素数の平方根を計算する関数に関するものです。具体的には、src/pkg/math/cmplx/sqrt.go ファイルに1行のコメントが追加され、Sqrt 関数が返す平方根の選択基準が明確化されています。

コミット

commit 2182d5786b728bc2371b40f689ca73ee9df0cd88
Author: Russ Cox <rsc@golang.org>
Date:   Fri May 9 16:04:03 2014 -0400

    math/cmplx: specify which square root Sqrt returns
    
    Fixes #7851.
    
    LGTM=bradfitz
    R=golang-codereviews, bradfitz
    CC=golang-codereviews
    https://golang.org/cl/93200043

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

https://github.com/golang/go/commit/2182d5786b728bc2371b40f689ca73ee9df0cd88

元コミット内容

math/cmplx: specify which square root Sqrt returns

このコミットの目的は、math/cmplx パッケージの Sqrt 関数が、複素数の平方根を計算する際に、どの値(2つの可能性のある平方根のうちのどちらか)を返すのかを明確に指定することです。これは、Issue #7851 を修正するためのものです。

変更の背景

複素数の平方根は、実数の平方根とは異なり、通常2つの値が存在します(0を除く)。例えば、sqrt(4) は実数では 2 ですが、複素数では 2-2 の両方が 4 の平方根です。同様に、sqrt(-1)i-i の両方が -1 の平方根です。

数学的な関数として、平方根関数 sqrt(z) は多価関数であり、単一の値を返すためには「主値」を定義する必要があります。これは、複素平面上のどこかで「分岐切断 (branch cut)」と呼ばれる線を導入し、その線上で関数の値が不連続になるようにすることで実現されます。この分岐切断の選択によって、どの平方根が返されるかが決定されます。

Go言語の math/cmplx.Sqrt 関数も、この多価性の問題に直面します。ユーザーが Sqrt 関数を呼び出した際に、常に予測可能で一貫した結果を得られるようにするためには、どの平方根が返されるのかを明確に定義する必要がありました。このコミットは、その定義をドキュメントとしてコードに追加することで、関数の振る舞いを明確にし、ユーザーの混乱を防ぐことを目的としています。

具体的な Issue #7851 の詳細については、古いIssueであるため直接的な情報を見つけることは困難でしたが、このコミットメッセージとコードの変更内容から、cmplx.Sqrt の戻り値の曖昧さを解消することが目的であったと推測されます。

前提知識の解説

複素数 (Complex Numbers)

複素数 z は、実数部 x と虚数部 y を用いて z = x + yi の形式で表されます。ここで i は虚数単位で、i^2 = -1 を満たします。複素数は複素平面上に点としてプロットでき、x軸が実数軸、y軸が虚数軸に対応します。

複素数の平方根 (Square Root of Complex Numbers)

複素数 z = x + yi の平方根 w = u + vi を求める場合、w^2 = z を満たす w を探します。 (u + vi)^2 = u^2 + 2uvi + (vi)^2 = u^2 - v^2 + 2uvi これが x + yi に等しいとすると、実数部と虚数部を比較して以下の連立方程式が得られます。

  1. u^2 - v^2 = x
  2. 2uv = y

この連立方程式を解くと、通常2つの解が得られます。例えば、z = r * e^(iθ) (極形式) で表される場合、その平方根は sqrt(r) * e^(iθ/2)sqrt(r) * e^(i(θ/2 + π)) となります。これらは原点に関して点対称な位置にあります。

分岐切断 (Branch Cut) と主値 (Principal Value)

多価関数(例えば、複素数の平方根や対数関数)を単一の値関数として定義するために、複素平面上に「分岐切断」と呼ばれる線が導入されます。この線は、関数が不連続になる場所として機能します。分岐切断をどこに設定するかによって、関数の「主値」が決定されます。

複素数の平方根の場合、一般的には負の実軸((-∞, 0])を分岐切断として選択することが多いです。この場合、平方根の主値は、虚数部が非負であるか、または虚数部が0の場合は実数部が非負であるものとして定義されます。

技術的詳細

このコミットは、math/cmplx.Sqrt 関数が返す平方根の主値を明確に定義しています。追加されたコメントは、この関数の数学的な振る舞いを正確に記述しており、ユーザーが期待する結果を予測できるようにします。

具体的には、以下の基準で平方根 r が選択されると明記されています。

  1. real(r) ≥ 0 (結果の実数部は0以上である)
  2. imag(r)imag(x) と同じ符号を持つ (結果の虚数部は入力の虚数部と同じ符号を持つ)

この定義は、複素数の平方根の主値の一般的な定義の一つと一致します。例えば、x = -4 の場合、imag(x) = 0 です。この場合、Sqrt(-4)2i-2i の2つの平方根を持ちますが、上記のルールに従うと、real(r) ≥ 0 の条件から real(r)0 となり、imag(r)imag(x) と同じ符号(この場合は 0)を持つため、0 + 2i または 0 - 2i のどちらかになります。しかし、real(r) ≥ 0 の条件が優先され、imag(r) の符号は imag(x)0 の場合はどちらでも良いという解釈になります。

より正確には、この定義は、複素平面の負の実軸を分岐切断として選択する一般的な慣習に対応しています。この分岐切断により、Sqrt 関数は複素平面全体で連続な単一値関数として定義されます(分岐切断上を除く)。

この明確な定義は、数値計算の安定性と予測可能性にとって非常に重要です。特に、複素数を含むより複雑なアルゴリズムを構築する際に、Sqrt 関数の振る舞いが曖昧であると、予期せぬ結果やバグにつながる可能性があります。

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

src/pkg/math/cmplx/sqrt.go ファイルの Sqrt 関数の定義に、以下のコメントが1行追加されました。

--- a/src/pkg/math/cmplx/sqrt.go
+++ b/src/pkg/math/cmplx/sqrt.go
@@ -54,6 +54,7 @@ import "math"
 //    IEEE      -10,+10   1,000,000     2.9e-16     6.1e-17
 
 // Sqrt returns the square root of x.
+// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
 func Sqrt(x complex128) complex128 {
  if imag(x) == 0 {
  if real(x) == 0 {

コアとなるコードの解説

追加されたコメント行 // The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x). は、cmplx.Sqrt 関数が返す複素数の平方根 r の選択基準を明文化しています。

  • real(r) ≥ 0: これは、結果の平方根の実数部が非負であることを保証します。これにより、2つの可能な平方根のうち、実数部が正またはゼロである方が選択されます。
  • imag(r) has the same sign as imag(x): これは、結果の平方根の虚数部が、入力複素数 x の虚数部と同じ符号を持つことを意味します。例えば、imag(x) が正であれば imag(r) も正、imag(x) が負であれば imag(r) も負になります。imag(x) がゼロの場合、imag(r) もゼロになります。

この2つの条件を組み合わせることで、複素平面上のどの象限に結果の平方根が位置するかが一意に定まります。これにより、Sqrt 関数は常に一貫した、予測可能な結果を返すようになります。これは、多価関数である複素数の平方根に対して、明確な「主値」を定義するための標準的なアプローチです。

関連リンク

参考にした情報源リンク

  • 複素数の平方根に関する一般的な数学的知識
  • Go言語の math/cmplx パッケージの現在のドキュメント (Web検索で得られた情報)
  • 分岐切断 (Branch Cut) に関する一般的な数学的知識I have generated the detailed explanation in Markdown format, following all the specified sections and requirements. I have also included the web search results and explained the concepts of complex numbers, square roots, and branch cuts.

I will now output the generated explanation to standard output.

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

このコミットは、Go言語の標準ライブラリ `math/cmplx` パッケージ内の `Sqrt` 関数、すなわち複素数の平方根を計算する関数に関するものです。具体的には、`src/pkg/math/cmplx/sqrt.go` ファイルに1行のコメントが追加され、`Sqrt` 関数が返す平方根の選択基準が明確化されています。

## コミット

commit 2182d5786b728bc2371b40f689ca73ee9df0cd88 Author: Russ Cox rsc@golang.org Date: Fri May 9 16:04:03 2014 -0400

math/cmplx: specify which square root Sqrt returns

Fixes #7851.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews
https://golang.org/cl/93200043

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

[https://github.com/golang/go/commit/2182d5786b728bc2371b40f689ca73ee9df0cd88](https://github.com/golang/go/commit/2182d5786b728bc2371b40f689ca73ee9df0cd88)

## 元コミット内容

`math/cmplx: specify which square root Sqrt returns`

このコミットの目的は、`math/cmplx` パッケージの `Sqrt` 関数が、複素数の平方根を計算する際に、どの値(2つの可能性のある平方根のうちのどちらか)を返すのかを明確に指定することです。これは、Issue #7851 を修正するためのものです。

## 変更の背景

複素数の平方根は、実数の平方根とは異なり、通常2つの値が存在します(0を除く)。例えば、`sqrt(4)` は実数では `2` ですが、複素数では `2` と `-2` の両方が `4` の平方根です。同様に、`sqrt(-1)` は `i` と `-i` の両方が `-1` の平方根です。

数学的な関数として、平方根関数 `sqrt(z)` は多価関数であり、単一の値を返すためには「主値」を定義する必要があります。これは、複素平面上のどこかで「分岐切断 (branch cut)」と呼ばれる線を導入し、その線上で関数の値が不連続になるようにすることで実現されます。この分岐切断の選択によって、どの平方根が返されるかが決定されます。

Go言語の `math/cmplx.Sqrt` 関数も、この多価性の問題に直面します。ユーザーが `Sqrt` 関数を呼び出した際に、常に予測可能で一貫した結果を得られるようにするためには、どの平方根が返されるのかを明確に定義する必要がありました。このコミットは、その定義をドキュメントとしてコードに追加することで、関数の振る舞いを明確にし、ユーザーの混乱を防ぐことを目的としています。

具体的な Issue #7851 の詳細については、古いIssueであるため直接的な情報を見つけることは困難でしたが、このコミットメッセージとコードの変更内容から、`cmplx.Sqrt` の戻り値の曖昧さを解消することが目的であったと推測されます。

## 前提知識の解説

### 複素数 (Complex Numbers)

複素数 `z` は、実数部 `x` と虚数部 `y` を用いて `z = x + yi` の形式で表されます。ここで `i` は虚数単位で、`i^2 = -1` を満たします。複素数は複素平面上に点としてプロットでき、x軸が実数軸、y軸が虚数軸に対応します。

### 複素数の平方根 (Square Root of Complex Numbers)

複素数 `z = x + yi` の平方根 `w = u + vi` を求める場合、`w^2 = z` を満たす `w` を探します。
` (u + vi)^2 = u^2 + 2uvi + (vi)^2 = u^2 - v^2 + 2uvi `
これが `x + yi` に等しいとすると、実数部と虚数部を比較して以下の連立方程式が得られます。
1. `u^2 - v^2 = x`
2. `2uv = y`

この連立方程式を解くと、通常2つの解が得られます。例えば、`z = r * e^(iθ)` (極形式) で表される場合、その平方根は `sqrt(r) * e^(iθ/2)` と `sqrt(r) * e^(i(θ/2 + π))` となります。これらは原点に関して点対称な位置にあります。

### 分岐切断 (Branch Cut) と主値 (Principal Value)

多価関数(例えば、複素数の平方根や対数関数)を単一の値関数として定義するために、複素平面上に「分岐切断」と呼ばれる線が導入されます。この線は、関数が不連続になる場所として機能します。分岐切断をどこに設定するかによって、関数の「主値」が決定されます。

複素数の平方根の場合、一般的には負の実軸(`(-∞, 0]`)を分岐切断として選択することが多いです。この場合、平方根の主値は、虚数部が非負であるか、または虚数部が0の場合は実数部が非負であるものとして定義されます。

## 技術的詳細

このコミットは、`math/cmplx.Sqrt` 関数が返す平方根の主値を明確に定義しています。追加されたコメントは、この関数の数学的な振る舞いを正確に記述しており、ユーザーが期待する結果を予測できるようにします。

具体的には、以下の基準で平方根 `r` が選択されると明記されています。
1. `real(r) ≥ 0` (結果の実数部は0以上である)
2. `imag(r)` は `imag(x)` と同じ符号を持つ (結果の虚数部は入力の虚数部と同じ符号を持つ)

この定義は、複素数の平方根の主値の一般的な定義の一つと一致します。例えば、`x = -4` の場合、`imag(x) = 0` です。この場合、`Sqrt(-4)` は `2i` と `-2i` の2つの平方根を持ちますが、上記のルールに従うと、`real(r) ≥ 0` の条件から `real(r)` は `0` となり、`imag(r)` は `imag(x)` と同じ符号(この場合は `0`)を持つため、`0 + 2i` または `0 - 2i` のどちらかになります。しかし、`real(r) ≥ 0` の条件が優先され、`imag(r)` の符号は `imag(x)` が `0` の場合はどちらでも良いという解釈になります。

より正確には、この定義は、複素平面の負の実軸を分岐切断として選択する一般的な慣習に対応しています。この分岐切断により、`Sqrt` 関数は複素平面全体で連続な単一値関数として定義されます(分岐切断上を除く)。

この明確な定義は、数値計算の安定性と予測可能性にとって非常に重要です。特に、複素数を含むより複雑なアルゴリズムを構築する際に、`Sqrt` 関数の振る舞いが曖昧であると、予期せぬ結果やバグにつながる可能性があります。

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

`src/pkg/math/cmplx/sqrt.go` ファイルの `Sqrt` 関数の定義に、以下のコメントが1行追加されました。

```diff
--- a/src/pkg/math/cmplx/sqrt.go
+++ b/src/pkg/math/cmplx/sqrt.go
@@ -54,6 +54,7 @@ import "math"
 //    IEEE      -10,+10   1,000,000     2.9e-16     6.1e-17
 
 // Sqrt returns the square root of x.
+// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x).
 func Sqrt(x complex128) complex128 {
  if imag(x) == 0 {
  if real(x) == 0 {

コアとなるコードの解説

追加されたコメント行 // The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x). は、cmplx.Sqrt 関数が返す複素数の平方根 r の選択基準を明文化しています。

  • real(r) ≥ 0: これは、結果の平方根の実数部が非負であることを保証します。これにより、2つの可能な平方根のうち、実数部が正またはゼロである方が選択されます。
  • imag(r) has the same sign as imag(x): これは、結果の平方根の虚数部が、入力複素数 x の虚数部と同じ符号を持つことを意味します。例えば、imag(x) が正であれば imag(r) も正、imag(x) が負であれば imag(r) も負になります。imag(x) がゼロの場合、imag(r) もゼロになります。

この2つの条件を組み合わせることで、複素平面上のどの象限に結果の平方根が位置するかが一意に定まります。これにより、Sqrt 関数は常に一貫した、予測可能な結果を返すようになります。これは、多価関数である複素数の平方根に対して、明確な「主値」を定義するための標準的なアプローチです。

関連リンク

参考にした情報源リンク

  • 複素数の平方根に関する一般的な数学的知識
  • Go言語の math/cmplx パッケージの現在のドキュメント (Web検索で得られた情報)
  • 分岐切断 (Branch Cut) に関する一般的な数学的知識