Global and semi-global minimal models for elliptic curves over number fields

When E is an elliptic curve defined over a number field K of class number 1, then it has a global minimal model, and we have a method to compute it, namely E.global_minimal_model(). Until Sage-6.7 this was done using Tate’s algorithm to minimise one prime at a time without affecting the other primes. When the class number is not 1, a different approach is used.

In the general case global minimal models may or may not exist. This module includes functions to determine this, and to find a global minimal model when it does exist. The obstruction to the existence of a global minimal model is encoded in an ideal class, which is trivial if and only if a global minimal model exists: we provide a function which returns this class. When the obstruction is not trivial, there exist models which are minimal at all primes except at a single prime in the obstruction class, where the discriminant valuation is 12 more than the minimal valuation at that prime; we provide a function to return such a model.

The implementation of this functionality is based on work of Kraus [Kra1989] which gives a local condition for when a pair of number field elements c4, c6 belong to a Weierstrass model which is integral at a prime P, together with a global version. Only primes dividing 2 or 3 are hard to deal with. In order to compute the corresponding integral model one then needs to combine together the local transformations implicit in [Kra1989] into a single global one.

Various utility functions relating to the testing and use of Kraus’s conditions are included here.

AUTHORS:

  • John Cremona (2015)

sage.schemes.elliptic_curves.kraus.c4c6_model(c4, c6, assume_nonsingular=False)[source]

Return the elliptic curve [0,0,0,-c4/48,-c6/864] with given c-invariants.

INPUT:

  • c4, c6 – elements of a number field

  • assume_nonsingular – boolean (default: False); if True, check for integrality and nosingularity

OUTPUT:

The elliptic curve with a-invariants [0,0,0,c4/48,c6/864], whose c-invariants are the given c4, c6. If the supplied invariants are singular, returns None when assume_nonsingular is False and raises an ArithmeticError otherwise.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.kraus import c4c6_model
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^3 - 10)                                             # needs sage.rings.number_field
sage: c4c6_model(-217728*a - 679104, 141460992*a + 409826304)                   # needs sage.rings.number_field
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
 over Number Field in a with defining polynomial x^3 - 10

sage: c4, c6 = EllipticCurve('389a1').c_invariants()
sage: c4c6_model(c4,c6)
Elliptic Curve defined by y^2 = x^3 - 7/3*x + 107/108 over Rational Field
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.kraus import c4c6_model
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field
>>> c4c6_model(-Integer(217728)*a - Integer(679104), Integer(141460992)*a + Integer(409826304))                   # needs sage.rings.number_field
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
 over Number Field in a with defining polynomial x^3 - 10

>>> c4, c6 = EllipticCurve('389a1').c_invariants()
>>> c4c6_model(c4,c6)
Elliptic Curve defined by y^2 = x^3 - 7/3*x + 107/108 over Rational Field
from sage.schemes.elliptic_curves.kraus import c4c6_model
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^3 - 10)                                             # needs sage.rings.number_field
c4c6_model(-217728*a - 679104, 141460992*a + 409826304)                   # needs sage.rings.number_field
c4, c6 = EllipticCurve('389a1').c_invariants()
c4c6_model(c4,c6)
sage.schemes.elliptic_curves.kraus.c4c6_nonsingular(c4, c6)[source]

Check if c4, c6 are integral with valid associated discriminant.

INPUT:

  • c4, c6 – elements of a number field

OUTPUT:

Boolean, True if c4, c6 are both integral and c43c62 is a nonzero multiple of 1728.

EXAMPLES:

Over Q:

sage: from sage.schemes.elliptic_curves.kraus import c4c6_nonsingular
sage: c4c6_nonsingular(0,0)
False
sage: c4c6_nonsingular(0,1/2)
False
sage: c4c6_nonsingular(2,3)
False
sage: c4c6_nonsingular(4,8)
False
sage: all(c4c6_nonsingular(*E.c_invariants()) for E in cremona_curves([    11..100]))
True
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.kraus import c4c6_nonsingular
>>> c4c6_nonsingular(Integer(0),Integer(0))
False
>>> c4c6_nonsingular(Integer(0),Integer(1)/Integer(2))
False
>>> c4c6_nonsingular(Integer(2),Integer(3))
False
>>> c4c6_nonsingular(Integer(4),Integer(8))
False
>>> all(c4c6_nonsingular(*E.c_invariants()) for E in cremona_curves((ellipsis_range(    Integer(11),Ellipsis,Integer(100)))))
True
from sage.schemes.elliptic_curves.kraus import c4c6_nonsingular
c4c6_nonsingular(0,0)
c4c6_nonsingular(0,1/2)
c4c6_nonsingular(2,3)
c4c6_nonsingular(4,8)
all(c4c6_nonsingular(*E.c_invariants()) for E in cremona_curves([    11..100]))

