Ticket #4000: trac4000_0.patch

File trac4000_0.patch, 94.3 KB (added by spancratz, 8 years ago)

Main patch

  • module_list.py

    # HG changeset patch
    # User William Stein <wstein@gmail.com>
    # Date 1279483889 -7200
    # Node ID 040e85ea22a4fa6865f0c9d8ba58332932eecc93
    # Parent  8dec8b43ccca5f104b1e280cb33c8f4c2c1b8f85
    Trac 4000.  Implements QQ[] via FLINT
    
    diff -r 8dec8b43ccca -r 040e85ea22a4 module_list.py
    a b  
    13531353              language = 'c++',
    13541354              include_dirs = ['sage/libs/ntl/']),
    13551355
     1356    Extension('sage.rings.polynomial.polynomial_rational_flint',
     1357              sources = ['sage/rings/polynomial/polynomial_rational_flint.pyx', 'sage/libs/flint/fmpq_poly.c'],
     1358              language = 'c++',
     1359              extra_compile_args=["-std=c99", "-D_XPG6"],
     1360              libraries = ["csage", "flint", "ntl", "gmpxx", "gmp"],
     1361              include_dirs = [SAGE_ROOT + '/local/include/FLINT/', SAGE_ROOT + '/devel/sage/sage/libs/flint/'],
     1362              depends = [SAGE_ROOT + "/local/include/FLINT/flint.h"]),
     1363
    13561364    Extension('sage.rings.polynomial.polynomial_modn_dense_ntl',
    13571365              sources = ['sage/rings/polynomial/polynomial_modn_dense_ntl.pyx'],
    13581366              libraries = ['ntl', 'stdc++', 'gmp'],
  • sage/calculus/all.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/calculus/all.py
    a b  
    3939        sage: type(a)
    4040        <type 'sage.symbolic.expression.Expression'>
    4141        sage: R.<x> = QQ[]; type(x)
    42         <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
     42        <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
    4343        sage: a = symbolic_expression(2*x^2 + 3); a
    4444        2*x^2 + 3
    4545        sage: type(a)
  • sage/categories/primer.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/categories/primer.py
    a b  
    8080    sage: p.factor()
    8181    6*(x + 1)^2
    8282
    83     sage: pQ = QQ[x] ( p )
     83    sage: R.<x> = PolynomialRing(QQ, sparse=True)
     84    sage: pQ = R ( p )
    8485    sage: type(pQ)
    85     <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
     86    <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse_field'>
    8687    sage: pQ.factor()
    8788    (6) * (x + 1)^2
    8889
  • sage/combinat/sf/jack.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/combinat/sf/jack.py
    a b  
    495495            sage: l = lambda c: [ (i[0],[j for j in sorted(i[1].items())]) for i in sorted(c.items())]
    496496            sage: P._m_cache(2)
    497497            sage: l(P._self_to_m_cache[2])
    498             [([1, 1], [([1, 1], 1)]), ([2], [([1, 1], 2/(t + 1)), ([2], 1)])]
     498            [([1, 1], [([1, 1], 1)]), ([2], [([1, 1], -2/(-t - 1)), ([2], 1)])]
    499499            sage: l(P._m_to_self_cache[2])
    500             [([1, 1], [([1, 1], 1)]), ([2], [([1, 1], -2/(t + 1)), ([2], 1)])]
     500            [([1, 1], [([1, 1], 1)]), ([2], [([1, 1], 2/(-t - 1)), ([2], 1)])]
    501501            sage: P._m_cache(3)
    502502            sage: l(P._m_to_self_cache[3])
    503503            [([1, 1, 1], [([1, 1, 1], 1)]),
    504504             ([2, 1], [([1, 1, 1], -6/(t + 2)), ([2, 1], 1)]),
    505              ([3], [([1, 1, 1], 6/(t^2 + 3*t + 2)), ([2, 1], -3/(2*t + 1)), ([3], 1)])]
     505             ([3], [([1, 1, 1], -6/(-t^2 - 3*t - 2)), ([2, 1], -3/(2*t + 1)), ([3], 1)])]
    506506            sage: l(P._self_to_m_cache[3])
    507507            [([1, 1, 1], [([1, 1, 1], 1)]),
    508508             ([2, 1], [([1, 1, 1], 6/(t + 2)), ([2, 1], 1)]),
    509              ([3], [([1, 1, 1], 6/(2*t^2 + 3*t + 1)), ([2, 1], 3/(2*t + 1)), ([3], 1)])]
     509             ([3], [([1, 1, 1], -6/(-2*t^2 - 3*t - 1)), ([2, 1], 3/(2*t + 1)), ([3], 1)])]
    510510        """
    511511        if n in self._self_to_m_cache:
    512512            return
     
    536536            sage: p11 = Partition([1,1])
    537537            sage: f = P._to_m(p2)
    538538            sage: f(p11)
    539             2/(t + 1)
     539            -2/(-t - 1)
    540540            sage: f(p2)
    541541            1
    542542            sage: f = P._to_m(p11)
     
    554554       
    555555            sage: P = JackPolynomialsP(QQ)
    556556            sage: P([1])^2 # indirect doctest
    557             (2*t/(t+1))*JackP[1, 1] + JackP[2]
     557            (-2*t/(-t-1))*JackP[1, 1] + JackP[2]
    558558            sage: P._m(_)
    559559            2*m[1, 1] + m[2]
    560560            sage: P = JackPolynomialsP(QQ, 2)
     
    685685       
    686686            sage: s = SFASchur(J.base_ring())
    687687            sage: J(s([3])) # indirect doctest
    688             ((t^2-3*t+2)/(6*t^2+18*t+12))*JackJ[1, 1, 1] + ((2*t-2)/(2*t^2+5*t+2))*JackJ[2, 1] + (1/(2*t^2+3*t+1))*JackJ[3]
     688            ((-t^2+3*t-2)/(-6*t^2-18*t-12))*JackJ[1, 1, 1] + ((2*t-2)/(2*t^2+5*t+2))*JackJ[2, 1] + (1/(2*t^2+3*t+1))*JackJ[3]
    689689            sage: J(s([2,1]))
    690690            ((t-1)/(3*t+6))*JackJ[1, 1, 1] + (1/(t+2))*JackJ[2, 1]
    691691            sage: J(s([1,1,1]))
     
    698698       
    699699            sage: J = JackPolynomialsJ(QQ)
    700700            sage: J([1])^2 #indirect doctest
    701             (t/(t+1))*JackJ[1, 1] + (1/(t+1))*JackJ[2]
     701            (-t/(-t-1))*JackJ[1, 1] + (1/(t+1))*JackJ[2]
    702702            sage: J([2])^2
    703             (2*t^2/(2*t^2+3*t+1))*JackJ[2, 2] + (4*t/(3*t^2+4*t+1))*JackJ[3, 1] + ((t+1)/(6*t^2+5*t+1))*JackJ[4]
     703            (-2*t^2/(-2*t^2-3*t-1))*JackJ[2, 2] + (-4*t/(-3*t^2-4*t-1))*JackJ[3, 1] + ((t+1)/(6*t^2+5*t+1))*JackJ[4]
    704704        """
    705705        return self( self._P(left) * self._P(right) )
    706706
  • sage/libs/flint/fmpz.pxi

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/libs/flint/fmpz.pxi
    a b  
    22
    33cdef extern from "FLINT/fmpz.h":
    44   
    5     ctypedef void* fmpz_t
     5    ctypedef void * fmpz_t
     6    ctypedef void * mpz_t
    67
    78    fmpz_t fmpz_init(unsigned long limbs)
    89    void fmpz_clear(fmpz_t f)
    910    void fmpz_print(fmpz_t f)
    1011    int fmpz_is_one(fmpz_t f)
     12   
     13    void fmpz_to_mpz(mpz_t rop, fmpz_t op)
  • sage/misc/explain_pickle.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/misc/explain_pickle.py
    a b  
    1717    pg_make_integer = unpickle_global('sage.rings.integer', 'make_integer')
    1818    pg_make_integer('c1p')
    1919    sage: explain_pickle(dumps(polygen(QQ)))
    20     pg_Polynomial_rational_dense = unpickle_global('sage.rings.polynomial.polynomial_element_generic', 'Polynomial_rational_dense')
     20    pg_Polynomial_rational_flint = unpickle_global('sage.rings.polynomial.polynomial_rational_flint', 'Polynomial_rational_flint')
    2121    pg_PolynomialRing = unpickle_global('sage.rings.polynomial.polynomial_ring_constructor', 'PolynomialRing')
    2222    pg_RationalField = unpickle_global('sage.rings.rational_field', 'RationalField')
    2323    pg = unpickle_instantiate(pg_RationalField, ())
    2424    pg_make_rational = unpickle_global('sage.rings.rational', 'make_rational')
    25     pg_Polynomial_rational_dense(pg_PolynomialRing(pg, 'x', None, False), [pg_make_rational('0'), pg_make_rational('1')], False, True)
     25    pg_Polynomial_rational_flint(pg_PolynomialRing(pg, 'x', None, False), [pg_make_rational('0'), pg_make_rational('1')], False, True)
    2626    sage: sage_eval(explain_pickle(dumps(polygen(QQ)))) == polygen(QQ)
    2727    True
    2828
     
    3939    from sage.rings.integer import make_integer
    4040    make_integer('c1p')
    4141    sage: explain_pickle(dumps(polygen(QQ)), in_current_sage=True)
    42     from sage.rings.polynomial.polynomial_element_generic import Polynomial_rational_dense
     42    from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
    4343    from sage.rings.rational import make_rational
    44     Polynomial_rational_dense(PolynomialRing(RationalField(), 'x', None, False), [make_rational('0'), make_rational('1')], False, True)
     44    Polynomial_rational_flint(PolynomialRing(RationalField(), 'x', None, False), [make_rational('0'), make_rational('1')], False, True)
    4545
    4646The explain_pickle function has several use cases.
    4747
  • sage/rings/arith.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/arith.py
    a b  
    14761476        2*X^3 + 4*X^2
    14771477        sage: R.<X>=QQ[]
    14781478        sage: __LCM_sequence(Sequence((2*X+4,2*X^2,2)))
    1479         4*X^3 + 8*X^2
     1479        X^3 + 2*X^2
    14801480    """
    14811481    if len(v) == 0:
    14821482        return ZZ(1)
  • sage/rings/complex_field.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/complex_field.py
    a b  
    123123        sage: C(S.gen())
    124124        Traceback (most recent call last):
    125125        ...
    126         TypeError: unable to coerce to a ComplexNumber: <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
     126        TypeError: unable to coerce to a ComplexNumber: <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
    127127   
    128128    This illustrates precision.
    129129   
  • sage/rings/polynomial/polynomial_element.pyx

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/polynomial/polynomial_element.pyx
    a b  
    14361436       
    14371437        EXAMPLES::
    14381438       
    1439             sage: x = polygen(QQ)
     1439            sage: R.<x> = PolynomialRing(QQ, implementation="FLINT")
    14401440            sage: f = x^3+2/3*x^2 - 5/3
    14411441            sage: f._repr_()
    14421442            'x^3 + 2/3*x^2 - 5/3'
    14431443            sage: f.rename('vaughn')
    1444             sage: f
    1445             vaughn
     1444            Traceback (most recent call last):
     1445            ...
     1446            NotImplementedError: object does not support renaming: x^3 + 2/3*x^2 - 5/3
    14461447        """
    14471448        return self._repr()
    14481449
     
    20152016
    20162017        Note that some subclasses may implement their own
    20172018        denominator function. For example, see
    2018         :class:`sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense`
     2019        :class:`sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint`
    20192020
    20202021        .. warning::
    20212022
     
    20792080
    20802081        Note that some subclases may implement its own numerator
    20812082        function. For example, see
    2082         :class:`sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense`
     2083        :class:`sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint`
    20832084
    20842085        .. warning::
    20852086
     
    49074908    def is_irreducible(self):
    49084909        """
    49094910        Return True precisely if this polynomial is irreducible over its
    4910         base ring. Testing irreducibility over
    4911         `\ZZ/n\ZZ` for composite `n` is not
     4911        base ring.
     4912
     4913        Testing irreducibility over `\ZZ/n\ZZ` for composite `n` is not
    49124914        implemented.
    4913        
    4914         The function returns False for polynomials which are units,
    4915         and raises an exception for the zero polynomial.
    49164915
    49174916        EXAMPLES::
    49184917       
     
    49244923            sage: (x^3 + 2).is_irreducible()
    49254924            True
    49264925            sage: R(0).is_irreducible()
    4927             Traceback (most recent call last):
    4928             ...
    4929             ValueError: self must be nonzero
    4930        
    4931         See \#5140:
     4926            False
     4927       
     4928        See \#5140,
     4929       
     4930        ::
     4931       
    49324932            sage: R(1).is_irreducible()
    49334933            False
    49344934            sage: R(4).is_irreducible()
     
    49364936            sage: R(5).is_irreducible()
    49374937            True
    49384938
    4939         The base ring does matter: for example, 2x is irreducible as a
    4940         polynomial in QQ[x], but not in ZZ[x]:
     4939        The base ring does matter:  for example, 2x is irreducible as a
     4940        polynomial in QQ[x], but not in ZZ[x],
     4941       
     4942        ::
    49414943       
    49424944            sage: R.<x> = ZZ[]
    49434945            sage: R(2*x).is_irreducible()
     
    49584960            True
    49594961        """
    49604962        if self.is_zero():
    4961             raise ValueError, "self must be nonzero"
     4963            return False
    49624964        if self.is_unit():
    49634965            return False
    49644966        if self.degree() == 0:
  • sage/rings/polynomial/polynomial_element_generic.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/polynomial/polynomial_element_generic.py
    a b  
    604604    def __init__(self, parent, x=None, check=True, is_gen = False, construct=False):
    605605        Polynomial_generic_dense.__init__(self, parent, x, check, is_gen)
    606606
     607############################################################################
     608# XXX:  Ensures that the generic polynomials implemented in SAGE via PARI  #
     609# until at least until 4.5.0 unpickle correctly as polynomials implemented #
     610# via FLINT.                                                               #
     611from sage.structure.sage_object import register_unpickle_override
     612from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
    607613
    608 class Polynomial_rational_dense(Polynomial_generic_field):
    609     """
    610     A dense polynomial over the rational numbers.
    611     """
    612     def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
    613         Polynomial.__init__(self, parent, is_gen=is_gen)
    614 
    615         if construct:
    616             self.__poly = x
    617             return
    618 
    619         self.__poly = pari([]).Polrev()
    620 
    621         if x is None:
    622             return         # leave initialized to 0 polynomial.
    623 
    624 
    625         if fraction_field_element.is_FractionFieldElement(x):
    626             if not x.denominator().is_unit():
    627                 raise TypeError, "denominator must be a unit"
    628             elif x.denominator() != 1:
    629                 x = x.numerator() * x.denominator().inverse_of_unit()
    630             else:
    631                 x = x.numerator()
    632        
    633         if isinstance(x, Polynomial):
    634             if x.parent() == self.parent():
    635                 from copy import copy
    636                 self.__poly = copy(x.__poly)
    637                 return
    638             else:
    639                 x = [QQ(a) for a in x.list()]
    640                 check = False
    641 
    642         elif isinstance(x, dict):
    643             x = self._dict_to_list(x, QQ(0))
    644            
    645            
    646         elif isinstance(x, pari_gen):
    647             f = x.Polrev()
    648             self.__poly = f
    649             assert self.__poly.type() == "t_POL"           
    650             return
    651            
    652         elif not isinstance(x, list):
    653             x = [x]   # constant polynomials
    654 
    655         if check:
    656             x = [QQ(z) for z in x]
    657 
    658         self.__list = list(x)
    659         while len(self.__list) > 0 and not self.__list[-1]:
    660             del self.__list[-1]
    661        
    662         # NOTE: It is much faster to convert to string and let pari's parser at it,
    663         # which is why we pass str(x) in.
    664         self.__poly = pari(str(x)).Polrev()
    665         assert self.__poly.type() == "t_POL"
    666 
    667     def _repr(self, name=None):
    668         if name is None:
    669             name = self.parent().variable_name()
    670         return str(self.__poly).replace("x", name)
    671 
    672     def _repr_(self):
    673         return self._repr()
    674 
    675     def __reduce__(self):
    676         return Polynomial_rational_dense, \
    677                (self.parent(), self.list(), False, self.is_gen())
    678        
    679     def __getitem__(self, n):
    680         return QQ(self.__poly[n])
    681 
    682     def __getslice__(self, i, j):
    683         if i < 0:
    684             i = 0
    685         v = [QQ(x) for x in self.__poly[i:j]]
    686         P = self.parent()
    687         return P([0]*int(i) + v)
    688 
    689     def _pow(self, n):
    690         if self.degree() <= 0:
    691             return self.parent()(self[0]**n)
    692         if n < 0:
    693             return (~self)**(-n)
    694         return Polynomial_rational_dense(self.parent(), self.__poly**n, construct=True)
    695      
    696     def _add_(self, right):
    697         return Polynomial_rational_dense(self.parent(),
    698                                          self.__poly + right.__poly, construct=True)
    699 
    700     def is_irreducible(self):
    701         """
    702         EXAMPLES::
    703 
    704             sage: R.<x> = QQ[]
    705             sage: (x^2 + 2).is_irreducible()
    706             True
    707             sage: (x^2 - 1).is_irreducible()
    708             False
    709 
    710         See trac #5140::
    711 
    712             sage: (2*x).is_irreducible()
    713             True
    714 
    715         TESTS::
    716             sage: R(0).is_irreducible()
    717             Traceback (most recent call last):
    718             ...
    719             ValueError: must be nonzero
    720         """
    721         if self.is_zero():
    722             raise ValueError, "must be nonzero"
    723         S = PolynomialRing(ZZ, self.variable_name())
    724         f = S(self.denominator()*self)
    725         f //= f.content()
    726         return f.is_irreducible()
    727 
    728     def galois_group(self, pari_group=False, algorithm='pari'):
    729         r"""
    730         Return the Galois group of f as a permutation group.
    731 
    732         INPUT:
    733 
    734         - ``self`` -- an irreducible polynomial
    735            
    736         - ``pari_group`` -- bool (default: False); if True instead return the
    737           Galois group as a PARI group.  This has a useful label in it, and may
    738           be slightly faster since it doesn't require looking up a group in
    739           Gap.  To get a permutation group from a PARI group P, type
    740           ``PermutationGroup(P)``.
    741 
    742         - ``algorithm`` -- ``'pari'``, ``'kash'``, ``'magma'`` (default: ``'pari'``,
    743           except when the degree is `\ge 12` when ``'kash'`` is tried). NOTE:
    744           ``'magma'`` also does not return a proven correct result.  Please see
    745           the Magma docs for how to get a proven result.
    746 
    747         ALGORITHM: The Galois group is computed using PARI in C library mode,
    748         or possibly kash or magma.
    749 
    750         .. note::
    751        
    752             The PARI documentation contains the following warning: The method
    753             used is that of resolvent polynomials and is sensitive to the
    754             current precision. The precision is updated internally but, in very
    755             rare cases, a wrong result may be returned if the initial precision
    756             was not sufficient.
    757 
    758         EXAMPLES::
    759 
    760             sage: R.<x> = PolynomialRing(QQ)
    761             sage: f = x^4 - 17*x^3 - 2*x + 1
    762             sage: G = f.galois_group(); G            # optional - database_gap
    763             Transitive group number 5 of degree 4
    764             sage: G.gens()                           # optional - database_gap
    765             [(1,2,3,4), (1,2)]
    766             sage: G.order()                          # optional - database_gap
    767             24
    768 
    769         It is potentially useful to instead obtain the corresponding
    770         PARI group, which is little more than a 4-tuple.  See the
    771         PARI manual for the exact details.  (Note that the third
    772         entry in the tuple is in the new standard ordering.)
    773        
    774         ::
    775 
    776             sage: f = x^4 - 17*x^3 - 2*x + 1
    777             sage: G = f.galois_group(pari_group=True); G
    778             PARI group [24, -1, 5, "S4"] of degree 4
    779             sage: PermutationGroup(G)                # optional - database_gap
    780             Transitive group number 5 of degree 4
    781 
    782         You can use KASH to compute Galois groups as well.  The
    783         advantage is that KASH can compute Galois groups of fields up
    784         to degree 23, whereas PARI only goes to degree 11.  (In my
    785         not-so-thorough experiments PARI is faster than KASH.)
    786 
    787         ::
    788 
    789             sage: f = x^4 - 17*x^3 - 2*x + 1
    790             sage: f.galois_group(algorithm='kash')      # optional - kash
    791             Transitive group number 5 of degree 4
    792        
    793             sage: f = x^4 - 17*x^3 - 2*x + 1
    794             sage: f.galois_group(algorithm='magma')     # optional - magma, database_gap
    795             Transitive group number 5 of degree 4
    796         """
    797         from sage.groups.all import PariGroup, PermutationGroup, TransitiveGroup
    798 
    799         if not self.is_irreducible():
    800             raise ValueError, "polynomial must be irreducible"
    801        
    802         if self.degree() > 11 and algorithm=='pari':
    803             algorithm = 'kash'
    804 
    805         if algorithm == 'kash':
    806             try:
    807                 from sage.interfaces.all import kash
    808                 kash.eval('X := PolynomialRing(RationalField()).1')
    809                 s = self._repr(name='X')
    810                 G = kash('Galois(%s)'%s)
    811                 d = int(kash.eval('%s.ext1'%G.name()))
    812                 n = int(kash.eval('%s.ext2'%G.name()))
    813                 return TransitiveGroup(d, n)
    814             except RuntimeError, msg:
    815                 raise NotImplementedError, str(msg) + "\nSorry, computation of Galois groups of fields of degree bigger than 11 is not yet implemented.  Try installing the optional free (closed source) KASH package, which supports larger degrees, or use algorithm='magma' if you have magma."
    816         elif algorithm == 'magma':
    817             from sage.interfaces.all import magma
    818             X = magma(self).GaloisGroup()
    819             try:
    820                 n, d = X.TransitiveGroupIdentification(nvals=2)
    821                 d = int(d)
    822                 n = int(n)
    823             except RuntimeError, msg:
    824                 raise RuntimeError, str(msg) + "\nUnable to lookup description of Galois group as a transitive group.\n%s"%X
    825             return TransitiveGroup(d, n)
    826            
    827         G = self.__poly.polgalois()
    828         H = PariGroup(G, self.degree())
    829         if pari_group:
    830             return H
    831         else:
    832             return PermutationGroup(H)
    833 
    834     @coerce_binop
    835     def quo_rem(self, right):
    836         """
    837         Returns a tuple (quotient, remainder) where
    838         self = quotient*right + remainder.
    839 
    840         EXAMPLES::
    841 
    842             sage: R.<x> = QQ[]
    843             sage: f = x^5 + 17*x + 3
    844             sage: g = x^3 - 19
    845             sage: q,r = f.quo_rem(g)
    846             sage: q*g + r
    847             x^5 + 17*x + 3       
    848         """
    849         v = self.__poly.divrem(right.__poly)
    850         return Polynomial_rational_dense(self.parent(), v[0], construct=True), \
    851                Polynomial_rational_dense(self.parent(), v[1], construct=True)
    852        
    853                                    
    854     def _mul_(self, right):
    855         """
    856         EXAMPLES::
    857 
    858             sage: R.<x> = QQ[]
    859             sage: (x - QQ('2/3'))*(x^2 - 8*x + 16)
    860             x^3 - 26/3*x^2 + 64/3*x - 32/3
    861         """
    862         return self.parent()(self.__poly * right.__poly, construct=True)       
    863 
    864     def _sub_(self, right):
    865         """
    866         EXAMPLES::
    867 
    868             sage: R.<x> = QQ[]
    869             sage: x^5 + 17*x^3 + x+ 3 - (x^3 - 19)
    870             x^5 + 16*x^3 + x + 22
    871         """
    872         return self.parent()(self.__poly - right.__poly, construct=True)
    873                                
    874     def _unsafe_mutate(self, n, value):
    875         try:
    876             del self.__list
    877         except AttributeError:
    878             pass
    879         n = int(n)
    880         if n < 0:
    881             raise IndexError, "n must be >= 0"
    882         if n <= self.__poly.poldegree():
    883             self.__poly[n] = QQ(value)
    884         else:
    885             self.__poly = self.__poly + pari('(%s)*x^%s'%(QQ(value),n))
    886         if hasattr(self, "__list"):
    887             del self.__list
    888      
    889 
    890     def real_root_intervals(self):
    891         """
    892         Returns isolating intervals for the real roots of this polynomial.
    893 
    894         EXAMPLE::
    895 
    896             sage: R.<x> = PolynomialRing(QQ)
    897             sage: f = (x - 1/2) * (x - 3/4) * (x - 3/2)
    898             sage: f.real_root_intervals()
    899             [((243/512, 1215/2048), 1), ((729/1024, 1701/2048), 1), ((243/256, 1011/512), 1)]
    900         """
    901 
    902         from sage.rings.polynomial.real_roots import real_roots
    903 
    904         return real_roots(self)
    905 
    906     def __copy__(self):
    907         """
    908         Return a copy of this polynomial.
    909         """
    910         f = Polynomial_rational_dense(self.parent())
    911         from copy import copy
    912         f.__poly = copy(self.__poly)
    913         return f
    914        
    915     def degree(self, gen=None):
    916         """
    917         Return the degree of this polynomial. The zero polynomial
    918         has degree -1.
    919 
    920         EXAMPLES::
    921 
    922             sage: R.<x> = QQ[]
    923             sage: (x^5 + 17*x^3 + x+ 3).degree()
    924             5
    925             sage: R(0).degree()
    926             -1
    927             sage: type(x.degree())
    928             <type 'sage.rings.integer.Integer'>
    929         """
    930         return ZZ(max(self.__poly.poldegree(), -1))
    931 
    932     def discriminant(self):
    933         """
    934         EXAMPLES::
    935 
    936             sage: _.<x> = PolynomialRing(QQ)
    937             sage: f = x^3 + 3*x - 17
    938             sage: f.discriminant()
    939             -7911
    940         """
    941         return QQ(self.__poly.poldisc())
    942 
    943     def disc(self):
    944         """
    945         Same as :meth:`.discriminant`.
    946 
    947         EXAMPLES::
    948 
    949             sage: _.<x> = PolynomialRing(QQ)
    950             sage: f = x^3 + 3*x - 17
    951             sage: f.disc()
    952             -7911
    953         """
    954         return self.discriminant()
    955        
    956     def numerator(self):
    957         """
    958         Returns the numerator of self as a polynomial in `\ZZ[x]`.
    959        
    960         EXAMPLES::
    961 
    962             sage: R.<x> = QQ[]
    963             sage: (x/2).numerator()
    964             x
    965             sage: (x + 1/2).numerator()
    966             2*x + 1
    967             sage: (x^2/12 - 1/15).numerator()
    968             5*x^2 - 4
    969             sage: f = R.random_element(60)
    970             sage: f.numerator() in ZZ['x']
    971             True
    972             sage: f.numerator() / f.denominator() == f
    973             True
    974         """
    975         return ZZ[self.variable_name()](self.denominator() * self)
    976        
    977     def denominator(self):
    978         """
    979         Returns the denominator of self as an element of `\ZZ`.
    980        
    981         EXAMPLES::
    982 
    983             sage: R.<x> = QQ[]
    984             sage: (x/2).denominator()
    985             2
    986             sage: (x/2 + 1/3).denominator()
    987             6
    988             sage: R.<x> = QQ[]
    989             sage: f = R.random_element(50)
    990             sage: f * f.denominator() in ZZ['x']
    991             True
    992         """
    993         return integer.LCM_list([a.denominator() for a in self])
    994      
    995     def factor_mod(self, p):
    996         """
    997         Return the factorization of self modulo the prime p.
    998 
    999         INPUT:
    1000 
    1001         - ``p`` -- prime
    1002 
    1003         OUTPUT:
    1004        
    1005         factorization of self reduced modulo p.
    1006 
    1007         EXAMPLES::
    1008 
    1009             sage: R.<x> = QQ[]
    1010             sage: (x^5 + 17*x^3 + x+ 3).factor_mod(3)
    1011             x * (x^2 + 1)^2
    1012             sage: (x^5 + 2).factor_mod(5)
    1013             (x + 2)^5       
    1014         """
    1015         import sage.rings.finite_rings.constructor as finite_field
    1016         p = integer.Integer(p)
    1017         if not p.is_prime():
    1018             raise ValueError, "p must be prime"
    1019         G = self._pari_().factormod(p)
    1020         K = finite_field.FiniteField(p)
    1021         R = K[self.parent().variable_name()]
    1022         return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
    1023 
    1024     def factor_padic(self, p, prec=10):
    1025         """
    1026         Return p-adic factorization of self to given precision.
    1027 
    1028         INPUT:
    1029 
    1030         - p -- prime
    1031         - prec -- integer; the precision
    1032 
    1033         OUTPUT:
    1034 
    1035         factorization of self viewed as a polynomial over the p-adics
    1036 
    1037         EXAMPLES::
    1038 
    1039             sage: R.<x> = QQ[]
    1040             sage: f = x^3 - 2
    1041             sage: f.factor_padic(2)
    1042             (1 + O(2^10))*x^3 + (O(2^10))*x^2 + (O(2^10))*x + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10))
    1043             sage: f.factor_padic(3)
    1044             (1 + O(3^10))*x^3 + (O(3^10))*x^2 + (O(3^10))*x + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10))
    1045             sage: f.factor_padic(5)
    1046             ((1 + O(5^10))*x + (2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))) * ((1 + O(5^10))*x^2 + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x + (4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10)))
    1047         """
    1048         from sage.rings.padics.factory import Qp
    1049         p = integer.Integer(p)
    1050         if not p.is_prime():
    1051             raise ValueError, "p must be prime"
    1052         prec = integer.Integer(prec)
    1053         if prec <= 0:
    1054             raise ValueError, "prec must be positive"
    1055         K = Qp(p, prec, type='capped-rel')
    1056         R = K[self.parent().variable_name()]
    1057         return R(self).factor() # absprec = prec)
    1058 
    1059     def list(self):
    1060         """
    1061         Return a new copy of the list of the underlying
    1062         elements of self.
    1063 
    1064         EXAMPLES::
    1065 
    1066             sage: _.<x> = PolynomialRing(QQ)
    1067             sage: f = x^3 + 3*x - 17/13; f
    1068             x^3 + 3*x - 17/13
    1069             sage: v = f.list(); v
    1070             [-17/13, 3, 0, 1]
    1071             sage: v[0] = 0
    1072             sage: f
    1073             x^3 + 3*x - 17/13
    1074             sage: f.list()
    1075             [-17/13, 3, 0, 1]           
    1076         """
    1077         return [QQ(x) for x in self.__poly.Vecrev()]
    1078 
    1079    
    1080 
    1081 ##     def partial_fraction(self, g):
    1082 ##         """
    1083 ##         Return partial fraction decomposition of self/g, where g
    1084 ##         has the same parent as self.
    1085 ##         """
    1086 ##         g = self.parent()(g)
    1087 ##         from sage.interfaces.maxima import maxima
    1088 ##         h = maxima(self)/maxima(g)
    1089 ##         k = h.partfrac(self.parent().variable())
    1090 
    1091     def rescale(self, a):
    1092         """
    1093         Return `f(a*X)`.
    1094         """
    1095         b = 1
    1096         c = []
    1097         for i in range(self.degree()+1):
    1098             c.append(b*self[i])
    1099             b *= a
    1100         return self.parent()(c)
    1101 
    1102     def hensel_lift(self, p, e):
    1103         """
    1104         Assuming that self factors modulo `p` into distinct factors,
    1105         computes the Hensel lifts of these factors modulo `p^e`.  We
    1106         assume that `p` has integer coefficients.
    1107         """
    1108         p = integer.Integer(p)
    1109         if not p.is_prime():
    1110             raise ValueError, "p must be prime"
    1111         e = integer.Integer(e)
    1112         if e < 1:
    1113             raise ValueError, "e must be at least 1"
    1114         F = self.factor_mod(p)
    1115         y = []
    1116         for g, n in F:
    1117             if n > 1:
    1118                 raise ArithmeticError, "The polynomial must be square free modulo p."
    1119             y.append(g)
    1120         H = self._pari_().polhensellift(y, p, e)
    1121         from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
    1122         R = IntegerModRing(p**e)
    1123         S = R[self.parent().variable_name()]
    1124         return [S(eval(str(m.Vec().Polrev().Vec()))) for m in H]
     614register_unpickle_override( \
     615    'sage.rings.polynomial.polynomial_element_generic', \
     616    'Polynomial_rational_dense', Polynomial_rational_flint)
    1125617
    1126618class Polynomial_padic_generic_dense(Polynomial_generic_dense, Polynomial_generic_domain):
    1127619    def __init__(self, parent, x=None, check=True, is_gen = False, construct=False, absprec=None):
  • new file sage/rings/polynomial/polynomial_rational_flint.pxd

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/polynomial/polynomial_rational_flint.pxd
    - +  
     1###############################################################################
     2#          Copyright (C) 2010 Sebastian Pancratz <sfp@pancratz.org>           #
     3#                                                                             #
     4#     Distributed under the terms of the GNU General Public License (GPL)     #
     5#                                                                             #
     6#                        http://www.gnu.org/licenses/                         #
     7###############################################################################
     8
     9include "../../ext/cdefs.pxi"
     10include "../../libs/flint/fmpz.pxi"
     11include "../../libs/flint/fmpz_poly.pxi"
     12include "../../libs/flint/fmpq_poly.pxd"
     13
     14from sage.rings.polynomial.polynomial_element cimport Polynomial
     15
     16cdef class Polynomial_rational_flint(Polynomial):
     17    cdef fmpq_poly_t __poly
     18
     19    cdef Polynomial_rational_flint _new(self)
     20    cpdef _unsafe_mutate(self, unsigned long n, value)
     21    cpdef Polynomial truncate(self, long n)
     22
  • new file sage/rings/polynomial/polynomial_rational_flint.pyx

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/polynomial/polynomial_rational_flint.pyx
    - +  
     1r"""
     2Univariate polynomials over `\QQ` implemented via FLINT
     3
     4AUTHOR:
     5
     6- Sebastian Pancratz
     7"""
     8
     9###############################################################################
     10#          Copyright (C) 2010 Sebastian Pancratz <sfp@pancratz.org>           #
     11#                                                                             #
     12#     Distributed under the terms of the GNU General Public License (GPL)     #
     13#                                                                             #
     14#                        http://www.gnu.org/licenses/                         #
     15###############################################################################
     16
     17include "../../ext/stdsage.pxi"
     18include "../../ext/interrupt.pxi"
     19include "../../ext/gmp.pxi"
     20include "../../libs/ntl/decl.pxi"
     21
     22include "../../ext/cdefs.pxi"
     23include "../../libs/flint/fmpz.pxi"
     24include "../../libs/flint/fmpz_poly.pxi"
     25include "../../libs/flint/fmpq_poly.pxd"
     26
     27from sage.interfaces.all import singular as singular_default
     28
     29from sage.libs.all import pari, pari_gen
     30from sage.libs.flint.ntl_interface cimport *
     31from sage.libs.flint.fmpz_poly cimport fmpz_poly_set
     32
     33from sage.rings.integer cimport Integer
     34from sage.rings.integer_ring import ZZ
     35from sage.rings.fraction_field_element import FractionFieldElement
     36from sage.rings.rational cimport Rational
     37from sage.rings.rational_field import QQ
     38from sage.rings.polynomial.polynomial_element cimport Polynomial
     39from sage.rings.polynomial.polynomial_element import is_Polynomial
     40from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
     41
     42from sage.structure.element cimport Element, ModuleElement, RingElement
     43from sage.structure.element import coerce_binop
     44from sage.structure.factorization import Factorization
     45
     46
     47cdef inline bint _do_sig(fmpq_poly_t op):
     48    """
     49    Returns 1 when signal handling should be carried out for an operation
     50    on this polynomial and 0 otherwise.
     51
     52    Strictly speaking, whether or not signal handling should be carried
     53    ought to depend on the operation as well as the operands in question.
     54    For simplicity we carry out signal handling for all but the simplest
     55    of operands regardless of the operation.
     56
     57    TESTS::
     58
     59        sage: R.<t> = QQ[]
     60        sage: f = 1 + t/2
     61        sage: g = 2/3 + t^2
     62        sage: _ = f * g      # indirect doctest
     63    """
     64    return fmpz_poly_max_limbs(fmpq_poly_numref(op)) > 1 \
     65                                                 or fmpq_poly_degree(op) > 1000
     66
     67cdef class Polynomial_rational_flint(Polynomial):
     68    """
     69    Univariate polynomials over the rationals, implemented via FLINT.
     70   
     71    Internally, we represent rational polynomial as the quotient of an integer
     72    polynomial and a positive denominator which is coprime to the content of
     73    the numerator.
     74   
     75    The implementation is based on the C module fmpq_poly written on top of
     76    FLINT 1.
     77    """
     78
     79    ###########################################################################
     80    # Allocation & initialisation                                             #
     81    ###########################################################################
     82   
     83    cdef Polynomial_rational_flint _new(self):
     84        """
     85        Quickly creates a new polynomial object in this class.
     86       
     87        OUTPUT:
     88       
     89        - Polynomial of type Polynomial_rational_flint
     90       
     91        TESTS::
     92       
     93            sage: R.<t> = QQ[]
     94            sage: f = 2/3*t^2
     95            sage: g = -1/2*t + 2
     96            sage: f + g           # indirect doctest
     97            2/3*t^2 - 1/2*t + 2
     98        """
     99        cdef Polynomial_rational_flint res = PY_NEW(Polynomial_rational_flint)
     100        res._parent = self._parent
     101        res._is_gen = 0
     102        return res
     103
     104    def __cinit__(self):
     105        """
     106        Initialises the underlying data structure.
     107       
     108        TESTS::
     109       
     110            sage: R.<t> = QQ[]
     111            sage: f = 2/3 * t - 7  #indirect doctest
     112        """
     113        fmpq_poly_init(self.__poly)
     114
     115    def __dealloc__(self):
     116        """
     117        Deallocates the underlying data structure.
     118       
     119        TESTS::
     120       
     121            sage: R.<t> = QQ[]
     122            sage: f = 1/3 * t
     123            sage: del f        # untested
     124        """
     125        fmpq_poly_clear(self.__poly)
     126
     127    def __init__(self, parent, x=None, check=True, is_gen=False, construct=False):
     128        """
     129        Initialises the associated data for the polynomial self.
     130       
     131        INPUT:
     132       
     133        - ``parent`` - Polynomial ring, the parent of self
     134        - ``x`` - Data for the new polynomial self, e.g. a polynomial, an
     135          integer, a rational, a list of rationals, a dictionary with keys
     136          the degrees and the rational coefficients, etc (default: ``None``)
     137        - `check`` - Whether the integrity of the data needs to be verified,
     138          largely ignored by this method (default: ``True``)
     139        - ``is_gen`` - Whether self shall be initialised as the generator of
     140          the parent polynomial ring
     141        - ``construct`` - Whether the element shall always be constructed
     142          as an independent copy of any input data (default: ``False``)
     143       
     144        TESTS::
     145       
     146            sage: R.<t> = QQ[]
     147            sage: f = -4 * t^2 + 1/3 * t - 1/7  # indirect doctest
     148        """
     149        cdef long deg
     150        cdef unsigned long n
     151        cdef Rational c
     152        cdef list L1
     153        cdef mpq_t * L2
     154       
     155        Polynomial.__init__(self, parent, is_gen=is_gen)
     156       
     157        if is_gen:
     158            fmpq_poly_set_coeff_si(self.__poly, 1, 1)
     159       
     160        elif PY_TYPE_CHECK(x, Polynomial_rational_flint):
     161            fmpq_poly_set(self.__poly, (<Polynomial_rational_flint> x).__poly)
     162
     163        elif PY_TYPE_CHECK(x, int):
     164            fmpq_poly_set_si(self.__poly, <int> x)
     165       
     166        elif PY_TYPE_CHECK(x, Integer):
     167            fmpq_poly_set_mpz(self.__poly, (<Integer> x).value)
     168
     169        elif PY_TYPE_CHECK(x, Rational):
     170            fmpq_poly_set_mpq(self.__poly, (<Rational> x).value)
     171
     172        elif PY_TYPE_CHECK(x, list) or PY_TYPE_CHECK(x, tuple):
     173           
     174            if len(x) == 0:
     175                return
     176            elif len(x) == 1:
     177                Polynomial_rational_flint.__init__(self, parent, x[0], \
     178                                check=check, is_gen=False, construct=construct)
     179                return
     180           
     181            L1 = [e if isinstance(e, Rational) else Rational(e) for e in x]
     182            n  = <unsigned long> len(x)
     183            _sig_on
     184            L2 = <mpq_t *> malloc(n * sizeof(mpq_t))
     185            for deg from 0 <= deg < n:
     186                mpq_init(L2[deg])
     187                mpq_set(L2[deg], (<Rational> L1[deg]).value)
     188            _fmpq_poly_from_list(self.__poly, L2, n)
     189            for deg from 0 <= deg < n:
     190                mpq_clear(L2[deg])
     191            free(L2)
     192            _sig_off
     193           
     194#           deg = 0
     195#           for e in x:
     196#               c = Rational(e)
     197#               fmpq_poly_set_coeff_mpq(self.__poly, deg, c.value)
     198#               deg += 1
     199           
     200        elif PY_TYPE_CHECK(x, dict):
     201            for deg, e in x.iteritems():
     202                c = Rational(e)
     203                fmpq_poly_set_coeff_mpq(self.__poly, deg, c.value)
     204
     205        elif PY_TYPE_CHECK(x, pari_gen):
     206            k = self._parent.base_ring()
     207            x = [k(w) for w in x.Vecrev()]
     208            Polynomial_rational_flint.__init__(self, parent, x, check=True, \
     209                                             is_gen=False, construct=construct)
     210
     211        elif PY_TYPE_CHECK(x, Polynomial):
     212            k = self._parent.base_ring()
     213            x = [k(w) for w in list(x)]
     214            Polynomial_rational_flint.__init__(self, parent, x, check=True, \
     215                                             is_gen=False, construct=construct)
     216
     217        elif PY_TYPE_CHECK(x, FractionFieldElement) and (x.parent().base() is parent or x.parent().base() == parent) and x.denominator() == 1:
     218            x = x.numerator()
     219            Polynomial_rational_flint.__init__(self, parent, x, check=check, \
     220                                            is_gen=is_gen, construct=construct)
     221
     222        else:
     223            x = parent.base_ring()(x)
     224            Polynomial_rational_flint.__init__(self, parent, x, check=check, \
     225                                            is_gen=is_gen, construct=construct)
     226   
     227    def __reduce__(self):
     228        """
     229        This is used when pickling polynomials.
     230       
     231        TESTS::
     232       
     233            sage: R.<t> = QQ[]
     234            sage: f = 2/3 * t^2 + 1
     235            sage: r = f.__reduce__(); r
     236            (<type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>, (Univariate Polynomial Ring in t over Rational Field, [1, 0, 2/3], False, False))
     237            sage: r[0](*r[1])
     238            2/3*t^2 + 1
     239            sage: loads(dumps(f)) == f
     240            True
     241        """
     242        return Polynomial_rational_flint, \
     243               (self.parent(), self.list(), False, self.is_gen())
     244
     245    def __copy__(self):
     246        """
     247        Returns a copy of self.
     248
     249        TESTS::
     250       
     251            sage: R.<t> = QQ[]
     252            sage: f = 4/5 * t^3 - 1/17
     253            sage: copy(f) == f
     254            True
     255        """
     256        cdef Polynomial_rational_flint res = self._new()
     257        fmpq_poly_set(res.__poly, self.__poly)
     258        return res
     259   
     260    def _singular_(self, singular=singular_default, have_ring=False):
     261        """
     262        Returns a Singular representation of self.
     263
     264        INPUT:
     265
     266        - ``singular`` - Singular interpreter (default: default interpreter)
     267        - ``have_ring`` - set to True if the ring was already set in Singular
     268
     269        EXAMPLES::
     270
     271            sage: P.<x> = PolynomialRing(QQ)
     272            sage: f = 3*x^2 + 2*x + 5
     273            sage: singular(f)
     274            3*x^2+2*x+5
     275        """
     276        if not have_ring:
     277            self._parent._singular_(singular).set_ring()  # Expensive!
     278        return singular(self._singular_init_())
     279
     280    def list(self):
     281        """
     282        Returns a list with the coefficients of self.
     283
     284        EXAMPLES::
     285
     286            sage: R.<t> = QQ[]
     287            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     288            sage: f.list()
     289            [1, 1, 1/2, 1/3, 1/4]
     290            sage: g = R(0)
     291            sage: g.list()
     292            []
     293        """
     294        cdef unsigned long length = fmpq_poly_length(self.__poly)
     295        return [self[n] for n in range(length)]
     296
     297    ###########################################################################
     298    # Basis access                                                            #
     299    ###########################################################################
     300
     301    def degree(self):
     302        """
     303        Returns the degree of self.
     304       
     305        By convention, the degree of the zero polynomial is -1.
     306       
     307        EXAMPLES::
     308       
     309            sage: R.<t> = QQ[]
     310            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     311            sage: f.degree()
     312            4
     313            sage: g = R(0)
     314            sage: g.degree()
     315            -1
     316        """
     317        cdef Integer deg = PY_NEW(Integer)
     318        mpz_set_si(deg.value, fmpq_poly_degree(self.__poly))
     319        return deg
     320
     321    def __getitem__(self, long n):
     322        """
     323        Returns the `n`th coefficient of self.
     324       
     325        INPUT:
     326       
     327        - ``n`` - Degree of the monomial whose coefficient is to be returned
     328       
     329        EXAMPLES::
     330           
     331            sage: R.<t> = QQ[]
     332            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     333            sage: f[-1], f[0], f[3], f[5]            # indirect doctest
     334            (0, 1, 1/3, 0)
     335        """
     336        cdef Rational z = PY_NEW(Rational)
     337        if 0 <= n and n < fmpq_poly_length(self.__poly):
     338            fmpq_poly_get_coeff_mpq(z.value, self.__poly, n)
     339        return z
     340
     341    def __getslice__(self, long i, long j):
     342        """
     343        Returns the subpolynomial of self from the `i`th to the `j`th
     344        coefficient, where the lower bound is inclusive and the upper bound
     345        is exclusive.
     346       
     347        INPUT:
     348       
     349        - ``i`` - Lower index for the slice
     350        - ``j`` - Upper index for the slice
     351       
     352        EXAMPLES::
     353       
     354            sage: R.<t> = QQ[]
     355            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     356            sage: f[1:3]                             # indirect doctest
     357            1/2*t^2 + t
     358        """
     359        cdef Polynomial_rational_flint res = self._new()
     360        cdef bint do_sig = _do_sig(self.__poly)
     361       
     362        if do_sig: _sig_on
     363        fmpq_poly_getslice(res.__poly, self.__poly, i, j)
     364        if do_sig: _sig_off
     365        return res
     366
     367    cpdef _unsafe_mutate(self, unsigned long n, value):
     368        """
     369        Sets the `n`th coefficient of self to value.
     370       
     371        TESTS::
     372       
     373            sage: R.<t> = QQ[]
     374            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     375            sage: f._unsafe_mutate(4, 1/5)
     376            sage: f
     377            1/5*t^4 + 1/3*t^3 + 1/2*t^2 + t + 1
     378       
     379        WARNING:
     380       
     381        Polynomials in Sage are meant to be immutable, and some methods may
     382        rely on this convention.  This method should be used only with the
     383        utmost care.
     384        """
     385        cdef bint do_sig = _do_sig(self.__poly)
     386       
     387        if PY_TYPE_CHECK(value, int):
     388            if do_sig: _sig_on
     389            fmpq_poly_set_coeff_si(self.__poly, n, value)
     390            if do_sig: _sig_off
     391        elif PY_TYPE_CHECK(value, Integer):
     392            if do_sig: _sig_on
     393            fmpq_poly_set_coeff_mpz(self.__poly, n, (<Integer> value).value)
     394            if do_sig: _sig_off
     395        elif PY_TYPE_CHECK(value, Rational):
     396            if do_sig: _sig_on
     397            fmpq_poly_set_coeff_mpq(self.__poly, n, (<Rational> value).value)
     398            if do_sig: _sig_off
     399        else:
     400            value = Rational(value)
     401            if do_sig: _sig_on
     402            fmpq_poly_set_coeff_mpq(self.__poly, n, (<Rational> value).value)
     403            if do_sig: _sig_off
     404
     405    def __call__(self, *x, **kwds):
     406        """
     407        Calls this polynomial with the given parameters, which can be
     408        interpreted as polynomial composition or evaluation by this
     409        method.
     410
     411        If the argument is not simply an integer, a rational, or a
     412        polynomial, the call is passed on to the generic implementation
     413        in the Polynomial class.
     414       
     415        EXAMPLES:
     416
     417        The first example illustrates polynomial composition::
     418       
     419            sage: R.<t> = QQ[]
     420            sage: f = t^2 - 1
     421            sage: g = t + 1
     422            sage: f(g)          # indirect doctest
     423            t^2 + 2*t
     424               
     425        Now we illustrate how a polynomial can be evaluated at a rational
     426        number::
     427       
     428            sage: f(-2/3)       # indirect doctest
     429            -5/9
     430        """
     431        cdef Polynomial_rational_flint f
     432        cdef Rational r
     433       
     434        if len(x) == 1:
     435            a = x[0]
     436            if isinstance(a, Polynomial_rational_flint):
     437                f = (<Polynomial_rational_flint> a)._new()
     438                _sig_on
     439                fmpq_poly_compose(f.__poly, self.__poly, \
     440                    (<Polynomial_rational_flint> a).__poly)
     441                _sig_off
     442                return f
     443            if isinstance(a, Rational):
     444                r = PY_NEW(Rational)
     445                _sig_on
     446                fmpq_poly_evaluate_mpq(r.value, self.__poly, (<Rational> a).value)
     447                _sig_off
     448                return r
     449            if isinstance(a, Integer):
     450                r = PY_NEW(Rational)
     451                _sig_on
     452                fmpq_poly_evaluate_mpz(r.value, self.__poly, (<Integer> a).value)
     453                _sig_off
     454                return r
     455
     456        return Polynomial.__call__(self, *x, **kwds)
     457
     458    cpdef Polynomial truncate(self, long n):
     459        """
     460        Returns self truncated modulo `t^n`.
     461       
     462        INPUT:
     463       
     464        - ``n`` - The power of `t` modulo which self is truncated
     465       
     466        EXAMPLES::
     467       
     468            sage: R.<t> = QQ[]
     469            sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
     470            sage: f.truncate(0)
     471            0
     472            sage: f.truncate(2)
     473            -t + 1
     474        """
     475        cdef Polynomial_rational_flint res
     476        cdef bint do_sig
     477       
     478        if (n >= fmpq_poly_length(self.__poly)):
     479            return self
     480        else:
     481            res = self._new()
     482            if n > 0:
     483                do_sig = _do_sig(self.__poly)
     484                if do_sig: _sig_on
     485                fmpq_poly_truncate(res.__poly, self.__poly, n)
     486                if do_sig: _sig_off
     487            return res
     488
     489    def reverse(self, n = None):
     490        """
     491        Reverses the coefficients of self - thought of as a polynomial of
     492        length `n`.
     493       
     494        Assumes that whenever `n` is not ``None`` it is an integral value
     495        that fits into an unsigned long.  Otherwise, a ValueError is raised.
     496       
     497        INPUT:
     498       
     499        - ``n`` - Integral value that fits in an unsigned long:  the power
     500          of `t` modulo which we consider self before reversing it
     501          (default:  ``None``, interpreted as the length of self)
     502       
     503        OUTPUT:
     504       
     505        - The reversed polynomial as a Polynomial_rational_flint
     506       
     507        EXAMPLES:
     508       
     509        We first consider the simplest case, where we reverse all coefficients
     510        of a polynomial and obtain a polynomial of the same degree::
     511       
     512            sage: R.<t> = QQ[]
     513            sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4
     514            sage: f.reverse()
     515            t^4 + t^3 + 1/2*t^2 + 1/3*t + 1/4
     516       
     517        Next, an example we the returned polynomial has lower degree because
     518        the original polynomial has low coefficients equal to zero::
     519       
     520            sage: R.<t> = QQ[]
     521            sage: f = 3/4*t^2 + 6*t^7
     522            sage: f.reverse()
     523            3/4*t^5 + 6
     524       
     525        The next example illustrates the passing of a value for `n` less than
     526        the length of self, notationally resulting in truncation prior to
     527        reversing::
     528       
     529            sage: R.<t> = QQ[]
     530            sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4
     531            sage: f.reverse(3)
     532            t^2 + t + 1/2
     533       
     534        Now we illustrate the passing of a value for `n` greater than the
     535        length of self, notationally resulting in zero padding at the top
     536        end prior to reversing::
     537       
     538            sage: R.<t> = QQ[]
     539            sage: f = 1 + t + t^2 / 2 + t^3 / 3
     540            sage: f.reverse(5)
     541            t^4 + t^3 + 1/2*t^2 + 1/3*t
     542       
     543        TESTS::
     544       
     545        We illustrate two ways in which the interpretation of `n` as an
     546        unsigned long int may fail.  Firstly, an integral value which is
     547        too large, yielding an OverflowError::
     548       
     549            sage: R.<t> = QQ[]
     550            sage: f = 1 + t/2
     551            sage: f.reverse(2**64)
     552            Traceback (most recent call last):
     553            ...
     554            OverflowError: long int too large to convert
     555       
     556        Secondly, a value which cannot be converted to an integral value,
     557        resulting in a TypeError::
     558           
     559            sage: R.<t> = QQ[]
     560            sage: f = 1 + t/2
     561            sage: f.reverse(I)
     562            Traceback (most recent call last):
     563            ...
     564            TypeError: can't convert complex to int; use int(abs(z))
     565        """
     566        cdef unsigned long len
     567        cdef Polynomial_rational_flint res
     568        cdef bint do_sig
     569       
     570        if n is None:
     571            len = fmpq_poly_length(self.__poly)
     572        else:
     573            len = <unsigned long> n
     574       
     575        res = self._new()
     576        do_sig = _do_sig(self.__poly)
     577        if do_sig: _sig_on
     578        fmpq_poly_reverse(res.__poly, self.__poly, len)
     579        if do_sig: _sig_off
     580        return res
     581   
     582    ###########################################################################
     583    # Comparisons                                                             #
     584    ###########################################################################
     585
     586    def is_zero(self):
     587        """
     588        Returns whether or not self is the zero polynomial.
     589       
     590        EXAMPLES::
     591       
     592            sage: R.<t> = QQ[]
     593            sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
     594            sage: f.is_zero()
     595            False
     596            sage: R(0).is_zero()
     597            True
     598        """
     599        return bool(fmpq_poly_is_zero(self.__poly))
     600
     601    def __nonzero__(self):
     602        """
     603        Returns whether or not self is non-zero.
     604       
     605        EXAMPLES::
     606       
     607            sage: R.<t> = QQ[]
     608            sage: f = 1 - t + 1/2*t^2 - 1/3*t^3
     609            sage: bool(f)
     610            True
     611            sage: bool(R(0))
     612            False
     613        """
     614        return not fmpq_poly_is_zero(self.__poly)
     615
     616    ###########################################################################
     617    # Shifting                                                                #
     618    ###########################################################################
     619
     620    def __lshift__(self, n):
     621        """
     622        Notationally multiplies self by `t^n`.
     623       
     624        EXAMPLES::
     625       
     626            sage: R.<t> = QQ[]
     627            sage: t << 10                     # indirect doctest
     628            t^11
     629       
     630        TESTS::
     631       
     632            sage: R.<t> = QQ[]
     633            sage: f = R.random_element(1000)
     634            sage: (f << 23) >> 23 == f        # indirect doctest
     635            True
     636        """
     637        cdef unsigned long k = <unsigned long> n
     638        cdef Polynomial_rational_flint f = <Polynomial_rational_flint> self
     639        cdef Polynomial_rational_flint res
     640        cdef bint do_sig
     641       
     642        if k == 0 or fmpq_poly_is_zero(f.__poly):
     643            return self
     644        else:
     645            res = f._new()
     646            do_sig = fmpq_poly_length(f.__poly) > 5000 or n > 5000
     647           
     648            if do_sig: _sig_on
     649            fmpq_poly_left_shift(res.__poly, f.__poly, k)
     650            if do_sig: _sig_off
     651            return res
     652
     653    def __rshift__(self, n):
     654        """
     655        Notationally returns the quotient of Euclidean division of self
     656        by `t^n`.
     657       
     658        EXAMPLES::
     659       
     660            sage: R.<t> = QQ[]
     661            sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
     662            sage: f >> 2
     663            1/4*t^2 + 1/3*t + 1/2
     664        """
     665        cdef unsigned long k = <unsigned long> n
     666        cdef Polynomial_rational_flint f = <Polynomial_rational_flint> self
     667        cdef Polynomial_rational_flint res
     668        cdef bint do_sig
     669       
     670        if k == 0 or fmpq_poly_is_zero(f.__poly):
     671            return self
     672        else:
     673            res = f._new()
     674            do_sig = _do_sig(f.__poly)
     675           
     676            if do_sig: _sig_on
     677            fmpq_poly_right_shift(res.__poly, f.__poly, k)
     678            if do_sig: _sig_off
     679            return res
     680
     681    ###########################################################################
     682    # Arithmetic                                                              #
     683    ###########################################################################
     684
     685    cpdef ModuleElement _add_(self, ModuleElement right):
     686        """
     687        Returns the sum of two rational polynomials.
     688       
     689        EXAMPLES::
     690       
     691            sage: R.<t> = QQ[]
     692            sage: f = 2/3 + t + 2*t^3
     693            sage: g = -1 + t/3 - 10/11*t^4
     694            sage: f + g
     695            -10/11*t^4 + 2*t^3 + 4/3*t - 1/3
     696       
     697        TESTS::
     698       
     699            sage: R.<t> = QQ[]
     700            sage: f = R.random_element(2000)
     701            sage: f + f == 2 * f              # indirect doctest
     702            True
     703        """
     704        cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
     705        cdef Polynomial_rational_flint res = self._new()
     706        cdef bint do_sig = _do_sig(self.__poly) or _do_sig(op2.__poly)
     707       
     708        if do_sig: _sig_on
     709        fmpq_poly_add(res.__poly, self.__poly, op2.__poly)
     710        if do_sig: _sig_off
     711        return res
     712
     713    cpdef ModuleElement _sub_(self, ModuleElement right):
     714        """
     715        Returns the difference of two rational polynomials.
     716       
     717        EXAMPLES::
     718
     719            sage: R.<t> = QQ[]
     720            sage: f = -10/11*t^4 + 2*t^3 + 4/3*t - 1/3
     721            sage: g = 2*t^3
     722            sage: f - g                                 # indirect doctest
     723            -10/11*t^4 + 4/3*t - 1/3
     724       
     725        TESTS::
     726       
     727            sage: R.<t> = QQ[]
     728            sage: f = R.random_element(2000)
     729            sage: f - f/2 == 1/2 * f          # indirect doctest
     730            True
     731            sage: f[:1000] == f - f[1000:]    # indirect doctest
     732            True
     733        """
     734        cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
     735        cdef Polynomial_rational_flint res = self._new()
     736        cdef bint do_sig = _do_sig(self.__poly) or _do_sig(op2.__poly)
     737       
     738        if do_sig: _sig_on
     739        fmpq_poly_sub(res.__poly, self.__poly, op2.__poly)
     740        if do_sig: _sig_off
     741        return res
     742
     743    cpdef ModuleElement _neg_(self):
     744        """
     745        Returns the difference of two rational polynomials.
     746       
     747        EXAMPLES::
     748       
     749            sage: R.<t> = QQ[]
     750            sage: f = 3*t/2
     751            sage: -f            # indirect doctest
     752            -3/2*t
     753       
     754        TESTS::
     755       
     756            sage: R.<t> = QQ[]
     757            sage: f = R.random_element(2000)
     758            sage: f + (-f) == 0               # indirect doctest
     759            True
     760        """
     761        cdef Polynomial_rational_flint res = self._new()
     762        cdef bint do_sig = _do_sig(self.__poly)
     763       
     764        if do_sig: _sig_on
     765        fmpq_poly_neg(res.__poly, self.__poly)
     766        if do_sig: _sig_off
     767        return res
     768
     769    @coerce_binop
     770    def quo_rem(self, right):
     771        """
     772        Returns the quotient and remainder of the Euclidean division of
     773        self and right.
     774       
     775        Raises a ZerodivisionError if right is zero.
     776       
     777        EXAMPLES::
     778       
     779            sage: R.<t> = QQ[]
     780            sage: f = R.random_element(2000)
     781            sage: g = R.random_element(1000)
     782            sage: q, r = f.quo_rem(g)
     783            sage: f == q*g + r
     784            True
     785        """
     786        if right.is_zero():
     787            raise ZeroDivisionError, "division by zero polynomial"
     788        if self.is_zero():
     789            return self, self
     790
     791        cdef Polynomial_rational_flint qq = self._new()
     792        cdef Polynomial_rational_flint rr = self._new()
     793
     794        _sig_on
     795        fmpq_poly_divrem(qq.__poly, rr.__poly, self.__poly, \
     796                         (<Polynomial_rational_flint> right).__poly)
     797        _sig_off
     798        return qq, rr
     799
     800    @coerce_binop
     801    def gcd(self, right):
     802        """
     803        Returns the (monic) greatest common divisor of self and right.
     804       
     805        Corner cases:  if self and right are both zero, returns zero.  If
     806        only one of them is zero, returns the other polynomial, up to
     807        normalisation.
     808       
     809        EXAMPLES::
     810       
     811            sage: R.<t> = QQ[]
     812            sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3
     813            sage: g = 1/2 + 4*t + 2*t^4/3
     814            sage: f.gcd(g)
     815            1
     816            sage: f = (-3*t + 1/2) * f
     817            sage: g = (-3*t + 1/2) * (4*t^2/3 - 1) * g
     818            sage: f.gcd(g)
     819            t - 1/6
     820        """
     821        cdef Polynomial_rational_flint res = self._new()
     822       
     823        _sig_on
     824        fmpq_poly_gcd(res.__poly, self.__poly, \
     825                (<Polynomial_rational_flint> right).__poly)
     826        _sig_off
     827        return res
     828
     829    @coerce_binop
     830    def lcm(self, right):
     831        """
     832        Returns the monic (or zero) least common multiple of self and right.
     833       
     834        Corner cases:  if either of self and right are zero, returns zero.
     835        This behaviour is ensures that the relation lcm(a,b) gcd(a,b) == a b
     836        holds up to multiplication by rationals.
     837
     838        EXAMPLES::
     839
     840            sage: R.<t> = QQ[]
     841            sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3
     842            sage: g = 1/2 + 4*t + 2*t^4/3
     843            sage: f.lcm(g)
     844            t^7 - 4/7*t^6 - 3/2*t^5 + 8*t^4 - 75/28*t^3 - 66/7*t^2 + 87/8*t + 3/2
     845            sage: f.lcm(g) * f.gcd(g) // (f * g)
     846            -3/2
     847        """
     848        cdef Polynomial_rational_flint res = self._new()
     849       
     850        _sig_on
     851        fmpq_poly_lcm(res.__poly, self.__poly, \
     852                      (<Polynomial_rational_flint> right).__poly)
     853        _sig_off
     854        return res
     855
     856    @coerce_binop
     857    def xgcd(self, right):
     858        """
     859        Returns polynomials d, s, and t such that d == s * self + t * right,
     860        where d is the (monic) greatest common divisor of self and right.
     861        The choice of s and t is not specified any further.
     862       
     863        Corner cases:  if self and right are zero, returns zero polynomials.
     864        Otherwise, if only self is zero, returns (d, s, t) = (right, 0, 1) up
     865        to normalisation, and similarly if only right is zero.
     866       
     867        EXAMPLES::
     868       
     869            sage: R.<t> = QQ[]
     870            sage: f = 2/3 + 3/4 * t - t^2
     871            sage: g = -3 + 1/7 * t
     872            sage: f.xgcd(g)
     873            (1, -12/5095, -84/5095*t - 1701/5095)
     874        """
     875        cdef Polynomial_rational_flint d = self._new()
     876        cdef Polynomial_rational_flint s = self._new()
     877        cdef Polynomial_rational_flint t = self._new()
     878       
     879        _sig_on
     880        fmpq_poly_xgcd(d.__poly, s.__poly, t.__poly, self.__poly, (<Polynomial_rational_flint>right).__poly)
     881        _sig_off
     882        return d, s, t
     883
     884    cpdef RingElement _mul_(self, RingElement right):
     885        """
     886        Returns the product of self and right.
     887       
     888        EXAMPLES::
     889
     890            sage: R.<t> = QQ[]
     891            sage: f = -1 + 3*t/2 - t^3
     892            sage: g = 2/3 + 7/3*t + 3*t^2
     893            sage: f * g                           # indirect doctest
     894            -3*t^5 - 7/3*t^4 + 23/6*t^3 + 1/2*t^2 - 4/3*t - 2/3
     895       
     896        TESTS::
     897       
     898            sage: R.<t> = QQ[]
     899            sage: f = R.random_element(2000)
     900            sage: g = R.random_element(2000)
     901            sage: (f + g) * (f - g) == f^2 - g^2  # indirect doctest
     902            True
     903        """
     904        cdef Polynomial_rational_flint op2 = <Polynomial_rational_flint> right
     905        cdef Polynomial_rational_flint res = self._new()
     906        cdef bint do_sig = _do_sig(self.__poly) or _do_sig(op2.__poly)
     907       
     908        if do_sig: _sig_on
     909        fmpq_poly_mul(res.__poly, self.__poly, op2.__poly)
     910        if do_sig: _sig_off
     911        return res
     912
     913    cpdef ModuleElement _lmul_(self, RingElement right):
     914        r"""
     915        Returns right times self, where right is a rational number.
     916       
     917        EXAMPLES::
     918       
     919            sage: R.<t> = QQ[]
     920            sage: f = 3/2*t^3 - t + 1/3
     921            sage: 6 * f                  # indirect doctest
     922            9*t^3 - 6*t + 2
     923        """
     924        cdef Polynomial_rational_flint res = self._new()
     925        cdef bint do_sig = _do_sig(self.__poly)
     926       
     927        if do_sig: _sig_on
     928        fmpq_poly_scalar_mul_mpq(res.__poly, self.__poly, \
     929                                 (<Rational> right).value)
     930        if do_sig: _sig_off
     931        return res
     932
     933    cpdef ModuleElement _rmul_(self, RingElement right):
     934        r"""
     935        Returns self * right, where right is a rational number.
     936       
     937        EXAMPLES::
     938       
     939            sage: R.<t> = QQ[]
     940            sage: f = 3/2*t^3 - t + 1/3
     941            sage: f * 6                   # indirect doctest
     942            9*t^3 - 6*t + 2
     943        """
     944        cdef Polynomial_rational_flint res = self._new()
     945        cdef bint do_sig = _do_sig(self.__poly)
     946       
     947        if do_sig: _sig_on
     948        fmpq_poly_scalar_mul_mpq(res.__poly, self.__poly, \
     949                                 (<Rational> right).value)
     950        if do_sig: _sig_off
     951        return res
     952
     953    def __pow__(Polynomial_rational_flint self, exp, ignored):
     954        """
     955        Returns self raised to the power of exp.
     956       
     957        The corner case of exp == 0 is handled by returning the constant
     958        polynomial 1.  Note that this includes the case 0^0 == 1.
     959       
     960        This method only supports integral values for exp that fit into
     961        a signed long int.
     962       
     963        INPUT:
     964       
     965        - exp - Exponent
     966       
     967        OUTPUT:
     968       
     969        - Polynomial; self raised to the power of exp
     970       
     971        EXAMPLES::
     972
     973            sage: R.<t> = QQ[]
     974            sage: f = 1/2 + 2*t - t^2/3
     975            sage: f^0
     976            1
     977            sage: f^3
     978            -1/27*t^6 + 2/3*t^5 - 23/6*t^4 + 6*t^3 + 23/4*t^2 + 3/2*t + 1/8
     979
     980        TESTS::
     981       
     982            sage: R.<t> = QQ[]
     983            sage: f = 1/2 + t
     984            sage: f^0
     985            1
     986            sage: R(0)^0
     987            1
     988           
     989        We verify the size condition on the exponent::
     990       
     991            sage: R.<t> = QQ[]
     992            sage: (1 + t)^(2^31)
     993            Traceback (most recent call last):
     994            ...
     995            OverflowError: long int too large to convert to int
     996        """
     997        cdef long n
     998        cdef Polynomial_rational_flint res
     999       
     1000        if not PY_TYPE_CHECK(exp, Integer):
     1001            try:
     1002                exp = Integer(exp)
     1003            except TypeError:
     1004                raise TypeError, "non-integral exponents not supported"
     1005       
     1006        n = <long> exp
     1007       
     1008        if n < 0:
     1009            if fmpq_poly_is_zero(self.__poly):
     1010                raise ZeroDivisionError, "negative exponent in power of zero"
     1011            res = self._new()
     1012            _sig_on
     1013            fmpq_poly_power(res.__poly, self.__poly, -n)
     1014            _sig_off
     1015            return ~res
     1016        else:
     1017            res = self._new()
     1018            if self._is_gen:
     1019                fmpq_poly_set_coeff_si(res.__poly, n, 1)
     1020            else:
     1021                _sig_on
     1022                fmpq_poly_power(res.__poly, self.__poly, n)
     1023                _sig_off
     1024            return res
     1025
     1026    def __floordiv__(Polynomial_rational_flint self, right):
     1027        """
     1028        Returns the quotient of self and right obtain by Euclidean division.
     1029       
     1030        EXAMPLES::
     1031       
     1032            sage: R.<t> = QQ[]
     1033            sage: f = t^3 - t/2 + 1/5
     1034            sage: g = 2/3*t - 1
     1035            sage: f // g                       # indirect doctest
     1036            3/2*t^2 + 9/4*t + 21/8
     1037       
     1038        TESTS::
     1039       
     1040            sage: R.<t> = QQ[]
     1041            sage: f  = R.random_element(1000)
     1042            sage: g  = R.random_element(500)
     1043            sage: if g == 0: g = R(1)
     1044            sage: qr = f.quo_rem(g)
     1045            sage: q  = f // g                  # indirect doctest
     1046            sage: qr[0] == q
     1047            True
     1048        """
     1049        cdef Polynomial_rational_flint res
     1050        cdef bint do_sig
     1051       
     1052        if right == 0:
     1053            raise ZeroDivisionError, "division by zero polynomial"
     1054
     1055        if not PY_TYPE_CHECK(right, Polynomial_rational_flint):
     1056            if right in QQ:
     1057                res = self._new()
     1058                do_sig = _do_sig(self.__poly)
     1059               
     1060                if do_sig: _sig_on
     1061                fmpq_poly_scalar_div_mpq(res.__poly, self.__poly,
     1062                                                  (<Rational> QQ(right)).value)
     1063                if do_sig: _sig_off
     1064                return res
     1065           
     1066            right = self._parent(right)
     1067       
     1068        res = self._new()
     1069        _sig_on
     1070        fmpq_poly_floordiv(res.__poly, self.__poly,
     1071                                     (<Polynomial_rational_flint>right).__poly)
     1072        _sig_off
     1073        return res
     1074
     1075    def __mod__(Polynomial_rational_flint self, right):
     1076        """
     1077        Returns the remainder of self and right obtain by Euclidean division.
     1078       
     1079        EXAMPLES::
     1080       
     1081            sage: R.<t> = QQ[]
     1082            sage: f = t^3 - t/2 + 1/5
     1083            sage: g = 2/3*t - 1
     1084            sage: f % g                        # indirect doctest
     1085            113/40
     1086       
     1087        TESTS::
     1088       
     1089            sage: R.<t> = QQ[]
     1090            sage: f  = R.random_element(1000)
     1091            sage: g  = R.random_element(500)
     1092            sage: if g == 0: g = R(1)
     1093            sage: qr = f.quo_rem(g)
     1094            sage: r  = f % g                   # indirect doctest
     1095            sage: qr[1] == r
     1096            True
     1097        """
     1098        cdef Polynomial_rational_flint res
     1099       
     1100        if right == 0:
     1101            raise ZeroDivisionError, "division by zero polynomial"
     1102
     1103        if not PY_TYPE_CHECK(right, Polynomial_rational_flint):
     1104            right = self._parent(right)
     1105
     1106        res = self._new()
     1107        _sig_on
     1108        fmpq_poly_mod(res.__poly, self.__poly,
     1109                                     (<Polynomial_rational_flint>right).__poly)
     1110        _sig_off
     1111        return res
     1112
     1113    ###########################################################################
     1114    # Further methods                                                         #
     1115    ###########################################################################
     1116
     1117    def numerator(self):
     1118        """
     1119        Returns the numerator of self.
     1120       
     1121        Representing self as the quotient of an integer polynomial and
     1122        a positive integer denominator (coprime to the content of the
     1123        polynomial), returns the integer polynomial.
     1124       
     1125        EXAMPLE::
     1126       
     1127            sage: R.<t> = QQ[]
     1128            sage: f = (3 * t^3 + 1) / -3
     1129            sage: f.numerator()
     1130            -3*t^3 - 1
     1131        """
     1132        cdef Polynomial_integer_dense_flint num = \
     1133                                         PY_NEW(Polynomial_integer_dense_flint)
     1134        parent = ZZ[self.variable_name()]
     1135        _sig_on
     1136        Polynomial_integer_dense_flint.__init__(num, parent, x=None, \
     1137                                    check=False, is_gen=False, construct=False)
     1138        fmpz_poly_set(num.__poly, fmpq_poly_numref(self.__poly))
     1139        _sig_off
     1140        return num
     1141
     1142    def denominator(self):
     1143        """
     1144        Returns the denominator of self.
     1145
     1146        EXAMPLE::
     1147       
     1148            sage: R.<t> = QQ[]
     1149            sage: f = (3 * t^3 + 1) / -3
     1150            sage: f.denominator()
     1151            3
     1152        """
     1153        cdef Integer den = PY_NEW(Integer)
     1154        if fmpq_poly_denref(self.__poly) is NULL:
     1155            mpz_set_ui(den.value, 1)
     1156        else:
     1157            fmpz_to_mpz(den.value, fmpq_poly_denref(self.__poly))
     1158        return den
     1159   
     1160    def _derivative(self, var = None):
     1161        """
     1162        Returns the derivative of self with respect to ``var``.
     1163       
     1164        INPUT:
     1165       
     1166        -  ``var`` - Must be either (equal to) the generator of the polynomial
     1167           ring to which this polynomial belongs, or ``None``; either way the
     1168           behaviour is the same.
     1169       
     1170        OUTPUT:
     1171       
     1172        -  Derivative as a ``Polynomial_rational_flint``
     1173       
     1174        .. seealso:: :meth:`.derivative`
     1175       
     1176        EXAMPLES::
     1177           
     1178            sage: R.<x> = QQ[]
     1179            sage: f = x^4 - x - 1
     1180            sage: f._derivative()
     1181            4*x^3 - 1
     1182            sage: f._derivative(None)
     1183            4*x^3 - 1
     1184            sage: f._derivative(2*x)
     1185            Traceback (most recent call last):
     1186            ...
     1187            ValueError: Cannot differentiate with respect to 2*x
     1188            sage: y = var("y")
     1189            sage: f._derivative(y)
     1190            Traceback (most recent call last):
     1191            ...
     1192            ValueError: Cannot differentiate with respect to y
     1193        """
     1194        cdef Polynomial_rational_flint der
     1195        cdef bint do_sig
     1196       
     1197        if var is not None and var != self._parent.gen():
     1198            raise ValueError, "Cannot differentiate with respect to %s" %var
     1199       
     1200        der = self._new()
     1201        do_sig = _do_sig(self.__poly)
     1202       
     1203        if do_sig: _sig_on
     1204        fmpq_poly_derivative(der.__poly, self.__poly)
     1205        if do_sig: _sig_off
     1206        return der
     1207   
     1208    def real_root_intervals(self):
     1209        """
     1210        Returns isolating intervals for the real roots of self.
     1211
     1212        EXAMPLES:
     1213       
     1214        We compute the roots of the characteristic polynomial of some
     1215        Salem numbers::
     1216
     1217            sage: R.<t> = QQ[]
     1218            sage: f = 1 - t^2 - t^3 - t^4 + t^6
     1219            sage: f.real_root_intervals()
     1220            [((1/2, 3/4), 1), ((1, 3/2), 1)]
     1221        """
     1222        from sage.rings.polynomial.real_roots import real_roots
     1223        return real_roots(self)
     1224
     1225    @coerce_binop
     1226    def resultant(Polynomial_rational_flint self, right):
     1227        r"""
     1228        Returns the resultant of self and right.
     1229       
     1230        Enumerating the roots over `\QQ` as `r_1, \cdots, r_m` and
     1231        `s_1, \cdots, s_n` and letting `x` and `y` denote the leading
     1232        coefficients of `f` and `g`, the resultant of the two polynomials
     1233        is defined by
     1234       
     1235        .. math::
     1236       
     1237            x^{\deg g} y^{\deg f} \prod_{i,j} (r_i - s_j).
     1238       
     1239        Corner cases:  if one of the polynomials is zero, the resultant
     1240        is zero.  Note that otherwise if one of the polynomials is constant,
     1241        the last term in the above is the empty product.
     1242       
     1243        EXAMPLES::
     1244       
     1245            sage: R.<t> = QQ[]
     1246            sage: f = (t - 2/3) * (t + 4/5) * (t - 1)
     1247            sage: g = (t - 1/3) * (t + 1/2) * (t + 1)
     1248            sage: f.resultant(g)
     1249            119/1350
     1250            sage: h = (t - 1/3) * (t + 1/2) * (t - 1)
     1251            sage: f.resultant(h)
     1252            0
     1253        """
     1254        cdef Rational res = PY_NEW(Rational)
     1255        _sig_on
     1256        fmpq_poly_resultant(res.value, self.__poly, \
     1257                            (<Polynomial_rational_flint>right).__poly)
     1258        _sig_off
     1259        return res
     1260   
     1261    def is_irreducible(self):
     1262        r"""
     1263        Returns whether self is irreducible.
     1264
     1265        This method computes the primitive part as an element of `\ZZ[t]` and
     1266        calls the method ``is_irreducible`` for elements of that polynomial
     1267        ring.
     1268
     1269        By definition, over any integral domain, an element `r` is irreducible
     1270        if and only if it is non-zero, not a unit and whenever `r = ab` then 
     1271        `a` or `b` is a unit.
     1272
     1273        OUTPUT:
     1274
     1275        -  ``bool`` - Whether this polynomial is irreducible
     1276
     1277        EXAMPLES::
     1278
     1279            sage: R.<t> = QQ[]
     1280            sage: (t^2 + 2).is_irreducible()
     1281            True
     1282            sage: (t^2 - 1).is_irreducible()
     1283            False
     1284
     1285        TESTS::
     1286
     1287            sage: R.<t> = QQ[]
     1288            sage: R(0).is_irreducible()
     1289            False
     1290            sage: R(-1/2).is_irreducible()
     1291            False
     1292            sage: (t+1).is_irreducible()
     1293            True
     1294        """
     1295        cdef Polynomial_integer_dense_flint primitive
     1296        cdef unsigned long length = fmpq_poly_length(self.__poly)
     1297       
     1298        if length < 2:
     1299            return False
     1300        elif length == 2:
     1301            return True
     1302        else:
     1303            primitive = PY_NEW(Polynomial_integer_dense_flint)
     1304            parent = ZZ[self.variable_name()]
     1305            _sig_on
     1306            Polynomial_integer_dense_flint.__init__(primitive, parent, \
     1307                             x=None, check=True, is_gen=False, construct=False)
     1308            fmpz_poly_primitive_part(primitive.__poly, \
     1309                                     fmpq_poly_numref(self.__poly))
     1310            _sig_off
     1311            return primitive.is_irreducible()
     1312
     1313    ###########################################################################
     1314    # Methods using PARI                                                      #
     1315    ###########################################################################
     1316
     1317    def galois_group(self, pari_group = False, algorithm = 'pari'):
     1318        """
     1319        Returns the Galois group of self as a permutation group.
     1320       
     1321        INPUT:
     1322       
     1323        -  ``self`` - Irreducible polynomial
     1324       
     1325        -  ``pari_group`` - bool (default: ``False``); if ``True`` instead
     1326           return the Galois group as a PARI group.  This has a useful label
     1327           in it, and may be slightly faster since it doesn't require looking
     1328           up a group in Gap.  To get a permutation group from a PARI
     1329           group ``P``, type ``PermutationGroup(P)``.
     1330       
     1331        -  ``algorithm`` - ``'pari'``, ``'kash'``, ``'magma'`` (default:
     1332           ``'pari'``, except when the degree is at least 12 in which case
     1333           ``'kash'`` is tried).
     1334       
     1335        OUTPUT:
     1336       
     1337        -  Galois group
     1338       
     1339        ALGORITHM:
     1340       
     1341        The Galois group is computed using PARI in C library mode, or possibly
     1342        KASH or MAGMA.
     1343       
     1344        .. note::
     1345       
     1346            The PARI documentation contains the following warning: The method
     1347            used is that of resolvent polynomials and is sensitive to the
     1348            current precision. The precision is updated internally but, in very
     1349            rare cases, a wrong result may be returned if the initial precision
     1350            was not sufficient.
     1351           
     1352            MAGMA does not return a provably correct result.  Please see the
     1353            MAGMA documentation for how to obtain a provably correct result.
     1354       
     1355        EXAMPLES::
     1356       
     1357            sage: R.<x> = QQ[]
     1358            sage: f = x^4 - 17*x^3 - 2*x + 1
     1359            sage: G = f.galois_group(); G            # optional - database_gap
     1360            Transitive group number 5 of degree 4
     1361            sage: G.gens()                           # optional - database_gap
     1362            [(1,2,3,4), (1,2)]
     1363            sage: G.order()                          # optional - database_gap
     1364            24
     1365       
     1366        It is potentially useful to instead obtain the corresponding PARI
     1367        group, which is little more than a 4-tuple.  See the PARI manual for
     1368        the exact details.  (Note that the third entry in the tuple is in the
     1369        new standard ordering.)
     1370       
     1371        ::
     1372       
     1373            sage: f = x^4 - 17*x^3 - 2*x + 1
     1374            sage: G = f.galois_group(pari_group=True); G
     1375            PARI group [24, -1, 5, "S4"] of degree 4
     1376            sage: PermutationGroup(G)                # optional - database_gap
     1377            Transitive group number 5 of degree 4
     1378       
     1379        You can use KASH to compute Galois groups as well.  The advantage is
     1380        that KASH can compute Galois groups of fields up to degree 23, whereas
     1381        PARI only goes to degree 11.  (In my not-so-thorough experiments PARI
     1382        is faster than KASH.)
     1383       
     1384        ::
     1385       
     1386            sage: f = x^4 - 17*x^3 - 2*x + 1
     1387            sage: f.galois_group(algorithm='kash')   # optional - kash
     1388            Transitive group number 5 of degree 4
     1389       
     1390            sage: f = x^4 - 17*x^3 - 2*x + 1
     1391            sage: f.galois_group(algorithm='magma')  # optional - magma, database_gap
     1392            Transitive group number 5 of degree 4
     1393       
     1394        TESTS:
     1395
     1396        We illustrate the behaviour in the case of reducible polynomials::
     1397       
     1398            sage: R.<t> = QQ[]
     1399            sage: f = (1 + t)^2
     1400            sage: f.galois_group()
     1401            Traceback (most recent call last):
     1402            ...
     1403            ValueError: The polynomial must be irreducible
     1404        """
     1405        from sage.groups.all import PariGroup, PermutationGroup, TransitiveGroup
     1406       
     1407        if not self.is_irreducible():
     1408            raise ValueError, "The polynomial must be irreducible"
     1409       
     1410        if self.degree() > 11 and algorithm=='pari':
     1411            algorithm = 'kash'
     1412       
     1413        if algorithm == 'pari':
     1414            G = self._pari_().Polrev().polgalois()
     1415            H = PariGroup(G, self.degree())
     1416            if pari_group:
     1417                return H
     1418            else:
     1419                return PermutationGroup(H)
     1420       
     1421        elif algorithm == 'kash':
     1422            try:
     1423                from sage.interfaces.all import kash
     1424                kash.eval('X := PolynomialRing(RationalField()).1')
     1425                s = self._repr(name='X')
     1426                G = kash('Galois(%s)'%s)
     1427                d = int(kash.eval('%s.ext1'%G.name()))
     1428                n = int(kash.eval('%s.ext2'%G.name()))
     1429                return TransitiveGroup(d, n)
     1430            except RuntimeError, msg:
     1431                raise NotImplementedError, (str(msg) + "\nSorry, " +
     1432                    "computation of Galois groups of fields of degree " +
     1433                    "bigger than 11 is not yet implemented.  Try installing " +
     1434                    "the optional free (closed source) KASH package, which " +
     1435                    "supports larger degrees, or use algorithm='magma' if " +
     1436                    "you have magma.")
     1437       
     1438        elif algorithm == 'magma':
     1439            from sage.interfaces.all import magma
     1440            X = magma(self).GaloisGroup()
     1441            try:
     1442                n, d = X.TransitiveGroupIdentification(nvals=2)
     1443                d = int(d)
     1444                n = int(n)
     1445            except RuntimeError, msg:
     1446                raise RuntimeError, (str(msg) + "\nUnable to lookup " +
     1447                    "description of Galois group as a transitive " +
     1448                    "group.\n%s" %X)
     1449            return TransitiveGroup(d, n)
     1450       
     1451        else:
     1452            raise ValueError, "Algorithm %s not supported." %algorithm
     1453   
     1454    def factor_mod(self, p):
     1455        """
     1456        Returns the factorization of self modulo the prime ``p``.
     1457       
     1458        Assumes that the degree of this polynomial is at least one, and raises
     1459        a ``ValueError`` otherwise.
     1460       
     1461        INPUT:
     1462       
     1463        -  ``p`` - Prime number
     1464       
     1465        OUTPUT:
     1466       
     1467        -  Factorization of this polynomial  modulo ``p``
     1468       
     1469        EXAMPLES::
     1470       
     1471            sage: R.<x> = QQ[]
     1472            sage: (x^5 + 17*x^3 + x+ 3).factor_mod(3)
     1473            x * (x^2 + 1)^2
     1474            sage: (x^5 + 2).factor_mod(5)
     1475            (x + 2)^5
     1476        """
     1477        from sage.rings.finite_rings.constructor import FiniteField
     1478       
     1479        p = Integer(p)
     1480        if not p.is_prime():
     1481            raise ValueError, "p must be prime"
     1482       
     1483        if self.degree() < 1:
     1484            raise ValueError, "The polynomial must have degree at least 1"
     1485       
     1486        G = self._pari_().factormod(p)
     1487        K = FiniteField(p)
     1488        R = K[self.parent().variable_name()]
     1489        return R(1)._factor_pari_helper(G, unit=R(self).leading_coefficient())
     1490   
     1491    def factor_padic(self, p, prec=10):
     1492        """
     1493        Returns the ``p``-adic factorization of this polynomial to the given
     1494        precision.
     1495       
     1496        INPUT:
     1497       
     1498        -  ``p`` - Prime number
     1499        -  ``prec`` - Integer; the precision
     1500       
     1501        OUTPUT:
     1502       
     1503        -  Factorization of ``self`` viewed as a ``p``-adic polynomial
     1504       
     1505        EXAMPLES::
     1506       
     1507            sage: R.<x> = QQ[]
     1508            sage: f = x^3 - 2
     1509            sage: f.factor_padic(2)
     1510            (1 + O(2^10))*x^3 + (O(2^10))*x^2 + (O(2^10))*x + (2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10))
     1511            sage: f.factor_padic(3)
     1512            (1 + O(3^10))*x^3 + (O(3^10))*x^2 + (O(3^10))*x + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10))
     1513            sage: f.factor_padic(5)
     1514            ((1 + O(5^10))*x + (2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))) * ((1 + O(5^10))*x^2 + (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x + (4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10)))
     1515        """
     1516        from sage.rings.padics.factory import Qp
     1517       
     1518        p = Integer(p)
     1519        if not p.is_prime():
     1520            raise ValueError, "p must be prime"
     1521        prec = Integer(prec)
     1522        if prec <= 0:
     1523            raise ValueError, "prec must be positive"
     1524       
     1525        K = Qp(p, prec, type='capped-rel')
     1526        R = K[self.parent().variable_name()]
     1527        return R(self).factor()  # absprec = prec
     1528   
     1529    def hensel_lift(self, p, e):
     1530        r"""
     1531        Assuming that this polynomial factors modulo `p` into distinct
     1532        factors, computes the Hensel lifts of these factors modulo `p^e`.
     1533        We assume that self has integer coefficients.
     1534       
     1535        Returns an empty list if this polynomial has degree less than one.
     1536       
     1537        INPUT:
     1538       
     1539        -  ``p`` - Prime number; coerceable to ``Integer``
     1540        -  ``e`` - Exponent; coerceable to ``Integer``
     1541       
     1542        OUTPUT:
     1543       
     1544        -  Hensel lifts; list of polynomials over `\ZZ / p^e \ZZ`
     1545       
     1546        EXAMPLES::
     1547       
     1548            sage: R.<x> = QQ[]
     1549            sage: R((x-1)*(x+1)).hensel_lift(7, 2)
     1550            [x + 1, x + 48]
     1551       
     1552        TESTS::
     1553       
     1554            sage: R.<x> = QQ[]
     1555            sage: R(0).hensel_lift(7, 2)
     1556            []
     1557            sage: R(x).hensel_lift(7, 2)
     1558            [x]
     1559            sage: R(x-1).hensel_lift(7, 2)
     1560            [x + 48]
     1561        """
     1562        from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
     1563       
     1564        p = Integer(p)
     1565        if not p.is_prime():
     1566            raise ValueError, "p must be prime"
     1567        e = Integer(e)
     1568        if e < 1:
     1569            raise ValueError, "e must be at least 1"
     1570       
     1571        # The relevant PARI method doesn't seem to play well with constant and
     1572        # linear polynomials, so we handle these separately.
     1573        #
     1574        if self.degree() < 1:
     1575            return [ ]
     1576        elif self.degree() == 1:
     1577            R = IntegerModRing(p**e)
     1578            S = R[self.parent().variable_name()]
     1579            return [S(self)]
     1580       
     1581        F = self.factor_mod(p)
     1582        y = []
     1583        for g, n in F:
     1584            if n > 1:
     1585                raise ArithmeticError, ("The polynomial must be square free " +
     1586                    "modulo p")
     1587            y.append(g)
     1588        H = self._pari_().polhensellift(y, p, e)
     1589        R = IntegerModRing(p**e)
     1590        S = R[self.parent().variable_name()]
     1591        return [S(eval(str(m.Vec().Polrev().Vec()))) for m in H]
     1592   
     1593    def discriminant(self):
     1594        r"""
     1595        Returns the discriminant of this polynomial.
     1596       
     1597        The discriminant `R_n` is defined as
     1598       
     1599        .. math::
     1600       
     1601            R_n = a_n^{2 n-2} \prod_{1 \le i < j \le n} (r_i - r_j)^2,
     1602       
     1603        where `n` is the degree of this polynomial, `a_n` is the leading
     1604        coefficient and the roots over `\QQbar` are `r_1, \ldots, r_n`.
     1605       
     1606        The discriminant of constant polynomials is defined to be 0.
     1607       
     1608        OUTPUT:
     1609       
     1610        -  Discriminant, an element of the base ring of the polynomial ring
     1611       
     1612        .. note::
     1613
     1614            Note the identity `R_n(f) := (-1)^(n (n-1)/2) R(f,f') a_n^(n-k-2)`,
     1615            where `n` is the degree of this polynomial, `a_n` is the leading
     1616            coefficient, `f'` is the derivative of `f`, and `k` is the degree
     1617            of `f'`.  Calls :meth:`.resultant`.
     1618       
     1619        ALGORITHM:
     1620       
     1621        Use PARI.
     1622       
     1623        EXAMPLES:
     1624       
     1625        In the case of elliptic curves in special form, the discriminant is
     1626        easy to calculate::
     1627       
     1628            sage: R.<t> = QQ[]
     1629            sage: f = t^3 + t + 1
     1630            sage: d = f.discriminant(); d
     1631            -31
     1632            sage: d.parent() is QQ
     1633            True
     1634            sage: EllipticCurve([1, 1]).discriminant() / 16
     1635            -31
     1636       
     1637        ::
     1638       
     1639            sage: R.<t> = QQ[]
     1640            sage: f = 2*t^3 + t + 1
     1641            sage: d = f.discriminant(); d
     1642            -116
     1643       
     1644        ::
     1645       
     1646            sage: R.<t> = QQ[]
     1647            sage: f = t^3 + 3*t - 17
     1648            sage: f.discriminant()
     1649            -7911
     1650       
     1651        TESTS::
     1652       
     1653            sage: R.<t> = QQ[]
     1654            sage: R(0).discriminant()
     1655            0
     1656            sage: R(2/3).discriminant()
     1657            0
     1658            sage: (t + 1/2).discriminant()
     1659            1
     1660        """
     1661        return QQ(self._pari_().poldisc())
     1662   
     1663    # Alias for discriminant
     1664    disc = discriminant
     1665
  • sage/rings/polynomial/polynomial_ring.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/rings/polynomial/polynomial_ring.py
    a b  
    7070    sage: type(ZZ['x'].0)
    7171    <type 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint'>
    7272    sage: type(QQ['x'].0)
    73     <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
     73    <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
    7474    sage: type(RR['x'].0)
    7575    <type 'sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense'>
    7676    sage: type(Integers(4)['x'].0)
     
    12101210            sage: R = PRing(QQ, 'x'); R
    12111211            Univariate Polynomial Ring in x over Rational Field
    12121212            sage: type(R.gen())
    1213             <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>
     1213            <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
    12141214            sage: R = PRing(QQ, 'x', sparse=True); R
    12151215            Sparse Univariate Polynomial Ring in x over Rational Field
    12161216            sage: type(R.gen())
     
    12201220            sage: type(R.gen())
    12211221            <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field'>
    12221222        """
    1223         if implementation is None: implementation="NTL"
    12241223        from sage.rings.finite_rings.finite_field_base import is_FiniteField
     1224        from sage.rings.rational_field import QQ
     1225        from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
     1226        if implementation is None:
     1227            implementation = "NTL"
     1228
    12251229        if implementation == "NTL" and is_FiniteField(base_ring):
    1226             p=base_ring.characteristic()
    12271230            from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext
    12281231            from sage.libs.ntl.ntl_ZZ_pX import ntl_ZZ_pX
     1232            from sage.rings.polynomial.polynomial_zz_pex import Polynomial_ZZ_pEX
     1233
     1234            p = base_ring.characteristic()
    12291235            self._modulus = ntl_ZZ_pEContext(ntl_ZZ_pX(list(base_ring.polynomial()), p))
    1230             from sage.rings.polynomial.polynomial_zz_pex import Polynomial_ZZ_pEX
    1231             element_class=Polynomial_ZZ_pEX
     1236            element_class = Polynomial_ZZ_pEX
    12321237
    12331238        if not element_class:
    12341239            if sparse:
    12351240                element_class = polynomial_element_generic.Polynomial_generic_sparse_field
    12361241            elif isinstance(base_ring, rational_field.RationalField):
    1237                 element_class = polynomial_element_generic.Polynomial_rational_dense
     1242                from sage.rings.polynomial.polynomial_rational_flint import Polynomial_rational_flint
     1243                element_class = Polynomial_rational_flint
    12381244            elif is_RealField(base_ring):
    12391245                element_class = PolynomialRealDense
    12401246            else:
    12411247                element_class = polynomial_element_generic.Polynomial_generic_dense_field
     1248
    12421249        PolynomialRing_integral_domain.__init__(self, base_ring, name=name, sparse=sparse, element_class=element_class)
    12431250
    1244         from sage.rings.polynomial.polynomial_singular_interface import can_convert_to_singular
    12451251        self._has_singular = can_convert_to_singular(self)
    12461252
    12471253    def divided_difference(self, points, full_table=False):
  • sage/schemes/elliptic_curves/ell_generic.py

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/schemes/elliptic_curves/ell_generic.py
    a b  
    17731773            sage: [E.division_polynomial(3, two_torsion_multiplicity=i) for i in range(3)]
    17741774            [3*x^4 - 6*x^2 + 3*x - 1, 3*x^4 - 6*x^2 + 3*x - 1, 3*x^4 - 6*x^2 + 3*x - 1]
    17751775            sage: [type(E.division_polynomial(3, two_torsion_multiplicity=i)) for i in range(3)]
    1776             [<class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>,
    1777             <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>,
    1778             <class 'sage.rings.polynomial.polynomial_element_generic.Polynomial_rational_dense'>]
     1776            [<type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>,
     1777             <type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular'>,
     1778             <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>]
    17791779       
    17801780        ::
    17811781       
  • sage/structure/parent.pyx

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/structure/parent.pyx
    a b  
    163163        sage: sage.structure.parent.raise_attribute_error(QQ[x].gen(), "bla")
    164164        Traceback (most recent call last):
    165165        ...
    166         AttributeError: 'Polynomial_rational_dense' object has no attribute 'bla'
     166        AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'
    167167    """
    168168    cls = type(self)
    169169    if is_extension_type(cls):
     
    218218        Traceback (most recent call last):
    219219        ...
    220220        AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'lazy_attribute'
    221         sage: getattr_from_other_class(QQ[x].one(), A, "lazy_attribute")
     221        sage: getattr_from_other_class(PolynomialRing(QQ, name='x', sparse=True).one(), A, "lazy_attribute")
    222222        '1'
     223        sage: getattr_from_other_class(PolynomialRing(QQ, name='x', implementation="FLINT").one(), A, "lazy_attribute")
     224        Traceback (most recent call last):
     225        ...
     226        AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'lazy_attribute'
    223227
    224228    In general, descriptors are not yet well supported, because they
    225229    often do not accept to be cheated with the type of their instance::
  • sage/structure/sage_object.pyx

    diff -r 8dec8b43ccca -r 040e85ea22a4 sage/structure/sage_object.pyx
    a b  
    4242
    4343        EXAMPLES::
    4444       
    45             sage: x = PolynomialRing(QQ,'x').gen()
     45            sage: x = PolynomialRing(QQ, 'x', sparse=True).gen()
    4646            sage: g = x^3 + x - 5
    4747            sage: g
    4848            x^3 + x - 5