コラム 人と星とともにある数学 数学

Pythonでオイラー ゼータのオイラー積<前編>|Pythonで数学を学ぼう! 第13回

はじめに|レポート

9月・10月共通テーマ 超入門・ゼータ関数

毎月開催中Zoomオンラインセミナー、桜井進の算数・数学教室の9月・10月共通テーマは「超入門・ゼータ関数」です。

前回の「バーゼルの問題」の続きです。

9月26日(日)13:00-14:00 桜井進の魔法の算数教室

長年の構想がついに実現!
小学生からわかる 超入門・ゼータ関数
オイラーの無限のたし算を鑑賞

参加者 6組親子(6歳、小学生3名、中学生1名、高校生1名)
テキストPDF 21ページ

Pythonという強力な助っ人のおかげです。
Pythonなら、たった2行のコードでゼータ関数の計算も手軽に計算できます。
毎日Pythonのコードを作文しながら感動させられます。

9月26日(日)14:30-16:30 桜井進の数学浪漫紀行

超入門・ゼータ関数
オイラー、計算の旅

参加者 13名(小学生1名、高校生1名、大人11名)
テキストPDF 26ページ
オイラーの計算の旅を2時間で駆け巡りました。

セミナーでも使ったPythonコードをさらにブラッシュアップしました。

以下に紹介していきます。

Pythonでゼータ関数

10年以上の計算の末、オイラーは1935年に前回のバゼールの問題を劇的に解きました。はたして、そこに現れた新しい数学がゼータ関数です。

その姿は分数の和(無限級数)で、分母は自然数のべき乗の形をしたシンプルなものです。そして100年後、この関数にゼータζと名付けたのがリーマン(1826-1866)です。

バーゼルの問題とはζ(2)ということです。オイラーはゼータ関数の数値計算を手計算で行いました。

オイラーの手計算をPythonとともに駆け足で検証していきます。

必用なPythonコードはたったの2行です。ゼータ関数ζ(x)は、mpmathライブラリをインポートしmpmath.zeta(x)とするだけです。

>>> import mpmath
>>> print(mpmath.zeta(2))
>>> 1.64493406684823

まずこの結果を別な計算と比べてみましょう。

オイラーの結論はπ2/6でしたからこれをPythonで計算してみます。上のコードに続けます。

いま、mpmathライブラリをインポートしているので、円周率πはmpmath.piです。

>>> print(mpmath.pi**2/6)
>>> 1.64493406684823

たしかにmpmath.zeta(2)の結果とピッタリ一致しています。

1737年、オイラーの大発見|オイラー積

つぎにゼータを計算する数式がオイラー積です。

ゼータ関数の発見とほぼ同時にゼータの正体が解き明かされました。ゼータ関数は無限級数すなわち和の形をしていますが、オイラーはこれが素数の積に書き換えられることを発見しました。

これがゼータのオイラー積です。

なぜ素数を使った積の形に等しくなるのか?

ポイントは、自然数は素数の積にただ一通に書ける、という素因数分解の一意性です。

証明の解説は後回しにして、本当に素数の積がゼータに等しくなるのかに焦点をあててみましょう。

実は、オイラーの手計算の芸当は超絶的なのですが、オイラー積を計算した痕跡は見つけられません。さすがのオイラーもあきらめたのでしょう。

そこでPythonの出番です。

オイラー積は積ですから、階乗を定義する行う場合によく用いられる再帰的定義が考えられます。

まずn番目の素数を与える関数sympy.prime(n)を確認してみましょう。素数を扱う場合に非常に便利で強力な関数です。この関数のおかげでオイラー積のコードも簡単に書けます。

>>> import sympy
>>> sympy.prime(1)
>>> 2
>>> sympy.prime(2)
>>> 3
>>> sympy.prime(1000)
>>> 7919
>>> sympy.prime(10000)
>>> 104729
>>> sympy.prime(100000)
>>> 1299709
>>> sympy.prime(1234567)
>>> 19394489

sympy.prime(n)の引数nはPythonには珍しく数学の作法に合わせてあります。0スタートではなく1スタートなので便利です。

sympy.prime(n)を使えばオイラー積の再帰的定義は次のようになります。

>>> # 【再帰的定義】
>>> def eulerproduct(N):
>>>   if N == 0:
>>>     return 1
>>>   else:
>>>     product = 1/(1-1/(sympy.prime(N)**2))
>>>     return eulerproduct(N-1)*product

その結果が次です。

素数の個数が大きくなるにしたがって正しい数値が得られていく様子が確認できます。ただし2000コの素数までが限界でした。

とはいえオイラーを驚かせるには十分な結果でしょう。2000個の素数をいとも簡単に計算してみせたのですから。

今回はじめてオイラー積を計算してみようと思い、いとも簡単に実現できました。

Pythonのおかげです。初めて見る計算結果に感激しました。

理論的──素因数分解の一意性──に正しいことはわかっていても、数値計算だけは本当に計算してみなければわかりません。

284年前のオイラーがこの計算を見たならばどう思うでしょうか。

さて、これで計算を終わりにするのはちょっと心残りです。もっとたくさんの素数を使ってオイラー積の計算に挑戦したくなりました。

後編に続きます。

  • この記事を書いた人
  • 最新記事

桜井進(さくらいすすむ)様

1968年山形県生まれ。 サイエンスナビゲーター®。株式会社sakurAi Science Factory 代表取締役CEO。 (略歴) 東京工業大学理学部数学科卒、同大学大学院院社会理工学研究科博士課程中退。 東京理科大学大学院非常勤講師。 理数教育研究所Rimse「算数・数学の自由研究」中央審査委員。 高校数学教科書「数学活用」(啓林館)著者。 公益財団法人 中央教育研究所 理事。 国土地理院研究評価委員会委員。 2000年にサイエンスナビゲーターを名乗り、数学の驚きと感動を伝える講演活動をスタート。東京工業大学世界文明センターフェローを経て現在に至る。 子どもから大人までを対象とした講演会は年間70回以上。 全国で反響を呼び、テレビ・新聞・雑誌など様々なメディアに出演。 著書に『感動する!数学』『わくわく数の世界の大冒険』『面白くて眠れなくなる数学』など50冊以上。 サイエンスナビゲーターは株式会社sakurAi Science Factoryの登録商標です。

あわせて読みたい

-コラム, 人と星とともにある数学, 数学
-