Over number fields:

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
True
sage: K.<a> = NumberField(x^3 - 10)
sage: c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
True
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4c6_nonsingular(-Integer(217728)*a - Integer(679104), Integer(141460992)*a + Integer(409826304))
True
>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4c6_nonsingular(-Integer(217728)*a - Integer(679104), Integer(141460992)*a + Integer(409826304))
True
# needs sage.rings.number_field
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
K.<a> = NumberField(x^3 - 10)
c4c6_nonsingular(-217728*a - 679104, 141460992*a + 409826304)
sage.schemes.elliptic_curves.kraus.check_Kraus_global(c4, c6, assume_nonsingular=False, debug=False)[source]

Test if c4, c6 satisfy Kraus’s conditions at all primes.

INPUT:

  • c4, c6 – elements of a number field

  • assume_nonsingular – boolean (default: False); if True, check for integrality and nonsingularity

OUTPUT:

Either False if Kraus’s conditions fail, or, if they pass, an elliptic curve E which is integral and has c-invariants c4, c6.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_global
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
sage: c4, c6 = E.c_invariants()
sage: check_Kraus_global(c4,c6,debug=True)
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 3
Using b2=a + 1 gives a model integral at 3:
(0, 1/4*a + 1/4, 0, 10091/8*a - 128595/16, 4097171/64*a - 19392359/64)
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 2
Using (a1,a3)=(3*a,0) gives a model integral at 2:
(3*a, 0, 0, 3784/3*a - 23606/3, 1999160/27*a - 9807634/27)
(a1, b2, a3) = (3*a, a + 1, 0)
Using (r, s, t)=(1/3*a - 133/6, 3/2*a, -89/2*a + 5) should give a global integral model...
...and it does!
Elliptic Curve defined by
 y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
 over Number Field in a with defining polynomial x^2 - 10

sage: # needs sage.rings.number_field
sage: K.<a> = NumberField(x^2 - 15)
sage: E = EllipticCurve([0, 0, 0, 4536*a + 14148, -163728*a - 474336])
sage: c4, c6 = E.c_invariants()
sage: check_Kraus_global(c4,c6)
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
 over Number Field in a with defining polynomial x^2 - 15
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import check_Kraus_global
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> E = EllipticCurve([a,a,Integer(0),Integer(1263)*a-Integer(8032),Integer(62956)*a-Integer(305877)])
>>> c4, c6 = E.c_invariants()
>>> check_Kraus_global(c4,c6,debug=True)
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 3
Using b2=a + 1 gives a model integral at 3:
(0, 1/4*a + 1/4, 0, 10091/8*a - 128595/16, 4097171/64*a - 19392359/64)
Local Kraus conditions for (c4,c6)=(-60544*a + 385796,-55799680*a + 262126328) pass at all primes dividing 2
Using (a1,a3)=(3*a,0) gives a model integral at 2:
(3*a, 0, 0, 3784/3*a - 23606/3, 1999160/27*a - 9807634/27)
(a1, b2, a3) = (3*a, a + 1, 0)
Using (r, s, t)=(1/3*a - 133/6, 3/2*a, -89/2*a + 5) should give a global integral model...
...and it does!
Elliptic Curve defined by
 y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
 over Number Field in a with defining polynomial x^2 - 10

>>> # needs sage.rings.number_field
>>> K = NumberField(x**Integer(2) - Integer(15), names=('a',)); (a,) = K._first_ngens(1)
>>> E = EllipticCurve([Integer(0), Integer(0), Integer(0), Integer(4536)*a + Integer(14148), -Integer(163728)*a - Integer(474336)])
>>> c4, c6 = E.c_invariants()
>>> check_Kraus_global(c4,c6)
Elliptic Curve defined by y^2 = x^3 + (4536*a+14148)*x + (-163728*a-474336)
 over Number Field in a with defining polynomial x^2 - 15
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import check_Kraus_global
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
c4, c6 = E.c_invariants()
check_Kraus_global(c4,c6,debug=True)
# needs sage.rings.number_field
K.<a> = NumberField(x^2 - 15)
E = EllipticCurve([0, 0, 0, 4536*a + 14148, -163728*a - 474336])
c4, c6 = E.c_invariants()
check_Kraus_global(c4,c6)

