Kano001's picture
Upload 3077 files
6a86ad5 verified
raw
history blame
5.1 kB
"""Implementation of :class:`RealField` class. """
from sympy.external.gmpy import SYMPY_INTS
from sympy.core.numbers import Float
from sympy.polys.domains.field import Field
from sympy.polys.domains.simpledomain import SimpleDomain
from sympy.polys.domains.characteristiczero import CharacteristicZero
from sympy.polys.domains.mpelements import MPContext
from sympy.polys.polyerrors import CoercionFailed
from sympy.utilities import public
@public
class RealField(Field, CharacteristicZero, SimpleDomain):
"""Real numbers up to the given precision. """
rep = 'RR'
is_RealField = is_RR = True
is_Exact = False
is_Numerical = True
is_PID = False
has_assoc_Ring = False
has_assoc_Field = True
_default_precision = 53
@property
def has_default_precision(self):
return self.precision == self._default_precision
@property
def precision(self):
return self._context.prec
@property
def dps(self):
return self._context.dps
@property
def tolerance(self):
return self._context.tolerance
def __init__(self, prec=_default_precision, dps=None, tol=None):
context = MPContext(prec, dps, tol, True)
context._parent = self
self._context = context
self._dtype = context.mpf
self.zero = self.dtype(0)
self.one = self.dtype(1)
@property
def tp(self):
# XXX: Domain treats tp as an alis of dtype. Here we need to two
# separate things: dtype is a callable to make/convert instances.
# We use tp with isinstance to check if an object is an instance
# of the domain already.
return self._dtype
def dtype(self, arg):
# XXX: This is needed because mpmath does not recognise fmpz.
# It might be better to add conversion routines to mpmath and if that
# happens then this can be removed.
if isinstance(arg, SYMPY_INTS):
arg = int(arg)
return self._dtype(arg)
def __eq__(self, other):
return (isinstance(other, RealField)
and self.precision == other.precision
and self.tolerance == other.tolerance)
def __hash__(self):
return hash((self.__class__.__name__, self._dtype, self.precision, self.tolerance))
def to_sympy(self, element):
"""Convert ``element`` to SymPy number. """
return Float(element, self.dps)
def from_sympy(self, expr):
"""Convert SymPy's number to ``dtype``. """
number = expr.evalf(n=self.dps)
if number.is_Number:
return self.dtype(number)
else:
raise CoercionFailed("expected real number, got %s" % expr)
def from_ZZ(self, element, base):
return self.dtype(element)
def from_ZZ_python(self, element, base):
return self.dtype(element)
def from_ZZ_gmpy(self, element, base):
return self.dtype(int(element))
# XXX: We need to convert the denominators to int here because mpmath does
# not recognise mpz. Ideally mpmath would handle this and if it changed to
# do so then the calls to int here could be removed.
def from_QQ(self, element, base):
return self.dtype(element.numerator) / int(element.denominator)
def from_QQ_python(self, element, base):
return self.dtype(element.numerator) / int(element.denominator)
def from_QQ_gmpy(self, element, base):
return self.dtype(int(element.numerator)) / int(element.denominator)
def from_AlgebraicField(self, element, base):
return self.from_sympy(base.to_sympy(element).evalf(self.dps))
def from_RealField(self, element, base):
if self == base:
return element
else:
return self.dtype(element)
def from_ComplexField(self, element, base):
if not element.imag:
return self.dtype(element.real)
def to_rational(self, element, limit=True):
"""Convert a real number to rational number. """
return self._context.to_rational(element, limit)
def get_ring(self):
"""Returns a ring associated with ``self``. """
return self
def get_exact(self):
"""Returns an exact domain associated with ``self``. """
from sympy.polys.domains import QQ
return QQ
def gcd(self, a, b):
"""Returns GCD of ``a`` and ``b``. """
return self.one
def lcm(self, a, b):
"""Returns LCM of ``a`` and ``b``. """
return a*b
def almosteq(self, a, b, tolerance=None):
"""Check if ``a`` and ``b`` are almost equal. """
return self._context.almosteq(a, b, tolerance)
def is_square(self, a):
"""Returns ``True`` if ``a >= 0`` and ``False`` otherwise. """
return a >= 0
def exsqrt(self, a):
"""Non-negative square root for ``a >= 0`` and ``None`` otherwise.
Explanation
===========
The square root may be slightly inaccurate due to floating point
rounding error.
"""
return a ** 0.5 if a >= 0 else None
RR = RealField()