Ticket #9051: 9051-FpT_4.patch

File 9051-FpT_4.patch, 12.7 KB (added by robertwb, 12 years ago)
  • sage/rings/fraction_field_FpT.pxd

    # HG changeset patch
    # User Robert Bradshaw <robertwb@math.washington.edu>
    # Date 1275212100 25200
    # Node ID 3b9b429abf1fe5f51400be49ae7c8101c90cf315
    # Parent  3ea4df2703a8e3a94b723377fcbbaa836e9f033b
    #9051 - More speedups for GF(p)[t] and Frac(GF(p)[t]).
    
    diff -r 3ea4df2703a8 -r 3b9b429abf1f sage/rings/fraction_field_FpT.pxd
    a b  
    1313
    1414    cdef FpTElement _new_c(self)
    1515    cdef FpTElement _copy_c(self)
     16    cpdef numerator(self)
     17    cpdef denominator(self)
    1618    cpdef FpTElement next(self)
    1719    cpdef _sqrt_or_None(self)
    1820    cpdef bint is_square(self)
  • sage/rings/fraction_field_FpT.pyx

    diff -r 3ea4df2703a8 -r 3b9b429abf1f sage/rings/fraction_field_FpT.pyx
    a b  
    180180            sage: a.numer()
    181181            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
    182182        """
    183         cdef long n
    184         return self._parent.poly_ring(
    185             [zmod_poly_get_coeff_ui (self._numer, n) for n in range(0, zmod_poly_degree(self._numer)+1)])
     183        return self.numerator()
    186184
    187     def numerator(self):
     185    cpdef numerator(self):
    188186        """
    189187        Returns the numerator of this element, as an element of the polynomial ring.
    190188
     
    195193            sage: a.numerator()
    196194            t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1
    197195        """
    198         return self.numer()
     196        cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint)
     197        zmod_poly_init2_precomp(&res.x, self.p, self._numer.p_inv, self._numer.length)
     198        zmod_poly_set(&res.x, self._numer)
     199        res._parent = self._parent.poly_ring
     200        return res
    199201
    200202    def denom(self):
    201203        """
     
    208210            sage: a.denom()
    209211            t^3
    210212        """
    211         cdef long n
    212         return self._parent.poly_ring(
    213             [zmod_poly_get_coeff_ui (self._denom, n) for n in range(0, zmod_poly_degree(self._denom)+1)])
     213        return self.denominator()
    214214
    215     def denominator(self):
     215    cpdef denominator(self):
    216216        """
    217217        Returns the denominator of this element, as an element of the polynomial ring.
    218218
     
    223223            sage: a.denominator()
    224224            t^3
    225225        """
    226         return self.denom()
     226        cdef Polynomial_zmod_flint res = <Polynomial_zmod_flint>PY_NEW(Polynomial_zmod_flint)
     227        zmod_poly_init2_precomp(&res.x, self.p, self._denom.p_inv, self._denom.length)
     228        zmod_poly_set(&res.x, self._denom)
     229        res._parent = self._parent.poly_ring
     230        return res
     231   
     232    def __call__(self, *args, **kwds):
     233        """
     234        EXAMPLES::
     235       
     236            sage: K = Frac(GF(5)['t'])
     237            sage: t = K.gen()
     238            sage: t(3)
     239            3
     240            sage: f = t^2/(1-t)
     241            sage: f(2)
     242            1
     243            sage: f(t)
     244            4*t^2/(t + 4)
     245            sage: f(t^3)
     246            4*t^6/(t^3 + 4)
     247            sage: f((t+1)/t^3)
     248            (t^2 + 2*t + 1)/(t^6 + 4*t^4 + 4*t^3)
     249        """
     250        return self.numer()(*args, **kwds) / self.denom()(*args, **kwds)
     251   
     252    def subs(self, *args, **kwds):
     253        """
     254        EXAMPLES::
     255       
     256            sage: K = Frac(GF(11)['t'])
     257            sage: t = K.gen()
     258            sage: f = (t+1)/(t-1)
     259            sage: f.subs(t=2)
     260            3
     261            sage: f.subs(X=2)
     262            (t + 1)/(t + 10)
     263        """
     264        return self.numer().subs(*args, **kwds) / self.denom().subs(*args, **kwds)
     265   
     266    def valuation(self, v):
     267        """
     268        Returns the valuation of self at `v`.
     269       
     270        EXAMPLES::
     271       
     272            sage: R.<t> = GF(5)[]
     273            sage: f = (t+1)^2 * (t^2+t+1) / (t-1)^3
     274            sage: f.valuation(t+1)
     275            2
     276            sage: f.valuation(t-1)
     277            -3
     278            sage: f.valuation(t)
     279            0
     280        """
     281        return self.numer().valuation(v) - self.denom().valuation(v)
     282   
     283    def factor(self):
     284        """
     285        EXAMPLES::
     286       
     287            sage: K = Frac(GF(5)['t'])
     288            sage: t = K.gen()
     289            sage: f = 2 * (t+1) * (t^2+t+1)^2 / (t-1)
     290            sage: factor(f)
     291            (2) * (t + 4)^-1 * (t + 1) * (t^2 + t + 1)^2
     292        """
     293        return self.numer().factor() / self.denom().factor()
    227294
    228295    def _repr_(self):
    229296        """
  • sage/rings/fraction_field_element.pyx

    diff -r 3ea4df2703a8 -r 3b9b429abf1f sage/rings/fraction_field_element.pyx
    a b  
    3838
    3939from sage.structure.element cimport FieldElement, ModuleElement, RingElement, \
    4040        Element
     41from sage.structure.element import parent
    4142
    4243import integer_ring
    4344from integer_ring import ZZ
     
    11341135                (<FractionFieldElement>other).__denominator,
    11351136                self.__denominator*(<FractionFieldElement>other).__numerator)
    11361137
    1137     def valuation(self):
     1138    def valuation(self, v=None):
    11381139        """
    11391140        Return the valuation of self, assuming that the numerator and
    11401141        denominator have valuation functions defined on them.
     
    11421143        EXAMPLES::
    11431144       
    11441145            sage: x = PolynomialRing(RationalField(),'x').gen()
    1145             sage: f = (x**3 + x)/(x**2 - 2*x**3)
     1146            sage: f = (x^3 + x)/(x^2 - 2*x^3)
    11461147            sage: f
    11471148            (x^2 + 1)/(-2*x^2 + x)
    11481149            sage: f.valuation()
    11491150            -1
     1151            sage: f.valuation(x^2+1)
     1152            1
    11501153        """
    1151         return self.__numerator.valuation() - self.__denominator.valuation()
     1154        return self.__numerator.valuation(v) - self.__denominator.valuation(v)
    11521155
    11531156    def __nonzero__(self):
    11541157        """
  • sage/rings/polynomial/polynomial_element.pyx

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

    diff -r 3ea4df2703a8 -r 3b9b429abf1f sage/rings/polynomial/polynomial_zmod_flint.pyx
    a b  
    3535
    3636from sage.libs.ntl.ntl_lzz_pX import ntl_zz_pX
    3737from sage.structure.factorization import Factorization
    38 from sage.structure.element import coerce_binop
     38from sage.structure.element import coerce_binop, parent
    3939
    4040# We need to define this stuff before including the templating stuff
    4141# to make sure the function get_cparent is found since it is used in
     
    178178        EXAMPLE::
    179179
    180180            sage: P.<x> = PolynomialRing(GF(7))
    181             sage: f= x^2 + 1
     181            sage: f = x^2 + 1
    182182            sage: f(0)
    183183            1
    184184            sage: f(2)
     
    188188
    189189            sage: f(x+1)
    190190            x^2 + 2*x + 2
     191           
     192        Test some simple (but important) optimizations::
     193       
     194            sage: f(2) == f(P(2))
     195            True
     196            sage: f(x) is f
     197            True
     198            sage: f(1/x)
     199            (x^2 + 1)/x^2
    191200        """
    192         cdef Polynomial_zmod_flint t
     201        cdef Polynomial_zmod_flint t, y
     202        cdef long c
    193203        K = self._parent.base_ring()
    194         if len(kwds) == 0 and len(x) == 1:
    195             try:
    196                 x = K._coerce_(x[0])
    197                 return K(zmod_poly_evaluate(&self.x, int(x)))
    198             except TypeError:
    199                 pass
    200             try:
    201                 x = self.parent().coerce(x[0])
     204        if not kwds and len(x) == 1:
     205            P = parent(x[0])
     206            if K.has_coerce_map_from(P):
     207                x = K(x[0])
     208                return K(zmod_poly_evaluate(&self.x, x))
     209            elif self._parent.has_coerce_map_from(P):
     210                y = <Polynomial_zmod_flint>self._parent(x[0])
    202211                t = self._new()
    203                 zmod_poly_compose_horner(&t.x, &self.x,
    204                         &(<Polynomial_zmod_flint>x).x)
     212                if zmod_poly_degree(&y.x) == 0:
     213                    c = zmod_poly_evaluate(&self.x, zmod_poly_get_coeff_ui(&y.x, 0))
     214                    zmod_poly_set_coeff_ui(&t.x, 0, c)
     215                elif zmod_poly_degree(&y.x) == 1 and zmod_poly_get_coeff_ui(&y.x, 0) == 0:
     216                    c = zmod_poly_get_coeff_ui(&y.x, 1)
     217                    if c == 1:
     218                        return self
     219                zmod_poly_compose_horner(&t.x, &self.x, &y.x)
    205220                return t
    206             except TypeError:
    207                 pass
    208221        return Polynomial.__call__(self, *x, **kwds)
     222   
     223    def reverse(self, long degree=-1):
     224        """
     225        Return self with the coefficients reversed.
     226       
     227        EXAMPLES::
     228       
     229            sage: R.<x> = GF(101)[]
     230            sage: f = x^3 - x + 2; f
     231            x^3 + 100*x + 2
     232            sage: f.reverse()
     233            2*x^3 + 100*x^2 + 1
     234            sage: f.reverse() == f(1/x) * x^f.degree()
     235            True
     236       
     237        Note that if `f` has zero constant coefficient, its reverse will
     238        have lower degree.
     239       
     240        ::
     241       
     242            sage: f = x^3 + 2*x
     243            sage: f.reverse()
     244            2*x^2 + 1
     245           
     246        In this case, reverse is not an involution unless we explicitly
     247        specify a degree.
     248       
     249        ::
     250           
     251            sage: f
     252            x^3 + 2*x
     253            sage: f.reverse().reverse()
     254            x^2 + 2
     255            sage: f.reverse(5).reverse(5)
     256            x^3 + 2*x
     257        """
     258        if degree == -1:
     259            degree = zmod_poly_degree(&self.x)
     260        cdef Polynomial_zmod_flint t = self._new()
     261        zmod_poly_reverse(&t.x, &self.x, degree+1)
     262        return t
    209263
    210264    @coerce_binop
    211265    def resultant(self, Polynomial_zmod_flint other):