2020年最初に作ったアプリが、おかげさまでたくさんの方にみてもらえているようです。
「2020」という数は、
— tsujimotter (@tsujimotter) 2019年12月31日
・2つの平方数の和
・3つの平方数の和
・連続する4つの素数の平方数の和
・10連続偶数の平方和
でそれぞれ表せる数らしいので、その性質を可視化するページを作ってみました!#2020になる数式 #大晦日ハッカソン
Interesting properties of 2020.https://t.co/FT2DFTP0XO pic.twitter.com/fxZKJi5Fv9
上のアプリを公開後も、tsujimotterは「2020に関する数学トピック」についてあれこれ考えていました。今回紹介したいのは「2次形式で表せる素数」のお話です。上の話と比べると、かなり前提知識が必要な話なのですが、よろしければお付き合いください。
判別式 -2020 の2次形式で表せる素数
今回は、判別式 の2次形式
で表現できる素数の条件について考えたいと思います。
このような問題に対しては、虚2次体を考えるのが常套手段です。虚2次体 において、素数 が の整数環 の素イデアル を用いて
のように素イデアル分解される条件を考えます。 が式 のように2つの素イデアルに分解できるという条件に加えて、さらに が単項イデアルであれば、 は の形で表すことができます。
残念ながら、 は常に単項イデアルになるとは限りません。あとで計算するように のイデアル類群は
なので です。つまり はPIDではありません。
よって、素イデアル が単項イデアルかどうかは、別途判定する必要があります。
その辺の諸々の事情をひっくるめて、 が によって表現できる必要十分条件は、次のように表すことができます。
(i) は平方因子を持たない
(ii)
このとき、 とすると、次数 のモニックかつ既約な多項式 が存在し、 と の判別式のどちらも割らない奇素数 について次が成り立つ:
は が のヒルベルト類体であるような実代数的整数 の最小多項式としてとることができる。
さて、 として定理を適用しましょう。 は上の条件 (i), (ii) を満たすことに注意します。
このとき、次数が の整係数多項式 が存在して、その実根を とすると は のヒルベルト類体になります。
をどうやって求めたらよいでしょうか。これについては自分で計算するのは大変そうなので、SageMathの機能をお借りしましょう。
www.sagemath.org
SageMathやCoCalcの使い方については、こちらの木村先生の解説がとても丁寧です。
share.cocalc.com
SageMathが準備できたら以下のコードを打って、Shift+Enterしてみましょう。
d = 505
K = QuadraticField(-d); K
K.class_group()
すると、次のような結果が帰ってきます。
Number Field in a with defining polynomial x^2 + 505 with a = 22.47220505424424?*I Class group of order 8 with structure C4 x C2 of Number Field in a with defining polynomial x^2 + 505 with a = 22.47220505424424?*I
結果の英文をよむと、たしかに のイデアル類群は位数が 8 で、その構造は に同型であることがわかりますね。
次は のヒルベルト類体を計算するコードです。
H = K.hilbert_class_field('b'); H
結果は次の通りです。
Number Field in b with defining polynomial x^8 - 255*x^7 + 295*x^6 + 980*x^5 - 2058*x^4 + 980*x^3 + 295*x^2 - 255*x + 1 over its base field
このdefining polynomial(定義多項式)が です。
実際、 は次数 であり、さらに整係数の多項式であることが確認できますね。
素数 が で表せる必要十分条件
したがって、 とかける必要十分条件が次のように具体的に表せます:
整数 が存在し
かつ が整数解を持つ
なお、 の判別式はSageMathで次のように計算できます。
f = K.hilbert_class_field_defining_polynomial(); f disc = f.discriminant(); disc disc.factor()
結果:
x^8 - 255*x^7 + 295*x^6 + 980*x^5 - 2058*x^4 + 980*x^3 + 295*x^2 - 255*x + 1 1484238859152924835345594665461760000 2^14 * 3^34 * 5^4 * 17^4 * 101^4
よって
としておけば良さそうですね。
具体例 (1)
さて、これを確認するのはなかなかしんどそうですね。今回は2つの具体例を確認して終わりにしましょう。1つ目の具体例は です。
まず平方剰余の条件は次のようになります。
2番目の等号では平方剰余の相互法則を使いました。
右辺のルジャンドル記号がすべて になることは簡単にわかります。よって
が得られました。
次に ですが、これはSageMathで因数分解してもらいましょう。
p = 509 F=FiniteField(p) R.<x>=F[] f=factor(x^8 - 255*x^7 + 295*x^6 + 980*x^5 - 2058*x^4 + 980*x^3 + 295*x^2 - 255*x + 1) print p,f
結果は次の通りです:
509 (x + 22) * (x + 35) * (x + 160) * (x + 162) * (x + 231) * (x + 328) * (x + 379) * (x + 464)
が因子に入っていることから、少なくとも根 があることがわかりますね。よって、 は条件を満たします。
したがって、 は の形で表せるはずですが、実際
と表せます。たしかに成り立っていますね!
具体例 (2)
2つ目の具体例は です。
まず平方剰余の条件は次のようになります。
1つ目の例と同様に、右辺のルジャンドル記号がすべて になることは簡単にわかります。よって
が得られました。
次に ですが、これはSageMathで因数分解してもらいましょう。
p = 2029 F=FiniteField(p) R.<x>=F[] f=factor(x^8 - 255*x^7 + 295*x^6 + 980*x^5 - 2058*x^4 + 980*x^3 + 295*x^2 - 255*x + 1) print p,f
結果は次の通りです:
2029 (x + 200) * (x + 206) * (x + 344) * (x + 348) * (x + 871) * (x + 1113) * (x + 1329) * (x + 1421)
が因子に入っていることから、少なくとも根 があることがわかりますね。よって、 は条件を満たします。
したがって、 は の形で表せるはずですが、実際
と表せます。たしかに成り立っていますね!
今回の場合、 の の部分が、たまたま になりました。よって、こんな風に変形ができます。
まさに2020という数式ができあがりましたね!
お正月から整数論を堪能しましたので、そろそろ終わりにしたいと思います。
それでは今日はこの辺で。
おまけ:SageMath で までの例を全て計算する
SageMathを使って、定理の条件を一気に確認する方法がわかりましたので、紹介します。
の範囲で確認するコードです。
p=2 result = [] while p<3000: p=next_prime(p) F=FiniteField(p) R.<x>=F[] if kronecker(-2020,p) == 1: # 平方剰余の条件 f=factor(x^8 - 255*x^7 + 295*x^6 + 980*x^5 - 2058*x^4 + 980*x^3 + 295*x^2 - 255*x + 1) for i in range(len(f)): if f[i][0].degree() == 1: # 次数1の因子があった場合 print "{} {}".format(p, f) result.append(p) break print result
結果は以下の通り:
509 (x + 22) * (x + 35) * (x + 160) * (x + 162) * (x + 231) * (x + 328) * (x + 379) * (x + 464) 521 (x + 62) * (x + 200) * (x + 202) * (x + 232) * (x + 310) * (x + 393) * (x + 472) * (x + 479) 541 (x + 84) * (x + 97) * (x + 196) * (x + 295) * (x + 380) * (x + 396) * (x + 472) * (x + 530) 569 (x + 12) * (x + 92) * (x + 167) * (x + 230) * (x + 286) * (x + 332) * (x + 380) * (x + 522) 701 (x + 11) * (x + 255) * (x + 271) * (x + 323) * (x + 507) * (x + 599) * (x + 616) * (x + 668) 761 (x + 31) * (x + 117) * (x + 352) * (x + 491) * (x + 534) * (x + 567) * (x + 710) * (x + 748) 829 (x + 9) * (x + 69) * (x + 288) * (x + 308) * (x + 402) * (x + 431) * (x + 737) * (x + 817) 1181 (x + 233) * (x + 283) * (x + 459) * (x + 528) * (x + 633) * (x + 664) * (x + 705) * (x + 964) 1289 (x + 149) * (x + 277) * (x + 317) * (x + 364) * (x + 372) * (x + 470) * (x + 675) * (x + 988) 1801 (x + 703) * (x + 939) * (x + 959) * (x + 1035) * (x + 1053) * (x + 1192) * (x + 1316) * (x + 1553) 1949 (x + 322) * (x + 439) * (x + 515) * (x + 729) * (x + 909) * (x + 1246) * (x + 1547) * (x + 1834) 2029 (x + 200) * (x + 206) * (x + 344) * (x + 348) * (x + 871) * (x + 1113) * (x + 1329) * (x + 1421) 2069 (x + 227) * (x + 257) * (x + 636) * (x + 865) * (x + 875) * (x + 1217) * (x + 1892) * (x + 2052) 2141 (x + 65) * (x + 381) * (x + 987) * (x + 1100) * (x + 1141) * (x + 1388) * (x + 1614) * (x + 1633) 2269 (x + 33) * (x + 405) * (x + 665) * (x + 737) * (x + 902) * (x + 1952) * (x + 1994) * (x + 2133) 2309 (x + 262) * (x + 321) * (x + 633) * (x + 723) * (x + 1010) * (x + 1084) * (x + 1105) * (x + 1534) 2381 (x + 183) * (x + 603) * (x + 845) * (x + 1070) * (x + 1184) * (x + 1376) * (x + 1874) * (x + 2134) 2441 (x + 78) * (x + 179) * (x + 411) * (x + 879) * (x + 1530) * (x + 1909) * (x + 2232) * (x + 2291) 2549 (x + 673) * (x + 816) * (x + 831) * (x + 959) * (x + 1411) * (x + 1462) * (x + 1543) * (x + 2246) 2621 (x + 182) * (x + 1047) * (x + 1497) * (x + 1622) * (x + 1666) * (x + 1952) * (x + 2335) * (x + 2549) 2749 (x + 47) * (x + 117) * (x + 863) * (x + 1383) * (x + 1667) * (x + 2182) * (x + 2218) * (x + 2264) 2861 (x + 12) * (x + 484) * (x + 485) * (x + 584) * (x + 1669) * (x + 2534) * (x + 2595) * (x + 2826) [509, 521, 541, 569, 701, 761, 829, 1181, 1289, 1801, 1949, 2029, 2069, 2141, 2269, 2309, 2381, 2441, 2549, 2621, 2749, 2861]
よって、 については、 の形で表せるということですね。
実際、2次形式で表せることは以下のように確認できます。
for p in result: for y in range(1,3): x = p - 505*y*y if x.is_square(): print "{} == {}^2 + 505 {}^2".format(p, sqrt(x), y) break
結果は次の通りです。
509 == 2^2 + 505 1^2 521 == 4^2 + 505 1^2 541 == 6^2 + 505 1^2 569 == 8^2 + 505 1^2 701 == 14^2 + 505 1^2 761 == 16^2 + 505 1^2 829 == 18^2 + 505 1^2 1181 == 26^2 + 505 1^2 1289 == 28^2 + 505 1^2 1801 == 36^2 + 505 1^2 1949 == 38^2 + 505 1^2 2029 == 3^2 + 505 2^2 2069 == 7^2 + 505 2^2 2141 == 11^2 + 505 2^2 2269 == 42^2 + 505 1^2 2309 == 17^2 + 505 2^2 2381 == 19^2 + 505 2^2 2441 == 44^2 + 505 1^2 2549 == 23^2 + 505 2^2 2621 == 46^2 + 505 1^2 2749 == 27^2 + 505 2^2 2861 == 29^2 + 505 2^2
参考文献
- 作者:David A. Cox
- 出版社/メーカー: Wiley
- 発売日: 2013/04/29
- メディア: ペーパーバック