Complex multiplication for elliptic curves¶
This module implements the functions
hilbert_class_polynomialcm_j_invariantscm_ordersdiscriminants_with_bounded_class_numbercm_j_invariants_and_orderslargest_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
-invariants in the field
.INPUT:
K– a number fieldproof– (default: proof.number_field())
OUTPUT:
(list) – A list of CM
-invariants in the field
.EXAMPLE:
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
: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) [-12288000, 54000, 0, 287496, 1728, 16581375, -3375, 8000, -32768, -884736, -884736000, -147197952000, -262537412640768000, 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
-invariants in the field
, together with the associated orders.INPUT:
K– a number fieldproof– (default: proof.number_field())
OUTPUT:
(list) A list of 3-tuples
where
is a CM
-invariant in
with quadratic fundamental discriminant
and conductor
.EXAMPLE:
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
:sage: cm_j_invariants_and_orders(QuadraticField(-1, 'i')) [(-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 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] [(-3, 5), (-3, 5), (-4, 5), (-4, 5), (-15, 2), (-15, 2), (-15, 1), (-15, 1), (-20, 1), (-20, 1), (-35, 1), (-35, 1), (-40, 1), (-40, 1), (-115, 1), (-115, 1), (-235, 1), (-235, 1)]
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) [(-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), (-3, 6, 31710790944000*a^2 + 39953093016000*a + 50337742902000)]
-
sage.schemes.elliptic_curves.cm.cm_orders(h, proof=None)¶ Return a list of all pairs
where there is a CM order of
discriminant
with class number h, with
a fundamental
discriminant.INPUT:
– positive integerproof– (default: proof.number_field())
OUTPUT:
- list of 2-tuples

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]) (<type 'sage.rings.integer.Integer'>, <type '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
and values the
list of all pairs
, with
a fundamental discriminant such
that
has class number
. If the optional bound
is given,
return only those pairs with fundamental
, though
can
still be arbitrarily large.INPUT:
hmax– integer
– integer or None; if None returns all pairsproof– this code calls the PARI functionqfbclassno, so it could give wrong answers whenproof``==``False. The default is whateverproof.number_field()is. Ifproof==Falseand
is
None, at least the number of discriminants is correct, since it is double checked with Watkins’s table.
OUTPUT:
- dictionary
In case
is not given, we use Mark Watkins’s: “Class numbers of
imaginary quadratic fields” to compute a
that captures all
up to
(only available for
).EXAMPLES:
sage: v = sage.schemes.elliptic_curves.cm.discriminants_with_bounded_class_number(3) sage: v.keys() [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: [len(v[h]) for h in v.keys()] [13, 29, 25, 84, 29, 101, 38, 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)¶ Returns the Hilbert class polynomial for discriminant
.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
.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
TESTS:
sage: all([hilbert_class_polynomial(d, algorithm="arb") == \ ....: hilbert_class_polynomial(d, algorithm="sage") \ ....: for d in range(-1,-100,-1) if d%4 in [0,1]]) True
-
sage.schemes.elliptic_curves.cm.is_cm_j_invariant(j)¶ Returns whether or not this is a CM
-invariant.INPUT:
j– an element of a number field
OUTPUT:
A pair (bool, (d,f)) which is either (False, None) if
is not a
CM j-invariant or (True, (d,f)) if
is the
-invariant of the
immaginary quadratic order of discriminant
where
is
the associated fundamental discriminant and
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
is an algebraic integer of degree greater than
this. It would be possible to implement a more general
version, using the fact that
must be supported on the
primes dividing the discriminant of the minimal polynomial of
.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))
TESTS:
sage: from sage.schemes.elliptic_curves.cm import is_cm_j_invariant sage: all([is_cm_j_invariant(j) == (True, (d,f)) for d,f,j in cm_j_invariants_and_orders(QQ)]) True
-
sage.schemes.elliptic_curves.cm.largest_fundamental_disc_with_class_number(h)¶ Return largest absolute value of any fundamental discriminant with class number
, and the number of fundamental discriminants with
that class number. This is known for
up to 100, by work of Mark
Watkins.INPUT:
– 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
