| 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) |