TESTS (see Issue #17295):

sage: # needs sage.rings.number_field
sage: K.<a> = NumberField(x^3 - 7*x - 5)
sage: E = EllipticCurve([a, 0, 1, 2*a^2 + 5*a + 3, -a^2 - 3*a - 2])
sage: assert E.conductor().norm() == 8
sage: G = K.galois_group(names='b')
sage: def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()])
sage: EL = conj_curve(E,G[0])
sage: L = EL.base_field()
sage: assert L.class_number() == 2
sage: EL.isogeny_class()  # long time (~10s)
Isogeny class of Elliptic Curve defined by
 y^2 + (-1/90*b^4+7/18*b^2-1/2*b-98/45)*x*y + y = x^3 + (1/45*b^5-1/18*b^4-7/9*b^3+41/18*b^2+167/90*b-29/9)*x + (-1/90*b^5+1/30*b^4+7/18*b^3-4/3*b^2-61/90*b+11/5)
 over Number Field in b with defining polynomial x^6 - 42*x^4 + 441*x^2 - 697
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = NumberField(x**Integer(3) - Integer(7)*x - Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> E = EllipticCurve([a, Integer(0), Integer(1), Integer(2)*a**Integer(2) + Integer(5)*a + Integer(3), -a**Integer(2) - Integer(3)*a - Integer(2)])
>>> assert E.conductor().norm() == Integer(8)
>>> G = K.galois_group(names='b')
>>> def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()])
>>> EL = conj_curve(E,G[Integer(0)])
>>> L = EL.base_field()
>>> assert L.class_number() == Integer(2)
>>> EL.isogeny_class()  # long time (~10s)
Isogeny class of Elliptic Curve defined by
 y^2 + (-1/90*b^4+7/18*b^2-1/2*b-98/45)*x*y + y = x^3 + (1/45*b^5-1/18*b^4-7/9*b^3+41/18*b^2+167/90*b-29/9)*x + (-1/90*b^5+1/30*b^4+7/18*b^3-4/3*b^2-61/90*b+11/5)
 over Number Field in b with defining polynomial x^6 - 42*x^4 + 441*x^2 - 697
# needs sage.rings.number_field
K.<a> = NumberField(x^3 - 7*x - 5)
E = EllipticCurve([a, 0, 1, 2*a^2 + 5*a + 3, -a^2 - 3*a - 2])
assert E.conductor().norm() == 8
G = K.galois_group(names='b')
def conj_curve(E, sigma): return EllipticCurve([sigma(a) for a in E.ainvs()])
EL = conj_curve(E,G[0])
L = EL.base_field()
assert L.class_number() == 2
EL.isogeny_class()  # long time (~10s)
sage.schemes.elliptic_curves.kraus.check_Kraus_local(c4, c6, P, assume_nonsingular=False)[source]

Check Kraus’s conditions locally at a prime P.

INPUT:

  • c4, c6 – elements of a number field

  • P – a prime ideal of the number field

  • assume_nonsingular – boolean (default: False); if True, check for integrality and nonsingularity

OUTPUT:

Tuple: either (True, E) if there is a Weierstrass model E integral at P and with invariants c4, c6, or (False, None) if there is none.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 15)
sage: P2 = K.primes_above(2)[0]
sage: P3 = K.primes_above(3)[0]
sage: P5 = K.primes_above(5)[0]
sage: E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
sage: c4, c6 = E.c_invariants()
sage: flag, E = check_Kraus_local(c4,c6,P2); flag
True
sage: E.is_local_integral_model(P2) and (c4,c6)==E.c_invariants()
True
sage: flag, E = check_Kraus_local(c4,c6,P3); flag
True
sage: E.is_local_integral_model(P3) and (c4,c6)==E.c_invariants()
True
sage: flag, E = check_Kraus_local(c4,c6,P5); flag
True
sage: E.is_local_integral_model(P5) and (c4,c6)==E.c_invariants()
True

