万能零点サーチャーの作り方
公開日
2025年1月27日
更新日
2025年2月23日

あなたも万能零点サーチャーを作ってみたくないですか?Pythonを使って万能零点サーチャーを作ってみましょう。
●参考記事
偏角の原理を使って五次方程式を解く
https://wakara.co.jp/mathlog/20201223
偏角の原理を使ってゼータ関数の零点を見つけよう!
https://wakara.co.jp/mathlog/20211221
●講師紹介:松中宏樹
https://wakara.co.jp/instructor/hirok…
●和からHP
万能零点サーチャーをPythonで作る理由
今回は、万能零点サーチャー を Python で作っていきます。
Python を使う理由は 複素数の計算が非常に楽 だからです。
Python では 虚数単位 i を j で表すことができ、
例えば 3 + 5j のように書くと、複素数 として認識されます。
掛け算や割り算はもちろん、
複素数を関数に入れて計算することも簡単にできます。
この柔軟さが Python を選んだ一番の理由です。
使用するライブラリと定数の設定
今回は、サイン や コサイン を使って積分を行うため、
math ライブラリをインポートします。
まずは、プログラム内で使用する定数を定義していきます。
• N = 100:積分路の分割数です。
演習を100等分にして積分します。
• M = 8:荘園の個数です。
外側の円の中に、8つの小さい円を配置して探索します。
• C_RATIO = 2/3:
外円 と 小円 の 半径の比 です。
小円の半径を、外円の 2/3 に設定しています。
• BOUND = 0.5:
積分結果の絶対値が 0.5 を超えた場合、
その領域に零点がある と判断します。
• EPSILON = 1e-6:
零点の近似精度 です。
f(z) の絶対値が 10^{-6} より小さい場合、
零点にたどり着いた とみなします。
積分を実装する
まず、複素関数の積分 を行う関数を作成します。
積分路は円周なので、円を N 等分して、
その各点で積分を行います。
• 中心 C = a + bi :円の中心。
• 半径 r :円の半径。
積分路上の各点を計算するために、複素数の形式 で表します。
具体的には、
• Z_k = C + r \cdot e^{i \theta}
• \theta = \frac{2\pi k}{N}
これを使って、 f{\prime}(z) / f(z) の積分を行い、
結果を ** 2\pi i ** で割ります。
これにより、領域内の零点の個数 が求められます。
コードの実装
以下は、積分を行う関数のコードです。
import math
def contour_integral(f, f_prime, a, b, r):
integral = 0
for k in range(N):
theta_k = (2 * math.pi * k) / N
z_k = (a + r * math.cos(theta_k)) + (b + r * math.sin(theta_k)) * 1j
z_k1 = (a + r * math.cos((2 * math.pi * (k + 1)) / N)) + (b + r * math.sin((2 * math.pi * (k + 1)) / N)) * 1j
integral += f_prime(z_k) / f(z_k) * (z_k1 – z_k)
return integral * (1j / (2 * math.pi))
積分結果 は、零点の個数 を示します。
この結果が 0 なら、その領域に零点は存在しません。
1 なら 1つの零点 があり、2 なら 2つの零点 があります。
再帰的な探索
次に、零点を探すために、
再帰的な探索関数 を作成します。
これは、魚群探知機のように 円の中を探索していくものです。
1. 中心 C = a + bi の値を確認します。
絶対値が EPSILON より小さければ、零点に到達。
2. そうでなければ、円周上を N 等分して積分します。
3. 積分結果が BOUND を超えていれば、
その領域に零点がある ので、
より小さい円 を描いて再帰的に探索します。
4. 小さい円は 半径を C\_RATIO 倍 にして、
中心 を 円周上の各点 に移動させていきます。
この手順を 零点が見つかるまで 繰り返します。
コードの実装
以下は、再帰的に零点を探索する関数のコードです。
def search_zero(f, f_prime, a, b, r):
# 零点の近似判定
if abs(f(a + b * 1j)) < EPSILON:
print(f”零点発見: {a} + {b}i”)
return
# 積分して零点の個数を確認
num_zeros = abs(contour_integral(f, f_prime, a, b, r))
if num_zeros < BOUND:
return
# より小さい円で再帰的に探索
r_next = r * C_RATIO
for i in range(M):
theta_i = (2 * math.pi * i) / M
a_next = a + r * C_RATIO * math.cos(theta_i)
b_next = b + r * C_RATIO * math.sin(theta_i)
search_zero(f, f_prime, a_next, b_next, r_next)
この関数を実行すると、再帰的に零点を探索 し、
見つかった零点を表示 します。
実際に動かしてみる
例えば、
• f(z) = z^2 – 3z + 2
• f{\prime}(z) = 2z – 3
この関数は、1 と 2 に零点を持っています。
これを使って、零点サーチャー を実行してみましょう。
def f(z):
return z**2 – 3*z + 2
def f_prime(z):
return 2*z – 3
search_zero(f, f_prime, 0, 0, 3)
実行結果は以下のようになります。
零点発見: 1.0 + 0.0i
零点発見: 2.0 + 0.0i
おわりに
これで、万能零点サーチャー の作り方を解説しました。
今回のサーチャーは、
• 複素関数 にも使える
• 少しの誤差を許容 できる
• 零点のない領域も確認 できる
という強力なツールです。
次は、これを使って リーマン予想の検証 に挑戦していきます。
興味のある方は、次回もぜひお楽しみに。