Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Dense univariate polynomials over `\RR`, implemented using MPFR
TESTS:
Check that operations with numpy elements work well (see :trac:`18076` and :trac:`8426`)::
sage: import numpy sage: x = polygen(RR) sage: x * numpy.int32('1') x sage: numpy.int32('1') * x x sage: x * numpy.int64('1') x sage: numpy.int64('1') * x x sage: x * numpy.float32('1.5') 1.50000000000000*x sage: numpy.float32('1.5') * x 1.50000000000000*x """ from __future__ import absolute_import
from cysignals.memory cimport check_allocarray, check_reallocarray, sig_free from cysignals.signals cimport sig_on, sig_off
from cpython cimport PyInt_AS_LONG, PyFloat_AS_DOUBLE
from sage.structure.parent cimport Parent from .polynomial_element cimport Polynomial, _dict_to_list from sage.rings.real_mpfr cimport RealField_class, RealNumber from sage.rings.integer cimport Integer, smallInteger from sage.rings.rational cimport Rational
from sage.structure.element cimport Element, ModuleElement, RingElement from sage.structure.element cimport parent from sage.structure.element import coerce_binop from sage.libs.mpfr cimport *
from sage.libs.all import pari_gen
cdef class PolynomialRealDense(Polynomial): r"""
TESTS::
sage: f = RR['x'].random_element() sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: isinstance(f, PolynomialRealDense) True
"""
cdef Py_ssize_t _degree cdef mpfr_t* _coeffs cdef RealField_class _base_ring
def __cinit__(self): """ TESTS::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: PolynomialRealDense(RR['x']) 0 """
def __init__(self, Parent parent, x=0, check=None, bint is_gen=False, construct=None): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: PolynomialRealDense(RR['x'], [1, int(2), RR(3), 4/1, pi]) 3.14159265358979*x^4 + 4.00000000000000*x^3 + 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: PolynomialRealDense(RR['x'], None) 0
TESTS:
Check that errors and interrupts are handled properly (see :trac:`10100`)::
sage: a = var('a') sage: PolynomialRealDense(RR['x'], [1,a]) Traceback (most recent call last): ... TypeError: Cannot evaluate symbolic expression to a numeric value. sage: R.<x> = SR[] sage: (x-a).change_ring(RR) Traceback (most recent call last): ... TypeError: Cannot evaluate symbolic expression to a numeric value. sage: sig_on_count() 0
Test that we don't clean up uninitialized coefficients (:trac:`9826`)::
sage: k.<a> = GF(7^3) sage: P.<x> = PolynomialRing(k) sage: (a*x).complex_roots() Traceback (most recent call last): ... TypeError: unable to convert 'a' to a real number
Check that :trac:`17190` is fixed::
sage: RR['x']({}) 0 """ cdef Py_ssize_t i, degree except TypeError: # x is not iterable x = [self._base_ring(x)]
cdef mpfr_t* coeffs mpfr_set_d(coeffs[i], PyFloat_AS_DOUBLE(a), rnd) else: finally:
def __dealloc__(self): cdef Py_ssize_t i
def __reduce__(self): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2, 0, 1]) sage: loads(dumps(f)) == f True """
cdef _normalize(self): """ Remove all leading 0's. """ cdef Py_ssize_t i
cdef get_unsafe(self, Py_ssize_t i): """ Return the `i`-th coefficient of ``self``.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], range(5)); f 4.00000000000000*x^4 + 3.00000000000000*x^3 + 2.00000000000000*x^2 + x sage: f[0] 0.000000000000000 sage: f[3] 3.00000000000000 sage: f[5] 0.000000000000000
Test slices::
sage: R.<x> = RealField(10)[] sage: f = (x+1)^5; f x^5 + 5.0*x^4 + 10.*x^3 + 10.*x^2 + 5.0*x + 1.0 sage: f[:3] 10.*x^2 + 5.0*x + 1.0 """
cdef PolynomialRealDense _new(self, Py_ssize_t degree): cdef Py_ssize_t i
def degree(self): """ Return the degree of the polynomial.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [1, 2, 3]); f 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: f.degree() 2
TESTS::
sage: type(f.degree()) <type 'sage.rings.integer.Integer'> """
cpdef Polynomial truncate(self, long n): r""" Returns the polynomial of degree `< n` which is equivalent to self modulo `x^n`.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RealField(10)['x'], [1, 2, 4, 8]) sage: f.truncate(3) 4.0*x^2 + 2.0*x + 1.0 sage: f.truncate(100) 8.0*x^3 + 4.0*x^2 + 2.0*x + 1.0 sage: f.truncate(1) 1.0 sage: f.truncate(0) 0 """ cdef Py_ssize_t i
def truncate_abs(self, RealNumber bound): """ Truncate all high order coefficients below bound.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RealField(10)['x'], [10^-k for k in range(10)]) sage: f 1.0e-9*x^9 + 1.0e-8*x^8 + 1.0e-7*x^7 + 1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0 sage: f.truncate_abs(0.5e-6) 1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0 sage: f.truncate_abs(10.0) 0 sage: f.truncate_abs(1e-100) == f True """ cdef Py_ssize_t i
cpdef shift(self, Py_ssize_t n): r""" Returns this polynomial multiplied by the power `x^n`. If `n` is negative, terms below `x^n` will be discarded. Does not change this polynomial.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [1, 2, 3]); f 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 sage: f.shift(10) 3.00000000000000*x^12 + 2.00000000000000*x^11 + x^10 sage: f.shift(-1) 3.00000000000000*x + 2.00000000000000 sage: f.shift(-10) 0
TESTS::
sage: f = RR['x'](0) sage: f.shift(3).is_zero() True sage: f.shift(-3).is_zero() True """ cdef Py_ssize_t i cdef PolynomialRealDense f else:
cpdef list list(self, bint copy=True): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [1, 0, -2]); f -2.00000000000000*x^2 + 1.00000000000000 sage: f.list() [1.00000000000000, 0.000000000000000, -2.00000000000000] """ cdef RealNumber r cdef Py_ssize_t i
def __neg__(self): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2,0,1]) sage: -f -x^2 + 2.00000000000000 """ cdef Py_ssize_t i
cpdef _add_(left, _right): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2,0,1]); f x^2 - 2.00000000000000 sage: g = PolynomialRealDense(RR['x'], range(5)); g 4.00000000000000*x^4 + 3.00000000000000*x^3 + 2.00000000000000*x^2 + x sage: f+g 4.00000000000000*x^4 + 3.00000000000000*x^3 + 3.00000000000000*x^2 + x - 2.00000000000000 sage: g + f == f + g True sage: f + (-f) 0 """ cdef Py_ssize_t i else:
cpdef _sub_(left, _right): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-3,0,1]); f x^2 - 3.00000000000000 sage: g = PolynomialRealDense(RR['x'], range(4)); g 3.00000000000000*x^3 + 2.00000000000000*x^2 + x sage: f-g -3.00000000000000*x^3 - x^2 - x - 3.00000000000000 sage: (f-g) == -(g-f) True """ cdef Py_ssize_t i else:
cpdef _lmul_(self, Element c): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-5,0,0,1]); f x^3 - 5.00000000000000 sage: 4.0 * f 4.00000000000000*x^3 - 20.0000000000000 sage: f * -0.2 -0.200000000000000*x^3 + 1.00000000000000 """ cdef Py_ssize_t i return self._new(-1)
cpdef _mul_(left, _right): """ Here we use the naive `O(n^2)` algorithm, as asymptotically faster algorithms such as Karatsuba can have very inaccurate results due to intermediate rounding errors.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [1e20, 1]) sage: g = PolynomialRealDense(RR['x'], [1e30, 1]) sage: f*g x^2 + 1.00000000010000e30*x + 1.00000000000000e50 sage: f._mul_karatsuba(g,0) x^2 + 1.00000000000000e50 sage: f = PolynomialRealDense(RR['x'], range(5)) sage: g = PolynomialRealDense(RR['x'], range(3)) sage: f*g 8.00000000000000*x^6 + 10.0000000000000*x^5 + 7.00000000000000*x^4 + 4.00000000000000*x^3 + x^2 """ cdef Py_ssize_t i, j cdef PolynomialRealDense f cdef mpfr_t tmp else: # Yes, we could make this more efficient by initializing with # a multiple of left rather than all zeros...
def _derivative(self, var=None): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [pi, 0, 2, 1]); sage: f.derivative() 3.00000000000000*x^2 + 4.00000000000000*x """ return self._new(-1)
def integral(self): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [3, pi, 1]) sage: f.integral() 0.333333333333333*x^3 + 1.57079632679490*x^2 + 3.00000000000000*x """
def reverse(self): """ Returns `x^d f(1/x)` where `d` is the degree of `f`.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-3, pi, 0, 1]) sage: f.reverse() -3.00000000000000*x^3 + 3.14159265358979*x^2 + 1.00000000000000 """
@coerce_binop def quo_rem(self, PolynomialRealDense other): """ Return the quotient with remainder of ``self`` by ``other``.
EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2, 0, 1]) sage: g = PolynomialRealDense(RR['x'], [5, 1]) sage: q, r = f.quo_rem(g) sage: q x - 5.00000000000000 sage: r 23.0000000000000 sage: q*g + r == f True sage: fg = f*g sage: fg.quo_rem(f) (x + 5.00000000000000, 0) sage: fg.quo_rem(g) (x^2 - 2.00000000000000, 0)
sage: f = PolynomialRealDense(RR['x'], range(5)) sage: g = PolynomialRealDense(RR['x'], [pi,3000,4]) sage: q, r = f.quo_rem(g) sage: g*q + r == f True
TESTS:
Check that :trac:`18467` is fixed::
sage: S.<x> = RR[] sage: z = S.zero() sage: z.degree() -1 sage: q, r = z.quo_rem(x) sage: q.degree() -1 """ raise ZeroDivisionError("other must be nonzero") cdef PolynomialRealDense q, r cdef Py_ssize_t i, j cdef mpfr_t tmp # Make divisor monic for simplicity # This is the standard division algorithm
def __call__(self, *args, **kwds): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2, 0, 1]) sage: f(10) 98.0000000000000 sage: f(CC.0) -3.00000000000000 sage: f(2.0000000000000000000000000000000000000000000) 2.00000000000000 sage: f(RealField(10)(2)) 2.0 sage: f(pi) 1.00000000000000*pi^2 - 2.00000000000000
sage: f = PolynomialRealDense(RR['x'], range(5)) sage: f(1) 10.0000000000000 sage: f(-1) 2.00000000000000 sage: f(0) 0.000000000000000 sage: f = PolynomialRealDense(RR['x']) sage: f(12) 0.000000000000000
TESTS::
sage: R.<x> = RR[] # trac #17311 sage: (x^2+1)(x=5) 26.0000000000000 """ else:
else:
cdef Py_ssize_t i cdef RealNumber res
else: # Optimize some very useful and common cases: else:
def change_ring(self, R): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense sage: f = PolynomialRealDense(RR['x'], [-2, 0, 1.5]) sage: f.change_ring(QQ) 3/2*x^2 - 2 sage: f.change_ring(RealField(10)) 1.5*x^2 - 2.0 sage: f.change_ring(RealField(100)) 1.5000000000000000000000000000*x^2 - 2.0000000000000000000000000000 """ cdef Py_ssize_t i cdef PolynomialRealDense f else:
def make_PolynomialRealDense(parent, data): """ EXAMPLES::
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import make_PolynomialRealDense sage: make_PolynomialRealDense(RR['x'], [1,2,3]) 3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000 """
|