sage: # needs sage.rings.number_field
sage: c4 = 123+456*a
sage: c6 = 789+101112*a
sage: check_Kraus_local(c4,c6,P2)
(False, None)
sage: check_Kraus_local(c4,c6,P3)
(False, None)
sage: check_Kraus_local(c4,c6,P5)
(False, None)
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import check_Kraus_local
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(15), names=('a',)); (a,) = K._first_ngens(1)
>>> P2 = K.primes_above(Integer(2))[Integer(0)]
>>> P3 = K.primes_above(Integer(3))[Integer(0)]
>>> P5 = K.primes_above(Integer(5))[Integer(0)]
>>> E = EllipticCurve([a,a,Integer(0),Integer(1263)*a-Integer(8032),Integer(62956)*a-Integer(305877)])
>>> c4, c6 = E.c_invariants()
>>> flag, E = check_Kraus_local(c4,c6,P2); flag
True
>>> E.is_local_integral_model(P2) and (c4,c6)==E.c_invariants()
True
>>> flag, E = check_Kraus_local(c4,c6,P3); flag
True
>>> E.is_local_integral_model(P3) and (c4,c6)==E.c_invariants()
True
>>> flag, E = check_Kraus_local(c4,c6,P5); flag
True
>>> E.is_local_integral_model(P5) and (c4,c6)==E.c_invariants()
True

>>> # needs sage.rings.number_field
>>> c4 = Integer(123)+Integer(456)*a
>>> c6 = Integer(789)+Integer(101112)*a
>>> check_Kraus_local(c4,c6,P2)
(False, None)
>>> check_Kraus_local(c4,c6,P3)
(False, None)
>>> check_Kraus_local(c4,c6,P5)
(False, None)
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import check_Kraus_local
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 15)
P2 = K.primes_above(2)[0]
P3 = K.primes_above(3)[0]
P5 = K.primes_above(5)[0]
E = EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
c4, c6 = E.c_invariants()
flag, E = check_Kraus_local(c4,c6,P2); flag
E.is_local_integral_model(P2) and (c4,c6)==E.c_invariants()
flag, E = check_Kraus_local(c4,c6,P3); flag
E.is_local_integral_model(P3) and (c4,c6)==E.c_invariants()
flag, E = check_Kraus_local(c4,c6,P5); flag
E.is_local_integral_model(P5) and (c4,c6)==E.c_invariants()
# needs sage.rings.number_field
c4 = 123+456*a
c6 = 789+101112*a
check_Kraus_local(c4,c6,P2)
check_Kraus_local(c4,c6,P3)
check_Kraus_local(c4,c6,P5)
sage.schemes.elliptic_curves.kraus.check_Kraus_local_2(c4, c6, P, a1=None, assume_nonsingular=False)[source]

Test if c4, c6 satisfy Kraus’s conditions at a prime P dividing 2.

INPUT:

  • c4, c6 – integral elements of a number field

  • P – a prime ideal of the number field which divides 2

  • a1 – an integral elements of a number field, or None (default)

  • assume_nonsingular – boolean (default: False); if True, check for integrality and nonsingularity

OUTPUT:

Either (False, 0, 0) if Kraus’s conditions fail, or (True, a1, a3) if they pass, in which case the elliptic curve which is the (a12/12,a1/2,a3/2)-transform of [0,0,0,c4/48,c6/864] is integral at P. If a1 is provided and valid then the output will be (True, a1, a3) for suitable a3.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_2
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796  # EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
sage: c6 = -55799680*a + 262126328
sage: P = K.primes_above(2)[0]
sage: check_Kraus_local_2(c4,c6,P)
(True, a, 0)
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import check_Kraus_local_2
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)  # EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> P = K.primes_above(Integer(2))[Integer(0)]
>>> check_Kraus_local_2(c4,c6,P)
(True, a, 0)
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import check_Kraus_local_2
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796  # EllipticCurve([a,a,0,1263*a-8032,62956*a-305877])
c6 = -55799680*a + 262126328
P = K.primes_above(2)[0]
check_Kraus_local_2(c4,c6,P)
sage.schemes.elliptic_curves.kraus.check_Kraus_local_3(c4, c6, P, assume_nonsingular=False, debug=False)[source]

Test if c4, c6 satisfy Kraus’s conditions at a prime P dividing 3.

INPUT:

  • c4, c6 – elements of a number field

  • P – a prime ideal of the number field which divides 3

  • assume_nonsingular – boolean (default: False); if True, check for integrality and nosingularity

OUTPUT:

