tsujimotterのノートブック

日曜数学者 tsujimotter の「趣味で数学」実践ノート

#2020になる数式 (マニアック編):判別式-2020の2次形式

2020年最初に作ったアプリが、おかげさまでたくさんの方にみてもらえているようです。


上のアプリを公開後も、tsujimotterは「2020に関する数学トピック」についてあれこれ考えていました。今回紹介したいのは「2次形式で表せる素数」のお話です。上の話と比べると、かなり前提知識が必要な話なのですが、よろしければお付き合いください。


判別式 -2020 の2次形式で表せる素数

今回は、判別式  D = -2020 の2次形式

 X^2 + 505Y^2

で表現できる素数の条件について考えたいと思います。


このような問題に対しては、虚2次体を考えるのが常套手段です。虚2次体  K = \mathbb{Q}(\sqrt{-505}) において、素数  p K の整数環  \mathcal{O}_K の素イデアル  \mathfrak{p}, \mathfrak{p}' を用いて

 (p) = \mathfrak{p}\mathfrak{p}' \tag{1}

のように素イデアル分解される条件を考えます。 (p) が式  (1) のように2つの素イデアルに分解できるという条件に加えて、さらに \mathfrak{p}, \mathfrak{p}' が単項イデアルであれば p X^2 + nY^2 の形で表すことができます。


残念ながら、 \mathfrak{p}, \mathfrak{p}' は常に単項イデアルになるとは限りません。あとで計算するように  \mathbb{Q}(\sqrt{-505}) のイデアル類群は

 \operatorname{Cl}(\mathbb{Q}(\sqrt{-505})) \simeq C_4 \times C_2 \tag{2}

なので  h(-2020) = h(\mathbb{Q}(\sqrt{-505})) = 8 です。つまり  \mathcal{O}_{\mathbb{Q}(\sqrt{-505})} はPIDではありません。

よって、素イデアル  \mathfrak{p}, \mathfrak{p}' が単項イデアルかどうかは、別途判定する必要があります。


その辺の諸々の事情をひっくるめて、 p X^2 + 505Y^2 によって表現できる必要十分条件は、次のように表すことができます。

定理(参考文献のTheorem 5.1.)
 n を正の整数とし、次の条件 (i), (ii) を満たすとする:
(i)  n は平方因子を持たない
(ii)  n \equiv 3 \pmod{4}

このとき、 D = -4n とすると、次数  h(D) のモニックかつ既約な多項式  f_n(x) \in \mathbb{Z}[x] が存在し、 n f_n(x) の判別式のどちらも割らない奇素数  p について次が成り立つ:

整数  X, Y が存在し  p = X^2+nY^2  \Longleftrightarrow  \left( \cfrac{D}{p} \right) = 1 かつ  f_n(x) \equiv 0 \pmod{p} が整数解を持つ

 f_n(x) L = K(\alpha) K = \mathbb{Q}(\sqrt{-n}) のヒルベルト類体であるような実代数的整数  \alpha の最小多項式としてとることができる。

かなりややこしい定理ですね。上の定理の意味の解説については、次のスライドで紹介していますので、よかったらご覧ください:
www.slideshare.net


さて、 n = 505 として定理を適用しましょう。 n は上の条件 (i), (ii) を満たすことに注意します。

このとき、次数が  h(-2020) = 8 の整係数多項式  f_{505}(x) が存在して、その実根を  \alpha とすると  L = K(\alpha) K のヒルベルト類体になります。


 f_{505}(x) をどうやって求めたらよいでしょうか。これについては自分で計算するのは大変そうなので、SageMathの機能をお借りしましょう。

SageMathは次のページのCoCalcというところから利用できます。インストールしなくてもウェブ上で使えて便利です。
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

結果の英文をよむと、たしかに  K = \mathbb{Q}(\sqrt{-505}) のイデアル類群は位数が 8 で、その構造は  C_4 \times C_2 に同型であることがわかりますね。


次は  K のヒルベルト類体を計算するコードです。

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(定義多項式)が  f_{505}(x) です。

 f_{505}(x) = x^8 - 255x^7 + 295x^6 + 980x^5 - 2058x^4 + 980x^3 + 295x^2 - 255x + 1

実際、 f_{505}(x) は次数  8 であり、さらに整係数の多項式であることが確認できますね。

