Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Trac 16680: more polishing of EllipticCurve_finite_field.cardinality()
Browse files Browse the repository at this point in the history
  • Loading branch information
pjbruin committed Jul 19, 2014
1 parent 1ec55e3 commit 545410e
Showing 1 changed file with 34 additions and 37 deletions.
71 changes: 34 additions & 37 deletions src/sage/schemes/elliptic_curves/ell_finite_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,38 +741,36 @@ def _cardinality_with_j_invariant_0(self):
self._order = Integer(N)
return self._order

def cardinality(self, algorithm='heuristic', extension_degree=1):
def cardinality(self, algorithm='pari', extension_degree=1):
r"""
Return the number of points on this elliptic curve over an
extension field (default: the base field).
Return the number of points on this elliptic curve.
INPUT:
- ``algorithm`` - string (default: 'heuristic'), used
only for point counting over prime fields
- ``algorithm`` -- string (default: ``'pari'``), used only for
point counting over prime fields:
- ``'heuristic'`` - use a heuristic to choose between
``'pari'`` and ``'bsgs'``
- ``'pari'`` -- use the baby-step giant-step or
Schoof-Elkies-Atkin methods as implemented in the PARI
C-library function ``ellap``
- ``'pari'`` - use the baby step giant step or SEA methods
as implemented in PARI via the C-library function ellap
- ``'bsgs'`` -- use the baby-step giant-step method as
implemented in Sage, with the Cremona-Sutherland version
of Mestre's trick
- ``'bsgs'`` - use the baby step giant step method as
implemented in Sage, with the Cremona-Sutherland version
of Mestre's trick
- ``'all'`` -- compute cardinality with both ``'pari'`` and
``'bsgs'``; return result if they agree or raise a
``RuntimeError`` if they do not
- ``'all'`` - (over prime fields only) compute cardinality
with all of PARI and bsgs; return result if they agree
or raise a ``RuntimeError`` if they do not
- ``extension_degree`` -- an integer `d` (default: 1): if the
base field is `\GF{q}`, return the cardinality of ``self``
over the extension `\GF{q^d}` of degree `d`.
- ``extension_degree`` - int (default: 1); if the
base field is `k=GF(p^n)` and extension_degree=d, returns
the cardinality of `E(GF(p^{n d}))`
OUTPUT: an integer
OUTPUT:
The cardinality is cached.
The order of the group of rational points of ``self`` over its
base field, or over an extension field of degree `d` as above.
The result is cached.
Over prime fields, one of the above algorithms is used. Over
non-prime fields, the serious point counting is done on a standard
Expand All @@ -783,7 +781,7 @@ def cardinality(self, algorithm='heuristic', extension_degree=1):
EXAMPLES::
sage: EllipticCurve(GF(4,'a'),[1,2,3,4,5]).cardinality()
sage: EllipticCurve(GF(4, 'a'), [1,2,3,4,5]).cardinality()
8
sage: k.<a> = GF(3^3)
sage: l = [a^2 + 1, 2*a^2 + 2*a + 1, a^2 + a + 1, 2, 2*a]
Expand All @@ -793,49 +791,50 @@ def cardinality(self, algorithm='heuristic', extension_degree=1):
::
sage: l = [1, 1, 0, 2, 0]
sage: EllipticCurve(k,l).cardinality()
sage: EllipticCurve(k, l).cardinality()
38
An even bigger extension (which we check against Magma)::
sage: EllipticCurve(GF(3^100,'a'),[1,2,3,4,5]).cardinality()
sage: EllipticCurve(GF(3^100, 'a'), [1,2,3,4,5]).cardinality()
515377520732011331036459693969645888996929981504
sage: magma.eval("Order(EllipticCurve([GF(3^100)|1,2,3,4,5]))") # optional - magma
'515377520732011331036459693969645888996929981504'
::
sage: EllipticCurve(GF(10007),[1,2,3,4,5]).cardinality()
sage: EllipticCurve(GF(10007), [1,2,3,4,5]).cardinality()
10076
sage: EllipticCurve(GF(10007),[1,2,3,4,5]).cardinality(algorithm='pari')
sage: EllipticCurve(GF(10007), [1,2,3,4,5]).cardinality(algorithm='pari')
10076
sage: EllipticCurve(GF(next_prime(10**20)),[1,2,3,4,5]).cardinality()
sage: EllipticCurve(GF(next_prime(10**20)), [1,2,3,4,5]).cardinality()
100000000011093199520
The cardinality is cached::
sage: E = EllipticCurve(GF(3^100,'a'),[1,2,3,4,5])
sage: E = EllipticCurve(GF(3^100, 'a'), [1,2,3,4,5])
sage: E.cardinality() is E.cardinality()
True
sage: E=EllipticCurve(GF(11^2,'a'),[3,3])
sage: E = EllipticCurve(GF(11^2, 'a'), [3,3])
sage: E.cardinality()
128
sage: EllipticCurve(GF(11^100,'a'),[3,3]).cardinality()
sage: EllipticCurve(GF(11^100, 'a'), [3,3]).cardinality()
137806123398222701841183371720896367762643312000384671846835266941791510341065565176497846502742959856128
TESTS::
sage: EllipticCurve(GF(10009),[1,2,3,4,5]).cardinality(algorithm='foobar')
sage: EllipticCurve(GF(10009), [1,2,3,4,5]).cardinality(algorithm='foobar')
Traceback (most recent call last):
...
ValueError: Algorithm is not known
If the cardinality has already been computed, then the ``algorithm``
keyword is ignored::
sage: EllipticCurve(GF(10007),[1,2,3,4,5]).cardinality(algorithm='pari')
sage: E = EllipticCurve(GF(10007), [1,2,3,4,5])
sage: E.cardinality(algorithm='pari')
10076
sage: EllipticCurve(GF(10007),[1,2,3,4,5]).cardinality(algorithm='foobar')
sage: E.cardinality(algorithm='foobar')
10076
"""
if extension_degree>1:
Expand Down Expand Up @@ -874,12 +873,10 @@ def cardinality(self, algorithm='heuristic', extension_degree=1):
# Over prime fields, we have a variety of algorithms to choose from:

if d == 1:
if algorithm == 'heuristic':
if algorithm in ('heuristic', 'sea'): # for backwards compatibility
algorithm = 'pari'
if algorithm == 'pari':
N = self.cardinality_pari()
elif algorithm == 'sea':
N = self.cardinality_pari() # purely for backwards compatibility
elif algorithm == 'bsgs':
N = self.cardinality_bsgs()
elif algorithm == 'all':
Expand Down

0 comments on commit 545410e

Please sign in to comment.