Either (False, 0) if Kraus’s conditions fail, or (True, b2) if they pass, in which case the elliptic curve which is the (b2/12,0,0)-transform of [0,0,0,c4/48,c6/864] is integral at P.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import check_Kraus_local_3
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: P3a, P3b = K.primes_above(3)
sage: check_Kraus_local_3(c4,c6,P3a)
(True, 0)
sage: check_Kraus_local_3(c4,c6,P3b)
(True, -a)
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import check_Kraus_local_3
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> P3a, P3b = K.primes_above(Integer(3))
>>> check_Kraus_local_3(c4,c6,P3a)
(True, 0)
>>> check_Kraus_local_3(c4,c6,P3b)
(True, -a)
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import check_Kraus_local_3
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
P3a, P3b = K.primes_above(3)
check_Kraus_local_3(c4,c6,P3a)
check_Kraus_local_3(c4,c6,P3b)

An example in a field where 3 is ramified:

sage: # needs sage.rings.number_field
sage: K.<a> = NumberField(x^2 - 15)
sage: c4 = -60504*a + 386001
sage: c6 = -55346820*a + 261045153
sage: P3 = K.primes_above(3)[0]
sage: check_Kraus_local_3(c4,c6,P3)
(True, a)
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> K = NumberField(x**Integer(2) - Integer(15), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60504)*a + Integer(386001)
>>> c6 = -Integer(55346820)*a + Integer(261045153)
>>> P3 = K.primes_above(Integer(3))[Integer(0)]
>>> check_Kraus_local_3(c4,c6,P3)
(True, a)
# needs sage.rings.number_field
K.<a> = NumberField(x^2 - 15)
c4 = -60504*a + 386001
c6 = -55346820*a + 261045153
P3 = K.primes_above(3)[0]
check_Kraus_local_3(c4,c6,P3)
sage.schemes.elliptic_curves.kraus.make_integral(a, P, e)[source]

Return b in OK with Pe|(ab), given a in OK,P.

INPUT:

  • a – a number field element integral at P

  • P – a prime ideal of the number field

  • e – positive integer

OUTPUT:

A globally integral number field element b which is congruent to a modulo Pe.

ALGORITHM:

Totally naive, we simply test residues modulo Pe until one works. We will only use this when P is a prime dividing 2 and e is the ramification degree, so the number of residues to check is at worst 2d where d is the degree of the field.

EXAMPLES:

sage: from sage.schemes.elliptic_curves.kraus import make_integral

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: P = K.primes_above(2)[0]
sage: e = P.ramification_index(); e
2
sage: x = 1/5
sage: b = make_integral(x, P, e); b
1
sage: (b-x).valuation(P) >= e
True
sage: make_integral(1/a, P, e)
Traceback (most recent call last):
...
ArithmeticError: Cannot lift 1/10*a to O_K mod (Fractional ideal (2, a))^2
>>> from sage.all import *
>>> from sage.schemes.elliptic_curves.kraus import make_integral

>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.primes_above(Integer(2))[Integer(0)]
>>> e = P.ramification_index(); e
2
>>> x = Integer(1)/Integer(5)
>>> b = make_integral(x, P, e); b
1
>>> (b-x).valuation(P) >= e
True
>>> make_integral(Integer(1)/a, P, e)
Traceback (most recent call last):
...
ArithmeticError: Cannot lift 1/10*a to O_K mod (Fractional ideal (2, a))^2
from sage.schemes.elliptic_curves.kraus import make_integral
# needs sage.rings.number_field
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
P = K.primes_above(2)[0]
e = P.ramification_index(); e
x = 1/5
b = make_integral(x, P, e); b
(b-x).valuation(P) >= e
make_integral(1/a, P, e)
sage.schemes.elliptic_curves.kraus.semi_global_minimal_model(E, debug=False)[source]

Return a global minimal model for this elliptic curve if it exists, or a model minimal at all but one prime otherwise.

INPUT:

  • E – an elliptic curve over a number field

  • debug – boolean (default: False); if True, prints some messages about the progress of the computation

OUTPUT:

A tuple (Emin, I) where Emin is an elliptic curve which is either a global minimal model of E if one exists (i.e., an integral model which is minimal at every prime), or a semi-global minimal model (i.e., an integral model which is minimal at every prime except one). I is the unit ideal of Emin is a global minimal model, else is the unique prime at which Emin is not minimal. Thus in all cases, Emin.minimal_discriminant_ideal() * I**12 == (E.discriminant()).

Note

