57
57
from sage .rings .power_series_ring import PowerSeriesRing
58
58
from . import hyperelliptic_generic
59
59
from sage .misc .cachefunc import cached_method
60
+ from sage .misc .superseded import deprecated_function_alias
60
61
from sage .matrix .constructor import identity_matrix , matrix
61
62
from sage .misc .functional import rank
62
63
from sage .misc .lazy_import import lazy_import
@@ -297,7 +298,7 @@ def frobenius_matrix(self, N=None, algorithm='hypellfrob'):
297
298
ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81
298
299
"""
299
300
if algorithm != 'hypellfrob' :
300
- raise ValueError ("Unknown algorithm" )
301
+ raise ValueError ("unknown algorithm" )
301
302
302
303
# By default, use precision enough to be able to compute the
303
304
# frobenius minimal polynomial
@@ -306,7 +307,7 @@ def frobenius_matrix(self, N=None, algorithm='hypellfrob'):
306
307
307
308
return self .frobenius_matrix_hypellfrob (N = N )
308
309
309
- def frobenius_polynomial_cardinalities (self , a = None ):
310
+ def _frobenius_polynomial_cardinalities (self , a = None ):
310
311
r"""
311
312
Compute the charpoly of frobenius, as an element of `\ZZ[x]`,
312
313
by computing the number of points on the curve over `g` extensions
@@ -321,33 +322,33 @@ def frobenius_polynomial_cardinalities(self, a=None):
321
322
322
323
sage: R.<t> = PolynomialRing(GF(37))
323
324
sage: H = HyperellipticCurve(t^5 + t + 2)
324
- sage: H.frobenius_polynomial_cardinalities( )
325
+ sage: H.frobenius_polynomial(algorithm='cardinalities' )
325
326
x^4 + x^3 - 52*x^2 + 37*x + 1369
326
327
327
328
A quadratic twist::
328
329
329
330
sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
330
- sage: H.frobenius_polynomial_cardinalities( )
331
+ sage: H.frobenius_polynomial(algorithm='cardinalities' )
331
332
x^4 - x^3 - 52*x^2 - 37*x + 1369
332
333
333
334
Curve over a non-prime field::
334
335
335
336
sage: K.<z> = GF(7**2)
336
337
sage: R.<t> = PolynomialRing(K)
337
338
sage: H = HyperellipticCurve(t^5 + z*t + z^2)
338
- sage: H.frobenius_polynomial_cardinalities( )
339
+ sage: H.frobenius_polynomial(algorithm='cardinalities' )
339
340
x^4 + 8*x^3 + 70*x^2 + 392*x + 2401
340
341
341
342
This method may actually be useful when ``hypellfrob`` does not work::
342
343
343
344
sage: K = GF(7)
344
345
sage: R.<t> = PolynomialRing(K)
345
346
sage: H = HyperellipticCurve(t^9 + t^3 + 1)
346
- sage: H.frobenius_polynomial_matrix (algorithm='hypellfrob ')
347
+ sage: H.frobenius_polynomial (algorithm='matrix ')
347
348
Traceback (most recent call last):
348
349
...
349
350
ValueError: In the current implementation, p must be greater than (2g+1)(2N-1) = 81
350
- sage: H.frobenius_polynomial_cardinalities( )
351
+ sage: H.frobenius_polynomial(algorithm='cardinalities' )
351
352
x^8 - 5*x^7 + 7*x^6 + 36*x^5 - 180*x^4 + 252*x^3 + 343*x^2 - 1715*x + 2401
352
353
"""
353
354
g = self .genus ()
@@ -372,7 +373,7 @@ def frobenius_polynomial_cardinalities(self, a=None):
372
373
373
374
return ZZ ['x' ](coeffs ).reverse ()
374
375
375
- def frobenius_polynomial_matrix (self , M = None , algorithm = 'hypellfrob' ):
376
+ def _frobenius_polynomial_matrix (self , M = None , algorithm = 'hypellfrob' ):
376
377
r"""
377
378
Compute the charpoly of frobenius, as an element of `\ZZ[x]`,
378
379
by computing the charpoly of the frobenius matrix.
@@ -384,25 +385,25 @@ def frobenius_polynomial_matrix(self, M=None, algorithm='hypellfrob'):
384
385
385
386
sage: R.<t> = PolynomialRing(GF(37))
386
387
sage: H = HyperellipticCurve(t^5 + t + 2)
387
- sage: H.frobenius_polynomial_matrix( )
388
+ sage: H.frobenius_polynomial(algorithm='matrix' )
388
389
x^4 + x^3 - 52*x^2 + 37*x + 1369
389
390
390
391
A quadratic twist::
391
392
392
393
sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
393
- sage: H.frobenius_polynomial_matrix( )
394
+ sage: H.frobenius_polynomial(algorithm='matrix' )
394
395
x^4 - x^3 - 52*x^2 - 37*x + 1369
395
396
396
397
Curves defined over larger prime fields::
397
398
398
399
sage: K = GF(49999)
399
400
sage: R.<t> = PolynomialRing(K)
400
401
sage: H = HyperellipticCurve(t^9 + t^5 + 1)
401
- sage: H.frobenius_polynomial_matrix( )
402
+ sage: H.frobenius_polynomial(algorithm='matrix' )
402
403
x^8 + 281*x^7 + 55939*x^6 + 14144175*x^5 + 3156455369*x^4 + 707194605825*x^3
403
404
+ 139841906155939*x^2 + 35122892542149719*x + 6249500014999800001
404
405
sage: H = HyperellipticCurve(t^15 + t^5 + 1)
405
- sage: H.frobenius_polynomial_matrix( ) # long time, 8s on a Corei7
406
+ sage: H.frobenius_polynomial(algorithm='matrix' ) # long time, 8s on a Corei7
406
407
x^14 - 76*x^13 + 220846*x^12 - 12984372*x^11 + 24374326657*x^10 - 1203243210304*x^9
407
408
+ 1770558798515792*x^8 - 74401511415210496*x^7 + 88526169366991084208*x^6
408
409
- 3007987702642212810304*x^5 + 3046608028331197124223343*x^4
@@ -440,7 +441,7 @@ def frobenius_polynomial_matrix(self, M=None, algorithm='hypellfrob'):
440
441
441
442
return ZZ ['x' ](f )
442
443
443
- def frobenius_polynomial_pari (self ):
444
+ def _frobenius_polynomial_pari (self ):
444
445
r"""
445
446
Compute the charpoly of frobenius, as an element of `\ZZ[x]`,
446
447
by calling the PARI function ``hyperellcharpoly``.
@@ -449,43 +450,43 @@ def frobenius_polynomial_pari(self):
449
450
450
451
sage: R.<t> = PolynomialRing(GF(37))
451
452
sage: H = HyperellipticCurve(t^5 + t + 2)
452
- sage: H.frobenius_polynomial_pari( )
453
+ sage: H.frobenius_polynomial(algorithm='pari' )
453
454
x^4 + x^3 - 52*x^2 + 37*x + 1369
454
455
455
456
A quadratic twist::
456
457
457
458
sage: H = HyperellipticCurve(2*t^5 + 2*t + 4)
458
- sage: H.frobenius_polynomial_pari( )
459
+ sage: H.frobenius_polynomial(algorithm='pari' )
459
460
x^4 - x^3 - 52*x^2 - 37*x + 1369
460
461
461
462
Slightly larger example::
462
463
463
464
sage: K = GF(2003)
464
465
sage: R.<t> = PolynomialRing(K)
465
466
sage: H = HyperellipticCurve(t^7 + 487*t^5 + 9*t + 1)
466
- sage: H.frobenius_polynomial_pari( )
467
+ sage: H.frobenius_polynomial(algorithm='pari' )
467
468
x^6 - 14*x^5 + 1512*x^4 - 66290*x^3 + 3028536*x^2 - 56168126*x + 8036054027
468
469
469
470
Curves defined over a non-prime field are supported as well::
470
471
471
472
sage: K.<a> = GF(7^2)
472
473
sage: R.<t> = PolynomialRing(K)
473
474
sage: H = HyperellipticCurve(t^5 + a*t + 1)
474
- sage: H.frobenius_polynomial_pari( )
475
+ sage: H.frobenius_polynomial(algorithm='pari' )
475
476
x^4 + 4*x^3 + 84*x^2 + 196*x + 2401
476
477
477
478
sage: K.<z> = GF(23**3)
478
479
sage: R.<t> = PolynomialRing(K)
479
480
sage: H = HyperellipticCurve(t^3 + z*t + 4)
480
- sage: H.frobenius_polynomial_pari( )
481
+ sage: H.frobenius_polynomial(algorithm='pari' )
481
482
x^2 - 15*x + 12167
482
483
483
484
Over prime fields of odd characteristic, `h` may be nonzero::
484
485
485
486
sage: K = GF(101)
486
487
sage: R.<t> = PolynomialRing(K)
487
488
sage: H = HyperellipticCurve(t^5 + 27*t + 3, t)
488
- sage: H.frobenius_polynomial_pari( )
489
+ sage: H.frobenius_polynomial(algorithm='pari' )
489
490
x^4 + 2*x^3 - 58*x^2 + 202*x + 10201
490
491
491
492
TESTS:
@@ -495,17 +496,33 @@ def frobenius_polynomial_pari(self):
495
496
sage: P.<x> = PolynomialRing(GF(3))
496
497
sage: u = x^10 + x^9 + x^8 + x
497
498
sage: C = HyperellipticCurve(u)
498
- sage: C.frobenius_polynomial_pari( )
499
+ sage: C.frobenius_polynomial(algorithm='pari' )
499
500
x^8 + 2*x^7 + 6*x^6 + 9*x^5 + 18*x^4 + 27*x^3 + 54*x^2 + 54*x + 81
500
501
"""
501
502
f , h = self .hyperelliptic_polynomials ()
502
503
return ZZ ['x' ](pari ([f , h ]).hyperellcharpoly ())
503
504
505
+ frobenius_polynomial_cardinalities = deprecated_function_alias (40528 , _frobenius_polynomial_cardinalities )
506
+ frobenius_polynomial_matrix = deprecated_function_alias (40528 , _frobenius_polynomial_matrix )
507
+ frobenius_polynomial_pari = deprecated_function_alias (40528 , _frobenius_polynomial_pari )
508
+
504
509
@cached_method
505
- def frobenius_polynomial (self ):
510
+ def frobenius_polynomial (self , algorithm = None , ** kwargs ):
506
511
r"""
507
512
Compute the charpoly of frobenius, as an element of `\ZZ[x]`.
508
513
514
+ INPUT:
515
+
516
+ - ``algorithm`` -- (default: ``None``) the algorithm to use, one of
517
+ ``'cardinalities'``, ``'matrix'``, or ``'pari'``.
518
+
519
+ Refer to :meth:`frobenius_polynomial_cardinalities`,
520
+ :meth:`frobenius_polynomial_matrix`, and
521
+ :meth:`frobenius_polynomial_pari` respectively.
522
+
523
+ - ``**kwargs`` -- additional keyword arguments passed to the
524
+ methods above. Undocumented feature, may be removed in the future.
525
+
509
526
EXAMPLES::
510
527
511
528
sage: R.<t> = PolynomialRing(GF(37))
@@ -578,6 +595,15 @@ def frobenius_polynomial(self):
578
595
sage: C.frobenius_polynomial()
579
596
x^8 + 2*x^7 + 6*x^6 + 9*x^5 + 18*x^4 + 27*x^3 + 54*x^2 + 54*x + 81
580
597
"""
598
+ if algorithm == "cardinalities" :
599
+ return self ._frobenius_polynomial_cardinalities (** kwargs )
600
+ elif algorithm == "matrix" :
601
+ return self ._frobenius_polynomial_matrix (** kwargs )
602
+ elif algorithm == "pari" :
603
+ return self ._frobenius_polynomial_pari (** kwargs )
604
+ elif algorithm is not None :
605
+ raise ValueError (f"unknown algorithm { algorithm } " )
606
+
581
607
K = self .base_ring ()
582
608
e = K .degree ()
583
609
q = K .cardinality ()
@@ -588,11 +614,11 @@ def frobenius_polynomial(self):
588
614
if (e == 1 and
589
615
q >= (2 * g + 1 )* (2 * self ._frobenius_coefficient_bound_charpoly ()- 1 ) and
590
616
h == 0 and f .degree () % 2 ):
591
- return self .frobenius_polynomial_matrix ( )
617
+ return self .frobenius_polynomial ( algorithm = 'matrix' )
592
618
elif q % 2 == 1 :
593
- return self .frobenius_polynomial_pari ( )
619
+ return self .frobenius_polynomial ( algorithm = 'pari' )
594
620
else :
595
- return self .frobenius_polynomial_cardinalities ( )
621
+ return self .frobenius_polynomial ( algorithm = 'cardinalities' )
596
622
597
623
def _points_fast_sqrt (self ):
598
624
"""
@@ -1031,7 +1057,7 @@ def count_points_exhaustive(self, n=1, naive=False):
1031
1057
a .append (self .cardinality_exhaustive (extension_degree = i ))
1032
1058
1033
1059
# let's not be too naive and compute the frobenius polynomial
1034
- f = self .frobenius_polynomial_cardinalities (a = a )
1060
+ f = self ._frobenius_polynomial_cardinalities (a = a )
1035
1061
return self .count_points_frobenius_polynomial (n = n , f = f )
1036
1062
1037
1063
def count_points_hypellfrob (self , n = 1 , N = None , algorithm = None ):
@@ -1116,7 +1142,7 @@ def count_points_hypellfrob(self, n=1, N=None, algorithm=None):
1116
1142
M = self .frobenius_matrix (N = N , algorithm = 'hypellfrob' )
1117
1143
return self .count_points_matrix_traces (n = n ,M = M ,N = N )
1118
1144
elif algorithm == 'charpoly' :
1119
- f = self .frobenius_polynomial_matrix (algorithm = 'hypellfrob' )
1145
+ f = self ._frobenius_polynomial_matrix (algorithm = 'hypellfrob' )
1120
1146
return self .count_points_frobenius_polynomial (n = n ,f = f )
1121
1147
else :
1122
1148
raise ValueError ("Unknown algorithm" )
0 commit comments