Ticket #7585: 7585_9_frac_and_coerce_updates.patch

File 7585_9_frac_and_coerce_updates.patch, 15.1 KB (added by David Roe, 13 years ago)
  • sage/rings/fraction_field.py

    # HG changeset patch
    # User David Roe <roed@math.harvard.edu>
    # Date 1260893171 18000
    # Node ID a352f2739b86e62eaf636454b4baf15c42d1a838
    # Parent  45df5909ac43dbd9dbc5f9aef01d25abfb0d9c72
    Added some classes for fraction fields over univariate polynomial rings over fields and ideals therin.  Moved orders in number fields to the new coercion model.  Hooked the FpT class into the fraction field method on polynomial rings.
    
    diff -r 45df5909ac43 -r a352f2739b86 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        """
     
    249249            x
    250250        """
    251251        if isinstance(S, FractionField_generic) and \
    252             self.__R.has_coerce_map_from(S.ring()):
     252            self._R.has_coerce_map_from(S.ring()):
    253253                return CallableConvertMap(S, self, \
    254254                        lambda x: self._element_class(self, x.numerator(),
    255255                            x.denominator()), parent_as_first_arg=False)
    256         if self.__R.has_coerce_map_from(S):
     256        if self._R.has_coerce_map_from(S):
    257257            return CallableConvertMap(S, self, self._element_class,
    258258                    parent_as_first_arg=True)
    259259        return None
     
    280280            sage: R.base_ring()
    281281            Integer Ring
    282282        """
    283         return self.__R.base_ring()
     283        return self._R.base_ring()
    284284
    285285    def characteristic(self):
    286286        """
     
    296296            sage: R = Frac(GF(5)['w']); R.characteristic()
    297297            5
    298298        """
    299         return self.__R.characteristic()
     299        return self._R.characteristic()
    300300   
    301301    def _repr_(self):
    302302        """
     
    305305            sage: str(Frac(ZZ['x']))
    306306            'Fraction Field of Univariate Polynomial Ring in x over Integer Ring'
    307307        """
    308         return "Fraction Field of %s"%self.__R
     308        return "Fraction Field of %s"%self._R
    309309
    310310    def _latex_(self):
    311311        """
     
    314314            sage: latex(Frac(GF(7)['x,y,z']))
    315315            \mathrm{Frac}(\Bold{F}_{7}[x, y, z])
    316316        """
    317         return "\\mathrm{Frac}(%s)"%latex.latex(self.__R)
     317        return "\\mathrm{Frac}(%s)"%latex.latex(self._R)
    318318
    319319    def _magma_init_(self, magma):
    320320        """
     
    360360            sage: R.ring()
    361361            Multivariate Polynomial Ring in x, y over Rational Field
    362362        """
    363         return self.__R
     363        return self._R
    364364   
    365365    def is_exact(self):
    366366        """
     
    378378            self.__is_exact = r
    379379        return r
    380380
    381     def _element_constructor_(self, x, coerce=True):
     381    def _element_constructor_(self, x, y=1, coerce=True):
    382382        """
    383383        Construct an element of this fraction field.
    384384       
     
    405405                return x
    406406            else:
    407407                return self._element_class(self, x.numerator(), x.denominator())
    408         return self._element_class(self, x, 1,
     408        return self._element_class(self, x, y,
    409409                coerce=coerce, reduce = self.is_exact())
    410410
    411411    def construction(self):
     
    439439        """
    440440        if not isinstance(other, FractionField_generic):
    441441            return cmp(type(self), type(other))
    442         return cmp(self.__R, other.__R)
     442        return cmp(self._R, other._R)
    443443
    444444    def ngens(self):
    445445        """
     
    452452            sage: R.ngens()
    453453            10
    454454        """
    455         return self.__R.ngens()
     455        return self._R.ngens()
    456456
    457457    def gen(self, i=0):
    458458        """
     
    469469            sage: R.3
    470470            z3
    471471        """
    472         x = self.__R.gen(i)
    473         one = self.__R.one_element()
     472        x = self._R.gen(i)
     473        one = self._R.one_element()
    474474        r = self._element_class(self, x, one, coerce=False, reduce=False)
    475475        return r
    476476
     
    527527            sage: F.random_element(degree=5)
    528528            (-12*x^5 - 2*x^4 - x^3 - 95*x^2 + x + 2)/(-x^5 + x^4 - x^3 + x^2)
    529529        """
    530         return self._element_class(self, self.__R.random_element(*args, **kwds),
    531                 self.__R.random_element(*args, **kwds),
     530        return self._element_class(self, self._R.random_element(*args, **kwds),
     531                self._R.random_element(*args, **kwds),
    532532                coerce = False, reduce=True)
    533533
     534class FractionField_1poly_field(FractionField_generic):
     535    """
     536    The fraction field of a univariate polynomial ring over a field.
     537
     538    Many of the functions here are included for coherence with number fields.
     539    """
     540    def ring_of_integers(self):
     541        """
     542        Returns the ring of integers in this fraction field.
     543
     544        EXAMPLES::
     545
     546            sage: K = FractionField(GF(5)['t'])
     547            sage: K.ring_of_integers()
     548            Univariate Polynomial Ring in t over Finite Field of size 5
     549        """
     550        return self._R
     551
     552    def maximal_order(self):
     553        """
     554        Returns the maximal order in this fraction field.
     555
     556        EXAMPLES::
     557
     558            sage: K = FractionField(GF(5)['t'])
     559            sage: K.maximal_order()
     560            Univariate Polynomial Ring in t over Finite Field of size 5
     561        """
     562        return self._R
     563       
     564    def uniformizer(self, P, others = "positive"):
     565        """
     566        Returns an element of self with valuation 1 at the prime ideal P.
     567       
     568        INPUT:
     569       
     570       
     571        -  ``self`` - a polynomial ring over a field
     572       
     573        -  ``P`` - a prime ideal of self
     574       
     575        -  ``others`` - either "positive" (default), in which
     576           case the element will have non-negative valuation at all other
     577           primes of self, or "negative", in which case the element will have
     578           non-positive valuation at all other primes of self.  This has no
     579           effect for this field; it's here for compatibility.     
     580       
     581        EXAMPLES::
     582       
     583            sage: K.<t> = FractionField(GF(5)['t'])
     584            sage: K.uniformizer(K.ring_of_integers().ideal(t^2 + 2))
     585            t^2 + 2
     586        """
     587        from sage.rings.ideal import is_Ideal
     588        if not (is_Ideal(P) and P.ring() is self.ring_of_integers()):
     589            P = self.ideal(P)
     590        if not P.is_maximal():
     591            raise ValueError, "P must be a nonzero prime"
     592        # Fraction fields of univariate polynomial rings are PIDs.  So we can just take a generator.
     593        return P.gen()
     594   
     595    def residue_field(self, prime, names = None, check = True):
     596        """
     597        Returns the residue field at a given prime.
     598
     599        EXAMPLES::
     600
     601            sage: R.<t> = GF(5)[]; K = R.fraction_field()
     602            sage: K.residue_field(t^2 + 2)
     603            Residue field in tbar of Principal ideal (t^2 + 2) of Univariate Polynomial Ring in t over Finite Field of size 5
     604        """
     605        # This allows principal ideals to be specified using a generator:
     606        try:
     607            prime = self._R.ideal(prime)
     608        except TypeError:
     609            pass
     610
     611        from sage.rings.ideal import is_Ideal
     612        if not (is_Ideal(prime) and prime.ring() is self._R):
     613            raise ValueError, "%s is not an ideal of %s"%(prime,self._R)
     614        if check:
     615            if not self._R.base_ring().is_finite():
     616                raise TypeError, "residue fields only supported for polynomial rings over finite fields."
     617            if not prime.is_prime():
     618                raise ValueError, "%s is not a prime ideal"%prime
     619        from sage.rings.residue_field import ResidueField
     620        return ResidueField(prime, names = names, check = False)
  • sage/rings/fraction_field_FpT.pyx

    diff -r 45df5909ac43 -r a352f2739b86 sage/rings/fraction_field_FpT.pyx
    a b  
    1111from sage.libs.flint.zmod_poly cimport *
    1212from sage.structure.element cimport Element, ModuleElement, RingElement
    1313from sage.rings.integer_ring import ZZ
    14 from sage.rings.fraction_field import FractionField_generic
     14from sage.rings.fraction_field import FractionField_1poly_field
    1515from sage.rings.integer_mod cimport IntegerMod_int
    1616from sage.rings.integer cimport Integer
    1717from sage.rings.polynomial.polynomial_zmod_flint cimport Polynomial_zmod_flint
     
    1919
    2020from sage.rings.integer_mod cimport jacobi_int, mod_inverse_int, mod_pow_int
    2121
    22 class FpT(FractionField_generic):
     22class FpT(FractionField_1poly_field):
    2323    """
    2424    This class represents the fraction field GF(p)(T) for `2 < p < 2^16`.
    2525
     
    4646        assert 2 < p < 2**16
    4747        self.p = p
    4848        self.poly_ring = R
    49         FractionField_generic.__init__(self, R, element_class = FpTElement)
     49        FractionField_1poly_field.__init__(self, R, element_class = FpTElement)
    5050        self._populate_coercion_lists_(coerce_list=[Polyring_FpT_coerce(self), Fp_FpT_coerce(self), ZZ_FpT_coerce(self)])
    5151   
    5252    def __iter__(self):
     
    14281428                      From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
    14291429                      To:   Finite Field of size 5
    14301430                    then
    1431                       Lifting morphism:
     1431                      Lifting map:
    14321432                      From: Finite Field of size 5
    14331433                      To:   Integer Ring
    14341434            sage: t = K.gen()
  • sage/rings/fraction_field_element.pyx

    diff -r 45df5909ac43 -r a352f2739b86 sage/rings/fraction_field_element.pyx
    a b  
    962962            cdict['_FractionFieldElement__denominator'],
    963963            coerce=False, reduce=False)
    964964   
     965class FractionFieldElement_1poly_field(FractionFieldElement):
     966    """
     967    A fraction field element where the parent is the fraction field of a univariate polynomial ring.
     968
     969    Many of the functions here are included for coherence with number fields.   
     970    """
     971    def is_integral(self):
     972        """
     973        Returns whether this element is actually a polynomial.
     974
     975        EXAMPLES::
     976
     977            sage: R.<t> = GF(5)[]
     978            sage: K = R.fraction_field
     979        """
     980        if self.__denominator != 1:
     981            self.reduce()
     982        if self.__denominator == 1:
     983            return int(self.__numerator)
     984        else:
     985            raise TypeError, "denominator must equal 1"
     986
  • sage/rings/morphism.pyx

    diff -r 45df5909ac43 -r a352f2739b86 sage/rings/morphism.pyx
    a b  
    856856            sage: type(f(2))          # indirect doctest
    857857            <type 'sage.rings.rational.Rational'>
    858858        """
    859         return self.codomain()._coerce_(x)
     859        return self.codomain().coerce(x)
    860860
    861861import sage.structure.all
    862862
  • sage/rings/number_field/order.py

    diff -r 45df5909ac43 -r a352f2739b86 sage/rings/number_field/order.py
    a b  
    213213            raise ValueError, "ideal must be integral; use fractional_ideal to create a non-integral ideal."
    214214        return I
    215215
     216    def _coerce_map_from_(self, R):
     217        """
     218        Orders currently only have coerce maps from the integers.
     219       
     220        EXAMPLES::
     221
     222            sage: k.<a> = NumberField(x^2 + 5077)
     223            sage: Ok = k.maximal_order()
     224            sage: Ok.has_coerce_map_from(k) #indirect doctest
     225            False
     226            sage: Ok.has_coerce_map_from(ZZ)
     227            True
     228        """
     229        return R is ZZ or R is int or R is long
     230
    216231    def __mul__(self, right):
    217232        """
    218233        Create an ideal in this order using the notation ``Ok*gens``
     
    10131028            if module_rep.rank() != self._K.degree():
    10141029                raise ValueError, "the module must have full rank."
    10151030       
    1016     def __call__(self, x):
     1031    def _element_constructor_(self, x):
    10171032        r"""
    10181033        Coerce ``x`` into this order.
    10191034
     
    13611376        self._absolute_order = absolute_order
    13621377        self._module_rep = absolute_order._module_rep
    13631378
    1364     def __call__(self, x):
     1379    def _element_constructor_(self, x):
    13651380        """
    13661381        Coerce an element into this relative order.
    13671382
  • sage/rings/polynomial/polynomial_ring.py

    diff -r 45df5909ac43 -r a352f2739b86 sage/rings/polynomial/polynomial_ring.py
    a b  
    15261526        else:
    15271527            raise ValueError, "algorithm must be one of 'divided_difference' or 'neville'"
    15281528
     1529    def fraction_field(self):
     1530        """
     1531        Returns the fraction field of self.
     1532
     1533        EXAMPLES::
     1534
     1535            sage: R.<t> = GF(5)[]
     1536            sage: R.fraction_field()
     1537            Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 5
     1538        """
     1539        try:
     1540            return self._fraction_field
     1541        except AttributeError:
     1542            R = self.base_ring()
     1543            p = R.characteristic()
     1544            if p != 0 and R.is_prime_field() and 2 < p and p < 2**16:
     1545                from sage.rings.fraction_field_FpT import FpT
     1546                self._fraction_field = FpT(self)
     1547            else:
     1548                from sage.rings.fraction_field import FractionField_1poly_field
     1549                self._fraction_field = FractionField_1poly_field(self)
     1550            return self._fraction_field
     1551
     1552    def residue_field(self, prime, names = None, check = True):
     1553        """
     1554        Returns the residue field at a given prime.
     1555
     1556        EXAMPLES::
     1557
     1558            sage: R.<t> = GF(5)[]
     1559            sage: R.residue_field(t^2 + 2)
     1560            Residue field in tbar of Principal ideal (t^2 + 2) of Univariate Polynomial Ring in t over Finite Field of size 5
     1561        """
     1562        # This allows principal ideals to be specified using a generator:
     1563        try:
     1564            prime = self.ideal(prime)
     1565        except TypeError:
     1566            pass
     1567
     1568        from sage.rings.ideal import is_Ideal
     1569        if not (is_Ideal(prime) and prime.ring() is self):
     1570            raise ValueError, "%s is not an ideal of %s"%(prime,self)
     1571        if check:
     1572            if not self.base_ring().is_finite():
     1573                raise TypeError, "residue fields only supported for polynomial rings over finite fields."
     1574            if not prime.is_prime():
     1575                raise ValueError, "%s is not a prime ideal"%prime
     1576        from sage.rings.residue_field import ResidueField
     1577        return ResidueField(prime, names = names, check = False)
     1578
    15291579class PolynomialRing_dense_padic_ring_generic(PolynomialRing_integral_domain):
    15301580    pass
    15311581