This function is normally not called directly by users, who will use the elliptic curve method global_minimal_model() instead; that method also applied various reductions after minimising the model.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: K.class_number()
2
sage: E = EllipticCurve([0,0,0,-186408*a - 589491, 78055704*a + 246833838])
sage: from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
sage: Emin, P = semi_global_minimal_model(E)
sage: Emin
Elliptic Curve defined by
 y^2 + 3*x*y + (2*a-11)*y = x^3 + (a-10)*x^2 + (-152*a-415)*x + (1911*a+5920)
 over Number Field in a with defining polynomial x^2 - 10
sage: E.minimal_discriminant_ideal()*P**12 == K.ideal(Emin.discriminant())
True
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> K.class_number()
2
>>> E = EllipticCurve([Integer(0),Integer(0),Integer(0),-Integer(186408)*a - Integer(589491), Integer(78055704)*a + Integer(246833838)])
>>> from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
>>> Emin, P = semi_global_minimal_model(E)
>>> Emin
Elliptic Curve defined by
 y^2 + 3*x*y + (2*a-11)*y = x^3 + (a-10)*x^2 + (-152*a-415)*x + (1911*a+5920)
 over Number Field in a with defining polynomial x^2 - 10
>>> E.minimal_discriminant_ideal()*P**Integer(12) == K.ideal(Emin.discriminant())
True
# needs sage.rings.number_field
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
K.class_number()
E = EllipticCurve([0,0,0,-186408*a - 589491, 78055704*a + 246833838])
from sage.schemes.elliptic_curves.kraus import semi_global_minimal_model
Emin, P = semi_global_minimal_model(E)
Emin
E.minimal_discriminant_ideal()*P**12 == K.ideal(Emin.discriminant())
sage.schemes.elliptic_curves.kraus.sqrt_mod_4(x, P)[source]

Return a local square root mod 4, if it exists.

INPUT:

  • x – an integral number field element

  • P – a prime ideal of the number field dividing 2

OUTPUT:

A pair (True, r) where that r2x has valuation at least 2e, or (False, 0) if there is no such r. Note that r2modP2e only depends on rmodPe.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import sqrt_mod_4
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: P = K.primes_above(2)[0]
sage: sqrt_mod_4(1 + 2*a, P)
(False, 0)
sage: sqrt_mod_4(-1 + 2*a, P)
(True, a + 1)
sage: (1+a)^2 - (-1 + 2*a)
12
sage: e = P.ramification_index()
sage: ((1+a)^2 - (-1+2*a)).mod(P**e)
0
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import sqrt_mod_4
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.primes_above(Integer(2))[Integer(0)]
>>> sqrt_mod_4(Integer(1) + Integer(2)*a, P)
(False, 0)
>>> sqrt_mod_4(-Integer(1) + Integer(2)*a, P)
(True, a + 1)
>>> (Integer(1)+a)**Integer(2) - (-Integer(1) + Integer(2)*a)
12
>>> e = P.ramification_index()
>>> ((Integer(1)+a)**Integer(2) - (-Integer(1)+Integer(2)*a)).mod(P**e)
0
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import sqrt_mod_4
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
P = K.primes_above(2)[0]
sqrt_mod_4(1 + 2*a, P)
sqrt_mod_4(-1 + 2*a, P)
(1+a)^2 - (-1 + 2*a)
e = P.ramification_index()
((1+a)^2 - (-1+2*a)).mod(P**e)
sage.schemes.elliptic_curves.kraus.test_a1a3_global(c4, c6, a1, a3, debug=False)[source]

Test if a1, a3 are valid at all primes P dividing 2.

INPUT:

  • c4, c6 – elements of a number field

  • a1, a3 – elements of the number field

OUTPUT:

The elliptic curve which is the (a12/12,a1/2,a3/2)-transform of [0,0,0,c4/48,c6/864] if this is integral at all primes P dividing 2, else False.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_global
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: test_a1a3_global(c4,c6,a,a,debug=False)
False
sage: test_a1a3_global(c4,c6,a,0)
Elliptic Curve defined by
 y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
 over Number Field in a with defining polynomial x^2 - 10
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import test_a1a3_global
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> test_a1a3_global(c4,c6,a,a,debug=False)
False
>>> test_a1a3_global(c4,c6,a,Integer(0))
Elliptic Curve defined by
 y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
 over Number Field in a with defining polynomial x^2 - 10
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import test_a1a3_global
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
test_a1a3_global(c4,c6,a,a,debug=False)
test_a1a3_global(c4,c6,a,0)
sage.schemes.elliptic_curves.kraus.test_a1a3_local(c4, c6, P, a1, a3, debug=False)[source]