素数  p X^2 + 505Y^2 で表せる必要十分条件

したがって、 p = X^2 + 505Y^2 とかける必要十分条件が次のように具体的に表せます:

 p \neq 5, 101 f_{505}(x) の判別式を割らない奇素数とする。このとき次が成り立つ:

整数  X, Y が存在し  p = X^2+505Y^2
 \Longleftrightarrow  \left(\cfrac{-2020}{p}\right) = 1 かつ  f_{505}(x) = x^8 - 255x^7 + 295x^6 + 980x^5 - 2058x^4 + 980x^3 + 295x^2 - 255x + 1 \equiv 0 \pmod{p} が整数解を持つ


なお、 f_{505}(x) の判別式は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

よって

 p \neq 2, 3, 5, 17, 101

としておけば良さそうですね。

具体例 (1)

さて、これを確認するのはなかなかしんどそうですね。今回は2つの具体例を確認して終わりにしましょう。1つ目の具体例は  p = 509 です。

まず平方剰余の条件は次のようになります。

 \displaystyle \begin{align} \left(\frac{-2020}{509}\right) &= \left(\frac{-1}{509}\right)\left(\frac{5}{509}\right)\left(\frac{101}{509}\right) \\
&= \left(\frac{-1}{509}\right)\left(\frac{509}{5}\right)\left(\frac{509}{101}\right) \\
&= \left(\frac{-1}{509}\right)\left(\frac{4}{5}\right)\left(\frac{4}{101}\right) \end{align}

2番目の等号では平方剰余の相互法則を使いました。

右辺のルジャンドル記号がすべて  +1 になることは簡単にわかります。よって

 \displaystyle \left(\frac{-2020}{509}\right) = +1

が得られました。


次に  f_{505}(x) \equiv 0 \pmod{509} ですが、これは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)

 (x + 22) が因子に入っていることから、少なくとも根  x \equiv -22 \pmod{509} があることがわかりますね。よって、 p = 509 は条件を満たします。


したがって、 p = 509 X^2 + 505Y^2 の形で表せるはずですが、実際

 509 = 2^2 + 505\cdot 1^2

と表せます。たしかに成り立っていますね!

具体例 (2)

2つ目の具体例は  p = 2029 です。

まず平方剰余の条件は次のようになります。

 \displaystyle \begin{align} \left(\frac{-2020}{2029}\right) &= \left(\frac{-1}{2029}\right)\left(\frac{5}{2029}\right)\left(\frac{101}{2029}\right) \\
&= \left(\frac{-1}{2029}\right)\left(\frac{2029}{5}\right)\left(\frac{2029}{101}\right) \\
&= \left(\frac{-1}{2029}\right)\left(\frac{4}{5}\right)\left(\frac{9}{101}\right) \end{align}

1つ目の例と同様に、右辺のルジャンドル記号がすべて  +1 になることは簡単にわかります。よって

 \displaystyle \left(\frac{-2020}{2029}\right) = +1

が得られました。


次に  f_{505}(x) \equiv 0 \pmod{2029} ですが、これは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)

 (x + 200) が因子に入っていることから、少なくとも根  x \equiv -200 \pmod{2029} があることがわかりますね。よって、 p = 2029 は条件を満たします。


したがって、 p = 2029 X^2 + 505Y^2 の形で表せるはずですが、実際

 2029 = 3^2 + 505\cdot 2^2

と表せます。たしかに成り立っていますね!

今回の場合、 X^2 + 505Y^2 Y の部分が、たまたま  Y = 2 になりました。よって、こんな風に変形ができます。

 2029 = 3^2 + 505\cdot 2^2 = 3^2 + 2020\cdot 1^2

まさに2020という数式ができあがりましたね!



お正月から整数論を堪能しましたので、そろそろ終わりにしたいと思います。

それでは今日はこの辺で。

おまけ:SageMath で  p < 3000 までの例を全て計算する

SageMathを使って、定理の条件を一気に確認する方法がわかりましたので、紹介します。

 p < 3000 の範囲で確認するコードです。

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]

よって、 p = 509, 521, 541, 569, 701, 761, 829, 1181, 1289, 1801, 1949, 2029, 2069, 2141, 2269, 2309, 2381, 2441, 2549, 2621, 2749, 2861 については、 p = X^2 + 505Y^2 の形で表せるということですね。


実際、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