Pebble Coding

ソフトウェアエンジニアによるIT関連技術の備忘録

Nagell-Lutzの定理

Nagell-Lutzの定理

y^{2}=x^{3} + a x^{2} + b x + c を整数係数a,b,cを持つ非特異3次曲線とする。
P=(x,y)を有限位数の有理点とする時 x,yは整数である。

これは、整数ではない有理点が存在するときは、無限位数となるということも同時に示している。

例えば、y^{2} = x^{3} + 2 (a=0, b=0, c=2)の場合を考えると、
 P = (-1, 1) は有理点だが、この曲線の2倍公式(c=2)

 x1 = \frac { x^{4} - 8cx } {4 x^{3} + 4c}

 y1 = \sqrt {x1^{3} + c}
を使って求めた2P,4Pは
2P: ( \frac {17} {4}, \frac {71} {8} )
4P: ( \frac {66113} {80656}, \frac {36583777} {22906304})
のようになる。
(本当は3Pを計算したかったが複雑になるので代わりに4Pを計算した)
この点をいくら加算していっても、有限回で無限遠点に到達することはなく、これらは有限位数の有利点ではない。
ちなみにこの楕円関数の有限位数の点は無限遠点しかない。

この2倍公式の計算はpythonを用いた。 (実はこの記事の主題はこれである。)

from math import *
from fractions import Fraction
from sys import *

def twice(x, y):
    x2 = (x*x*x*x-16*x)/(4*x*x*x+8)
    y2 = sqrt_frac(x2*x2*x2+2)
    return x2, y2

def sqrt_frac(x):
    n = x.numerator
    d = x.denominator
    r_n = 0
    r_d = 1
    found = False 
    for i in range(100000000):
        if i*i == n:
            r_n = i
            found = True
            break
        if i*i > n:
            break
    if not found:
        sys.exit()

    found = False
    for i in range(100000000):
        if i*i == d:
            r_d = i
            found = True
            break
        if i*i > d:
            break
    if not found:
        sys.exit()

    return Fraction(r_n, r_d)

r1x, r1y = twice(Fraction(-1), Fraction(1)) 
print(r1x, r1y)
r2x, r2y = twice(r1x, r1y)
print(r2x, r2y)
r3x, r3y = twice(r2x, r2y)
print(r3x, r3y)

有理数の計算にはFractionを用いた。
整数のsqrtを計算方法が分からなかったので、自前で関数を作った。
このプログラムでは、8P=(r3x, r3y)を求めるには精度が足りずにクラッシュする。

参考:http://www.u.dendai.ac.jp/~ochi/algeoB_05.pdf

それにしても、fractionをフル精度でsqrtしてくれるライブラリってないのかな。