Test if a1, a3 are valid at a prime P dividing 2.

INPUT:

  • c4, c6 – elements of a number field

  • P – a prime ideal of the number field which divides 2

  • a1, a3 – elements of the number field

OUTPUT:

The elliptic curve which is the (a12/12,a1/2,a3/2)-transform of [0,0,0,c4/48,c6/864] if this is integral at P, else False.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import test_a1a3_local
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: P = K.primes_above(2)[0]
sage: test_a1a3_local(c4,c6,P,a,0)
Elliptic Curve defined by
 y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
 over Number Field in a with defining polynomial x^2 - 10
sage: test_a1a3_local(c4,c6,P,a,a,debug=True)
test_a1a3_local: not integral at Fractional ideal (2, a)
False
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import test_a1a3_local
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> P = K.primes_above(Integer(2))[Integer(0)]
>>> test_a1a3_local(c4,c6,P,a,Integer(0))
Elliptic Curve defined by
 y^2 + a*x*y = x^3 + (3784/3*a-24106/3)*x + (1772120/27*a-2790758/9)
 over Number Field in a with defining polynomial x^2 - 10
>>> test_a1a3_local(c4,c6,P,a,a,debug=True)
test_a1a3_local: not integral at Fractional ideal (2, a)
False
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import test_a1a3_local
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
P = K.primes_above(2)[0]
test_a1a3_local(c4,c6,P,a,0)
test_a1a3_local(c4,c6,P,a,a,debug=True)
sage.schemes.elliptic_curves.kraus.test_b2_global(c4, c6, b2, debug=False)[source]

Test if b2 gives a valid model at all primes dividing 3.

INPUT:

  • c4, c6 – elements of a number field

  • b2 – an element of the number field

OUTPUT:

The elliptic curve which is the (b2/12,0,0)-transform of [0,0,0,c4/48,c6/864] if this is integral at all primes P dividing 3, else False.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: b2 = a+1
sage: from sage.schemes.elliptic_curves.kraus import test_b2_global
sage: test_b2_global(c4,c6,b2)
Elliptic Curve defined by
 y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
sage: test_b2_global(c4,c6,0,debug=True)
test_b2_global: not integral at all primes dividing 3
False
sage: test_b2_global(c4,c6,-a,debug=True)
test_b2_global: not integral at all primes dividing 3
False
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> b2 = a+Integer(1)
>>> from sage.schemes.elliptic_curves.kraus import test_b2_global
>>> test_b2_global(c4,c6,b2)
Elliptic Curve defined by
 y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
>>> test_b2_global(c4,c6,Integer(0),debug=True)
test_b2_global: not integral at all primes dividing 3
False
>>> test_b2_global(c4,c6,-a,debug=True)
test_b2_global: not integral at all primes dividing 3
False
# needs sage.rings.number_field
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
b2 = a+1
from sage.schemes.elliptic_curves.kraus import test_b2_global
test_b2_global(c4,c6,b2)
test_b2_global(c4,c6,0,debug=True)
test_b2_global(c4,c6,-a,debug=True)
sage.schemes.elliptic_curves.kraus.test_b2_local(c4, c6, P, b2, debug=False)[source]

Test if b2 gives a valid model at a prime dividing 3.

INPUT:

  • c4, c6 – elements of a number field

  • P – a prime ideal of the number field which divides 3

  • b2 – an element of the number field

OUTPUT:

The elliptic curve which is the (b2/12,0,0)-transform of [0,0,0,c4/48,c6/864] if this is integral at P, else False.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: P3a, P3b = K.primes_above(3)
sage: from sage.schemes.elliptic_curves.kraus import test_b2_local
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> P3a, P3b = K.primes_above(Integer(3))
>>> from sage.schemes.elliptic_curves.kraus import test_b2_local
# needs sage.rings.number_field
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2 - 10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
P3a, P3b = K.primes_above(3)
from sage.schemes.elliptic_curves.kraus import test_b2_local

b2=0 works at the first prime but not the second:

sage: b2 = 0
sage: test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (3784/3*a-96449/12)*x + (1743740/27*a-32765791/108)
 over Number Field in a with defining polynomial x^2 - 10
sage: test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
False
>>> from sage.all import *
>>> b2 = Integer(0)
>>> test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (3784/3*a-96449/12)*x + (1743740/27*a-32765791/108)
 over Number Field in a with defining polynomial x^2 - 10
