@@ -13,6 +13,8 @@ AUTHOR:
13
13
- Yann Laigle-Chapuy (2010-01) initial implementation
14
14
- Lorenz Panny (2023-01): :meth:`minpoly_mod`
15
15
"""
16
+ from cysignals.signals cimport sig_on, sig_off
17
+
16
18
from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class
17
19
from sage.libs.ntl.ZZ_pE cimport ZZ_pE_to_ZZ_pX
18
20
from sage.libs.ntl.ZZ_pX cimport ZZ_pX_deg, ZZ_pX_coeff
@@ -483,3 +485,86 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template):
483
485
x^ 4 + x^ 3 + x
484
486
"""
485
487
return self .shift(- n)
488
+
489
+ def reverse (self , degree = None ):
490
+ r """
491
+ Return the polynomial obtained by reversing the coefficients
492
+ of this polynomial. If degree is set then this function behaves
493
+ as if this polynomial has degree `degree`.
494
+
495
+ EXAMPLES::
496
+
497
+ sage: R. <x> = GF( 101^ 2) []
498
+ sage: f = x^ 13 + 11* x^ 10 + 32* x^ 6 + 4
499
+ sage: f. reverse( )
500
+ 4* x^ 13 + 32* x^ 7 + 11* x^ 3 + 1
501
+ sage: f. reverse( degree=15)
502
+ 4* x^ 15 + 32* x^ 9 + 11* x^ 5 + x^ 2
503
+ sage: f. reverse( degree=2)
504
+ 4* x^ 2
505
+ """
506
+ self ._parent._modulus.restore()
507
+
508
+ # Construct output polynomial
509
+ cdef Polynomial_ZZ_pEX r
510
+ r = Polynomial_ZZ_pEX.__new__ (Polynomial_ZZ_pEX)
511
+ celement_construct(& r.x, (< Polynomial_template> self )._cparent)
512
+ r._parent = (< Polynomial_template> self )._parent
513
+ r._cparent = (< Polynomial_template> self )._cparent
514
+
515
+ # When a degree has been supplied, ensure it is a valid input
516
+ cdef unsigned long d
517
+ if degree is not None :
518
+ try :
519
+ d = degree
520
+ except ValueError :
521
+ raise ValueError (" degree argument must be a non-negative integer, got %s " % (degree))
522
+ ZZ_pEX_reverse_hi(r.x, (< Polynomial_ZZ_pEX> self ).x, d)
523
+ else :
524
+ ZZ_pEX_reverse(r.x, (< Polynomial_ZZ_pEX> self ).x)
525
+ return r
526
+
527
+ def inverse_series_trunc (self , prec ):
528
+ r """
529
+ Compute and return the inverse of self modulo `x^ prec`.
530
+ The constant term of self must be invertible.
531
+
532
+ EXAMPLES::
533
+
534
+ sage: R. <x> = GF( 101^ 2) []
535
+ sage: z2 = R. base_ring( ) . gen( )
536
+ sage: f = ( 3* z2 + 57) * x^ 3 + ( 13* z2 + 94) * x^ 2 + ( 7* z2 + 2) * x + 66* z2 + 15
537
+ sage:
538
+ sage: f. inverse_series_trunc( 1)
539
+ 51* z2 + 92
540
+ sage: f. inverse_series_trunc( 2)
541
+ ( 30* z2 + 30) * x + 51* z2 + 92
542
+ sage: f. inverse_series_trunc( 3)
543
+ ( 42* z2 + 94) * x^ 2 + ( 30* z2 + 30) * x + 51* z2 + 92
544
+ sage: f. inverse_series_trunc( 4)
545
+ ( 99* z2 + 96) * x^ 3 + ( 42* z2 + 94) * x^ 2 + ( 30* z2 + 30) * x + 51* z2 + 92
546
+ """
547
+ self ._parent._modulus.restore()
548
+
549
+ # Ensure precision is non-negative
550
+ if prec <= 0 :
551
+ raise ValueError (" the precision must be positive, got {}" .format(prec))
552
+
553
+ # Ensure we can invert the constant term
554
+ const_term = self .get_coeff_c(0 )
555
+ if not const_term.is_unit():
556
+ raise ValueError (" constant term {} is not a unit" .format(const_term))
557
+
558
+ # Construct output polynomial
559
+ cdef Polynomial_ZZ_pEX r
560
+ r = Polynomial_ZZ_pEX.__new__ (Polynomial_ZZ_pEX)
561
+ celement_construct(& r.x, (< Polynomial_template> self )._cparent)
562
+ r._parent = (< Polynomial_template> self )._parent
563
+ r._cparent = (< Polynomial_template> self )._cparent
564
+
565
+ # Call to NTL for the inverse truncation
566
+ if prec > 0 :
567
+ sig_on()
568
+ ZZ_pEX_InvTrunc(r.x, self .x, prec)
569
+ sig_off()
570
+ return r
0 commit comments