Ticket #12173: 17060.patch

File 17060.patch, 4.3 KB (added by jpflori, 10 years ago)

Take #10617 into account

  • sage/libs/flint/fmpz.pxi

    diff --git a/sage/libs/flint/fmpz.pxi b/sage/libs/flint/fmpz.pxi
    a b  
    1818    void fmpz_sub_ui_inplace(fmpz_t output, unsigned long x)
    1919   
    2020    void fmpz_to_mpz(mpz_t rop, fmpz_t op)
     21    void mpz_to_fmpz(fmpz_t rop, mpz_t op)
     22
  • sage/rings/polynomial/polynomial_integer_dense_flint.pyx

    diff --git a/sage/rings/polynomial/polynomial_integer_dense_flint.pyx b/sage/rings/polynomial/polynomial_integer_dense_flint.pyx
    a b  
    5050cdef extern from "FLINT/flint.h":
    5151    int FLINT_BITS
    5252
    53 
    5453cdef class Polynomial_integer_dense_flint(Polynomial):
    5554    r"""
    5655    A dense polynomial over the integers, implemented via FLINT.
     
    6968        """
    7069        fmpz_poly_clear(self.__poly)
    7170
    72 
    7371    cdef Polynomial_integer_dense_flint _new(self):
    7472        r"""
    7573        Quickly creates a new initialized Polynomial_integer_dense_flint
     
    259257                fmpz_poly_set_coeff_mpz(self.__poly, i, (<Integer>a).value)
    260258                sig_off()
    261259
     260    def __call__(self, *x, **kwds):
     261        """
     262        Calls this polynomial with the given parameters, which can be
     263        interpreted as polynomial composition or evaluation by this
     264        method.
     265
     266        If the argument is not simply an integer (``int``, ``long`` or
     267        ``Integer``) or a polynomial (of the same type as ``self``),
     268        the call is passed on to the generic implementation in the
     269        ``Polynomial`` class.
     270
     271        EXAMPLES:
     272
     273        The first example illustrates polynomial composition::
     274       
     275            sage: R.<t> = ZZ[]
     276            sage: f = t^2 - 1
     277            sage: g = t + 1
     278            sage: f(g)          # indirect doctest
     279            t^2 + 2*t
     280               
     281        Now we illustrate how a polynomial can be evaluated at an
     282        integer::
     283       
     284            sage: f(2)          # indirect doctest
     285            3
     286        """
     287        cdef Polynomial_integer_dense_flint f
     288        cdef Integer a, z
     289
     290        cdef unsigned long limbs
     291        cdef fmpz_t a_fmpz
     292        cdef fmpz_t z_fmpz
     293       
     294        if len(x) == 1:
     295            x0 = x[0]
     296            if isinstance(x, Polynomial_integer_dense_flint):
     297                f = self._new()
     298                _sig_on
     299                fmpz_poly_compose(f.__poly, self.__poly, \
     300                    (<Polynomial_integer_dense_flint> x0).__poly)
     301                _sig_off
     302                return f
     303            if isinstance(x0, (int, long)):
     304                x0 = Integer(x0)
     305            if isinstance(x0, Integer):
     306                a = <Integer> x0
     307
     308                if fmpz_poly_length(self.__poly) == 0:
     309                    return ZZ.zero()
     310                if mpz_sgn(a.value) == 0:
     311                    return self[0]
     312
     313                # As of FLINT1.5, memory management for the fmpz_t type
     314                # has to be done manually.  Without inspection of all
     315                # coefficients, we can only naively bound the size of
     316                # the answer by the very large value of "limbs" below. 
     317                # If this number is too large, we move on to the generic
     318                # polynomial evaluation code, which might either happen
     319                # to work (in special cases) or simply run out of memory.
     320                #
     321                # It is expected that this workaround is unnecessary
     322                # with FLINT2.
     323                if fmpz_poly_length(self.__poly) <= ((1 << 25) / fmpz_poly_length(self.__poly) - fmpz_poly_limbs(self.__poly)) / mpz_size(a.value):
     324
     325                    z = PY_NEW(Integer)
     326
     327                    _sig_on
     328                    limbs = fmpz_poly_length(self.__poly) * (fmpz_poly_limbs(self.__poly) + fmpz_poly_length(self.__poly) * mpz_size(a.value))
     329                    a_fmpz = fmpz_init(mpz_size(a.value))
     330                    z_fmpz = fmpz_init(limbs)
     331                    mpz_to_fmpz(a_fmpz, a.value)
     332
     333                    fmpz_poly_evaluate(z_fmpz, self.__poly, a_fmpz)
     334
     335                    fmpz_to_mpz(z.value, z_fmpz)
     336                    fmpz_clear(a_fmpz)
     337                    fmpz_clear(z_fmpz)
     338                    _sig_off
     339
     340                    return z
     341
     342        return Polynomial.__call__(self, *x, **kwds)
    262343
    263344    cpdef Integer content(self):
    264345        r"""