>>> test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
False
b2 = 0
test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field

b2=a works at the second prime but not the first:

sage: b2 = -a                                                                   # needs sage.rings.number_field
sage: test_b2_local(c4,c6,P3a,b2,debug=True)                                    # needs sage.rings.number_field
test_b2_local: not integral at Fractional ideal (3, a + 1)
False
sage: test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (-1/4*a)*x^2 + (3784/3*a-192893/24)*x + (56378369/864*a-32879311/108)
 over Number Field in a with defining polynomial x^2 - 10
>>> from sage.all import *
>>> b2 = -a                                                                   # needs sage.rings.number_field
>>> test_b2_local(c4,c6,P3a,b2,debug=True)                                    # needs sage.rings.number_field
test_b2_local: not integral at Fractional ideal (3, a + 1)
False
>>> test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (-1/4*a)*x^2 + (3784/3*a-192893/24)*x + (56378369/864*a-32879311/108)
 over Number Field in a with defining polynomial x^2 - 10
b2 = -a                                                                   # needs sage.rings.number_field
test_b2_local(c4,c6,P3a,b2,debug=True)                                    # needs sage.rings.number_field
test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field

Using CRT we can do both with the same b2:

sage: b2 = K.solve_CRT([0,-a],[P3a,P3b]); b2                                    # needs sage.rings.number_field
a + 1
sage: test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
sage: test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined
 by y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
>>> from sage.all import *
>>> b2 = K.solve_CRT([Integer(0),-a],[P3a,P3b]); b2                                    # needs sage.rings.number_field
a + 1
>>> test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined by
 y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
>>> test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
Elliptic Curve defined
 by y^2 = x^3 + (1/4*a+1/4)*x^2 + (10091/8*a-128595/16)*x + (4097171/64*a-19392359/64)
 over Number Field in a with defining polynomial x^2 - 10
b2 = K.solve_CRT([0,-a],[P3a,P3b]); b2                                    # needs sage.rings.number_field
test_b2_local(c4,c6,P3a,b2)                                               # needs sage.rings.number_field
test_b2_local(c4,c6,P3b,b2)                                               # needs sage.rings.number_field
sage.schemes.elliptic_curves.kraus.test_rst_global(c4, c6, r, s, t, debug=False)[source]

Test if the (r,s,t)-transform of the standard c4,c6-model is integral.

INPUT:

  • c4, c6 – elements of a number field

  • r, s, t – elements of the number field

OUTPUT:

The elliptic curve which is the (r,s,t)-transform of [0,0,0,c4/48,c6/864] if this is integral at all primes P, else False.

EXAMPLES:

sage: # needs sage.rings.number_field
sage: from sage.schemes.elliptic_curves.kraus import test_rst_global
sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2-10)
sage: c4 = -60544*a + 385796
sage: c6 = -55799680*a + 262126328
sage: test_rst_global(c4,c6,1/3*a - 133/6, 3/2*a, -89/2*a + 5)
Elliptic Curve defined by
 y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
 over Number Field in a with defining polynomial x^2 - 10
sage: test_rst_global(c4,c6,a, 3, -89*a, debug=False)
False
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> from sage.schemes.elliptic_curves.kraus import test_rst_global
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2)-Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> c4 = -Integer(60544)*a + Integer(385796)
>>> c6 = -Integer(55799680)*a + Integer(262126328)
>>> test_rst_global(c4,c6,Integer(1)/Integer(3)*a - Integer(133)/Integer(6), Integer(3)/Integer(2)*a, -Integer(89)/Integer(2)*a + Integer(5))
Elliptic Curve defined by
 y^2 + 3*a*x*y + (-89*a+10)*y = x^3 + (a-89)*x^2 + (1202*a-5225)*x + (34881*a-151813)
 over Number Field in a with defining polynomial x^2 - 10
>>> test_rst_global(c4,c6,a, Integer(3), -Integer(89)*a, debug=False)
False
# needs sage.rings.number_field
from sage.schemes.elliptic_curves.kraus import test_rst_global
x = polygen(ZZ, 'x')
K.<a> = NumberField(x^2-10)
c4 = -60544*a + 385796
c6 = -55799680*a + 262126328
test_rst_global(c4,c6,1/3*a - 133/6, 3/2*a, -89/2*a + 5)
test_rst_global(c4,c6,a, 3, -89*a, debug=False)