Ticket #9051: trac_9051-flattened_and_rebased.patch

File trac_9051-flattened_and_rebased.patch, 83.6 KB (added by was, 11 years ago)

flattened parts1-4 and rebased against sage-4.4.4

  • module_list.py

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1260035621 28800
    # Node ID 13d49774623a1be860d0d4faaa05e3dcc3d39bdd
    # Parent  82f8c237c2358fc3c0a74cac29c47bf6f10a851e
    #7585 Fast arithmatic in F_p(t).
    * * *
    #7585 More work on F_p(t)
    
    Fix memory leak, misc speedups.
    * * *
    Added fraction_field_FpT.pxd.  Added doctests.  Made iterators work a bit better.
    * * *
    Finish up F_p(t)
    * * *
    #9051 - More speedups for GF(p)[t] and Frac(GF(p)[t]).
    
    diff -r 82f8c237c235 -r 13d49774623a module_list.py
    a b  
    10991099    Extension('sage.rings.fraction_field_element',
    11001100              sources = ['sage/rings/fraction_field_element.pyx']),
    11011101   
     1102    Extension('sage.rings.fraction_field_FpT',
     1103              sources = ['sage/rings/fraction_field_FpT.pyx'],
     1104              libraries = ["csage", "flint", "gmp", "gmpxx", "ntl", "zn_poly"],
     1105              extra_compile_args=["-std=c99", "-D_XPG6"],
     1106              include_dirs = [SAGE_ROOT+'/local/include/FLINT/'],
     1107              depends = [SAGE_ROOT + "/local/include/FLINT/flint.h"]),
     1108   
    11021109    Extension('sage.rings.laurent_series_ring_element',
    11031110              sources = ['sage/rings/laurent_series_ring_element.pyx']),
    11041111
  • sage/libs/flint/zmod_poly.pxd

    diff -r 82f8c237c235 -r 13d49774623a sage/libs/flint/zmod_poly.pxd
    a b  
    259259
    260260    # Factorization
    261261
    262     cdef int zmod_poly_isirreducible(zmod_poly_t p)
     262    cdef bint zmod_poly_isirreducible(zmod_poly_t p)
    263263
    264264    ctypedef struct zmod_poly_factors_struct:
    265265        unsigned long num_factors
     
    270270
    271271    cdef void zmod_poly_factor_init(zmod_poly_factor_t)
    272272    cdef void zmod_poly_factor_clear(zmod_poly_factor_t)
     273    cdef unsigned long zmod_poly_factor(zmod_poly_factor_t, zmod_poly_t)
    273274    cdef void zmod_poly_factor_square_free(zmod_poly_factor_t, zmod_poly_t)
    274     cdef void zmod_poly_factor(zmod_poly_factor_t, zmod_poly_t)
     275    cdef void zmod_poly_factor_berlekamp(zmod_poly_factor_t factors, zmod_poly_t f)
     276
     277    cdef void zmod_poly_factor_add(zmod_poly_factor_t fac, zmod_poly_t poly)
     278    cdef void zmod_poly_factor_concat(zmod_poly_factor_t res, zmod_poly_factor_t fac)
     279    cdef void zmod_poly_factor_print(zmod_poly_factor_t fac)
     280    cdef void zmod_poly_factor_pow(zmod_poly_factor_t fac, unsigned long exp)
    275281
    276282    #
    277283    # Differentiation
     
    285291   
    286292    cdef void zmod_poly_mulmod(zmod_poly_t res, zmod_poly_t poly1, zmod_poly_t poly2, zmod_poly_t f)
    287293    cdef void zmod_poly_powmod(zmod_poly_t res,zmod_poly_t pol, long exp, zmod_poly_t f)
    288 
    289     #
    290     # Polynomial factorization
    291     #
    292 
    293     cdef void zmod_poly_factor_init(zmod_poly_factor_t fac)
    294     cdef void zmod_poly_factor_clear(zmod_poly_factor_t fac)
    295     cdef void zmod_poly_factor_add(zmod_poly_factor_t fac, zmod_poly_t poly)
    296     cdef void zmod_poly_factor_concat(zmod_poly_factor_t res, zmod_poly_factor_t fac)
    297     cdef void zmod_poly_factor_print(zmod_poly_factor_t fac)
    298     cdef void zmod_poly_factor_pow(zmod_poly_factor_t fac, unsigned long exp)
    299     cdef void zmod_poly_factor_square_free(zmod_poly_factor_t res, zmod_poly_t f)
    300     cdef void zmod_poly_factor_berlekamp(zmod_poly_factor_t factors, zmod_poly_t f)
    301     cdef unsigned long zmod_poly_factor(zmod_poly_factor_t result, zmod_poly_t input)
    302     cdef int zmod_poly_isirreducible(zmod_poly_t f)
    303 
  • sage/libs/flint/zmod_poly_linkage.pxi

    diff -r 82f8c237c235 -r 13d49774623a sage/libs/flint/zmod_poly_linkage.pxi
    a b  
    456456        24998*x^2 + 29761*x + 2252
    457457
    458458        sage: f^-1
    459         1/(24998*x^2 + 29761*x + 2252)
     459        18649/(x^2 + 16863*x + 9612)
    460460
    461461        sage: f^-5
    462         1/(20269*x^10 + 20535*x^9 + 7313*x^8 + 7311*x^7 + 16853*x^6 + 142*x^5 + 23853*x^4 + 12065*x^3 + 516*x^2 + 8473*x + 17945)
     462        24620/(x^10 + 20309*x^9 + 29185*x^8 + 11948*x^7 + 1965*x^6 + 7713*x^5 + 5810*x^4 + 20457*x^3 + 30732*x^2 + 9706*x + 4485)
    463463
    464464     Testing the modulus:
    465465
     
    471471        15328*x + 6968
    472472
    473473        sage: pow(f, -2, g)
    474         1/(15328*x + 6968)
     474        16346/(x + 251)
    475475        sage: (f^2 % g)^-1
    476         1/(15328*x + 6968)
     476        16346/(x + 251)
    477477
    478478        sage: pow(f, 5, g)
    479479        7231*x + 17274
  • sage/rings/finite_rings/integer_mod.pxd

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/finite_rings/integer_mod.pxd
    a b  
    4949    cdef IntegerMod_int64 _new_c(self, int_fast64_t value)
    5050    cdef shift(IntegerMod_int64 self, int k)
    5151
     52cdef int jacobi_int(int_fast32_t a, int_fast32_t m) except -2
     53cdef int_fast32_t mod_inverse_int(int_fast32_t x, int_fast32_t n) except 0
     54cdef int_fast32_t mod_pow_int(int_fast32_t base, int_fast32_t exp, int_fast32_t n)
  • sage/rings/fraction_field.py

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/fraction_field.py
    a b  
    172172            sage: Frac(QQ['x,y']).variable_names()
    173173            ('x', 'y')
    174174        """
    175         self.__R = R
     175        self._R = R
    176176        self._element_class = element_class
    177177        self._element_init_pass_parent = False
    178         Parent.__init__(self, base=R, names=R._names, element_constructor=self._element_constructor_)
     178        Parent.__init__(self, base=R, names=R._names)
    179179
    180180    def __reduce__(self):
    181181        """
     
    185185            sage: loads(dumps(K)) is K
    186186            True
    187187        """
    188         return FractionField, (self.__R,)
     188        return FractionField, (self._R,)
    189189
    190190    def _coerce_map_from_(self, S):
    191191        """
     
    262262       
    263263        # The case ``S`` being `\QQ` requires special handling since `\QQ` is
    264264        # not implemented as a ``FractionField_generic``.
    265         if S is QQ and self.__R.has_coerce_map_from(ZZ):
     265        if S is QQ and self._R.has_coerce_map_from(ZZ):
    266266            return CallableConvertMap(S, self, \
    267267                lambda x: self._element_class(self, x.numerator(),
    268268                x.denominator()), parent_as_first_arg=False)
     
    274274                parent_as_first_arg=False)
    275275       
    276276        if isinstance(S, FractionField_generic) and \
    277             self.__R.has_coerce_map_from(S.ring()):
     277            self._R.has_coerce_map_from(S.ring()):
    278278            return CallableConvertMap(S, self, \
    279279                lambda x: self._element_class(self, x.numerator(),
    280280                x.denominator()), parent_as_first_arg=False)
    281281       
    282         if self.__R.has_coerce_map_from(S):
     282        if self._R.has_coerce_map_from(S):
    283283            return CallableConvertMap(S, self, self._element_class,
    284284                parent_as_first_arg=True)
    285285       
     
    338338            sage: R.base_ring()
    339339            Integer Ring
    340340        """
    341         return self.__R.base_ring()
     341        return self._R.base_ring()
    342342
    343343    def characteristic(self):
    344344        """
     
    354354            sage: R = Frac(GF(5)['w']); R.characteristic()
    355355            5
    356356        """
    357         return self.__R.characteristic()
     357        return self._R.characteristic()
    358358   
    359359    def _repr_(self):
    360360        """
     
    363363            sage: str(Frac(ZZ['x']))
    364364            'Fraction Field of Univariate Polynomial Ring in x over Integer Ring'
    365365        """
    366         return "Fraction Field of %s"%self.__R
     366        return "Fraction Field of %s"%self._R
    367367
    368368    def _latex_(self):
    369369        """
     
    372372            sage: latex(Frac(GF(7)['x,y,z']))
    373373            \mathrm{Frac}(\Bold{F}_{7}[x, y, z])
    374374        """
    375         return "\\mathrm{Frac}(%s)"%latex.latex(self.__R)
     375        return "\\mathrm{Frac}(%s)"%latex.latex(self._R)
    376376
    377377    def _magma_init_(self, magma):
    378378        """
     
    418418            sage: R.ring()
    419419            Multivariate Polynomial Ring in x, y over Rational Field
    420420        """
    421         return self.__R
     421        return self._R
    422422   
    423423    def is_exact(self):
    424424        """
     
    436436            self.__is_exact = r
    437437        return r
    438438
    439     def _element_constructor_(self, x, coerce=True):
     439    def _element_constructor_(self, x, y=1, coerce=True):
    440440        """
    441441        Construct an element of this fraction field.
    442442       
     
    463463                return x
    464464            else:
    465465                return self._element_class(self, x.numerator(), x.denominator())
    466         return self._element_class(self, x, 1,
     466        return self._element_class(self, x, y,
    467467                coerce=coerce, reduce = self.is_exact())
    468468
    469469    def construction(self):
     
    497497        """
    498498        if not isinstance(other, FractionField_generic):
    499499            return cmp(type(self), type(other))
    500         return cmp(self.__R, other.__R)
     500        return cmp(self._R, other._R)
    501501
    502502    def ngens(self):
    503503        """
     
    510510            sage: R.ngens()
    511511            10
    512512        """
    513         return self.__R.ngens()
     513        return self._R.ngens()
    514514
    515515    def gen(self, i=0):
    516516        """
     
    527527            sage: R.3
    528528            z3
    529529        """
    530         x = self.__R.gen(i)
    531         one = self.__R.one_element()
     530        x = self._R.gen(i)
     531        one = self._R.one_element()
    532532        r = self._element_class(self, x, one, coerce=False, reduce=False)
    533533        return r
    534534
     
    585585            sage: F.random_element(degree=5)
    586586            (-12*x^5 - 2*x^4 - x^3 - 95*x^2 + x + 2)/(-x^5 + x^4 - x^3 + x^2)
    587587        """
    588         return self._element_class(self, self.__R.random_element(*args, **kwds),
    589             self.__R._random_nonzero_element(*args, **kwds),
     588        return self._element_class(self, self._R.random_element(*args, **kwds),
     589            self._R._random_nonzero_element(*args, **kwds),
    590590            coerce = False, reduce=True)
    591591
     592class FractionField_1poly_field(FractionField_generic):
     593    """
     594    The fraction field of a univariate polynomial ring over a field.
     595
     596    Many of the functions here are included for coherence with number fields.
     597    """
     598    def __init__(self, R,
     599            element_class=fraction_field_element.FractionFieldElement_1poly_field):
     600        """
     601        Just changes the default for element_class
     602
     603        EXAMPLES::
     604
     605            sage: R.<t> = QQ[]; K = R.fraction_field()
     606            sage: K._element_class
     607            <class 'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>
     608        """
     609        FractionField_generic.__init__(self, R, element_class)
     610
     611    def ring_of_integers(self):
     612        """
     613        Returns the ring of integers in this fraction field.
     614
     615        EXAMPLES::
     616
     617            sage: K = FractionField(GF(5)['t'])
     618            sage: K.ring_of_integers()
     619            Univariate Polynomial Ring in t over Finite Field of size 5
     620        """
     621        return self._R
     622
     623    def maximal_order(self):
     624        """
     625        Returns the maximal order in this fraction field.
     626
     627        EXAMPLES::
     628
     629            sage: K = FractionField(GF(5)['t'])
     630            sage: K.maximal_order()
     631            Univariate Polynomial Ring in t over Finite Field of size 5
     632        """
     633        return self._R
     634
     635    def class_number(self):
     636        """
     637        Here for compatibility with number fields and function fields.
     638
     639        EXAMPLES::
     640
     641            sage: R.<t> = GF(5)[]; K = R.fraction_field()
     642            sage: K.class_number()
     643            1
     644        """
     645        return 1
  • new file sage/rings/fraction_field_FpT.pxd

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/fraction_field_FpT.pxd
    - +  
     1
     2from sage.libs.flint.zmod_poly cimport *
     3
     4from sage.rings.morphism cimport RingHomomorphism_coercion
     5from sage.categories.morphism cimport Morphism
     6from sage.structure.element cimport Element, ModuleElement, RingElement
     7from sage.categories.map cimport Section
     8
     9cdef class FpTElement(RingElement):
     10    cdef zmod_poly_t _numer, _denom
     11    cdef bint initalized
     12    cdef long p
     13
     14    cdef FpTElement _new_c(self)
     15    cdef FpTElement _copy_c(self)
     16    cpdef numerator(self)
     17    cpdef denominator(self)
     18    cpdef FpTElement next(self)
     19    cpdef _sqrt_or_None(self)
     20    cpdef bint is_square(self)
     21
     22cdef class FpT_iter:   
     23    cdef parent
     24    cdef long degree
     25    cdef FpTElement cur
     26    cdef zmod_poly_t g
  • new file sage/rings/fraction_field_FpT.pyx

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/fraction_field_FpT.pyx
    - +  
     1
     2
     3import sys
     4
     5include "../ext/cdefs.pxi"
     6include "../ext/gmp.pxi"
     7include "../ext/interrupt.pxi"
     8include "../ext/stdsage.pxi"
     9
     10from sage.rings.all import GF
     11from sage.libs.flint.zmod_poly cimport *
     12from sage.structure.element cimport Element, ModuleElement, RingElement
     13from sage.rings.integer_ring import ZZ
     14from sage.rings.fraction_field import FractionField_generic, FractionField_1poly_field
     15from sage.rings.finite_rings.integer_mod cimport IntegerMod_int
     16from sage.rings.integer cimport Integer
     17from sage.rings.polynomial.polynomial_zmod_flint cimport Polynomial_zmod_flint
     18import sage.algebras.algebra
     19
     20from sage.rings.finite_rings.integer_mod cimport jacobi_int, mod_inverse_int, mod_pow_int
     21
     22class FpT(FractionField_1poly_field):
     23    """
     24    This class represents the fraction field GF(p)(T) for `2 < p < 2^16`.
     25
     26    EXAMPLES::
     27
     28        sage: R.<T> = GF(71)[]
     29        sage: K = FractionField(R); K
     30        Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 71
     31        sage: 1-1/T
     32        (T + 70)/T
     33        sage: parent(1-1/T) is K
     34        True
     35    """
     36    def __init__(self, R, names=None):  # we include names so that one can use the syntax K.<t> = FpT(GF(5)['t']).  It's actually ignored
     37        """
     38        INPUT:
     39
     40        - ``R`` -- A polynomial ring over a finite field of prime order `p` with `2 < p < 2^16`
     41
     42        EXAMPLES::
     43       
     44            sage: R.<x> = GF(31)[]
     45            sage: K = R.fraction_field(); K
     46            Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 31
     47        """
     48        cdef long p = R.base_ring().characteristic()
     49        assert 2 < p < 2**16
     50        self.p = p
     51        self.poly_ring = R
     52        FractionField_1poly_field.__init__(self, R, element_class = FpTElement)
     53        self._populate_coercion_lists_(coerce_list=[Polyring_FpT_coerce(self), Fp_FpT_coerce(self), ZZ_FpT_coerce(self)])
     54   
     55    def __iter__(self):
     56        """
     57        Returns an iterator over this fraction field.
     58
     59        EXAMPLES::
     60
     61            sage: R.<t> = GF(3)[]; K = R.fraction_field()
     62            sage: iter(K)
     63            <sage.rings.fraction_field_FpT.FpT_iter object at ...>
     64        """
     65        return self.iter()
     66   
     67    def iter(self, bound=None, start=None):
     68        """
     69            sage: from sage.rings.fraction_field_FpT import *
     70            sage: R.<t> = FpT(GF(5)['t'])
     71            sage: list(R.iter(2))[350:355]
     72            [(t^2 + t + 1)/(t + 2),
     73             (t^2 + t + 2)/(t + 2),
     74             (t^2 + t + 4)/(t + 2),
     75             (t^2 + 2*t + 1)/(t + 2),
     76             (t^2 + 2*t + 2)/(t + 2)]
     77        """
     78        return FpT_iter(self, bound, start)
     79
     80cdef class FpTElement(RingElement):
     81    """
     82    An element of an FpT fraction field.
     83    """
     84   
     85    def __init__(self, parent, numer, denom=1, coerce=True, reduce=True):
     86        """
     87        INPUT:
     88
     89        - parent -- the Fraction field containing this element
     90        - numer -- something that can be converted into the polynomial ring, giving the numerator
     91        - denom -- something that can be converted into the polynomial ring, giving the numerator (default 1)
     92
     93        EXAMPLES::
     94       
     95            sage: from sage.rings.fraction_field_FpT import *
     96            sage: R.<t> = FpT(GF(5)['t'])
     97            sage: R(7)
     98            2
     99           
     100        """
     101        RingElement.__init__(self, parent)
     102        if coerce:
     103            numer = parent.poly_ring(numer)
     104            denom = parent.poly_ring(denom)
     105        self.p = parent.p
     106        zmod_poly_init(self._numer, self.p)
     107        zmod_poly_init(self._denom, self.p)
     108        self.initalized = True
     109        cdef long n
     110        for n, a in enumerate(numer):
     111            zmod_poly_set_coeff_ui(self._numer, n, a)
     112        for n, a in enumerate(denom):
     113            zmod_poly_set_coeff_ui(self._denom, n, a)
     114        if reduce:
     115            normalize(self._numer, self._denom, self.p)
     116
     117    def __dealloc__(self):
     118        """
     119        Deallocation.
     120
     121        EXAMPLES::
     122
     123            sage: K = GF(11)['t'].fraction_field()
     124            sage: t = K.gen()
     125            sage: del t # indirect doctest
     126        """
     127        if self.initalized:
     128            zmod_poly_clear(self._numer)
     129            zmod_poly_clear(self._denom)
     130   
     131    def __reduce__(self):
     132        """
     133        For pickling.
     134       
     135        TESTS::
     136       
     137            sage: K = GF(11)['t'].fraction_field()
     138            sage: loads(dumps(K.gen()))
     139            t
     140            sage: loads(dumps(1/K.gen()))
     141            1/t
     142        """
     143        return (unpickle_FpT_element,
     144                (self._parent, self.numer(), self.denom()))
     145   
     146    cdef FpTElement _new_c(self):
     147        """
     148        Creates a new FpTElement in the same field, leaving the value to be initialized.
     149        """
     150        cdef FpTElement x = <FpTElement>PY_NEW(FpTElement)
     151        x._parent = self._parent
     152        x.p = self.p
     153        zmod_poly_init_precomp(x._numer, x.p, self._numer.p_inv)
     154        zmod_poly_init_precomp(x._denom, x.p, self._numer.p_inv)
     155        x.initalized = True
     156        return x
     157   
     158    cdef FpTElement _copy_c(self):
     159        """
     160        Creates a new FpTElement in the same field, with the same value as self.
     161        """
     162        cdef FpTElement x = <FpTElement>PY_NEW(FpTElement)
     163        x._parent = self._parent
     164        x.p = self.p
     165        zmod_poly_init2_precomp(x._numer, x.p, self._numer.p_inv, self._numer.length)
     166        zmod_poly_init2_precomp(x._denom, x.p, self._denom.p_inv, self._denom.length)
     167        zmod_poly_set(x._numer, self._numer)
     168        zmod_poly_set(x._denom, self._denom)
     169        x.initalized = True
     170        return x
     171   
     172    def numer(self):
     173        """
     174        Returns the numerator of this element, as an element of the polynomial ring.
     175
     176        EXAMPLES::
     177
     178            sage: K = GF(11)['t'].fraction_field()
     179            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     180            sage: a.numer()
     181            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
     182        """
     183        return self.numerator()
     184
     185    cpdef numerator(self):
     186        """
     187        Returns the numerator of this element, as an element of the polynomial ring.
     188
     189        EXAMPLES::
     190
     191            sage: K = GF(11)['t'].fraction_field()
     192            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     193            sage: a.numerator()
     194            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
     195        """
     196        cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint)
     197        zmod_poly_init2_precomp(&res.x, self.p, self._numer.p_inv, self._numer.length)
     198        zmod_poly_set(&res.x, self._numer)
     199        res._parent = self._parent.poly_ring
     200        return res
     201
     202    def denom(self):
     203        """
     204        Returns the denominator of this element, as an element of the polynomial ring.
     205
     206        EXAMPLES::
     207
     208            sage: K = GF(11)['t'].fraction_field()
     209            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     210            sage: a.denom()
     211            t^3
     212        """
     213        return self.denominator()
     214
     215    cpdef denominator(self):
     216        """
     217        Returns the denominator of this element, as an element of the polynomial ring.
     218
     219        EXAMPLES::
     220
     221            sage: K = GF(11)['t'].fraction_field()
     222            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     223            sage: a.denominator()
     224            t^3
     225        """
     226        cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint)
     227        zmod_poly_init2_precomp(&res.x, self.p, self._denom.p_inv, self._denom.length)
     228        zmod_poly_set(&res.x, self._denom)
     229        res._parent = self._parent.poly_ring
     230        return res
     231   
     232    def __call__(self, *args, **kwds):
     233        """
     234        EXAMPLES::
     235       
     236            sage: K = Frac(GF(5)['t'])
     237            sage: t = K.gen()
     238            sage: t(3)
     239            3
     240            sage: f = t^2/(1-t)
     241            sage: f(2)
     242            1
     243            sage: f(t)
     244            4*t^2/(t + 4)
     245            sage: f(t^3)
     246            4*t^6/(t^3 + 4)
     247            sage: f((t+1)/t^3)
     248            (t^2 + 2*t + 1)/(t^6 + 4*t^4 + 4*t^3)
     249        """
     250        return self.numer()(*args, **kwds) / self.denom()(*args, **kwds)
     251   
     252    def subs(self, *args, **kwds):
     253        """
     254        EXAMPLES::
     255       
     256            sage: K = Frac(GF(11)['t'])
     257            sage: t = K.gen()
     258            sage: f = (t+1)/(t-1)
     259            sage: f.subs(t=2)
     260            3
     261            sage: f.subs(X=2)
     262            (t + 1)/(t + 10)
     263        """
     264        return self.numer().subs(*args, **kwds) / self.denom().subs(*args, **kwds)
     265   
     266    def valuation(self, v):
     267        """
     268        Returns the valuation of self at `v`.
     269       
     270        EXAMPLES::
     271       
     272            sage: R.<t> = GF(5)[]
     273            sage: f = (t+1)^2 * (t^2+t+1) / (t-1)^3
     274            sage: f.valuation(t+1)
     275            2
     276            sage: f.valuation(t-1)
     277            -3
     278            sage: f.valuation(t)
     279            0
     280        """
     281        return self.numer().valuation(v) - self.denom().valuation(v)
     282   
     283    def factor(self):
     284        """
     285        EXAMPLES::
     286       
     287            sage: K = Frac(GF(5)['t'])
     288            sage: t = K.gen()
     289            sage: f = 2 * (t+1) * (t^2+t+1)^2 / (t-1)
     290            sage: factor(f)
     291            (2) * (t + 4)^-1 * (t + 1) * (t^2 + t + 1)^2
     292        """
     293        return self.numer().factor() / self.denom().factor()
     294
     295    def _repr_(self):
     296        """
     297        Returns a string representation of this element.
     298       
     299        EXAMPLES::
     300
     301            sage: from sage.rings.fraction_field_FpT import *
     302            sage: R.<t> = FpT(GF(17)['t'])
     303            sage: -t # indirect doctest
     304            16*t
     305            sage: 1/t
     306            1/t
     307            sage: 1/(t+1)
     308            1/(t + 1)
     309            sage: 1-t/t
     310            0
     311            sage: (1-t)/t
     312            (16*t + 1)/t
     313        """
     314        if zmod_poly_degree(self._denom) == 0 and zmod_poly_get_coeff_ui(self._denom, 0) == 1:
     315            return repr(self.numer())
     316        else:
     317            numer_s = repr(self.numer())
     318            denom_s = repr(self.denom())
     319            if '-' in numer_s or '+' in numer_s:
     320                numer_s = "(%s)" % numer_s
     321            if '-' in denom_s or '+' in denom_s:
     322                denom_s = "(%s)" % denom_s
     323            return "%s/%s" % (numer_s, denom_s)
     324   
     325    def _latex_(self):
     326        r"""
     327        Returns a latex representation of this element.
     328
     329        EXAMPLES::
     330
     331            sage: K = GF(7)['t'].fraction_field(); t = K.gen(0)
     332            sage: latex(t^2 + 1) # indirect doctest
     333            t^{2} + 1
     334            sage: latex((t + 1)/(t-1))
     335            \frac{t + 1}{t + 6}
     336        """
     337        if zmod_poly_degree(self._denom) == 0 and zmod_poly_get_coeff_ui(self._denom, 0) == 1:
     338            return self.numer()._latex_()
     339        else:
     340            return "\\frac{%s}{%s}" % (self.numer()._latex_(), self.denom()._latex_())
     341   
     342    def __richcmp__(left, right, int op):
     343        """
     344        EXAMPLES::
     345       
     346            sage: K = Frac(GF(5)['t']); t = K.gen()
     347            sage: t == 1
     348            False
     349            sage: t + 1 < t^2
     350            True
     351        """
     352        return (<Element>left)._richcmp(right, op)
     353
     354    cdef int _cmp_c_impl(self, Element other) except -2:
     355        """
     356        Compares this with another element.
     357
     358        TESTS::
     359       
     360            sage: from sage.rings.fraction_field_FpT import *
     361            sage: R.<t> = FpT(GF(7)['t'])
     362            sage: t == t
     363            True
     364            sage: t == -t
     365            False
     366            sage: -t == 6*t
     367            True
     368            sage: 1/t == 1/t
     369            True
     370            sage: 1/t == 1/(t+1)
     371            False
     372            sage: 2*t/t == 2
     373            True
     374            sage: 2*t/2 == t
     375            True
     376        """
     377        # They are normalized.
     378        if (zmod_poly_equal(self._numer, (<FpTElement>other)._numer) and
     379            zmod_poly_equal(self._denom, (<FpTElement>other)._denom)):
     380            return 0
     381        else:
     382            return -1
     383   
     384    def __hash__(self):
     385        """
     386        Returns a hash value for this element.
     387
     388        TESTS::
     389           
     390            sage: from sage.rings.fraction_field_FpT import *
     391            sage: K.<t> = FpT(GF(7)['t'])
     392            sage: hash(K(0))
     393            0
     394            sage: hash(K(5))
     395            5
     396            sage: set([1, t, 1/t, t, t, 1/t, 1+1/t, t/t])
     397            set([1, t, 1/t, (t + 1)/t])
     398        """
     399        if self.denom() == 1:
     400            return hash(self.numer())
     401        return hash((self.numer(), self.numer()))
     402       
     403    def __neg__(self):
     404        """
     405        Negates this element.
     406
     407        EXAMPLES::
     408
     409            sage: K = GF(5)['t'].fraction_field(); t = K.gen(0)
     410            sage: a = (t^2 + 2)/(t-1)
     411            sage: -a # indirect doctest
     412            (4*t^2 + 3)/(t + 4)
     413        """
     414        cdef FpTElement x = self._copy_c()
     415        zmod_poly_neg(x._numer, x._numer)
     416        return x
     417       
     418    def __invert__(self):
     419        """
     420        Returns the multiplicative inverse of this element.
     421
     422        EXAMPLES::
     423
     424            sage: K = GF(5)['t'].fraction_field(); t = K.gen(0)
     425            sage: a = (t^2 + 2)/(t-1)
     426            sage: ~a # indirect doctest
     427            (t + 4)/(t^2 + 2)
     428        """
     429        if zmod_poly_degree(self._numer) == -1:
     430            raise ZeroDivisionError
     431        cdef FpTElement x = self._copy_c()
     432        zmod_poly_swap(x._numer, x._denom)
     433        return x
     434
     435    cpdef ModuleElement _add_(self, ModuleElement _other):
     436        """
     437        Returns the sum of this fraction field element and another.
     438
     439        EXAMPLES::
     440       
     441            sage: from sage.rings.fraction_field_FpT import *
     442            sage: R.<t> = FpT(GF(7)['t'])
     443            sage: t + t # indirect doctest
     444            2*t
     445            sage: (t + 3) + (t + 10)
     446            2*t + 6
     447            sage: sum([t] * 7)
     448            0
     449            sage: 1/t + t
     450            (t^2 + 1)/t
     451            sage: 1/t + 1/t^2
     452            (t + 1)/t^2
     453        """
     454        cdef FpTElement other = <FpTElement>_other
     455        cdef FpTElement x = self._new_c()
     456        zmod_poly_mul(x._numer, self._numer, other._denom)
     457        zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp
     458        zmod_poly_add(x._numer, x._numer, x._denom)
     459        zmod_poly_mul(x._denom, self._denom, other._denom)
     460        normalize(x._numer, x._denom, self.p)
     461        return x
     462
     463    cpdef ModuleElement _sub_(self, ModuleElement _other):
     464        """
     465        Returns the difference of this fraction field element and another.
     466
     467        EXAMPLES::
     468       
     469            sage: from sage.rings.fraction_field_FpT import *
     470            sage: R.<t> = FpT(GF(7)['t'])
     471            sage: t - t # indirect doctest
     472            0
     473            sage: (t + 3) - (t + 11)
     474            6
     475        """
     476        cdef FpTElement other = <FpTElement>_other
     477        cdef FpTElement x = self._new_c()
     478        zmod_poly_mul(x._numer, self._numer, other._denom)
     479        zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp
     480        zmod_poly_sub(x._numer, x._numer, x._denom)
     481        zmod_poly_mul(x._denom, self._denom, other._denom)
     482        normalize(x._numer, x._denom, self.p)
     483        return x
     484
     485    cpdef RingElement _mul_(self, RingElement _other):
     486        """
     487        Returns the product of this fraction field element and another.
     488
     489        EXAMPLES::
     490       
     491            sage: from sage.rings.fraction_field_FpT import *
     492            sage: R.<t> = FpT(GF(7)['t'])
     493            sage: t * t # indirect doctest
     494            t^2
     495            sage: (t + 3) * (t + 10)
     496            t^2 + 6*t + 2
     497        """
     498        cdef FpTElement other = <FpTElement>_other
     499        cdef FpTElement x = self._new_c()
     500        zmod_poly_mul(x._numer, self._numer, other._numer)
     501        zmod_poly_mul(x._denom, self._denom, other._denom)
     502        normalize(x._numer, x._denom, self.p)
     503        return x
     504
     505    cpdef RingElement _div_(self, RingElement _other):
     506        """
     507        Returns the quotient of this fraction field element and another.
     508
     509        EXAMPLES::
     510       
     511            sage: from sage.rings.fraction_field_FpT import *
     512            sage: R.<t> = FpT(GF(5)['t'])
     513            sage: t / t # indirect doctest
     514            1
     515            sage: (t + 3) / (t + 11)
     516            (t + 3)/(t + 1)
     517            sage: (t^2 + 2*t + 1) / (t + 1)
     518            t + 1
     519        """
     520        cdef FpTElement other = <FpTElement>_other
     521        if zmod_poly_degree(other._numer) == -1:
     522            raise ZeroDivisionError
     523        cdef FpTElement x = self._new_c()
     524        zmod_poly_mul(x._numer, self._numer, other._denom)
     525        zmod_poly_mul(x._denom, self._denom, other._numer)
     526        normalize(x._numer, x._denom, self.p)
     527        return x
     528   
     529    cpdef FpTElement next(self):
     530        """
     531        This function iterates through all polynomials, returning the "next" polynomial after this one.
     532
     533        The strategy is as follows:
     534       
     535        - We always leave the denominator monic.
     536
     537        - We progress through the elements with both numerator and denominator monic, and with the denominator less than the numerator. 
     538          For each such, we output all the scalar multiples of it, then all of the scalar multiples of its inverse.
     539
     540        - So if the leading coefficient of the numerator is less than p-1, we scale the numerator to increase it by 1.
     541
     542        - Otherwise, we consider the multiple with numerator and denominator monic. 
     543       
     544          - If the numerator is less than the denominator (lexicographically), we return the inverse of that element.
     545
     546          - If the numerator is greater than the denominator, we invert, and then increase the numerator (remaining monic) until we either get something relatively prime to the new denominator, or we reach the new denominator.  In this case, we increase the denominator and set the numerator to 1.
     547
     548        EXAMPLES::
     549       
     550            sage: from sage.rings.fraction_field_FpT import *
     551            sage: R.<t> = FpT(GF(3)['t'])
     552            sage: a = R(0)
     553            sage: for _ in range(30):
     554            ...       a = a.next()
     555            ...       print a
     556            ...   
     557            1
     558            2
     559            1/t
     560            2/t
     561            t
     562            2*t
     563            1/(t + 1)
     564            2/(t + 1)
     565            t + 1
     566            2*t + 2
     567            t/(t + 1)
     568            2*t/(t + 1)
     569            (t + 1)/t
     570            (2*t + 2)/t
     571            1/(t + 2)
     572            2/(t + 2)
     573            t + 2
     574            2*t + 1
     575            t/(t + 2)
     576            2*t/(t + 2)
     577            (t + 2)/t
     578            (2*t + 1)/t
     579            (t + 1)/(t + 2)
     580            (2*t + 2)/(t + 2)
     581            (t + 2)/(t + 1)
     582            (2*t + 1)/(t + 1)
     583            1/t^2
     584            2/t^2
     585            t^2
     586            2*t^2
     587        """
     588        cdef FpTElement next = self._copy_c()
     589        cdef long a, lead
     590        cdef zmod_poly_t g
     591        if zmod_poly_degree(self._numer) == -1:
     592            # self should be normalized, so denom == 1
     593            zmod_poly_set_coeff_ui(next._numer, 0, 1)
     594            return next
     595        lead = zmod_poly_leading(next._numer)
     596        if lead < self.p - 1:
     597            a = mod_inverse_int(lead, self.p)
     598            # no overflow since self.p < 2^16
     599            a = a * (lead + 1) % self.p
     600            zmod_poly_scalar_mul(next._numer, next._numer, a)
     601        else:
     602            a = mod_inverse_int(lead, self.p)
     603            zmod_poly_scalar_mul(next._numer, next._numer, a)
     604            # now both next._numer and next._denom are monic.  We figure out which is lexicographically bigger:
     605            a = zmod_poly_cmp(next._numer, next._denom)
     606            if a == 0:
     607                # next._numer and next._denom are relatively prime, so they're both 1.
     608                zmod_poly_inc(next._denom, True)
     609                return next
     610            zmod_poly_set(next._denom, next._numer)
     611            zmod_poly_set(next._numer, self._denom)
     612            if a < 0:
     613                # since next._numer is smaller, we flip and return the inverse.
     614                return next
     615            elif a > 0:
     616                # since next._numer is bigger, we're in the flipped phase.  We flip back, and increment the numerator (until we reach the denominator).
     617                zmod_poly_init(g, self.p)
     618                try:
     619                    while True:
     620                        zmod_poly_inc(next._numer, True)
     621                        if zmod_poly_equal(next._numer, next._denom):
     622                            # Since we've reached the denominator, we reset the numerator to 1 and increment the denominator.
     623                            zmod_poly_inc(next._denom, True)
     624                            zmod_poly_zero(next._numer)
     625                            zmod_poly_set_coeff_ui(next._numer, 0, 1)
     626                            break
     627                        else:
     628                            # otherwise, we keep incrementing until we have a relatively prime numerator.
     629                            zmod_poly_gcd(g, next._numer, next._denom)
     630                            if zmod_poly_is_one(g):
     631                                break
     632                finally:
     633                    zmod_poly_clear(g)
     634        return next
     635       
     636#         if zmod_poly_degree(self._numer) == -1:
     637#             zmod_poly_set_coeff_ui(x._numer, 0, 1)
     638#             zmod_poly_set_coeff_ui(x._denom, 0, 1)
     639#             return x
     640#         elif zmod_poly_degree(self._numer) == 0:
     641#             zmod_poly_set_coeff_ui(x._numer, 0, zmod_poly_get_coeff_ui(self._numer, 0) + 1)
     642#             zmod_poly_set_coeff_ui(x._denom, 0, 1)
     643#             if zmod_poly_get_coeff_ui(x._numer, 0) == 0:
     644#                 zmod_poly_set_coeff_ui(x._numer, 1, 1)
     645#             return x
     646#         cdef zmod_poly_t g
     647#         zmod_poly_init(g, self.p)
     648#         zmod_poly_set(x._numer, self._numer)
     649#         zmod_poly_set(x._denom, self._denom)
     650#         while True:
     651#             zmod_poly_inc(x._denom, True)
     652#             if zmod_poly_degree(x._numer) < zmod_poly_degree(x._denom):
     653#                 zmod_poly_inc(x._numer, False)
     654#                 zmod_poly_zero(x._denom)
     655#                 zmod_poly_set_coeff_ui(x._denom, 0, 1)
     656#             zmod_poly_gcd(g, x._numer, x._denom)
     657#             if zmod_poly_is_one(g):
     658#                 zmod_poly_clear(g)
     659#                 return x
     660   
     661    cpdef _sqrt_or_None(self):
     662        """
     663        Returns the squre root of self, or None. Differs from sqrt() by not raising an exception.
     664       
     665        TESTS::
     666       
     667            sage: from sage.rings.fraction_field_FpT import *
     668            sage: R.<t> = FpT(GF(17)['t'])
     669            sage: sqrt(t^2) # indirect doctest
     670            t
     671            sage: sqrt(1/t^2)
     672            1/t
     673            sage: sqrt((1+t)^2)
     674            t + 1
     675            sage: sqrt((1+t)^2 / t^2)
     676            (t + 1)/t
     677
     678            sage: sqrt(4 * (1+t)^2 / t^2)
     679            (2*t + 2)/t
     680           
     681            sage: sqrt(R(0))
     682            0
     683            sage: sqrt(R(-1))
     684            4
     685           
     686            sage: sqrt(t^4)
     687            t^2
     688            sage: sqrt(4*t^4/(1+t)^8)
     689            2*t^2/(t^4 + 4*t^3 + 6*t^2 + 4*t + 1)
     690           
     691            sage: R.<t> = FpT(GF(5)['t'])
     692            sage: [a for a in R.iter(2) if (a^2).sqrt() not in (a,-a)]
     693            []
     694            sage: [a for a in R.iter(2) if a.is_square() and a.sqrt()^2 != a]
     695            []
     696
     697        """
     698        if zmod_poly_degree(self._numer) == -1:
     699            return self
     700        if not zmod_poly_sqrt_check(self._numer) or not zmod_poly_sqrt_check(self._denom):
     701            return None
     702        cdef zmod_poly_t numer
     703        cdef zmod_poly_t denom
     704        cdef FpTElement res
     705        try:
     706            zmod_poly_init(denom, self.p)
     707            zmod_poly_init(numer, self.p)
     708            if not zmod_poly_sqrt0(numer, self._numer):
     709                return None
     710            if not zmod_poly_sqrt0(denom, self._denom):
     711                return None
     712            res = self._new_c()
     713            zmod_poly_swap(numer, res._numer)
     714            zmod_poly_swap(denom, res._denom)
     715            return res
     716        finally:
     717            zmod_poly_clear(numer)
     718            zmod_poly_clear(denom)
     719   
     720    cpdef bint is_square(self):
     721        """
     722        Returns True if this element is the square of another element of the fraction field.
     723
     724        EXAMPLES::
     725
     726            sage: K = GF(13)['t'].fraction_field(); t = K.gen()
     727            sage: t.is_square()
     728            False
     729            sage: (1/t^2).is_square()
     730            True
     731            sage: K(0).is_square()
     732            True
     733        """
     734        return self._sqrt_or_None() is not None
     735   
     736    def sqrt(self, extend=True, all=False):
     737        """
     738        Returns the square root of this element.
     739
     740        INPUT:
     741
     742        -  ``extend`` - bool (default: True); if True, return a
     743           square root in an extension ring, if necessary. Otherwise, raise a
     744           ValueError if the square is not in the base ring.
     745       
     746        -  ``all`` - bool (default: False); if True, return all
     747           square roots of self, instead of just one.
     748
     749        EXAMPLES::
     750       
     751            sage: from sage.rings.fraction_field_FpT import *
     752            sage: K = GF(7)['t'].fraction_field(); t = K.gen(0)
     753            sage: ((t + 2)^2/(3*t^3 + 1)^4).sqrt()
     754            (3*t + 6)/(t^6 + 3*t^3 + 4)
     755        """
     756        s = self._sqrt_or_None()
     757        if s is None:
     758            if extend:
     759                raise NotImplementedError, "function fields not yet implemented"
     760            else:
     761                raise ValueError, "not a perfect square"
     762        else:
     763            if all:
     764                if not s:
     765                    return [s]
     766                else:
     767                    return [s, -s]
     768            else:
     769                return s
     770   
     771    def __pow__(FpTElement self, Py_ssize_t e, dummy):
     772        """
     773        Returns the ``e``th power of this element.
     774
     775        EXAMPLES::
     776       
     777            sage: from sage.rings.fraction_field_FpT import *
     778            sage: R.<t> = FpT(GF(7)['t'])
     779            sage: t^5
     780            t^5
     781            sage: t^-5
     782            1/t^5
     783           
     784            sage: a = (t+1)/(t-1); a
     785            (t + 1)/(t + 6)
     786            sage: a^5
     787            (t^5 + 5*t^4 + 3*t^3 + 3*t^2 + 5*t + 1)/(t^5 + 2*t^4 + 3*t^3 + 4*t^2 + 5*t + 6)
     788            sage: a^7
     789            (t^7 + 1)/(t^7 + 6)
     790            sage: a^14
     791            (t^14 + 2*t^7 + 1)/(t^14 + 5*t^7 + 1)
     792           
     793            sage: (a^2)^2 == a^4
     794            True
     795            sage: a^3 * a^2 == a^5
     796            True
     797            sage: a^47 * a^92 == a^(47+92)
     798            True
     799        """
     800        cdef long a
     801        assert dummy is None
     802        cdef FpTElement x = self._new_c()
     803        if e >= 0:
     804            zmod_poly_pow(x._numer, self._numer, e)
     805            zmod_poly_pow(x._denom, self._denom, e)
     806        else:
     807            zmod_poly_pow(x._denom, self._numer, -e)
     808            zmod_poly_pow(x._numer, self._denom, -e)
     809            if zmod_poly_leading(x._denom) != 1:
     810                a = mod_inverse_int(zmod_poly_leading(x._denom), self.p)
     811                zmod_poly_scalar_mul(x._numer, x._numer, a)
     812                zmod_poly_scalar_mul(x._denom, x._denom, a)
     813        return x
     814
     815       
     816cdef class FpT_iter:
     817    """
     818    Returns a class that iterates over all elements of an FpT.
     819
     820    EXAMPLES::
     821
     822        sage: K = GF(3)['t'].fraction_field()
     823        sage: I = K.iter(1)
     824        sage: list(I)
     825        [0,
     826         1,
     827         2,
     828         t,
     829         t + 1,
     830         t + 2,
     831         2*t,
     832         2*t + 1,
     833         2*t + 2,
     834         1/t,
     835         2/t,
     836         (t + 1)/t,
     837         (t + 2)/t,
     838         (2*t + 1)/t,
     839         (2*t + 2)/t,
     840         1/(t + 1),
     841         2/(t + 1),
     842         t/(t + 1),
     843         (t + 2)/(t + 1),
     844         2*t/(t + 1),
     845         (2*t + 1)/(t + 1),
     846         1/(t + 2),
     847         2/(t + 2),
     848         t/(t + 2),
     849         (t + 1)/(t + 2),
     850         2*t/(t + 2),
     851         (2*t + 2)/(t + 2)]
     852    """
     853    def __init__(self, parent, degree=None, FpTElement start=None):
     854        """
     855        INPUTS:
     856       
     857        - parent -- The FpT that we're iterating over.
     858
     859        - degree -- The maximum degree of the numerator and denominator of the elements over which we iterate.
     860       
     861        - start -- (default 0) The element on which to start.
     862
     863        EXAMPLES::
     864
     865            sage: K = GF(11)['t'].fraction_field()
     866            sage: I = K.iter(2) # indirect doctest
     867            sage: for a in I:
     868            ...       if a.denom()[0] == 3 and a.numer()[1] == 2:
     869            ...           print a; break
     870            2*t/(t + 3)
     871        """
     872        #if degree is None:
     873        #    raise NotImplementedError
     874        self.parent = parent
     875        self.cur = start
     876        self.degree = -2 if degree is None else degree
     877   
     878    def __cinit__(self, parent, *args, **kwds):
     879        """
     880        Memory allocation for the temp variable storing the gcd of the numerator and denominator.
     881
     882        TESTS::
     883
     884            sage: from sage.rings.fraction_field_FpT import FpT_iter
     885            sage: K = GF(7)['t'].fraction_field()
     886            sage: I = FpT_iter(K, 3) # indirect doctest
     887            sage: I
     888            <sage.rings.fraction_field_FpT.FpT_iter object at ...>
     889        """
     890        zmod_poly_init(self.g, parent.characteristic())
     891   
     892    def __dealloc__(self):
     893        """
     894        Deallocating of the self.g
     895
     896        TESTS::
     897
     898            sage: from sage.rings.fraction_field_FpT import FpT_iter
     899            sage: K = GF(7)['t'].fraction_field()
     900            sage: I = FpT_iter(K, 3)
     901            sage: del I # indirect doctest
     902        """
     903        zmod_poly_clear(self.g)
     904   
     905    def __iter__(self):
     906        """
     907        Returns this iterator.
     908
     909        TESTS::
     910
     911            sage: from sage.rings.fraction_field_FpT import FpT_iter
     912            sage: K = GF(3)['t'].fraction_field()
     913            sage: I = FpT_iter(K, 3)
     914            sage: for a in I: # indirect doctest
     915            ...       if a.numer()[1] == 1 and a.denom()[1] == 2 and a.is_square():
     916            ...            print a; break
     917            (t^2 + t + 1)/(t^2 + 2*t + 1)
     918        """
     919        return self
     920   
     921    def __next__(self):
     922        """
     923        Returns the next element to iterate over.
     924
     925        This is achieved by iterating over monic denominators, and for each denominator,
     926        iterating over all numerators relatively prime to the given denominator.
     927
     928        EXAMPLES::
     929       
     930            sage: from sage.rings.fraction_field_FpT import *
     931            sage: K.<t> = FpT(GF(3)['t'])
     932            sage: list(K.iter(1)) # indirect doctest
     933            [0,
     934             1,
     935             2,
     936             t,
     937             t + 1,
     938             t + 2,
     939             2*t,
     940             2*t + 1,
     941             2*t + 2,
     942             1/t,
     943             2/t,
     944             (t + 1)/t,
     945             (t + 2)/t,
     946             (2*t + 1)/t,
     947             (2*t + 2)/t,
     948             1/(t + 1),
     949             2/(t + 1),
     950             t/(t + 1),
     951             (t + 2)/(t + 1),
     952             2*t/(t + 1),
     953             (2*t + 1)/(t + 1),
     954             1/(t + 2),
     955             2/(t + 2),
     956             t/(t + 2),
     957             (t + 1)/(t + 2),
     958             2*t/(t + 2),
     959             (2*t + 2)/(t + 2)]
     960             
     961            sage: len(list(K.iter(3)))
     962            2187
     963
     964            sage: K.<t> = FpT(GF(5)['t'])
     965            sage: L = list(K.iter(3)); len(L)
     966            78125
     967            sage: L[:10]
     968            [0, 1, 2, 3, 4, t, t + 1, t + 2, t + 3, t + 4]
     969            sage: L[2000]
     970            (3*t^3 + 3*t^2 + 3*t + 4)/(t + 2)
     971            sage: L[-1]
     972            (4*t^3 + 4*t^2 + 4*t + 4)/(t^3 + 4*t^2 + 4*t + 4)
     973        """
     974        cdef FpTElement next
     975        if self.cur is None:
     976            self.cur = self.parent(0)
     977        elif self.degree == -2:
     978            self.cur = self.cur.next()
     979        else:
     980            next = self.cur._copy_c()
     981            _sig_on
     982            while True:
     983                zmod_poly_inc(next._numer, False)
     984                if zmod_poly_degree(next._numer) > self.degree:
     985                    zmod_poly_inc(next._denom, True)
     986                    if zmod_poly_degree(next._denom) > self.degree:
     987                        raise StopIteration
     988                    zmod_poly_zero(next._numer)
     989                    zmod_poly_set_coeff_ui(next._numer, 0, 1)
     990                zmod_poly_gcd(self.g, next._numer, next._denom)
     991                if zmod_poly_is_one(self.g):
     992                    break
     993            _sig_off
     994            self.cur = next
     995#            self.cur = self.cur.next()
     996#            if zmod_poly_degree(self.cur._numer) > self.degree:
     997#                raise StopIteration
     998        return self.cur
     999
     1000cdef class Polyring_FpT_coerce(RingHomomorphism_coercion):
     1001    cdef long p
     1002    """
     1003    This class represents the coercion map from GF(p)[t] to GF(p)(t)
     1004
     1005    EXAMPLES::
     1006
     1007        sage: R.<t> = GF(5)[]
     1008        sage: K = R.fraction_field()
     1009        sage: f = K.coerce_map_from(R); f
     1010        Ring Coercion morphism:
     1011          From: Univariate Polynomial Ring in t over Finite Field of size 5
     1012          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1013        sage: type(f)
     1014        <type 'sage.rings.fraction_field_FpT.Polyring_FpT_coerce'>
     1015    """
     1016    def __init__(self, R):
     1017        """
     1018        INPUTS:
     1019       
     1020        - R -- An FpT
     1021
     1022        EXAMPLES::
     1023
     1024            sage: R.<t> = GF(next_prime(2000))[]
     1025            sage: K = R.fraction_field() # indirect doctest
     1026        """
     1027        RingHomomorphism_coercion.__init__(self, R.ring_of_integers().Hom(R), check=False)
     1028        self.p = R.base_ring().characteristic()
     1029       
     1030    cpdef Element _call_(self, _x):
     1031        """
     1032        Applies the coercion.
     1033
     1034        EXAMPLES::
     1035
     1036            sage: R.<t> = GF(5)[]
     1037            sage: K = R.fraction_field()
     1038            sage: f = K.coerce_map_from(R)
     1039            sage: f(t^2 + 1) # indirect doctest
     1040            t^2 + 1
     1041        """
     1042        cdef Polynomial_zmod_flint x = <Polynomial_zmod_flint?> _x
     1043        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1044        ans._parent = self._codomain
     1045        ans.p = self.p
     1046        zmod_poly_init(ans._numer, ans.p)
     1047        zmod_poly_init(ans._denom, ans.p)
     1048        zmod_poly_set(ans._numer, &x.x)
     1049        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1050        ans.initalized = True
     1051        return ans
     1052
     1053    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     1054        """
     1055        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     1056
     1057        If ``reduce`` is specified as False, then the result won't be normalized.
     1058
     1059        EXAMPLES::
     1060
     1061            sage: R.<t> = GF(5)[]
     1062            sage: K = R.fraction_field()
     1063            sage: f = K.coerce_map_from(R)
     1064            sage: f(2*t + 2, t + 3) # indirect doctest
     1065            (2*t + 2)/(t + 3)
     1066            sage: f(2*t + 2, 2)
     1067            t + 1
     1068            sage: f(2*t + 2, 2, reduce=False)
     1069            (2*t + 2)/2
     1070        """
     1071        cdef Polynomial_zmod_flint x = <Polynomial_zmod_flint?> _x
     1072        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1073        ans._parent = self._codomain
     1074        ans.p = self.p
     1075        zmod_poly_init(ans._numer, ans.p)
     1076        zmod_poly_init(ans._denom, ans.p)
     1077        cdef long r
     1078        zmod_poly_set(ans._numer, &x.x)
     1079        if len(args) == 0:
     1080            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1081        elif len(args) == 1:
     1082            y = args[0]
     1083            if PY_TYPE_CHECK(y, Integer):
     1084                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1085                if r == 0:
     1086                    raise ZeroDivisionError
     1087                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1088            else:
     1089                # could use the coerce keyword being set to False to not check this...
     1090                if not (PY_TYPE_CHECK(y, Element) and y.parent() is self._domain):
     1091                    # We could special case integers and GF(p) elements here.
     1092                    y = self._domain(y)
     1093                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1094        else:
     1095            raise ValueError, "FpT only supports two positional arguments"
     1096        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1097            normalize(ans._numer, ans._denom, ans.p)
     1098        ans.initalized = True
     1099        return ans
     1100
     1101    def section(self):
     1102        """
     1103        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1104        back to ``GF(p)[t]``, defined on elements with unit denominator.
     1105
     1106        EXAMPLES::
     1107
     1108            sage: R.<t> = GF(5)[]
     1109            sage: K = R.fraction_field()
     1110            sage: f = K.coerce_map_from(R)
     1111            sage: g = f.section(); g
     1112            Section map:
     1113              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1114              To:   Univariate Polynomial Ring in t over Finite Field of size 5
     1115            sage: t = K.gen()
     1116            sage: g(t)
     1117            t
     1118            sage: g(1/t)
     1119            Traceback (most recent call last):
     1120            ...
     1121            ValueError: not integral
     1122        """
     1123        return FpT_Polyring_section(self)
     1124
     1125cdef class FpT_Polyring_section(Section):
     1126    cdef long p
     1127    """
     1128    This class represents the section from GF(p)(t) back to GF(p)[t]
     1129
     1130    EXAMPLES::
     1131
     1132        sage: R.<t> = GF(5)[]
     1133        sage: K = R.fraction_field()
     1134        sage: f = R.convert_map_from(K); f
     1135        Section map:
     1136          From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1137          To:   Univariate Polynomial Ring in t over Finite Field of size 5
     1138        sage: type(f)
     1139        <type 'sage.rings.fraction_field_FpT.FpT_Polyring_section'>
     1140    """
     1141    def __init__(self, Polyring_FpT_coerce f):
     1142        """
     1143        INPUTS:
     1144       
     1145        - f -- A Polyring_FpT_coerce homomorphism
     1146
     1147        EXAMPLES::
     1148
     1149            sage: R.<t> = GF(next_prime(2000))[]
     1150            sage: K = R.fraction_field()
     1151            sage: R(K.gen(0)) # indirect doctest
     1152            t
     1153        """
     1154        self.p = f.p
     1155        Section.__init__(self, f)
     1156   
     1157    cpdef Element _call_(self, _x):
     1158        """
     1159        Applies the section.
     1160
     1161        EXAMPLES::
     1162
     1163            sage: R.<t> = GF(7)[]
     1164            sage: K = R.fraction_field()
     1165            sage: f = K.coerce_map_from(R)
     1166            sage: g = f.section(); g
     1167            Section map:
     1168              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1169              To:   Univariate Polynomial Ring in t over Finite Field of size 7
     1170            sage: t = K.gen()
     1171            sage: g(t^2) # indirect doctest
     1172            t^2
     1173            sage: g(1/t)
     1174            Traceback (most recent call last):
     1175            ...
     1176            ValueError: not integral
     1177        """
     1178        cdef FpTElement x = <FpTElement?>_x
     1179        cdef Polynomial_zmod_flint ans
     1180        if zmod_poly_degree(x._denom) != 0:
     1181            normalize(x._numer, x._denom, self.p)
     1182            if zmod_poly_degree(x._denom) != 0:
     1183                raise ValueError, "not integral"
     1184        ans = PY_NEW(Polynomial_zmod_flint)
     1185        if zmod_poly_get_coeff_ui(x._denom, 0) != 1:
     1186            normalize(x._numer, x._denom, self.p)
     1187        zmod_poly_init(&ans.x, self.p)
     1188        zmod_poly_set(&ans.x, x._numer)
     1189        ans._parent = self._codomain
     1190        return ans
     1191
     1192cdef class Fp_FpT_coerce(RingHomomorphism_coercion):
     1193    cdef long p
     1194    """
     1195    This class represents the coercion map from GF(p) to GF(p)(t)
     1196
     1197    EXAMPLES::
     1198
     1199        sage: R.<t> = GF(5)[]
     1200        sage: K = R.fraction_field()
     1201        sage: f = K.coerce_map_from(GF(5)); f
     1202        Ring Coercion morphism:
     1203          From: Finite Field of size 5
     1204          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1205        sage: type(f)
     1206        <type 'sage.rings.fraction_field_FpT.Fp_FpT_coerce'>
     1207    """
     1208    def __init__(self, R):
     1209        """
     1210        INPUTS:
     1211       
     1212        - R -- An FpT
     1213
     1214        EXAMPLES::
     1215
     1216            sage: R.<t> = GF(next_prime(3000))[]
     1217            sage: K = R.fraction_field() # indirect doctest
     1218        """
     1219        RingHomomorphism_coercion.__init__(self, R.base_ring().Hom(R), check=False)
     1220        self.p = R.base_ring().characteristic()
     1221       
     1222    cpdef Element _call_(self, _x):
     1223        """
     1224        Applies the coercion.
     1225
     1226        EXAMPLES::
     1227
     1228            sage: R.<t> = GF(5)[]
     1229            sage: K = R.fraction_field()
     1230            sage: f = K.coerce_map_from(GF(5))
     1231            sage: f(GF(5)(3)) # indirect doctest
     1232            3
     1233        """
     1234        cdef IntegerMod_int x = <IntegerMod_int?> _x
     1235        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1236        ans._parent = self._codomain
     1237        ans.p = self.p
     1238        zmod_poly_init(ans._numer, ans.p)
     1239        zmod_poly_init(ans._denom, ans.p)
     1240        zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)
     1241        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1242        ans.initalized = True
     1243        return ans
     1244
     1245    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     1246        """
     1247        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     1248
     1249        If ``reduce`` is specified as False, then the result won't be normalized.
     1250
     1251        EXAMPLES::
     1252
     1253            sage: R.<t> = GF(5)[]
     1254            sage: K = R.fraction_field()
     1255            sage: f = K.coerce_map_from(GF(5))
     1256            sage: f(1, t + 3) # indirect doctest
     1257            1/(t + 3)
     1258            sage: f(2, 2*t)
     1259            1/t
     1260            sage: f(2, 2*t, reduce=False)
     1261            2/2*t
     1262        """
     1263        cdef IntegerMod_int x = <IntegerMod_int?> _x
     1264        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1265        ans._parent = self._codomain
     1266        ans.p = self.p
     1267        zmod_poly_init(ans._numer, ans.p)
     1268        zmod_poly_init(ans._denom, ans.p)
     1269        cdef long r
     1270        zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)
     1271        if len(args) == 0:
     1272            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1273        if len(args) == 1:
     1274            y = args[0]
     1275            if PY_TYPE_CHECK(y, Integer):
     1276                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1277                if r == 0:
     1278                    raise ZeroDivisionError
     1279                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1280            else:
     1281                R = self._codomain.ring_of_integers()
     1282                # could use the coerce keyword being set to False to not check this...
     1283                if not (PY_TYPE_CHECK(y, Element) and y.parent() is R):
     1284                    # We could special case integers and GF(p) elements here.
     1285                    y = R(y)
     1286                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1287        else:
     1288            raise ValueError, "FpT only supports two positional arguments"
     1289        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1290            normalize(ans._numer, ans._denom, ans.p)
     1291        ans.initalized = True
     1292        return ans
     1293
     1294    def section(self):
     1295        """
     1296        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1297        back to ``GF(p)``, defined on constant elements.
     1298
     1299        EXAMPLES::
     1300
     1301            sage: R.<t> = GF(5)[]
     1302            sage: K = R.fraction_field()
     1303            sage: f = K.coerce_map_from(GF(5))
     1304            sage: g = f.section(); g
     1305            Section map:
     1306              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1307              To:   Finite Field of size 5
     1308            sage: t = K.gen()
     1309            sage: g(f(1,3,reduce=False))
     1310            2
     1311            sage: g(t)
     1312            Traceback (most recent call last):
     1313            ...
     1314            ValueError: not constant           
     1315            sage: g(1/t)
     1316            Traceback (most recent call last):
     1317            ...
     1318            ValueError: not integral
     1319        """
     1320        return FpT_Fp_section(self)
     1321
     1322cdef class FpT_Fp_section(Section):
     1323    cdef long p
     1324    """
     1325    This class represents the section from GF(p)(t) back to GF(p)[t]
     1326
     1327    EXAMPLES::
     1328
     1329        sage: R.<t> = GF(5)[]
     1330        sage: K = R.fraction_field()
     1331        sage: f = GF(5).convert_map_from(K); f
     1332        Section map:
     1333          From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1334          To:   Finite Field of size 5
     1335        sage: type(f)
     1336        <type 'sage.rings.fraction_field_FpT.FpT_Fp_section'>
     1337    """
     1338    def __init__(self, Fp_FpT_coerce f):
     1339        """
     1340        INPUTS:
     1341       
     1342        - f -- An Fp_FpT_coerce homomorphism
     1343
     1344        EXAMPLES::
     1345
     1346            sage: R.<t> = GF(next_prime(2000))[]
     1347            sage: K = R.fraction_field()
     1348            sage: GF(next_prime(2000))(K(127)) # indirect doctest
     1349            127
     1350        """
     1351        self.p = f.p
     1352        Section.__init__(self, f)
     1353   
     1354    cpdef Element _call_(self, _x):
     1355        """
     1356        Applies the section.
     1357
     1358        EXAMPLES::
     1359
     1360            sage: R.<t> = GF(7)[]
     1361            sage: K = R.fraction_field()
     1362            sage: f = K.coerce_map_from(GF(7))
     1363            sage: g = f.section(); g
     1364            Section map:
     1365              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1366              To:   Finite Field of size 7
     1367            sage: t = K.gen()
     1368            sage: g(t^2) # indirect doctest
     1369            Traceback (most recent call last):
     1370            ...
     1371            ValueError: not constant
     1372            sage: g(1/t)
     1373            Traceback (most recent call last):
     1374            ...
     1375            ValueError: not integral
     1376            sage: g(K(4))
     1377            4
     1378            sage: g(K(0))
     1379            0
     1380        """
     1381        cdef FpTElement x = <FpTElement?>_x
     1382        cdef IntegerMod_int ans
     1383        if zmod_poly_degree(x._denom) != 0 or zmod_poly_degree(x._numer) > 0:
     1384            normalize(x._numer, x._denom, self.p)
     1385            if zmod_poly_degree(x._denom) != 0:
     1386                raise ValueError, "not integral"
     1387            if zmod_poly_degree(x._numer) > 0:
     1388                raise ValueError, "not constant"
     1389        ans = PY_NEW(IntegerMod_int)
     1390        ans.__modulus = self._codomain._pyx_order
     1391        if zmod_poly_get_coeff_ui(x._denom, 0) != 1:
     1392            normalize(x._numer, x._denom, self.p)
     1393        ans.ivalue = zmod_poly_get_coeff_ui(x._numer, 0)
     1394        ans._parent = self._codomain
     1395        return ans
     1396
     1397cdef class ZZ_FpT_coerce(RingHomomorphism_coercion):
     1398    cdef long p
     1399    """
     1400    This class represents the coercion map from ZZ to GF(p)(t)
     1401
     1402    EXAMPLES::
     1403
     1404        sage: R.<t> = GF(17)[]
     1405        sage: K = R.fraction_field()
     1406        sage: f = K.coerce_map_from(ZZ); f
     1407        Ring Coercion morphism:
     1408          From: Integer Ring
     1409          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 17
     1410        sage: type(f)
     1411        <type 'sage.rings.fraction_field_FpT.ZZ_FpT_coerce'>
     1412    """
     1413    def __init__(self, R):
     1414        """
     1415        INPUTS:
     1416       
     1417        - R -- An FpT
     1418
     1419        EXAMPLES::
     1420
     1421            sage: R.<t> = GF(next_prime(3000))[]
     1422            sage: K = R.fraction_field() # indirect doctest
     1423        """
     1424        RingHomomorphism_coercion.__init__(self, ZZ.Hom(R), check=False)
     1425        self.p = R.base_ring().characteristic()
     1426       
     1427    cpdef Element _call_(self, _x):
     1428        """
     1429        Applies the coercion.
     1430
     1431        EXAMPLES::
     1432
     1433            sage: R.<t> = GF(5)[]
     1434            sage: K = R.fraction_field()
     1435            sage: f = K.coerce_map_from(ZZ)
     1436            sage: f(3) # indirect doctest
     1437            3
     1438        """
     1439        cdef Integer x = <Integer?> _x
     1440        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1441        ans._parent = self._codomain
     1442        ans.p = self.p
     1443        zmod_poly_init(ans._numer, ans.p)
     1444        zmod_poly_init(ans._denom, ans.p)
     1445        zmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p))
     1446        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1447        ans.initalized = True
     1448        return ans
     1449
     1450    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     1451        """
     1452        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     1453
     1454        If ``reduce`` is specified as False, then the result won't be normalized.
     1455
     1456        EXAMPLES::
     1457
     1458            sage: R.<t> = GF(5)[]
     1459            sage: K = R.fraction_field()
     1460            sage: f = K.coerce_map_from(ZZ)
     1461            sage: f(1, t + 3) # indirect doctest
     1462            1/(t + 3)
     1463            sage: f(1,2)
     1464            3
     1465            sage: f(2, 2*t)
     1466            1/t
     1467            sage: f(2, 2*t, reduce=False)
     1468            2/2*t
     1469        """
     1470        cdef Integer x = <Integer?> _x
     1471        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1472        ans._parent = self._codomain
     1473        ans.p = self.p
     1474        zmod_poly_init(ans._numer, ans.p)
     1475        zmod_poly_init(ans._denom, ans.p)
     1476        cdef long r
     1477        zmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p))
     1478        if len(args) == 0:
     1479            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1480        if len(args) == 1:
     1481            y = args[0]
     1482            if PY_TYPE_CHECK(y, Integer):
     1483                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1484                if r == 0:
     1485                    raise ZeroDivisionError
     1486                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1487            else:
     1488                R = self._codomain.ring_of_integers()
     1489                # could use the coerce keyword being set to False to not check this...
     1490                if not (PY_TYPE_CHECK(y, Element) and y.parent() is R):
     1491                    # We could special case integers and GF(p) elements here.
     1492                    y = R(y)
     1493                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1494        else:
     1495            raise ValueError, "FpT only supports two positional arguments"
     1496        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1497            normalize(ans._numer, ans._denom, ans.p)
     1498        ans.initalized = True
     1499        return ans
     1500
     1501    def section(self):
     1502        """
     1503        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1504        back to ``ZZ``, defined on constant elements.
     1505
     1506        EXAMPLES::
     1507
     1508            sage: R.<t> = GF(5)[]
     1509            sage: K = R.fraction_field()
     1510            sage: f = K.coerce_map_from(ZZ)
     1511            sage: g = f.section(); g
     1512            Composite map:
     1513              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1514              To:   Integer Ring
     1515              Defn:   Section map:
     1516                      From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1517                      To:   Finite Field of size 5
     1518                    then
     1519                      Conversion via _integer_ method map:
     1520                      From: Finite Field of size 5
     1521                      To:   Integer Ring
     1522            sage: t = K.gen()
     1523            sage: g(f(1,3,reduce=False))
     1524            2
     1525            sage: g(t)
     1526            Traceback (most recent call last):
     1527            ...
     1528            ValueError: not constant           
     1529            sage: g(1/t)
     1530            Traceback (most recent call last):
     1531            ...
     1532            ValueError: not integral
     1533        """
     1534        return ZZ.convert_map_from(self._codomain.base_ring()) * Fp_FpT_coerce(self._codomain).section()
     1535
     1536cdef inline bint normalize(zmod_poly_t numer, zmod_poly_t denom, long p):
     1537    """
     1538    Puts numer/denom into a normal form: denominator monic and sharing no common factor with the numerator.
     1539
     1540    The normalized form of 0 is 0/1.
     1541
     1542    Returns True if numer and denom were changed.
     1543    """
     1544    cdef long a
     1545    cdef bint changed
     1546    if zmod_poly_degree(numer) == -1:
     1547        if zmod_poly_degree(denom) > 0 or zmod_poly_leading(denom) != 1:
     1548            changed = True
     1549        else:
     1550            changed = False
     1551        zmod_poly_truncate(denom, 0)
     1552        zmod_poly_set_coeff_ui(denom, 0, 1)
     1553        return changed
     1554    elif zmod_poly_degree(numer) == 0 or zmod_poly_degree(denom) == 0:
     1555        if zmod_poly_leading(denom) != 1:
     1556            a = mod_inverse_int(zmod_poly_leading(denom), p)
     1557            zmod_poly_scalar_mul(numer, numer, a)
     1558            zmod_poly_scalar_mul(denom, denom, a)
     1559            return True
     1560        return False
     1561    cdef zmod_poly_t g
     1562    changed = False
     1563    try:
     1564        zmod_poly_init_precomp(g, p, numer.p_inv)
     1565        zmod_poly_gcd(g, numer, denom)
     1566        if zmod_poly_degree(g) != 0:
     1567            # Divide knowing divisible by? Can we get these quotients as a byproduct of the gcd?
     1568            zmod_poly_div(numer, numer, g)
     1569            zmod_poly_div(denom, denom, g)
     1570            changed = True
     1571        if zmod_poly_leading(denom) != 1:
     1572            a = mod_inverse_int(zmod_poly_leading(denom), p)
     1573            zmod_poly_scalar_mul(numer, numer, a)
     1574            zmod_poly_scalar_mul(denom, denom, a)
     1575            changed = True
     1576        return changed
     1577    finally:
     1578        zmod_poly_clear(g)
     1579
     1580cdef inline unsigned long zmod_poly_leading(zmod_poly_t poly):
     1581    """
     1582    Returns the leading coefficient of ``poly``.
     1583    """
     1584    return zmod_poly_get_coeff_ui(poly, zmod_poly_degree(poly))
     1585
     1586cdef inline void zmod_poly_inc(zmod_poly_t poly, bint monic):
     1587    """
     1588    Sets poly to the "next" polynomial: this is just counting in base p.
     1589
     1590    If monic is True then will only iterate through monic polynomials.
     1591    """
     1592    cdef long n
     1593    cdef long a
     1594    cdef long p = poly.p
     1595    for n from 0 <= n <= zmod_poly_degree(poly) + 1:
     1596        a = zmod_poly_get_coeff_ui(poly, n) + 1
     1597        if a == p:
     1598            zmod_poly_set_coeff_ui(poly, n, 0)
     1599        else:
     1600            zmod_poly_set_coeff_ui(poly, n, a)
     1601            break
     1602    if monic and a == 2 and n == zmod_poly_degree(poly):
     1603        zmod_poly_set_coeff_ui(poly, n, 0)
     1604        zmod_poly_set_coeff_ui(poly, n+1, 1)
     1605
     1606cdef inline long zmod_poly_cmp(zmod_poly_t a, zmod_poly_t b):
     1607    """
     1608    Compares `a` and `b`, returning 0 if they are equal.
     1609
     1610    - If the degree of `a` is less than that of `b`, returns -1.
     1611
     1612    - If the degree of `b` is less than that of `a`, returns 1.
     1613
     1614    - Otherwise, compares `a` and `b` lexicographically, starting at the leading terms.
     1615    """
     1616    cdef long ad = zmod_poly_degree(a)
     1617    cdef long bd = zmod_poly_degree(b)
     1618    if ad < bd:
     1619        return -1
     1620    elif ad > bd:
     1621        return 1
     1622    cdef long d = zmod_poly_degree(a)
     1623    while d >= 0:
     1624        ad = zmod_poly_get_coeff_ui(a, d)
     1625        bd = zmod_poly_get_coeff_ui(b, d)
     1626        if ad < bd:
     1627            return -1
     1628        elif ad > bd:
     1629            return 1
     1630        d -= 1
     1631    return 0
     1632
     1633cdef void zmod_poly_pow(zmod_poly_t res, zmod_poly_t poly, unsigned long e):
     1634    """
     1635    Raises poly to the `e`th power and stores the result in ``res``.
     1636    """
     1637    if zmod_poly_degree(poly) < 2:
     1638        if zmod_poly_degree(poly) == -1:
     1639            zmod_poly_zero(res)
     1640            return
     1641        elif zmod_poly_is_one(poly):
     1642            zmod_poly_set(res, poly)
     1643            return
     1644        elif e > 1 and zmod_poly_degree(poly) == 1 and zmod_poly_get_coeff_ui(poly, 0) == 0 and zmod_poly_get_coeff_ui(poly, 1) == 1:
     1645            zmod_poly_left_shift(res, poly, e-1)
     1646            return
     1647   
     1648    # TODO: Could use the fact that (a+b)^p = a^p + b^p
     1649    # Only seems to be a big gain for large p, large exponents...
     1650    cdef zmod_poly_t pow2
     1651   
     1652    if e < 5:
     1653        if e == 0:
     1654            zmod_poly_zero(res)
     1655            zmod_poly_set_coeff_ui(res, 0, 1)
     1656        elif e == 1:
     1657            zmod_poly_set(res, poly)
     1658        elif e == 2:
     1659            zmod_poly_sqr(res, poly)
     1660        elif e == 3:
     1661            zmod_poly_sqr(res, poly)
     1662            zmod_poly_mul(res, res, poly)
     1663        elif e == 4:
     1664            zmod_poly_sqr(res, poly)
     1665            zmod_poly_sqr(res, res)
     1666    else:
     1667        zmod_poly_init(pow2, poly.p)
     1668        zmod_poly_zero(res)
     1669        zmod_poly_set_coeff_ui(res, 0, 1)
     1670        zmod_poly_set(pow2, poly)
     1671        while True:
     1672            if e & 1:
     1673                zmod_poly_mul(res, res, pow2)
     1674            e >>= 1
     1675            if e == 0:
     1676                break
     1677            zmod_poly_sqr(pow2, pow2)
     1678        zmod_poly_clear(pow2)
     1679
     1680
     1681cdef long sqrt_mod_int(long a, long p) except -1:
     1682    """
     1683    Returns the square root of a modulo p, as a long.
     1684    """
     1685    return GF(p)(a).sqrt()
     1686
     1687cdef bint zmod_poly_sqrt_check(zmod_poly_t poly):
     1688    """
     1689    Quick check to see if poly could possibly be a square.
     1690    """
     1691    return (zmod_poly_degree(poly) % 2 == 0
     1692        and jacobi_int(zmod_poly_leading(poly), poly.p) == 1
     1693        and jacobi_int(zmod_poly_get_coeff_ui(poly, 0), poly.p) != -1)
     1694 
     1695cdef bint zmod_poly_sqrt(zmod_poly_t res, zmod_poly_t poly):
     1696    """
     1697    Compute the square root of poly as res if res is a perfect square.
     1698   
     1699    Returns True on success, False on failure.
     1700    """
     1701    if not zmod_poly_sqrt_check(poly):
     1702        return False
     1703    return zmod_poly_sqrt0(res, poly)
     1704
     1705cdef bint zmod_poly_sqrt0(zmod_poly_t res, zmod_poly_t poly):
     1706    """
     1707    Compute the square root of poly as res if res is a perfect square, assuming that poly passes zmod_poly_sqrt_check.
     1708   
     1709    Returns True on success, False on failure.
     1710    """
     1711    if zmod_poly_degree(poly) == -1:
     1712        zmod_poly_zero(res)
     1713        return True
     1714    if zmod_poly_degree(poly) == 0:
     1715        zmod_poly_zero(res)
     1716        zmod_poly_set_coeff_ui(res, 0, sqrt_mod_int(zmod_poly_get_coeff_ui(poly, 0), poly.p))
     1717        return True
     1718    cdef zmod_poly_t g
     1719    cdef long p = poly.p
     1720    cdef long n, leading
     1721    cdef zmod_poly_factor_t factors
     1722    try:
     1723        zmod_poly_init(g, p)
     1724        zmod_poly_derivative(res, poly)
     1725        zmod_poly_gcd(g, res, poly)
     1726        if 2*zmod_poly_degree(g) < zmod_poly_degree(poly):
     1727            return False
     1728           
     1729        elif 2*zmod_poly_degree(g) > zmod_poly_degree(poly):
     1730            try:
     1731                zmod_poly_factor_init(factors)
     1732                leading = zmod_poly_leading(poly)
     1733                if leading == 1:
     1734                    zmod_poly_factor_square_free(factors, poly)
     1735                else:
     1736                    zmod_poly_scalar_mul(res, poly, mod_inverse_int(leading, p))
     1737                    zmod_poly_factor_square_free(factors, res)
     1738                for n in range(factors.num_factors):
     1739                    if factors.exponents[n] % 2 != 0:
     1740                        return False
     1741                zmod_poly_pow(res, factors.factors[0], factors.exponents[0]//2)
     1742                for n in range(1, factors.num_factors):
     1743                    zmod_poly_pow(factors.factors[n], factors.factors[n], factors.exponents[n]//2)
     1744                    zmod_poly_mul(res, res, factors.factors[n])
     1745                if leading != 1:
     1746                    zmod_poly_scalar_mul(res, res, sqrt_mod_int(zmod_poly_leading(poly), p))
     1747                return True
     1748            finally:
     1749                zmod_poly_factor_clear(factors)
     1750           
     1751        else: # deg(g) == deg(poly)/2
     1752            zmod_poly_sqr(res, g)
     1753            leading = zmod_poly_leading(poly) * mod_inverse_int(zmod_poly_leading(res), p)
     1754            zmod_poly_scalar_mul(res, res, leading)
     1755            if zmod_poly_equal(res, poly):
     1756                zmod_poly_scalar_mul(res, g, sqrt_mod_int(leading, p))
     1757                return True
     1758            else:
     1759                return False
     1760    finally:
     1761        zmod_poly_clear(g)
     1762
     1763def unpickle_FpT_element(K, numer, denom):
     1764    """
     1765    Used for pickling.
     1766   
     1767    TESTS::
     1768       
     1769        sage: from sage.rings.fraction_field_FpT import unpickle_FpT_element
     1770        sage: R.<t> = GF(13)['t']
     1771        sage: unpickle_FpT_element(Frac(R), t+1, t)
     1772        (t + 1)/t
     1773    """
     1774    return FpTElement(K, numer, denom, coerce=False, reduce=False)
  • sage/rings/fraction_field_element.pyx

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/fraction_field_element.pyx
    a b  
    3838
    3939from sage.structure.element cimport FieldElement, ModuleElement, RingElement, \
    4040        Element
     41from sage.structure.element import parent
    4142
    4243import integer_ring
    4344from integer_ring import ZZ
     
    10451046                (<FractionFieldElement>other).__denominator,
    10461047                self.__denominator*(<FractionFieldElement>other).__numerator)
    10471048
    1048     def valuation(self):
     1049    def valuation(self, v=None):
    10491050        """
    10501051        Return the valuation of self, assuming that the numerator and
    10511052        denominator have valuation functions defined on them.
     
    10531054        EXAMPLES::
    10541055       
    10551056            sage: x = PolynomialRing(RationalField(),'x').gen()
    1056             sage: f = (x**3 + x)/(x**2 - 2*x**3)
     1057            sage: f = (x^3 + x)/(x^2 - 2*x^3)
    10571058            sage: f
    10581059            (x^2 + 1)/(-2*x^2 + x)
    10591060            sage: f.valuation()
    10601061            -1
     1062            sage: f.valuation(x^2+1)
     1063            1
    10611064        """
    1062         return self.__numerator.valuation() - self.__denominator.valuation()
     1065        return self.__numerator.valuation(v) - self.__denominator.valuation(v)
    10631066
    10641067    def __nonzero__(self):
    10651068        """
     
    11291132        return (make_element,
    11301133                (self._parent, self.__numerator, self.__denominator))
    11311134
     1135
     1136class FractionFieldElement_1poly_field(FractionFieldElement):
     1137    """
     1138    A fraction field element where the parent is the fraction field of a univariate polynomial ring.
     1139
     1140    Many of the functions here are included for coherence with number fields.   
     1141    """
     1142    def is_integral(self):
     1143        """
     1144        Returns whether this element is actually a polynomial.
     1145
     1146        EXAMPLES::
     1147
     1148            sage: R.<t> = GF(5)[]
     1149            sage: K = R.fraction_field
     1150        """
     1151        if self.__denominator != 1:
     1152            self.reduce()
     1153        return self.__denominator == 1
     1154
     1155    def support(self):
     1156        """
     1157        Returns a sorted list of primes dividing either the numerator or denominator of this element.
     1158
     1159        EXAMPLES::
     1160
     1161            sage: R.<t> = QQ[]
     1162            sage: h = (t^14 + 2*t^12 - 4*t^11 - 8*t^9 + 6*t^8 + 12*t^6 - 4*t^5 - 8*t^3 + t^2 + 2)/(t^6 + 6*t^5 + 9*t^4 - 2*t^2 - 12*t - 18)
     1163            sage: h.support()
     1164            [t - 1, t + 3, t^2 + 2, t^2 + t + 1, t^4 - 2]
     1165        """
     1166        L = [fac[0] for fac in self.numerator().factor()] + [fac[0] for fac in self.denominator().factor()]
     1167        L.sort()
     1168        return L
     1169
     1170
     1171
    11321172def make_element(parent, numerator, denominator):
    11331173    """
    11341174    Used for unpickling FractionFieldElement objects (and subclasses).
  • sage/rings/polynomial/polynomial_element.pyx

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/polynomial/polynomial_element.pyx
    a b  
    2626#                  http://www.gnu.org/licenses/
    2727################################################################################
    2828
     29cdef is_FractionField, is_RealField, is_ComplexField
     30cdef coerce_binop, generic_power, parent
     31cdef ZZ, QQ, RR, CC, RDF, CDF
     32
    2933import operator, copy, re
    3034
    3135import sage.rings.rational
     
    4953from sage.interfaces.all import singular as singular_default, is_SingularElement
    5054from sage.libs.all import pari, pari_gen, PariError
    5155
    52 from sage.rings.real_mpfr import RealField, is_RealNumber, is_RealField, RR
     56from sage.rings.real_mpfr import RealField, is_RealField, RR
    5357
    5458from sage.rings.complex_field import is_ComplexField, ComplexField
    5559CC = ComplexField()
     
    5862from sage.rings.complex_double import is_ComplexDoubleField, CDF
    5963from sage.rings.real_mpfi import is_RealIntervalField
    6064
    61 from sage.structure.element import RingElement, generic_power
     65from sage.structure.element import RingElement, generic_power, parent
    6266from sage.structure.element cimport Element, RingElement, ModuleElement, MonoidElement
    6367
    6468from sage.rings.rational_field import QQ, is_RationalField
    6569from sage.rings.integer_ring import ZZ, is_IntegerRing
     70from sage.rings.fraction_field import is_FractionField
    6671
    6772from sage.rings.integral_domain import is_IntegralDomain
    6873from sage.structure.parent_gens cimport ParentWithGens
     
    461466            sage: f(2, 1/2)
    462467            15/8
    463468       
     469        Some special cases are optimized.
     470       
     471        ::
     472       
     473            sage: R.<x> = QQ[]
     474            sage: f = x^3-2*x
     475            sage: f(x) is f
     476            True
     477            sage: f(1/x)
     478            (-2*x^2 + 1)/x^3
     479           
     480            sage: f = x^100 + 3
     481            sage: f(0)
     482            3
     483            sage: parent(f(0))
     484            Rational Field
     485            sage: parent(f(Qp(5)(0)))
     486            5-adic Field with capped relative precision 20
     487       
    464488        TESTS:
    465489
    466490        The following shows that \#2360 is indeed fixed.
     
    565589            except AttributeError:
    566590                return result
    567591
     592        if a == self._parent.gen():
     593            return self
     594        elif is_FractionField(parent(a)):
     595            try:
     596                a_inverse = ~a
     597                if a_inverse.denominator() == 1:
     598                    a_inverse = a_inverse.numerator()
     599                    return self.reverse()(a_inverse) / a_inverse**self.degree()
     600            except AttributeError:
     601                pass
     602
    568603        i = d - 1
    569604        if len(x) > 1:
    570605            while i >= 0:
    571606                result = result * a + self[i](other_args)
    572607                i -= 1
     608        elif not a:
     609            c = self[0]
     610            return c + c*a
    573611        elif (d < 4 or d > 50000) and self._compiled is None:
    574612            while i >= 0:
    575613                result = result * a + self[i]
  • sage/rings/polynomial/polynomial_ring.py

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/polynomial/polynomial_ring.py
    a b  
    15461546        else:
    15471547            raise ValueError, "algorithm must be one of 'divided_difference' or 'neville'"
    15481548
     1549    def fraction_field(self):
     1550        """
     1551        Returns the fraction field of self.
     1552
     1553        EXAMPLES::
     1554
     1555            sage: R.<t> = GF(5)[]
     1556            sage: R.fraction_field()
     1557            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1558        """
     1559        try:
     1560            return self._fraction_field
     1561        except AttributeError:
     1562            R = self.base_ring()
     1563            p = R.characteristic()
     1564            if p != 0 and R.is_prime_field() and 2 < p and p < 2**16:
     1565                from sage.rings.fraction_field_FpT import FpT
     1566                self._fraction_field = FpT(self)
     1567            else:
     1568                from sage.rings.fraction_field import FractionField_1poly_field
     1569                self._fraction_field = FractionField_1poly_field(self)
     1570            return self._fraction_field
     1571
     1572    def fraction_field(self):
     1573        """
     1574        Returns the fraction field of self.
     1575
     1576        EXAMPLES::
     1577
     1578            sage: R.<t> = GF(5)[]
     1579            sage: R.fraction_field()
     1580            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1581        """
     1582        try:
     1583            return self._fraction_field
     1584        except AttributeError:
     1585            R = self.base_ring()
     1586            p = R.characteristic()
     1587            if p != 0 and R.is_prime_field() and 2 < p and p < 2**16:
     1588                from sage.rings.fraction_field_FpT import FpT
     1589                self._fraction_field = FpT(self)
     1590            else:
     1591                from sage.rings.fraction_field import FractionField_1poly_field
     1592                self._fraction_field = FractionField_1poly_field(self)
     1593            return self._fraction_field
     1594
    15491595class PolynomialRing_dense_padic_ring_generic(PolynomialRing_integral_domain):
    15501596    pass
    15511597
  • sage/rings/polynomial/polynomial_zmod_flint.pyx

    diff -r 82f8c237c235 -r 13d49774623a sage/rings/polynomial/polynomial_zmod_flint.pyx
    a b  
    3535
    3636from sage.libs.ntl.ntl_lzz_pX import ntl_zz_pX
    3737from sage.structure.factorization import Factorization
    38 from sage.structure.element import coerce_binop
     38from sage.structure.element import coerce_binop, parent
    3939
    4040# We need to define this stuff before including the templating stuff
    4141# to make sure the function get_cparent is found since it is used in
     
    178178        EXAMPLE::
    179179
    180180            sage: P.<x> = PolynomialRing(GF(7))
    181             sage: f= x^2 + 1
     181            sage: f = x^2 + 1
    182182            sage: f(0)
    183183            1
    184184            sage: f(2)
     
    188188
    189189            sage: f(x+1)
    190190            x^2 + 2*x + 2
     191           
     192        Test some simple (but important) optimizations::
     193       
     194            sage: f(2) == f(P(2))
     195            True
     196            sage: f(x) is f
     197            True
     198            sage: f(1/x)
     199            (x^2 + 1)/x^2
    191200        """
    192         cdef Polynomial_zmod_flint t
     201        cdef Polynomial_zmod_flint t, y
     202        cdef long c
    193203        K = self._parent.base_ring()
    194         if len(kwds) == 0 and len(x) == 1:
    195             try:
    196                 x = K._coerce_(x[0])
    197                 return K(zmod_poly_evaluate(&self.x, int(x)))
    198             except TypeError:
    199                 pass
    200             try:
    201                 x = self.parent().coerce(x[0])
     204        if not kwds and len(x) == 1:
     205            P = parent(x[0])
     206            if K.has_coerce_map_from(P):
     207                x = K(x[0])
     208                return K(zmod_poly_evaluate(&self.x, x))
     209            elif self._parent.has_coerce_map_from(P):
     210                y = <Polynomial_zmod_flint>self._parent(x[0])
    202211                t = self._new()
    203                 zmod_poly_compose_horner(&t.x, &self.x,
    204                         &(<Polynomial_zmod_flint>x).x)
     212                if zmod_poly_degree(&y.x) == 0:
     213                    c = zmod_poly_evaluate(&self.x, zmod_poly_get_coeff_ui(&y.x, 0))
     214                    zmod_poly_set_coeff_ui(&t.x, 0, c)
     215                elif zmod_poly_degree(&y.x) == 1 and zmod_poly_get_coeff_ui(&y.x, 0) == 0:
     216                    c = zmod_poly_get_coeff_ui(&y.x, 1)
     217                    if c == 1:
     218                        return self
     219                zmod_poly_compose_horner(&t.x, &self.x, &y.x)
    205220                return t
    206             except TypeError:
    207                 pass
    208221        return Polynomial.__call__(self, *x, **kwds)
    209 
     222   
    210223    @coerce_binop
    211224    def resultant(self, Polynomial_zmod_flint other):
    212225        """
     
    601614            sage: p.reverse(degree=2)
    602615            x^2 + 2*x + 3
    603616
     617            sage: R.<x> = GF(101)[]
     618            sage: f = x^3 - x + 2; f
     619            x^3 + 100*x + 2
     620            sage: f.reverse()
     621            2*x^3 + 100*x^2 + 1
     622            sage: f.reverse() == f(1/x) * x^f.degree()
     623            True
     624       
     625        Note that if `f` has zero constant coefficient, its reverse will
     626        have lower degree.
     627       
     628        ::
     629       
     630            sage: f = x^3 + 2*x
     631            sage: f.reverse()
     632            2*x^2 + 1
     633           
     634        In this case, reverse is not an involution unless we explicitly
     635        specify a degree.
     636       
     637        ::
     638           
     639            sage: f
     640            x^3 + 2*x
     641            sage: f.reverse().reverse()
     642            x^2 + 2
     643            sage: f.reverse(5).reverse(5)
     644            x^3 + 2*x
     645
    604646        TESTS::
    605647
    606648            sage: p.reverse(degree=1.5r)