Ticket #9051: 9051-FpT_2.patch

File 9051-FpT_2.patch, 66.6 KB (added by robertwb, 12 years ago)
  • sage/rings/fraction_field.py

    # HG changeset patch
    # User David Roe <roed@math.harvard.edu>
    # Date 1260892899 18000
    # Node ID 45e73dd95edd3e33d0757766550698687392fd40
    # Parent  a2a1e2eafbcaf6fdb624db1cc2b6c3f2bffc1796
    Added fraction_field_FpT.pxd.  Added doctests.  Made iterators work a bit better.
    
    diff -r a2a1e2eafbca -r 45e73dd95edd 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 a2a1e2eafbca -r 45e73dd95edd 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 FpTElement next(self)
     17    cpdef _sqrt_or_None(self)
     18    cpdef bint is_square(self)
     19
     20cdef class FpT_iter:   
     21    cdef parent
     22    cdef long degree
     23    cdef FpTElement cur
     24    cdef zmod_poly_t g
     25   
     26cdef class Polyring_FpT_coerce(RingHomomorphism_coercion):
     27    cdef long p
     28cdef class FpT_Polyring_section(Section):
     29    cdef long p
     30cdef class Fp_FpT_coerce(RingHomomorphism_coercion):
     31    cdef long p
     32cdef class FpT_Fp_section(Section):
     33    cdef long p
     34cdef class ZZ_FpT_coerce(RingHomomorphism_coercion):
     35    cdef long p
     36#cdef class int_FpT_coerce(Morphism):
     37#    cdef long p
     38
     39
     40
  • sage/rings/fraction_field_FpT.pyx

    diff -r a2a1e2eafbca -r 45e73dd95edd sage/rings/fraction_field_FpT.pyx
    a b  
     1
     2
    13import sys
    24
     5include "../ext/cdefs.pxi"
     6include "../ext/gmp.pxi"
     7include "../ext/interrupt.pxi"
     8include "../ext/stdsage.pxi"
     9
    310from sage.rings.all import GF
    4 from sage.rings.ring cimport Field
    511from sage.libs.flint.zmod_poly cimport *
    612from sage.structure.element cimport Element, ModuleElement, RingElement
     13from sage.rings.integer_ring import ZZ
     14from sage.rings.fraction_field import FractionField_generic
     15from sage.rings.integer_mod cimport IntegerMod_int
     16from sage.rings.integer cimport Integer
     17from sage.rings.polynomial.polynomial_zmod_flint cimport Polynomial_zmod_flint
    718import sage.algebras.algebra
    819
    920from sage.rings.integer_mod cimport jacobi_int, mod_inverse_int, mod_pow_int
    1021
    11 class Fpt(Field):
    12     def __init__(self, long p, names='t'):
     22class FpT(FractionField_generic):
     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: TestSuite(R).run()
     32    """
     33    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
     34        """
     35        INPUT:
     36
     37        - ``R`` -- A polynomial ring over a finite field of prime order `p` with `2 < p < 2^16`
     38
     39        EXAMPLES::
     40       
     41            sage: R.<x> = GF(31)[]
     42            sage: K = R.fraction_field(); K
     43            Fraction Field of Univariate Polynomial Ring in x over Finite Field of size 31
     44        """
     45        cdef long p = R.base_ring().characteristic()
    1346        assert 2 < p < 2**16
    14         if isinstance(names, tuple):
    15             names, = names
    1647        self.p = p
    17         base_ring = GF(p)
    18         self.poly_ring = base_ring[names]
    19         sage.algebras.algebra.Algebra.__init__(self, base_ring, names=names, normalize=True)
    20         self._populate_coercion_lists_(element_constructor=FptElement)
    21    
    22 #    def _element_constructor_(self, *args):
    23 #        return FptElement(self, *args)
    24    
    25     def ngens(self):
    26         return 1
    27    
    28     def gen(self, ix):
    29         assert ix == 0
    30         return FptElement(self, self.poly_ring.gen())
    31    
    32     def characteristic(self):
    33         return self.p
    34    
    35     def _coerce_map_from_(self, R):
    36         return self.poly_ring.has_coerce_map_from(R)
     48        self.poly_ring = R
     49        FractionField_1poly_field.__init__(self, R, element_class = FpTElement)
     50        self._populate_coercion_lists_(coerce_list=[Polyring_FpT_coerce(self), Fp_FpT_coerce(self), ZZ_FpT_coerce(self)])
    3751   
    3852    def __iter__(self):
     53        """
     54        Returns an iterator over this fraction field.
     55
     56        EXAMPLES::
     57
     58            sage: R.<t> = GF(3)[]; K = R.fraction_field()
     59            sage: iter(K)
     60            <sage.rings.fraction_field_FpT.FpT_iter object at ...>
     61        """
    3962        return self.iter()
    4063   
    4164    def iter(self, bound=None, start=None):
    4265        """
    4366            sage: from sage.rings.fraction_field_FpT import *
    44             sage: R.<t> = Fpt(5)
    45             sage: list(R.iter(2))
     67            sage: R.<t> = FpT(GF(5)['t'])
     68            sage: list(R.iter(2))[350:355]
     69            [(t^2 + t + 1)/(t + 2),
     70             (t^2 + t + 2)/(t + 2),
     71             (t^2 + t + 4)/(t + 2),
     72             (t^2 + 2*t + 1)/(t + 2),
     73             (t^2 + 2*t + 2)/(t + 2)]
    4674        """
    47         return Fpt_iter(self, bound, start)
     75        return FpT_iter(self, bound, start)
    4876
    49 cdef class FptElement(RingElement):
     77cdef class FpTElement(RingElement):
     78    """
     79    An element of an FpT fraction field.
     80    """
     81   
     82    def __init__(self, parent, numer, denom=1, coerce=True, reduce=True):
     83        """
     84        INPUT:
    5085
    51     cdef long p
    52     cdef zmod_poly_t _numer, _denom
    53     cdef bint initalized
     86        - parent -- the Fraction field containing this element
     87        - numer -- something that can be converted into the polynomial ring, giving the numerator
     88        - denom -- something that can be converted into the polynomial ring, giving the numerator (default 1)
    5489
    55     def __init__(self, parent, numer, denom=1):
    56         """
    5790        EXAMPLES::
    5891       
    5992            sage: from sage.rings.fraction_field_FpT import *
    60             sage: R.<t> = Fpt(5)
     93            sage: R.<t> = FpT(GF(5)['t'])
    6194            sage: R(7)
    6295            2
    6396           
    6497        """
    6598        RingElement.__init__(self, parent)
    66         numer = parent.poly_ring(numer)
    67         denom = parent.poly_ring(denom)
     99        if coerce:
     100            numer = parent.poly_ring(numer)
     101            denom = parent.poly_ring(denom)
    68102        self.p = parent.p
    69103        zmod_poly_init(self._numer, self.p)
    70104        zmod_poly_init(self._denom, self.p)
     
    74108            zmod_poly_set_coeff_ui(self._numer, n, a)
    75109        for n, a in enumerate(denom):
    76110            zmod_poly_set_coeff_ui(self._denom, n, a)
    77         normalize(self._numer, self._denom, self.p)
     111        if reduce:
     112            normalize(self._numer, self._denom, self.p)
    78113
    79114    def __dealloc__(self):
     115        """
     116        Deallocation.
     117
     118        EXAMPLES::
     119
     120            sage: K = GF(11)['t'].fraction_field()
     121            sage: t = K.gen()
     122            sage: del t # indirect doctest
     123        """
    80124        if self.initalized:
    81125            zmod_poly_clear(self._numer)
    82126            zmod_poly_clear(self._denom)
    83127   
    84     cdef FptElement _new_c(self):
    85         cdef FptElement x = <FptElement>PY_NEW(FptElement)
     128    cdef FpTElement _new_c(self):
     129        """
     130        Creates a new FpTElement in the same field, leaving the value to be initialized.
     131        """
     132        cdef FpTElement x = <FpTElement>PY_NEW(FpTElement)
    86133        x._parent = self._parent
    87134        x.p = self.p
    88135        zmod_poly_init_precomp(x._numer, x.p, self._numer.p_inv)
     
    90137        x.initalized = True
    91138        return x
    92139   
    93     cdef FptElement _copy_c(self):
    94         cdef FptElement x = <FptElement>PY_NEW(FptElement)
     140    cdef FpTElement _copy_c(self):
     141        """
     142        Creates a new FpTElement in the same field, with the same value as self.
     143        """
     144        cdef FpTElement x = <FpTElement>PY_NEW(FpTElement)
    95145        x._parent = self._parent
    96146        x.p = self.p
    97147        zmod_poly_init2_precomp(x._numer, x.p, self._numer.p_inv, self._numer.length)
     
    102152        return x
    103153   
    104154    def numer(self):
     155        """
     156        Returns the numerator of this element, as an element of the polynomial ring.
     157
     158        EXAMPLES::
     159
     160            sage: K = GF(11)['t'].fraction_field()
     161            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     162            sage: a.numer()
     163            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
     164        """
    105165        cdef long n
    106166        return self._parent.poly_ring(
    107167            [zmod_poly_get_coeff_ui (self._numer, n) for n in range(0, zmod_poly_degree(self._numer)+1)])
    108168
     169    def numerator(self):
     170        """
     171        Returns the numerator of this element, as an element of the polynomial ring.
     172
     173        EXAMPLES::
     174
     175            sage: K = GF(11)['t'].fraction_field()
     176            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     177            sage: a.numerator()
     178            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
     179        """
     180        return self.numer()
     181
    109182    def denom(self):
     183        """
     184        Returns the denominator of this element, as an element of the polynomial ring.
     185
     186        EXAMPLES::
     187
     188            sage: K = GF(11)['t'].fraction_field()
     189            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     190            sage: a.denom()
     191            t^3
     192        """
    110193        cdef long n
    111194        return self._parent.poly_ring(
    112195            [zmod_poly_get_coeff_ui (self._denom, n) for n in range(0, zmod_poly_degree(self._denom)+1)])
    113196
     197    def denominator(self):
     198        """
     199        Returns the denominator of this element, as an element of the polynomial ring.
     200
     201        EXAMPLES::
     202
     203            sage: K = GF(11)['t'].fraction_field()
     204            sage: t = K.gen(0); a = (t + 1/t)^3 - 1
     205            sage: a.denominator()
     206            t^3
     207        """
     208        return self.denom()
     209
    114210    def _repr_(self):
    115211        """
     212        Returns a string representation of this element.
     213       
     214        EXAMPLES::
     215
    116216            sage: from sage.rings.fraction_field_FpT import *
    117             sage: R.<t> = Fpt(17)
    118             sage: -t
     217            sage: R.<t> = FpT(GF(17)['t'])
     218            sage: -t # indirect doctest
    119219            16*t
    120220            sage: 1/t
    121221            1/t
     
    138238            return "%s/%s" % (numer_s, denom_s)
    139239   
    140240    def _latex_(self):
     241        r"""
     242        Returns a latex representation of this element.
     243
     244        EXAMPLES::
     245
     246            sage: K = GF(7)['t'].fraction_field(); t = K.gen(0)
     247            sage: latex(t^2 + 1) # indirect doctest
     248            t^{2} + 1
     249            sage: latex((t + 1)/(t-1))
     250            \frac{t + 1}{t + 6}
     251        """
    141252        if zmod_poly_degree(self._denom) == 0 and zmod_poly_get_coeff_ui(self._denom, 0) == 1:
    142253            return self.numer()._latex_()
    143254        else:
    144             return "{%s}/{%s}" % (self.numer()._latex_(), self.denom()._latex_())
    145         return
     255            return "\\frac{%s}{%s}" % (self.numer()._latex_(), self.denom()._latex_())
    146256   
    147     def __cmp__(self, other):
     257    def __richcmp__(left, right, int op):
    148258        """
     259        EXAMPLES::
     260       
     261            sage: K = Frac(GF(5)['t']); t = K.gen()
     262            sage: t == 1
     263            False
     264            sage: t + 1 < t^2
     265            True
     266        """
     267        return (<Element>left)._richcmp(right, op)
     268
     269    cdef int _cmp_c_impl(self, Element other) except -2:
     270        """
     271        Compares this with another element.
     272
    149273        TESTS::
    150274       
    151275            sage: from sage.rings.fraction_field_FpT import *
    152             sage: R.<t> = Fpt(7)
     276            sage: R.<t> = FpT(GF(7)['t'])
    153277            sage: t == t
    154278            True
    155279            sage: t == -t
     
    160284            True
    161285            sage: 1/t == 1/(t+1)
    162286            False
     287            sage: 2*t/t == 2
     288            True
     289            sage: 2*t/2 == t
     290            True
    163291        """
    164         if isinstance(other, FptElement):
    165             # They are normalized.
    166             if (zmod_poly_equal(self._numer, (<FptElement>other)._numer) and
    167                     zmod_poly_equal(self._denom, (<FptElement>other)._denom)):
    168                 return 0
    169             else:
    170                 return -1
     292        # They are normalized.
     293        if (zmod_poly_equal(self._numer, (<FpTElement>other)._numer) and
     294            zmod_poly_equal(self._denom, (<FpTElement>other)._denom)):
     295            return 0
    171296        else:
    172             return cmp(type(self), type(other))
     297            return -1
    173298   
    174299    def __hash__(self):
    175300        """
     301        Returns a hash value for this element.
     302
    176303        TESTS::
    177304           
    178305            sage: from sage.rings.fraction_field_FpT import *
    179             sage: K.<t> = Fpt(7)
     306            sage: K.<t> = FpT(GF(7)['t'])
    180307            sage: hash(K(0))
    181308            0
    182309            sage: hash(K(5))
    183310            5
    184311            sage: set([1, t, 1/t, t, t, 1/t, 1+1/t, t/t])
    185             set([1, (t + 1)/t, t, 1/t])
     312            set([1/t, 1, t, (t + 1)/t])
    186313        """
    187314        if self.denom() == 1:
    188315            return hash(self.numer())
    189316        return hash(str(self))
    190317       
    191318    def __neg__(self):
    192         cdef FptElement x = self._new_c()
     319        """
     320        Negates this element.
     321
     322        EXAMPLES::
     323
     324            sage: K = GF(5)['t'].fraction_field(); t = K.gen(0)
     325            sage: a = (t^2 + 2)/(t-1)
     326            sage: -a # indirect doctest
     327            (4*t^2 + 3)/(t + 4)
     328        """
     329        cdef FpTElement x = self._new_c()
    193330        zmod_poly_neg(x._numer, self._numer)
    194331        zmod_poly_set(x._denom, self._denom)
    195332        return x
    196333       
    197334    def __invert__(self):
     335        """
     336        Returns the multiplicative inverse of this element.
     337
     338        EXAMPLES::
     339
     340            sage: K = GF(5)['t'].fraction_field(); t = K.gen(0)
     341            sage: a = (t^2 + 2)/(t-1)
     342            sage: ~a # indirect doctest
     343            (t + 4)/(t^2 + 2)
     344        """
    198345        if zmod_poly_degree(self._numer) == -1:
    199346            raise ZeroDivisionError
    200         cdef FptElement x = self._new_c()
     347        cdef FpTElement x = self._new_c()
    201348        zmod_poly_set(x._denom, self._numer)
    202349        zmod_poly_set(x._numer, self._denom)
    203350        return x
    204351
    205352    cpdef ModuleElement _add_(self, ModuleElement _other):
    206353        """
     354        Returns the sum of this fraction field element and another.
     355
    207356        EXAMPLES::
    208357       
    209358            sage: from sage.rings.fraction_field_FpT import *
    210             sage: R.<t> = Fpt(7)
    211             sage: t + t
     359            sage: R.<t> = FpT(GF(7)['t'])
     360            sage: t + t # indirect doctest
    212361            2*t
    213362            sage: (t + 3) + (t + 10)
    214363            2*t + 6
    215364            sage: sum([t] * 7)
    216365            0
    217366            sage: 1/t + t
    218             (t^2 + 1)/(t)
     367            (t^2 + 1)/t
    219368            sage: 1/t + 1/t^2
    220             (t + 1)/(t^2)
     369            (t + 1)/t^2
    221370        """
    222         cdef FptElement other = <FptElement>_other
    223         cdef FptElement x = self._new_c()
     371        cdef FpTElement other = <FpTElement>_other
     372        cdef FpTElement x = self._new_c()
    224373        zmod_poly_mul(x._numer, self._numer, other._denom)
    225374        zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp
    226375        zmod_poly_add(x._numer, x._numer, x._denom)
     
    230379
    231380    cpdef ModuleElement _sub_(self, ModuleElement _other):
    232381        """
     382        Returns the difference of this fraction field element and another.
     383
    233384        EXAMPLES::
    234385       
    235386            sage: from sage.rings.fraction_field_FpT import *
    236             sage: R.<t> = Fpt(7)
    237             sage: t - t
     387            sage: R.<t> = FpT(GF(7)['t'])
     388            sage: t - t # indirect doctest
    238389            0
    239390            sage: (t + 3) - (t + 11)
    240             sage: 6
     391            6
    241392        """
    242         cdef FptElement other = <FptElement>_other
    243         cdef FptElement x = self._new_c()
     393        cdef FpTElement other = <FpTElement>_other
     394        cdef FpTElement x = self._new_c()
    244395        zmod_poly_mul(x._numer, self._numer, other._denom)
    245396        zmod_poly_mul(x._denom, self._denom, other._numer) # use x._denom as a temp
    246397        zmod_poly_sub(x._numer, x._numer, x._denom)
     
    250401
    251402    cpdef RingElement _mul_(self, RingElement _other):
    252403        """
     404        Returns the product of this fraction field element and another.
     405
    253406        EXAMPLES::
    254407       
    255408            sage: from sage.rings.fraction_field_FpT import *
    256             sage: R.<t> = Fpt(7)
    257             sage: t * t
     409            sage: R.<t> = FpT(GF(7)['t'])
     410            sage: t * t # indirect doctest
    258411            t^2
    259412            sage: (t + 3) * (t + 10)
    260413            t^2 + 6*t + 2
    261414        """
    262         cdef FptElement other = <FptElement>_other
    263         cdef FptElement x = self._new_c()
     415        cdef FpTElement other = <FpTElement>_other
     416        cdef FpTElement x = self._new_c()
    264417        zmod_poly_mul(x._numer, self._numer, other._numer)
    265418        zmod_poly_mul(x._denom, self._denom, other._denom)
    266419        normalize(x._numer, x._denom, self.p)
     
    268421
    269422    cpdef RingElement _div_(self, RingElement _other):
    270423        """
     424        Returns the quotient of this fraction field element and another.
     425
    271426        EXAMPLES::
    272427       
    273428            sage: from sage.rings.fraction_field_FpT import *
    274             sage: R.<t> = Fpt(5)
    275             sage: t / t
     429            sage: R.<t> = FpT(GF(5)['t'])
     430            sage: t / t # indirect doctest
    276431            1
    277432            sage: (t + 3) / (t + 11)
    278433            (t + 3)/(t + 1)
    279434            sage: (t^2 + 2*t + 1) / (t + 1)
    280435            t + 1
    281436        """
    282         cdef FptElement other = <FptElement>_other
     437        cdef FpTElement other = <FpTElement>_other
    283438        if zmod_poly_degree(other._numer) == -1:
    284439            raise ZeroDivisionError
    285         cdef FptElement x = self._new_c()
     440        cdef FpTElement x = self._new_c()
    286441        zmod_poly_mul(x._numer, self._numer, other._denom)
    287442        zmod_poly_mul(x._denom, self._denom, other._numer)
    288443        normalize(x._numer, x._denom, self.p)
    289444        return x
    290445   
    291     cpdef FptElement next(self):
    292         # TODO: This misses denom > numer...
     446    cpdef FpTElement next(self):
    293447        """
     448        This function iterates through all polynomials, returning the "next" polynomial after this one.
     449
     450        The strategy is as follows:
     451       
     452        - We always leave the denominator monic.
     453
     454        - We progress through the elements with both numerator and denominator monic, and with the denominator less than the numerator. 
     455          For each such, we output all the scalar multiples of it, then all of the scalar multiples of its inverse.
     456
     457        - So if the leading coefficient of the numerator is less than p-1, we scale the numerator to increase it by 1.
     458
     459        - Otherwise, we consider the multiple with numerator and denominator monic. 
     460       
     461          - If the numerator is less than the denominator (lexicographically), we return the inverse of that element.
     462
     463          - 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.
     464
    294465        EXAMPLES::
    295466       
    296467            sage: from sage.rings.fraction_field_FpT import *
    297             sage: R.<t> = Fpt(3)
     468            sage: R.<t> = FpT(GF(3)['t'])
    298469            sage: a = R(0)
    299             sage: for _ in range(15):
     470            sage: for _ in range(30):
    300471            ...       a = a.next()
    301472            ...       print a
    302473            ...   
    303474            1
    304475            2
     476            1/t
     477            2/t
    305478            t
     479            2*t
     480            1/(t + 1)
     481            2/(t + 1)
    306482            t + 1
    307             (t + 1)/(t)
     483            2*t + 2
     484            t/(t + 1)
     485            2*t/(t + 1)
     486            (t + 1)/t
     487            (2*t + 2)/t
     488            1/(t + 2)
     489            2/(t + 2)
    308490            t + 2
    309             (t + 2)/(t)
     491            2*t + 1
     492            t/(t + 2)
     493            2*t/(t + 2)
     494            (t + 2)/t
     495            (2*t + 1)/t
     496            (t + 1)/(t + 2)
     497            (2*t + 2)/(t + 2)
    310498            (t + 2)/(t + 1)
    311             2*t
    312             (2*t)/(t + 1)
    313             (2*t)/(t + 2)
    314             2*t + 1
    315             (2*t + 1)/(t)
    316499            (2*t + 1)/(t + 1)
    317             2*t + 2
     500            1/t^2
     501            2/t^2
     502            t^2
     503            2*t^2
    318504        """
    319         cdef FptElement x = self._new_c()
     505        cdef FpTElement next = self._copy_c()
     506        cdef long a, lead
     507        cdef zmod_poly_t g
    320508        if zmod_poly_degree(self._numer) == -1:
    321             zmod_poly_set_coeff_ui(x._numer, 0, 1)
    322             zmod_poly_set_coeff_ui(x._denom, 0, 1)
    323             return x
    324         elif zmod_poly_degree(self._numer) == 0:
    325             zmod_poly_set_coeff_ui(x._numer, 0, zmod_poly_get_coeff_ui(self._numer, 0) + 1)
    326             zmod_poly_set_coeff_ui(x._denom, 0, 1)
    327             if zmod_poly_get_coeff_ui(x._numer, 0) == 0:
    328                 zmod_poly_set_coeff_ui(x._numer, 1, 1)
    329             return x
    330         cdef zmod_poly_t g
    331         zmod_poly_init(g, self.p)
    332         zmod_poly_set(x._numer, self._numer)
    333         zmod_poly_set(x._denom, self._denom)
    334         while True:
    335             zmod_poly_inc(x._denom, True)
    336             if zmod_poly_degree(x._numer) < zmod_poly_degree(x._denom):
    337                 zmod_poly_inc(x._numer, False)
    338                 zmod_poly_zero(x._denom)
    339                 zmod_poly_set_coeff_ui(x._denom, 0, 1)
    340             zmod_poly_gcd(g, x._numer, x._denom)
    341             if zmod_poly_is_one(g):
    342                 zmod_poly_clear(g)
    343                 return x
     509            # self should be normalized, so denom == 1
     510            zmod_poly_set_coeff_ui(next._numer, 0, 1)
     511            return next
     512        lead = zmod_poly_leading(next._numer)
     513        if lead < self.p - 1:
     514            a = mod_inverse_int(lead, self.p)
     515            # no overflow since self.p < 2^16
     516            a = a * (lead + 1) % self.p
     517            zmod_poly_scalar_mul(next._numer, next._numer, a)
     518        else:
     519            a = mod_inverse_int(lead, self.p)
     520            zmod_poly_scalar_mul(next._numer, next._numer, a)
     521            # now both next._numer and next._denom are monic.  We figure out which is lexicographically bigger:
     522            a = zmod_poly_cmp(next._numer, next._denom)
     523            if a == 0:
     524                # next._numer and next._denom are relatively prime, so they're both 1.
     525                zmod_poly_inc(next._denom, True)
     526                return next
     527            zmod_poly_set(next._denom, next._numer)
     528            zmod_poly_set(next._numer, self._denom)
     529            if a < 0:
     530                # since next._numer is smaller, we flip and return the inverse.
     531                return next
     532            elif a > 0:
     533                # since next._numer is bigger, we're in the flipped phase.  We flip back, and increment the numerator (until we reach the denominator).
     534                zmod_poly_init(g, self.p)
     535                try:
     536                    while True:
     537                        zmod_poly_inc(next._numer, True)
     538                        if zmod_poly_equal(next._numer, next._denom):
     539                            # Since we've reached the denominator, we reset the numerator to 1 and increment the denominator.
     540                            zmod_poly_inc(next._denom, True)
     541                            zmod_poly_zero(next._numer)
     542                            zmod_poly_set_coeff_ui(next._numer, 0, 1)
     543                            break
     544                        else:
     545                            # otherwise, we keep incrementing until we have a relatively prime numerator.
     546                            zmod_poly_gcd(g, next._numer, next._denom)
     547                            if zmod_poly_is_one(g):
     548                                break
     549                finally:
     550                    zmod_poly_clear(g)
     551        return next
     552       
     553#         if zmod_poly_degree(self._numer) == -1:
     554#             zmod_poly_set_coeff_ui(x._numer, 0, 1)
     555#             zmod_poly_set_coeff_ui(x._denom, 0, 1)
     556#             return x
     557#         elif zmod_poly_degree(self._numer) == 0:
     558#             zmod_poly_set_coeff_ui(x._numer, 0, zmod_poly_get_coeff_ui(self._numer, 0) + 1)
     559#             zmod_poly_set_coeff_ui(x._denom, 0, 1)
     560#             if zmod_poly_get_coeff_ui(x._numer, 0) == 0:
     561#                 zmod_poly_set_coeff_ui(x._numer, 1, 1)
     562#             return x
     563#         cdef zmod_poly_t g
     564#         zmod_poly_init(g, self.p)
     565#         zmod_poly_set(x._numer, self._numer)
     566#         zmod_poly_set(x._denom, self._denom)
     567#         while True:
     568#             zmod_poly_inc(x._denom, True)
     569#             if zmod_poly_degree(x._numer) < zmod_poly_degree(x._denom):
     570#                 zmod_poly_inc(x._numer, False)
     571#                 zmod_poly_zero(x._denom)
     572#                 zmod_poly_set_coeff_ui(x._denom, 0, 1)
     573#             zmod_poly_gcd(g, x._numer, x._denom)
     574#             if zmod_poly_is_one(g):
     575#                 zmod_poly_clear(g)
     576#                 return x
    344577   
    345578    cpdef _sqrt_or_None(self):
    346579        """
     
    349582        TESTS::
    350583       
    351584            sage: from sage.rings.fraction_field_FpT import *
    352             sage: R.<t> = Fpt(17)
    353             sage: sqrt(t^2)
     585            sage: R.<t> = FpT(GF(17)['t'])
     586            sage: sqrt(t^2) # indirect doctest
    354587            t
    355588            sage: sqrt(1/t^2)
    356589            1/t
     
    370603            sage: sqrt(t^4)
    371604            t^2
    372605            sage: sqrt(4*t^4/(1+t)^8)
    373             4*t^2/(t^4 + 4*t^3 + 6*t^2 + 4*t + 1)
     606            2*t^2/(t^4 + 4*t^3 + 6*t^2 + 4*t + 1)
    374607           
    375             sage: R.<t> = Fpt(5)
     608            sage: R.<t> = FpT(GF(5)['t'])
    376609            sage: [a for a in R.iter(2) if (a^2).sqrt() not in (a,-a)]
    377610            []
    378611            sage: [a for a in R.iter(2) if a.is_square() and a.sqrt()^2 != a]
     
    385618            return None
    386619        cdef zmod_poly_t numer
    387620        cdef zmod_poly_t denom
    388         cdef FptElement res
     621        cdef FpTElement res
    389622        try:
    390623            zmod_poly_init(denom, self.p)
    391624            zmod_poly_init(numer, self.p)
     
    402635            zmod_poly_clear(denom)
    403636   
    404637    cpdef bint is_square(self):
     638        """
     639        Returns True if this element is the square of another element of the fraction field.
     640
     641        EXAMPLES::
     642
     643            sage: K = GF(13)['t'].fraction_field(); t = K.gen()
     644            sage: t.is_square()
     645            False
     646            sage: (1/t^2).is_square()
     647            True
     648            sage: K(0).is_square()
     649            True
     650        """
    405651        return self._sqrt_or_None() is not None
    406652   
    407     def sqrt(self):
     653    def sqrt(self, extend=True, all=False):
    408654        """
     655        Returns the square root of this element.
     656
     657        INPUT:
     658
     659        -  ``extend`` - bool (default: True); if True, return a
     660           square root in an extension ring, if necessary. Otherwise, raise a
     661           ValueError if the square is not in the base ring.
     662       
     663        -  ``all`` - bool (default: False); if True, return all
     664           square roots of self, instead of just one.
     665
    409666        EXAMPLES::
    410667       
    411668            sage: from sage.rings.fraction_field_FpT import *
    412             sage: R.<t> = Fpt(7)
     669            sage: K = GF(7)['t'].fraction_field(); t = K.gen(0)
     670            sage: ((t + 2)^2/(3*t^3 + 1)^4).sqrt()
     671            (3*t + 6)/(t^6 + 3*t^3 + 4)
    413672        """
    414673        s = self._sqrt_or_None()
    415674        if s is None:
    416             raise ValueError, "not a perfect square"
     675            if extend:
     676                raise NotImplementedError, "function fields not yet implemented"
     677            else:
     678                raise ValueError, "not a perfect square"
    417679        else:
    418             return s
     680            if all:
     681                if not s:
     682                    return [s]
     683                else:
     684                    return [s, -s]
     685            else:
     686                return s
    419687   
    420     def __pow__(FptElement self, Py_ssize_t e, dummy):
     688    def __pow__(FpTElement self, Py_ssize_t e, dummy):
    421689        """
     690        Returns the ``e``th power of this element.
     691
    422692        EXAMPLES::
    423693       
    424694            sage: from sage.rings.fraction_field_FpT import *
    425             sage: R.<t> = Fpt(7)
     695            sage: R.<t> = FpT(GF(7)['t'])
    426696            sage: t^5
    427697            t^5
    428698            sage: t^-5
     
    446716        """
    447717        cdef long a
    448718        assert dummy is None
    449         cdef FptElement x = self._new_c()
     719        cdef FpTElement x = self._new_c()
    450720        if e >= 0:
    451721            zmod_poly_pow(x._numer, self._numer, e)
    452722            zmod_poly_pow(x._denom, self._denom, e)
     
    460730        return x
    461731
    462732       
    463 cdef class Fpt_iter:
    464    
    465     cdef parent
    466     cdef long degree
    467     cdef FptElement cur
    468     cdef zmod_poly_t g
    469    
    470     def __init__(self, parent, degree=None, FptElement start=None):
    471         if degree is None:
    472             raise NotImplementedError
     733cdef class FpT_iter:
     734    """
     735    Returns a class that iterates over all elements of an FpT.
     736
     737    EXAMPLES::
     738
     739        sage: K = GF(3)['t'].fraction_field()
     740        sage: I = K.iter(1)
     741        sage: list(I)
     742        [0,
     743         1,
     744         2,
     745         t,
     746         t + 1,
     747         t + 2,
     748         2*t,
     749         2*t + 1,
     750         2*t + 2,
     751         1/t,
     752         2/t,
     753         (t + 1)/t,
     754         (t + 2)/t,
     755         (2*t + 1)/t,
     756         (2*t + 2)/t,
     757         1/(t + 1),
     758         2/(t + 1),
     759         t/(t + 1),
     760         (t + 2)/(t + 1),
     761         2*t/(t + 1),
     762         (2*t + 1)/(t + 1),
     763         1/(t + 2),
     764         2/(t + 2),
     765         t/(t + 2),
     766         (t + 1)/(t + 2),
     767         2*t/(t + 2),
     768         (2*t + 2)/(t + 2)]
     769    """
     770    def __init__(self, parent, degree=None, FpTElement start=None):
     771        """
     772        INPUTS:
     773       
     774        - parent -- The FpT that we're iterating over.
     775
     776        - degree -- The maximum degree of the numerator and denominator of the elements over which we iterate.
     777       
     778        - start -- (default 0) The element on which to start.
     779
     780        EXAMPLES::
     781
     782            sage: K = GF(11)['t'].fraction_field()
     783            sage: I = K.iter(2) # indirect doctest
     784            sage: for a in I:
     785            ...       if a.denom()[0] == 3 and a.numer()[1] == 2:
     786            ...           print a; break
     787            2*t/(t + 3)
     788        """
     789        #if degree is None:
     790        #    raise NotImplementedError
    473791        self.parent = parent
    474792        self.cur = start
    475         self.degree = sys.maxint if degree is None else degree
     793        self.degree = -2 if degree is None else degree
    476794   
    477795    def __cinit__(self, parent, *args, **kwds):
     796        """
     797        Memory allocation for the temp variable storing the gcd of the numerator and denominator.
     798
     799        TESTS::
     800
     801            sage: from sage.rings.fraction_field_FpT import FpT_iter
     802            sage: K = GF(7)['t'].fraction_field()
     803            sage: I = FpT_iter(K, 3) # indirect doctest
     804            sage: I
     805            <sage.rings.fraction_field_FpT.FpT_iter object at ...>
     806        """
    478807        zmod_poly_init(self.g, parent.characteristic())
    479808   
    480809    def __dealloc__(self):
     810        """
     811        Deallocating of the self.g
     812
     813        TESTS::
     814
     815            sage: from sage.rings.fraction_field_FpT import FpT_iter
     816            sage: K = GF(7)['t'].fraction_field()
     817            sage: I = FpT_iter(K, 3)
     818            sage: del I # indirect doctest
     819        """
    481820        zmod_poly_clear(self.g)
    482821   
    483822    def __iter__(self):
     823        """
     824        Returns this iterator.
     825
     826        TESTS::
     827
     828            sage: from sage.rings.fraction_field_FpT import FpT_iter
     829            sage: K = GF(3)['t'].fraction_field()
     830            sage: I = FpT_iter(K, 3)
     831            sage: for a in I: # indirect doctest
     832            ...       if a.numer()[1] == 1 and a.denom()[1] == 2 and a.is_square():
     833            ...            print a; break
     834            (t^2 + t + 1)/(t^2 + 2*t + 1)
     835        """
    484836        return self
    485837   
    486838    def __next__(self):
    487839        """
     840        Returns the next element to iterate over.
     841
     842        This is achieved by iterating over monic denominators, and for each denominator,
     843        iterating over all numerators relatively prime to the given denominator.
     844
    488845        EXAMPLES::
    489846       
    490847            sage: from sage.rings.fraction_field_FpT import *
    491             sage: K.<t> = Fpt(3)
    492             sage: list(K.iter(1))
     848            sage: K.<t> = FpT(GF(3)['t'])
     849            sage: list(K.iter(1)) # indirect doctest
    493850            [0,
    494851             1,
    495852             2,
     
    521878            sage: len(list(K.iter(3)))
    522879            2187
    523880
    524             sage: K.<t> = Fpt(5)
    525             sage: L = list(K.iter(3))
     881            sage: K.<t> = FpT(GF(5)['t'])
     882            sage: L = list(K.iter(3)); len(L)
    526883            78125
    527884            sage: L[:10]
    528885            [0, 1, 2, 3, 4, t, t + 1, t + 2, t + 3, t + 4]
     
    531888            sage: L[-1]
    532889            (4*t^3 + 4*t^2 + 4*t + 4)/(t^3 + 4*t^2 + 4*t + 4)
    533890        """
    534         cdef FptElement next
     891        cdef FpTElement next
    535892        if self.cur is None:
    536893            self.cur = self.parent(0)
     894        elif self.degree == -2:
     895            self.cur = self.cur.next()
    537896        else:
    538897            next = self.cur._copy_c()
     898            _sig_on
    539899            while True:
    540900                zmod_poly_inc(next._numer, False)
    541901                if zmod_poly_degree(next._numer) > self.degree:
     
    547907                zmod_poly_gcd(self.g, next._numer, next._denom)
    548908                if zmod_poly_is_one(self.g):
    549909                    break
     910            _sig_off
    550911            self.cur = next
    551912#            self.cur = self.cur.next()
    552913#            if zmod_poly_degree(self.cur._numer) > self.degree:
    553914#                raise StopIteration
    554915        return self.cur
    555916
     917cdef class Polyring_FpT_coerce(RingHomomorphism_coercion):
     918    """
     919    This class represents the coercion map from GF(p)[t] to GF(p)(t)
    556920
     921    EXAMPLES::
     922
     923        sage: R.<t> = GF(5)[]
     924        sage: K = R.fraction_field()
     925        sage: f = K.coerce_map_from(R); f
     926        Ring Coercion morphism:
     927          From: Univariate Polynomial Ring in t over Finite Field of size 5
     928          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     929        sage: type(f)
     930        <type 'sage.rings.fraction_field_FpT.Polyring_FpT_coerce'>
     931    """
     932    def __init__(self, R):
     933        """
     934        INPUTS:
     935       
     936        - R -- An FpT
     937
     938        EXAMPLES::
     939
     940            sage: R.<t> = GF(next_prime(2000))[]
     941            sage: K = R.fraction_field() # indirect doctest
     942        """
     943        RingHomomorphism_coercion.__init__(self, R.ring_of_integers().Hom(R), check=False)
     944        self.p = R.base_ring().characteristic()
     945       
     946    cpdef Element _call_(self, _x):
     947        """
     948        Applies the coercion.
     949
     950        EXAMPLES::
     951
     952            sage: R.<t> = GF(5)[]
     953            sage: K = R.fraction_field()
     954            sage: f = K.coerce_map_from(R)
     955            sage: f(t^2 + 1) # indirect doctest
     956            t^2 + 1
     957        """
     958        cdef Polynomial_zmod_flint x = <Polynomial_zmod_flint?> _x
     959        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     960        ans._parent = self._codomain
     961        ans.p = self.p
     962        zmod_poly_init(ans._numer, ans.p)
     963        zmod_poly_init(ans._denom, ans.p)
     964        zmod_poly_set(ans._numer, &x.x)
     965        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     966        ans.initalized = True
     967        return ans
     968
     969    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     970        """
     971        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     972
     973        If ``reduce`` is specified as False, then the result won't be normalized.
     974
     975        EXAMPLES::
     976
     977            sage: R.<t> = GF(5)[]
     978            sage: K = R.fraction_field()
     979            sage: f = K.coerce_map_from(R)
     980            sage: f(2*t + 2, t + 3) # indirect doctest
     981            (2*t + 2)/(t + 3)
     982            sage: f(2*t + 2, 2)
     983            t + 1
     984            sage: f(2*t + 2, 2, reduce=False)
     985            (2*t + 2)/2
     986        """
     987        cdef Polynomial_zmod_flint x = <Polynomial_zmod_flint?> _x
     988        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     989        ans._parent = self._codomain
     990        ans.p = self.p
     991        zmod_poly_init(ans._numer, ans.p)
     992        zmod_poly_init(ans._denom, ans.p)
     993        cdef long r
     994        zmod_poly_set(ans._numer, &x.x)
     995        if len(args) == 0:
     996            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     997        elif len(args) == 1:
     998            y = args[0]
     999            if PY_TYPE_CHECK(y, Integer):
     1000                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1001                if r == 0:
     1002                    raise ZeroDivisionError
     1003                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1004            else:
     1005                # could use the coerce keyword being set to False to not check this...
     1006                if not (PY_TYPE_CHECK(y, Element) and y.parent() is self._domain):
     1007                    # We could special case integers and GF(p) elements here.
     1008                    y = self._domain(y)
     1009                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1010        else:
     1011            raise ValueError, "FpT only supports two positional arguments"
     1012        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1013            normalize(ans._numer, ans._denom, ans.p)
     1014        ans.initalized = True
     1015        return ans
     1016
     1017    def section(self):
     1018        """
     1019        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1020        back to ``GF(p)[t]``, defined on elements with unit denominator.
     1021
     1022        EXAMPLES::
     1023
     1024            sage: R.<t> = GF(5)[]
     1025            sage: K = R.fraction_field()
     1026            sage: f = K.coerce_map_from(R)
     1027            sage: g = f.section(); g
     1028            Section map:
     1029              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1030              To:   Univariate Polynomial Ring in t over Finite Field of size 5
     1031            sage: t = K.gen()
     1032            sage: g(t)
     1033            t
     1034            sage: g(1/t)
     1035            Traceback (most recent call last):
     1036            ...
     1037            ValueError: not integral
     1038        """
     1039        return FpT_Polyring_section(self)
     1040
     1041cdef class FpT_Polyring_section(Section):
     1042    """
     1043    This class represents the section from GF(p)(t) back to GF(p)[t]
     1044
     1045    EXAMPLES::
     1046
     1047        sage: R.<t> = GF(5)[]
     1048        sage: K = R.fraction_field()
     1049        sage: f = R.convert_map_from(K); f
     1050        Section map:
     1051          From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1052          To:   Univariate Polynomial Ring in t over Finite Field of size 5
     1053        sage: type(f)
     1054        <type 'sage.rings.fraction_field_FpT.FpT_Polyring_section'>
     1055    """
     1056    def __init__(self, Polyring_FpT_coerce f):
     1057        """
     1058        INPUTS:
     1059       
     1060        - f -- A Polyring_FpT_coerce homomorphism
     1061
     1062        EXAMPLES::
     1063
     1064            sage: R.<t> = GF(next_prime(2000))[]
     1065            sage: K = R.fraction_field()
     1066            sage: R(K.gen(0)) # indirect doctest
     1067            t
     1068        """
     1069        self.p = f.p
     1070        Section.__init__(self, f)
     1071   
     1072    cpdef Element _call_(self, _x):
     1073        """
     1074        Applies the section.
     1075
     1076        EXAMPLES::
     1077
     1078            sage: R.<t> = GF(7)[]
     1079            sage: K = R.fraction_field()
     1080            sage: f = K.coerce_map_from(R)
     1081            sage: g = f.section(); g
     1082            Section map:
     1083              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1084              To:   Univariate Polynomial Ring in t over Finite Field of size 7
     1085            sage: t = K.gen()
     1086            sage: g(t^2) # indirect doctest
     1087            t^2
     1088            sage: g(1/t)
     1089            Traceback (most recent call last):
     1090            ...
     1091            ValueError: not integral
     1092        """
     1093        cdef FpTElement x = <FpTElement?>_x
     1094        cdef Polynomial_zmod_flint ans
     1095        if zmod_poly_degree(x._denom) != 0:
     1096            normalize(x._numer, x._denom, self.p)
     1097            if zmod_poly_degree(x._denom) != 0:
     1098                raise ValueError, "not integral"
     1099        ans = PY_NEW(Polynomial_zmod_flint)
     1100        if zmod_poly_get_coeff_ui(x._denom, 0) != 1:
     1101            normalize(x._numer, x._denom, self.p)
     1102        zmod_poly_init(&ans.x, self.p)
     1103        zmod_poly_set(&ans.x, x._numer)
     1104        ans._parent = self._codomain
     1105        return ans
     1106
     1107cdef class Fp_FpT_coerce(RingHomomorphism_coercion):
     1108    """
     1109    This class represents the coercion map from GF(p) to GF(p)(t)
     1110
     1111    EXAMPLES::
     1112
     1113        sage: R.<t> = GF(5)[]
     1114        sage: K = R.fraction_field()
     1115        sage: f = K.coerce_map_from(GF(5)); f
     1116        Ring Coercion morphism:
     1117          From: Finite Field of size 5
     1118          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1119        sage: type(f)
     1120        <type 'sage.rings.fraction_field_FpT.Fp_FpT_coerce'>
     1121    """
     1122    def __init__(self, R):
     1123        """
     1124        INPUTS:
     1125       
     1126        - R -- An FpT
     1127
     1128        EXAMPLES::
     1129
     1130            sage: R.<t> = GF(next_prime(3000))[]
     1131            sage: K = R.fraction_field() # indirect doctest
     1132        """
     1133        RingHomomorphism_coercion.__init__(self, R.base_ring().Hom(R), check=False)
     1134        self.p = R.base_ring().characteristic()
     1135       
     1136    cpdef Element _call_(self, _x):
     1137        """
     1138        Applies the coercion.
     1139
     1140        EXAMPLES::
     1141
     1142            sage: R.<t> = GF(5)[]
     1143            sage: K = R.fraction_field()
     1144            sage: f = K.coerce_map_from(GF(5))
     1145            sage: f(GF(5)(3)) # indirect doctest
     1146            3
     1147        """
     1148        cdef IntegerMod_int x = <IntegerMod_int?> _x
     1149        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1150        ans._parent = self._codomain
     1151        ans.p = self.p
     1152        zmod_poly_init(ans._numer, ans.p)
     1153        zmod_poly_init(ans._denom, ans.p)
     1154        zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)
     1155        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1156        ans.initalized = True
     1157        return ans
     1158
     1159    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     1160        """
     1161        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     1162
     1163        If ``reduce`` is specified as False, then the result won't be normalized.
     1164
     1165        EXAMPLES::
     1166
     1167            sage: R.<t> = GF(5)[]
     1168            sage: K = R.fraction_field()
     1169            sage: f = K.coerce_map_from(GF(5))
     1170            sage: f(1, t + 3) # indirect doctest
     1171            1/(t + 3)
     1172            sage: f(2, 2*t)
     1173            1/t
     1174            sage: f(2, 2*t, reduce=False)
     1175            2/2*t
     1176        """
     1177        cdef IntegerMod_int x = <IntegerMod_int?> _x
     1178        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1179        ans._parent = self._codomain
     1180        ans.p = self.p
     1181        zmod_poly_init(ans._numer, ans.p)
     1182        zmod_poly_init(ans._denom, ans.p)
     1183        cdef long r
     1184        zmod_poly_set_coeff_ui(ans._numer, 0, x.ivalue)
     1185        if len(args) == 0:
     1186            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1187        if len(args) == 1:
     1188            y = args[0]
     1189            if PY_TYPE_CHECK(y, Integer):
     1190                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1191                if r == 0:
     1192                    raise ZeroDivisionError
     1193                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1194            else:
     1195                R = self._codomain.ring_of_integers()
     1196                # could use the coerce keyword being set to False to not check this...
     1197                if not (PY_TYPE_CHECK(y, Element) and y.parent() is R):
     1198                    # We could special case integers and GF(p) elements here.
     1199                    y = R(y)
     1200                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1201        else:
     1202            raise ValueError, "FpT only supports two positional arguments"
     1203        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1204            normalize(ans._numer, ans._denom, ans.p)
     1205        ans.initalized = True
     1206        return ans
     1207
     1208    def section(self):
     1209        """
     1210        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1211        back to ``GF(p)``, defined on constant elements.
     1212
     1213        EXAMPLES::
     1214
     1215            sage: R.<t> = GF(5)[]
     1216            sage: K = R.fraction_field()
     1217            sage: f = K.coerce_map_from(GF(5))
     1218            sage: g = f.section(); g
     1219            Section map:
     1220              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1221              To:   Finite Field of size 5
     1222            sage: t = K.gen()
     1223            sage: g(f(1,3,reduce=False))
     1224            2
     1225            sage: g(t)
     1226            Traceback (most recent call last):
     1227            ...
     1228            ValueError: not constant           
     1229            sage: g(1/t)
     1230            Traceback (most recent call last):
     1231            ...
     1232            ValueError: not integral
     1233        """
     1234        return FpT_Fp_section(self)
     1235
     1236cdef class FpT_Fp_section(Section):
     1237    """
     1238    This class represents the section from GF(p)(t) back to GF(p)[t]
     1239
     1240    EXAMPLES::
     1241
     1242        sage: R.<t> = GF(5)[]
     1243        sage: K = R.fraction_field()
     1244        sage: f = GF(5).convert_map_from(K); f
     1245        Section map:
     1246          From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1247          To:   Finite Field of size 5
     1248        sage: type(f)
     1249        <type 'sage.rings.fraction_field_FpT.FpT_Fp_section'>
     1250    """
     1251    def __init__(self, Fp_FpT_coerce f):
     1252        """
     1253        INPUTS:
     1254       
     1255        - f -- An Fp_FpT_coerce homomorphism
     1256
     1257        EXAMPLES::
     1258
     1259            sage: R.<t> = GF(next_prime(2000))[]
     1260            sage: K = R.fraction_field()
     1261            sage: GF(next_prime(2000))(K(127)) # indirect doctest
     1262            127
     1263        """
     1264        self.p = f.p
     1265        Section.__init__(self, f)
     1266   
     1267    cpdef Element _call_(self, _x):
     1268        """
     1269        Applies the section.
     1270
     1271        EXAMPLES::
     1272
     1273            sage: R.<t> = GF(7)[]
     1274            sage: K = R.fraction_field()
     1275            sage: f = K.coerce_map_from(GF(7))
     1276            sage: g = f.section(); g
     1277            Section map:
     1278              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7
     1279              To:   Finite Field of size 7
     1280            sage: t = K.gen()
     1281            sage: g(t^2) # indirect doctest
     1282            Traceback (most recent call last):
     1283            ...
     1284            ValueError: not constant
     1285            sage: g(1/t)
     1286            Traceback (most recent call last):
     1287            ...
     1288            ValueError: not integral
     1289            sage: g(K(4))
     1290            4
     1291            sage: g(K(0))
     1292            0
     1293        """
     1294        cdef FpTElement x = <FpTElement?>_x
     1295        cdef IntegerMod_int ans
     1296        if zmod_poly_degree(x._denom) != 0 or zmod_poly_degree(x._numer) > 0:
     1297            normalize(x._numer, x._denom, self.p)
     1298            if zmod_poly_degree(x._denom) != 0:
     1299                raise ValueError, "not integral"
     1300            if zmod_poly_degree(x._numer) > 0:
     1301                raise ValueError, "not constant"
     1302        ans = PY_NEW(IntegerMod_int)
     1303        ans.__modulus = self._codomain._pyx_order
     1304        if zmod_poly_get_coeff_ui(x._denom, 0) != 1:
     1305            normalize(x._numer, x._denom, self.p)
     1306        ans.ivalue = zmod_poly_get_coeff_ui(x._numer, 0)
     1307        ans._parent = self._codomain
     1308        return ans
     1309
     1310cdef class ZZ_FpT_coerce(RingHomomorphism_coercion):
     1311    """
     1312    This class represents the coercion map from ZZ to GF(p)(t)
     1313
     1314    EXAMPLES::
     1315
     1316        sage: R.<t> = GF(17)[]
     1317        sage: K = R.fraction_field()
     1318        sage: f = K.coerce_map_from(ZZ); f
     1319        Ring Coercion morphism:
     1320          From: Integer Ring
     1321          To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 17
     1322        sage: type(f)
     1323        <type 'sage.rings.fraction_field_FpT.ZZ_FpT_coerce'>
     1324    """
     1325    def __init__(self, R):
     1326        """
     1327        INPUTS:
     1328       
     1329        - R -- An FpT
     1330
     1331        EXAMPLES::
     1332
     1333            sage: R.<t> = GF(next_prime(3000))[]
     1334            sage: K = R.fraction_field() # indirect doctest
     1335        """
     1336        RingHomomorphism_coercion.__init__(self, ZZ.Hom(R), check=False)
     1337        self.p = R.base_ring().characteristic()
     1338       
     1339    cpdef Element _call_(self, _x):
     1340        """
     1341        Applies the coercion.
     1342
     1343        EXAMPLES::
     1344
     1345            sage: R.<t> = GF(5)[]
     1346            sage: K = R.fraction_field()
     1347            sage: f = K.coerce_map_from(ZZ)
     1348            sage: f(3) # indirect doctest
     1349            3
     1350        """
     1351        cdef Integer x = <Integer?> _x
     1352        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1353        ans._parent = self._codomain
     1354        ans.p = self.p
     1355        zmod_poly_init(ans._numer, ans.p)
     1356        zmod_poly_init(ans._denom, ans.p)
     1357        zmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p))
     1358        zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1359        ans.initalized = True
     1360        return ans
     1361
     1362    cpdef Element _call_with_args(self, _x, args=(), kwds={}):
     1363        """
     1364        This function allows the map to take multiple arguments, usually used to specify both numerator and denominator.
     1365
     1366        If ``reduce`` is specified as False, then the result won't be normalized.
     1367
     1368        EXAMPLES::
     1369
     1370            sage: R.<t> = GF(5)[]
     1371            sage: K = R.fraction_field()
     1372            sage: f = K.coerce_map_from(ZZ)
     1373            sage: f(1, t + 3) # indirect doctest
     1374            1/(t + 3)
     1375            sage: f(1,2)
     1376            3
     1377            sage: f(2, 2*t)
     1378            1/t
     1379            sage: f(2, 2*t, reduce=False)
     1380            2/2*t
     1381        """
     1382        cdef Integer x = <Integer?> _x
     1383        cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1384        ans._parent = self._codomain
     1385        ans.p = self.p
     1386        zmod_poly_init(ans._numer, ans.p)
     1387        zmod_poly_init(ans._denom, ans.p)
     1388        cdef long r
     1389        zmod_poly_set_coeff_ui(ans._numer, 0, mpz_fdiv_ui(x.value, self.p))
     1390        if len(args) == 0:
     1391            zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1392        if len(args) == 1:
     1393            y = args[0]
     1394            if PY_TYPE_CHECK(y, Integer):
     1395                r = mpz_fdiv_ui((<Integer>y).value, self.p)
     1396                if r == 0:
     1397                    raise ZeroDivisionError
     1398                zmod_poly_set_coeff_ui(ans._denom, 0, r)
     1399            else:
     1400                R = self._codomain.ring_of_integers()
     1401                # could use the coerce keyword being set to False to not check this...
     1402                if not (PY_TYPE_CHECK(y, Element) and y.parent() is R):
     1403                    # We could special case integers and GF(p) elements here.
     1404                    y = R(y)
     1405                zmod_poly_set(ans._denom, &((<Polynomial_zmod_flint?>y).x))
     1406        else:
     1407            raise ValueError, "FpT only supports two positional arguments"
     1408        if not (kwds.has_key('reduce') and not kwds['reduce']):
     1409            normalize(ans._numer, ans._denom, ans.p)
     1410        ans.initalized = True
     1411        return ans
     1412
     1413    def section(self):
     1414        """
     1415        Returns the section of this inclusion: the partially defined map from ``GF(p)(t)``
     1416        back to ``ZZ``, defined on constant elements.
     1417
     1418        EXAMPLES::
     1419
     1420            sage: R.<t> = GF(5)[]
     1421            sage: K = R.fraction_field()
     1422            sage: f = K.coerce_map_from(ZZ)
     1423            sage: g = f.section(); g
     1424            Composite map:
     1425              From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1426              To:   Integer Ring
     1427              Defn:   Section map:
     1428                      From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1429                      To:   Finite Field of size 5
     1430                    then
     1431                      Lifting morphism:
     1432                      From: Finite Field of size 5
     1433                      To:   Integer Ring
     1434            sage: t = K.gen()
     1435            sage: g(f(1,3,reduce=False))
     1436            2
     1437            sage: g(t)
     1438            Traceback (most recent call last):
     1439            ...
     1440            ValueError: not constant           
     1441            sage: g(1/t)
     1442            Traceback (most recent call last):
     1443            ...
     1444            ValueError: not integral
     1445        """
     1446        return self._codomain.base_ring().coerce_map_from(ZZ).section() * Fp_FpT_coerce(self._codomain).section()
     1447
     1448# cdef class int_FpT_coerce(Morphism):
     1449#     """
     1450#     This class represents the coercion map from int to GF(p)(t)
     1451
     1452#     EXAMPLES::
     1453
     1454#         sage: R.<t> = GF(17)[]
     1455#         sage: K = R.fraction_field()
     1456#         sage: f = K.coerce_map_from(int); f
     1457#         Ring Coercion morphism:
     1458#           From: Integer Ring
     1459#           To:   Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 17
     1460#         sage: type(f)
     1461#         <type 'sage.rings.fraction_field_FpT.ZZ_FpT_coerce'>
     1462#     """
     1463#     def __init__(self, R):
     1464#         import sage.categories.homset
     1465#         from sage.structure.parent import Set_PythonType
     1466#         Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(int), R))
     1467#         self.p = R.base_ring().characteristic()
     1468
     1469#     cpdef Element _call_(self, a):
     1470#         cdef FpTElement ans = <FpTElement>PY_NEW(FpTElement)
     1471#         ans._parent = self._codomain
     1472#         ans.p = self.p
     1473#         zmod_poly_init(ans._numer, ans.p)
     1474#         zmod_poly_init(ans._denom, ans.p)
     1475#         cdef long amodp = PyInt_AS_LONG(a) % self.p
     1476#         if amodp < 0:
     1477#             amodp = self.p - amodp
     1478#         zmod_poly_set_coeff_ui(ans._numer, 0, amodp)
     1479#         zmod_poly_set_coeff_ui(ans._denom, 0, 1)
     1480#         ans.initalized = True
     1481#         return ans
     1482
     1483#     def _repr_type(self):
     1484#         return "Native" 
    5571485
    5581486cdef inline bint normalize(zmod_poly_t numer, zmod_poly_t denom, long p):
     1487    """
     1488    Puts numer/denom into a normal form: denominator monic and sharing no common factor with the numerator.
     1489
     1490    The normalized form of 0 is 0/1.
     1491
     1492    Returns True if numer and denom were changed.
     1493    """
    5591494    cdef long a
     1495    cdef bint changed
    5601496    if zmod_poly_degree(numer) == -1:
     1497        if zmod_poly_degree(denom) > 0 or zmod_poly_leading(denom) != 1:
     1498            changed = True
     1499        else:
     1500            changed = False
    5611501        zmod_poly_truncate(denom, 0)
    5621502        zmod_poly_set_coeff_ui(denom, 0, 1)
     1503        return changed
    5631504    elif zmod_poly_degree(numer) == 0 or zmod_poly_degree(denom) == 0:
    5641505        if zmod_poly_leading(denom) != 1:
    5651506            a = mod_inverse_int(zmod_poly_leading(denom), p)
     
    5681509            return True
    5691510        return False
    5701511    cdef zmod_poly_t g
    571     cdef bint changed = False
     1512    changed = False
    5721513    try:
    5731514        zmod_poly_init_precomp(g, p, numer.p_inv)
    5741515        zmod_poly_gcd(g, numer, denom)
     
    5871528        zmod_poly_clear(g)
    5881529
    5891530cdef inline unsigned long zmod_poly_leading(zmod_poly_t poly):
     1531    """
     1532    Returns the leading coefficient of ``poly``.
     1533    """
    5901534    return zmod_poly_get_coeff_ui(poly, zmod_poly_degree(poly))
    5911535
    5921536cdef inline void zmod_poly_inc(zmod_poly_t poly, bint monic):
     1537    """
     1538    Sets poly to the "next" polynomial: this is just counting in base p.
     1539
     1540    If monic is True then will only iterate through monic polynomials.
     1541    """
    5931542    cdef long n
    5941543    cdef long a
    5951544    cdef long p = poly.p
    5961545    for n from 0 <= n <= zmod_poly_degree(poly) + 1:
    5971546        a = zmod_poly_get_coeff_ui(poly, n) + 1
    598         if a == poly.p:
     1547        if a == p:
    5991548            zmod_poly_set_coeff_ui(poly, n, 0)
    6001549        else:
    6011550            zmod_poly_set_coeff_ui(poly, n, a)
     
    6041553        zmod_poly_set_coeff_ui(poly, n, 0)
    6051554        zmod_poly_set_coeff_ui(poly, n+1, 1)
    6061555
     1556cdef inline long zmod_poly_cmp(zmod_poly_t a, zmod_poly_t b):
     1557    """
     1558    Compares `a` and `b`, returning 0 if they are equal.
     1559
     1560    - If the degree of `a` is less than that of `b`, returns -1.
     1561
     1562    - If the degree of `b` is less than that of `a`, returns 1.
     1563
     1564    - Otherwise, compares `a` and `b` lexicographically, starting at the leading terms.
     1565    """
     1566    cdef long ad = zmod_poly_degree(a)
     1567    cdef long bd = zmod_poly_degree(b)
     1568    if ad < bd:
     1569        return -1
     1570    elif ad > bd:
     1571        return 1
     1572    cdef long d = zmod_poly_degree(a)
     1573    while d >= 0:
     1574        ad = zmod_poly_get_coeff_ui(a, d)
     1575        bd = zmod_poly_get_coeff_ui(b, d)
     1576        if ad < bd:
     1577            return -1
     1578        elif ad > bd:
     1579            return 1
     1580        d -= 1
     1581    return 0
     1582
    6071583cdef void zmod_poly_pow(zmod_poly_t res, zmod_poly_t poly, unsigned long e):
     1584    """
     1585    Raises poly to the `e`th power and stores the result in ``res``.
     1586    """
    6081587    if zmod_poly_degree(poly) < 2:
    6091588        if zmod_poly_degree(poly) == -1:
    6101589            zmod_poly_zero(res)
     
    6501629
    6511630
    6521631cdef long sqrt_mod_int(long a, long p) except -1:
     1632    """
     1633    Returns the square root of a modulo p, as a long.
     1634    """
    6531635    return GF(p)(a).sqrt()
    6541636
    6551637cdef bint zmod_poly_sqrt_check(zmod_poly_t poly):
  • sage/rings/fraction_field_element.pyx

    diff -r a2a1e2eafbca -r 45e73dd95edd sage/rings/fraction_field_element.pyx
    a b  
    11191119        return (make_element,
    11201120                (self._parent, self.__numerator, self.__denominator))
    11211121
     1122
     1123class FractionFieldElement_1poly_field(FractionFieldElement):
     1124    """
     1125    A fraction field element where the parent is the fraction field of a univariate polynomial ring.
     1126
     1127    Many of the functions here are included for coherence with number fields.   
     1128    """
     1129    def is_integral(self):
     1130        """
     1131        Returns whether this element is actually a polynomial.
     1132
     1133        EXAMPLES::
     1134
     1135            sage: R.<t> = GF(5)[]
     1136            sage: K = R.fraction_field
     1137        """
     1138        if self.__denominator != 1:
     1139            self.reduce()
     1140        return self.__denominator == 1
     1141
     1142    def support(self):
     1143        """
     1144        Returns a sorted list of primes dividing either the numerator or denominator of this element.
     1145
     1146        EXAMPLES::
     1147
     1148            sage: R.<t> = QQ[]
     1149            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)
     1150            sage: h.support()
     1151            [t - 1, t + 3, t^2 + 2, t^2 + t + 1, t^4 - 2]
     1152        """
     1153        L = [fac[0] for fac in self.numerator().factor()] + [fac[0] for fac in self.denominator().factor()]
     1154        L.sort()
     1155        return L
     1156
     1157
     1158
    11221159def make_element(parent, numerator, denominator):
    11231160    """
    11241161    Used for unpickling FractionFieldElement objects (and subclasses).
  • sage/rings/polynomial/polynomial_ring.py

    diff -r a2a1e2eafbca -r 45e73dd95edd sage/rings/polynomial/polynomial_ring.py
    a b  
    15171517        else:
    15181518            raise ValueError, "algorithm must be one of 'divided_difference' or 'neville'"
    15191519
     1520    def fraction_field(self):
     1521        """
     1522        Returns the fraction field of self.
     1523
     1524        EXAMPLES::
     1525
     1526            sage: R.<t> = GF(5)[]
     1527            sage: R.fraction_field()
     1528            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1529        """
     1530        try:
     1531            return self._fraction_field
     1532        except AttributeError:
     1533            R = self.base_ring()
     1534            p = R.characteristic()
     1535            if p != 0 and R.is_prime_field() and 2 < p and p < 2**16:
     1536                from sage.rings.fraction_field_FpT import FpT
     1537                self._fraction_field = FpT(self)
     1538            else:
     1539                from sage.rings.fraction_field import FractionField_1poly_field
     1540                self._fraction_field = FractionField_1poly_field(self)
     1541            return self._fraction_field
     1542
     1543    def fraction_field(self):
     1544        """
     1545        Returns the fraction field of self.
     1546
     1547        EXAMPLES::
     1548
     1549            sage: R.<t> = GF(5)[]
     1550            sage: R.fraction_field()
     1551            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1552        """
     1553        try:
     1554            return self._fraction_field
     1555        except AttributeError:
     1556            R = self.base_ring()
     1557            p = R.characteristic()
     1558            if p != 0 and R.is_prime_field() and 2 < p and p < 2**16:
     1559                from sage.rings.fraction_field_FpT import FpT
     1560                self._fraction_field = FpT(self)
     1561            else:
     1562                from sage.rings.fraction_field import FractionField_1poly_field
     1563                self._fraction_field = FractionField_1poly_field(self)
     1564            return self._fraction_field
     1565
    15201566class PolynomialRing_dense_padic_ring_generic(PolynomialRing_integral_domain):
    15211567    pass
    15221568