switching to high quality piper tts and added label translations
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
"""Implementation of :class:`ComplexField` class. """
|
||||
|
||||
|
||||
from sympy.external.gmpy import SYMPY_INTS
|
||||
from sympy.core.numbers import Float, I
|
||||
from sympy.polys.domains.characteristiczero import CharacteristicZero
|
||||
from sympy.polys.domains.field import Field
|
||||
from sympy.polys.domains.gaussiandomains import QQ_I
|
||||
from sympy.polys.domains.simpledomain import SimpleDomain
|
||||
from sympy.polys.polyerrors import DomainError, CoercionFailed
|
||||
from sympy.utilities import public
|
||||
|
||||
from mpmath import MPContext
|
||||
|
||||
|
||||
@public
|
||||
class ComplexField(Field, CharacteristicZero, SimpleDomain):
|
||||
"""Complex numbers up to the given precision. """
|
||||
|
||||
rep = 'CC'
|
||||
|
||||
is_ComplexField = is_CC = True
|
||||
|
||||
is_Exact = False
|
||||
is_Numerical = True
|
||||
|
||||
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._tolerance
|
||||
|
||||
def __init__(self, prec=None, dps=None, tol=None):
|
||||
# XXX: The tolerance parameter is ignored but is kept for backward
|
||||
# compatibility for now.
|
||||
|
||||
context = MPContext()
|
||||
|
||||
if prec is None and dps is None:
|
||||
context.prec = self._default_precision
|
||||
elif dps is None:
|
||||
context.prec = prec
|
||||
elif prec is None:
|
||||
context.dps = dps
|
||||
else:
|
||||
raise TypeError("Cannot set both prec and dps")
|
||||
|
||||
self._context = context
|
||||
|
||||
self._dtype = context.mpc
|
||||
self.zero = self.dtype(0)
|
||||
self.one = self.dtype(1)
|
||||
|
||||
# XXX: Neither of these is actually used anywhere.
|
||||
self._max_denom = max(2**context.prec // 200, 99)
|
||||
self._tolerance = self.one / self._max_denom
|
||||
|
||||
@property
|
||||
def tp(self):
|
||||
# XXX: Domain treats tp as an alias of dtype. Here we need 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, x, y=0):
|
||||
# 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(x, SYMPY_INTS):
|
||||
x = int(x)
|
||||
if isinstance(y, SYMPY_INTS):
|
||||
y = int(y)
|
||||
return self._dtype(x, y)
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, ComplexField) and self.precision == other.precision
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.__class__.__name__, self._dtype, self.precision))
|
||||
|
||||
def to_sympy(self, element):
|
||||
"""Convert ``element`` to SymPy number. """
|
||||
return Float(element.real, self.dps) + I*Float(element.imag, self.dps)
|
||||
|
||||
def from_sympy(self, expr):
|
||||
"""Convert SymPy's number to ``dtype``. """
|
||||
number = expr.evalf(n=self.dps)
|
||||
real, imag = number.as_real_imag()
|
||||
|
||||
if real.is_Number and imag.is_Number:
|
||||
return self.dtype(real, imag)
|
||||
else:
|
||||
raise CoercionFailed("expected complex number, got %s" % expr)
|
||||
|
||||
def from_ZZ(self, element, base):
|
||||
return self.dtype(element)
|
||||
|
||||
def from_ZZ_gmpy(self, element, base):
|
||||
return self.dtype(int(element))
|
||||
|
||||
def from_ZZ_python(self, element, base):
|
||||
return self.dtype(element)
|
||||
|
||||
def from_QQ(self, element, base):
|
||||
return self.dtype(int(element.numerator)) / int(element.denominator)
|
||||
|
||||
def from_QQ_python(self, element, base):
|
||||
return self.dtype(element.numerator) / element.denominator
|
||||
|
||||
def from_QQ_gmpy(self, element, base):
|
||||
return self.dtype(int(element.numerator)) / int(element.denominator)
|
||||
|
||||
def from_GaussianIntegerRing(self, element, base):
|
||||
return self.dtype(int(element.x), int(element.y))
|
||||
|
||||
def from_GaussianRationalField(self, element, base):
|
||||
x = element.x
|
||||
y = element.y
|
||||
return (self.dtype(int(x.numerator)) / int(x.denominator) +
|
||||
self.dtype(0, int(y.numerator)) / int(y.denominator))
|
||||
|
||||
def from_AlgebraicField(self, element, base):
|
||||
return self.from_sympy(base.to_sympy(element).evalf(self.dps))
|
||||
|
||||
def from_RealField(self, element, base):
|
||||
return self.dtype(element)
|
||||
|
||||
def from_ComplexField(self, element, base):
|
||||
return self.dtype(element)
|
||||
|
||||
def get_ring(self):
|
||||
"""Returns a ring associated with ``self``. """
|
||||
raise DomainError("there is no ring associated with %s" % self)
|
||||
|
||||
def get_exact(self):
|
||||
"""Returns an exact domain associated with ``self``. """
|
||||
return QQ_I
|
||||
|
||||
def is_negative(self, element):
|
||||
"""Returns ``False`` for any ``ComplexElement``. """
|
||||
return False
|
||||
|
||||
def is_positive(self, element):
|
||||
"""Returns ``False`` for any ``ComplexElement``. """
|
||||
return False
|
||||
|
||||
def is_nonnegative(self, element):
|
||||
"""Returns ``False`` for any ``ComplexElement``. """
|
||||
return False
|
||||
|
||||
def is_nonpositive(self, element):
|
||||
"""Returns ``False`` for any ``ComplexElement``. """
|
||||
return False
|
||||
|
||||
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``. Every complex number has a complex square root."""
|
||||
return True
|
||||
|
||||
def exsqrt(self, a):
|
||||
r"""Returns the principal complex square root of ``a``.
|
||||
|
||||
Explanation
|
||||
===========
|
||||
The argument of the principal square root is always within
|
||||
$(-\frac{\pi}{2}, \frac{\pi}{2}]$. The square root may be
|
||||
slightly inaccurate due to floating point rounding error.
|
||||
"""
|
||||
return a ** 0.5
|
||||
|
||||
CC = ComplexField()
|
||||
Reference in New Issue
Block a user