Complex multiplication for elliptic curves¶
This module implements the functions
hilbert_class_polynomial
cm_j_invariants
cm_orders
discriminants_with_bounded_class_number
cm_j_invariants_and_orders
largest_fundamental_disc_with_class_number
AUTHORS:
- Robert Bradshaw
- John Cremona
- William Stein
-
sage.schemes.elliptic_curves.cm.
cm_j_invariants
(K, proof=None)¶ Return a list of all CM j-invariants in the field K.
INPUT:
K
– a number fieldproof
– (default: proof.number_field())
OUTPUT:
(list) – A list of CM j-invariants in the field K.
EXAMPLES:
sage: cm_j_invariants(QQ) [-262537412640768000, -147197952000, -884736000, -12288000, -884736, -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375]
Over imaginary quadratic fields there are no more than over QQ:
sage: cm_j_invariants(QuadraticField(-1, 'i')) [-262537412640768000, -147197952000, -884736000, -12288000, -884736, -32768, -3375, 0, 1728, 8000, 54000, 287496, 16581375]
Over real quadratic fields there may be more, for example:
sage: len(cm_j_invariants(QuadraticField(5, 'a'))) 31
Over number fields K of many higher degrees this also works:
sage: K.<a> = NumberField(x^3 - 2) sage: cm_j_invariants(K) [-262537412640768000, -147197952000, -884736000, -884736, -32768, 8000, -3375, 16581375, 1728, 287496, 0, 54000, -12288000, 31710790944000*a^2 + 39953093016000*a + 50337742902000] sage: K.<a> = NumberField(x^4 - 2) sage: len(cm_j_invariants(K)) 23
-
sage.schemes.elliptic_curves.cm.
cm_j_invariants_and_orders
(K, proof=None)¶ Return a list of all CM j-invariants in the field K, together with the associated orders.
INPUT:
K
– a number fieldproof
– (default: proof.number_field())
OUTPUT:
(list) A list of 3-tuples (D,f,j) where j is a CM j-invariant in K with quadratic fundamental discriminant D and conductor f.
EXAMPLES:
sage: cm_j_invariants_and_orders(QQ) [(-3, 3, -12288000), (-3, 2, 54000), (-3, 1, 0), (-4, 2, 287496), (-4, 1, 1728), (-7, 2, 16581375), (-7, 1, -3375), (-8, 1, 8000), (-11, 1, -32768), (-19, 1, -884736), (-43, 1, -884736000), (-67, 1, -147197952000), (-163, 1, -262537412640768000)]
Over an imaginary quadratic field there are no more than over QQ:
sage: cm_j_invariants_and_orders(QuadraticField(-1, 'i')) [(-163, 1, -262537412640768000), (-67, 1, -147197952000), (-43, 1, -884736000), (-19, 1, -884736), (-11, 1, -32768), (-8, 1, 8000), (-7, 1, -3375), (-7, 2, 16581375), (-4, 1, 1728), (-4, 2, 287496), (-3, 1, 0), (-3, 2, 54000), (-3, 3, -12288000)]
Over real quadratic fields there may be more:
sage: v = cm_j_invariants_and_orders(QuadraticField(5,'a')); len(v) 31 sage: [(D, f) for D, f, j in v if j not in QQ] [(-235, 1), (-235, 1), (-115, 1), (-115, 1), (-40, 1), (-40, 1), (-35, 1), (-35, 1), (-20, 1), (-20, 1), (-15, 1), (-15, 1), (-15, 2), (-15, 2), (-4, 5), (-4, 5), (-3, 5), (-3, 5)]
Over number fields K of many higher degrees this also works:
sage: K.<a> = NumberField(x^3 - 2) sage: cm_j_invariants_and_orders(K) [(-163, 1, -262537412640768000), (-67, 1, -147197952000), (-43, 1, -884736000), (-19, 1, -884736), (-11, 1, -32768), (-8, 1, 8000), (-7, 1, -3375), (-7, 2, 16581375), (-4, 1, 1728), (-4, 2, 287496), (-3, 1, 0), (-3, 2, 54000), (-3, 3, -12288000), (-3, 6, 31710790944000*a^2 + 39953093016000*a + 50337742902000)]
-
sage.schemes.elliptic_curves.cm.
cm_orders
(h, proof=None)¶ Return a list of all pairs (D,f) where there is a CM order of discriminant Df2 with class number h, with D a fundamental discriminant.
INPUT:
- h – positive integer
proof
– (default: proof.number_field())
OUTPUT:
- list of 2-tuples (D,f)
EXAMPLES:
sage: cm_orders(0) [] sage: v = cm_orders(1); v [(-3, 3), (-3, 2), (-3, 1), (-4, 2), (-4, 1), (-7, 2), (-7, 1), (-8, 1), (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] sage: type(v[0][0]), type(v[0][1]) (<... 'sage.rings.integer.Integer'>, <... 'sage.rings.integer.Integer'>) sage: v = cm_orders(2); v [(-3, 7), (-3, 5), (-3, 4), (-4, 5), (-4, 4), (-4, 3), (-7, 4), (-8, 3), (-8, 2), (-11, 3), (-15, 2), (-15, 1), (-20, 1), (-24, 1), (-35, 1), (-40, 1), (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), (-148, 1), (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] sage: len(v) 29 sage: set([hilbert_class_polynomial(D*f^2).degree() for D,f in v]) {2}
Any degree up to 100 is implemented, but may be prohibitively slow:
sage: cm_orders(3) [(-3, 9), (-3, 6), (-11, 2), (-19, 2), (-23, 2), (-23, 1), (-31, 2), (-31, 1), (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), (-643, 1), (-883, 1), (-907, 1)] sage: len(cm_orders(4)) 84
-
sage.schemes.elliptic_curves.cm.
discriminants_with_bounded_class_number
(hmax, B=None, proof=None)¶ Return dictionary with keys class numbers h≤hmax and values the list of all pairs (D,f), with D<0 a fundamental discriminant such that Df2 has class number h. If the optional bound B is given, return only those pairs with fundamental |D|≤B, though f can still be arbitrarily large.
INPUT:
hmax
– integer- B – integer or None; if None returns all pairs
proof
– this code calls the PARI functionqfbclassno
, so it could give wrong answers whenproof``==``False
. The default is whateverproof.number_field()
is. Ifproof==False
and B isNone
, at least the number of discriminants is correct, since it is double checked with Watkins’s table.
OUTPUT:
- dictionary
In case B is not given, we use Mark Watkins’s: “Class numbers of imaginary quadratic fields” to compute a B that captures all h up to hmax (only available for hmax≤100).
EXAMPLES:
sage: v = sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(3) sage: sorted(v) [1, 2, 3] sage: v[1] [(-3, 3), (-3, 2), (-3, 1), (-4, 2), (-4, 1), (-7, 2), (-7, 1), (-8, 1), (-11, 1), (-19, 1), (-43, 1), (-67, 1), (-163, 1)] sage: v[2] [(-3, 7), (-3, 5), (-3, 4), (-4, 5), (-4, 4), (-4, 3), (-7, 4), (-8, 3), (-8, 2), (-11, 3), (-15, 2), (-15, 1), (-20, 1), (-24, 1), (-35, 1), (-40, 1), (-51, 1), (-52, 1), (-88, 1), (-91, 1), (-115, 1), (-123, 1), (-148, 1), (-187, 1), (-232, 1), (-235, 1), (-267, 1), (-403, 1), (-427, 1)] sage: v[3] [(-3, 9), (-3, 6), (-11, 2), (-19, 2), (-23, 2), (-23, 1), (-31, 2), (-31, 1), (-43, 2), (-59, 1), (-67, 2), (-83, 1), (-107, 1), (-139, 1), (-163, 2), (-211, 1), (-283, 1), (-307, 1), (-331, 1), (-379, 1), (-499, 1), (-547, 1), (-643, 1), (-883, 1), (-907, 1)] sage: v = sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(8, proof=False) sage: sorted(len(v[h]) for h in v) [13, 25, 29, 29, 38, 84, 101, 208]
Find all class numbers for discriminant up to 50:
sage: sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(hmax=5, B=50) {1: [(-3, 3), (-3, 2), (-3, 1), (-4, 2), (-4, 1), (-7, 2), (-7, 1), (-8, 1), (-11, 1), (-19, 1), (-43, 1)], 2: [(-3, 7), (-3, 5), (-3, 4), (-4, 5), (-4, 4), (-4, 3), (-7, 4), (-8, 3), (-8, 2), (-11, 3), (-15, 2), (-15, 1), (-20, 1), (-24, 1), (-35, 1), (-40, 1)], 3: [(-3, 9), (-3, 6), (-11, 2), (-19, 2), (-23, 2), (-23, 1), (-31, 2), (-31, 1), (-43, 2)], 4: [(-3, 13), (-3, 11), (-3, 8), (-4, 10), (-4, 8), (-4, 7), (-4, 6), (-7, 8), (-7, 6), (-7, 3), (-8, 6), (-8, 4), (-11, 5), (-15, 4), (-19, 5), (-19, 3), (-20, 3), (-20, 2), (-24, 2), (-35, 3), (-39, 2), (-39, 1), (-40, 2), (-43, 3)], 5: [(-47, 2), (-47, 1)]}
-
sage.schemes.elliptic_curves.cm.
hilbert_class_polynomial
(D, algorithm=None)¶ Return the Hilbert class polynomial for discriminant D.
INPUT:
D
(int) – a negative integer congruent to 0 or 1 modulo 4.algorithm
(string, default None).
OUTPUT:
(integer polynomial) The Hilbert class polynomial for the discriminant D.
ALGORITHM:
- If
algorithm
= “arb” (default): Use Arb’s implementation which uses complex interval arithmetic. - If
algorithm
= “sage”: Use complex approximations to the roots. - If
algorithm
= “magma”: Call the appropriate Magma function (if available).
AUTHORS:
- Sage implementation originally by Eduardo Ocampo Alvarez and AndreyTimofeev
- Sage implementation corrected by John Cremona (using corrected precision bounds from Andreas Enge)
- Magma implementation by David Kohel
EXAMPLES:
sage: hilbert_class_polynomial(-4) x - 1728 sage: hilbert_class_polynomial(-7) x + 3375 sage: hilbert_class_polynomial(-23) x^3 + 3491750*x^2 - 5151296875*x + 12771880859375 sage: hilbert_class_polynomial(-37*4) x^2 - 39660183801072000*x - 7898242515936467904000000 sage: hilbert_class_polynomial(-37*4, algorithm="magma") # optional - magma x^2 - 39660183801072000*x - 7898242515936467904000000 sage: hilbert_class_polynomial(-163) x + 262537412640768000 sage: hilbert_class_polynomial(-163, algorithm="sage") x + 262537412640768000 sage: hilbert_class_polynomial(-163, algorithm="magma") # optional - magma x + 262537412640768000
-
sage.schemes.elliptic_curves.cm.
is_cm_j_invariant
(j, method='new')¶ Return whether or not this is a CM j-invariant.
INPUT:
j
– an element of a number field K
OUTPUT:
A pair (bool, (d,f)) which is either (False, None) if j is not a CM j-invariant or (True, (d,f)) if j is the j-invariant of the imaginary quadratic order of discriminant D=df2 where d is the associated fundamental discriminant and f the index.
Note
The current implementation makes use of the classification of all orders of class number up to 100, and hence will raise an error if j is an algebraic integer of degree greater than this. It would be possible to implement a more general version, using the fact that d must be supported on the primes dividing the discriminant of the minimal polynomial of j.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.cm import is_cm_j_invariant sage: is_cm_j_invariant(0) (True, (-3, 1)) sage: is_cm_j_invariant(8000) (True, (-8, 1)) sage: K.<a> = QuadraticField(5) sage: is_cm_j_invariant(282880*a + 632000) (True, (-20, 1)) sage: K.<a> = NumberField(x^3 - 2) sage: is_cm_j_invariant(31710790944000*a^2 + 39953093016000*a + 50337742902000) (True, (-3, 6))
-
sage.schemes.elliptic_curves.cm.
largest_fundamental_disc_with_class_number
(h)¶ Return largest absolute value of any fundamental discriminant with class number h, and the number of fundamental discriminants with that class number. This is known for h up to 100, by work of Mark Watkins.
INPUT:
- h – integer
EXAMPLES:
sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(0) (0, 0) sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(1) (163, 9) sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(2) (427, 18) sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(10) (13843, 87) sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(100) (1856563, 1736) sage: sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(101) Traceback (most recent call last): ... NotImplementedError: largest discriminant not known for class number 101