123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- """Implementation of :class:`ExpressionDomain` class. """
- from sympy.core import sympify, SympifyError
- from sympy.polys.domains.characteristiczero import CharacteristicZero
- from sympy.polys.domains.field import Field
- from sympy.polys.domains.simpledomain import SimpleDomain
- from sympy.polys.polyutils import PicklableWithSlots
- from sympy.utilities import public
- eflags = dict(deep=False, mul=True, power_exp=False, power_base=False,
- basic=False, multinomial=False, log=False)
- @public
- class ExpressionDomain(Field, CharacteristicZero, SimpleDomain):
- """A class for arbitrary expressions. """
- is_SymbolicDomain = is_EX = True
- class Expression(PicklableWithSlots):
- """An arbitrary expression. """
- __slots__ = ('ex',)
- def __init__(self, ex):
- if not isinstance(ex, self.__class__):
- self.ex = sympify(ex)
- else:
- self.ex = ex.ex
- def __repr__(f):
- return 'EX(%s)' % repr(f.ex)
- def __str__(f):
- return 'EX(%s)' % str(f.ex)
- def __hash__(self):
- return hash((self.__class__.__name__, self.ex))
- def as_expr(f):
- return f.ex
- def numer(f):
- return f.__class__(f.ex.as_numer_denom()[0])
- def denom(f):
- return f.__class__(f.ex.as_numer_denom()[1])
- def simplify(f, ex):
- return f.__class__(ex.cancel().expand(**eflags))
- def __abs__(f):
- return f.__class__(abs(f.ex))
- def __neg__(f):
- return f.__class__(-f.ex)
- def _to_ex(f, g):
- try:
- return f.__class__(g)
- except SympifyError:
- return None
- def __add__(f, g):
- g = f._to_ex(g)
- if g is None:
- return NotImplemented
- elif g == EX.zero:
- return f
- elif f == EX.zero:
- return g
- else:
- return f.simplify(f.ex + g.ex)
- def __radd__(f, g):
- return f.simplify(f.__class__(g).ex + f.ex)
- def __sub__(f, g):
- g = f._to_ex(g)
- if g is None:
- return NotImplemented
- elif g == EX.zero:
- return f
- elif f == EX.zero:
- return -g
- else:
- return f.simplify(f.ex - g.ex)
- def __rsub__(f, g):
- return f.simplify(f.__class__(g).ex - f.ex)
- def __mul__(f, g):
- g = f._to_ex(g)
- if g is None:
- return NotImplemented
- if EX.zero in (f, g):
- return EX.zero
- elif f.ex.is_Number and g.ex.is_Number:
- return f.__class__(f.ex*g.ex)
- return f.simplify(f.ex*g.ex)
- def __rmul__(f, g):
- return f.simplify(f.__class__(g).ex*f.ex)
- def __pow__(f, n):
- n = f._to_ex(n)
- if n is not None:
- return f.simplify(f.ex**n.ex)
- else:
- return NotImplemented
- def __truediv__(f, g):
- g = f._to_ex(g)
- if g is not None:
- return f.simplify(f.ex/g.ex)
- else:
- return NotImplemented
- def __rtruediv__(f, g):
- return f.simplify(f.__class__(g).ex/f.ex)
- def __eq__(f, g):
- return f.ex == f.__class__(g).ex
- def __ne__(f, g):
- return not f == g
- def __bool__(f):
- return not f.ex.is_zero
- def gcd(f, g):
- from sympy.polys import gcd
- return f.__class__(gcd(f.ex, f.__class__(g).ex))
- def lcm(f, g):
- from sympy.polys import lcm
- return f.__class__(lcm(f.ex, f.__class__(g).ex))
- dtype = Expression
- zero = Expression(0)
- one = Expression(1)
- rep = 'EX'
- has_assoc_Ring = False
- has_assoc_Field = True
- def __init__(self):
- pass
- def to_sympy(self, a):
- """Convert ``a`` to a SymPy object. """
- return a.as_expr()
- def from_sympy(self, a):
- """Convert SymPy's expression to ``dtype``. """
- return self.dtype(a)
- def from_ZZ(K1, a, K0):
- """Convert a Python ``int`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_ZZ_python(K1, a, K0):
- """Convert a Python ``int`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_QQ(K1, a, K0):
- """Convert a Python ``Fraction`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_QQ_python(K1, a, K0):
- """Convert a Python ``Fraction`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_ZZ_gmpy(K1, a, K0):
- """Convert a GMPY ``mpz`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_QQ_gmpy(K1, a, K0):
- """Convert a GMPY ``mpq`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_GaussianIntegerRing(K1, a, K0):
- """Convert a ``GaussianRational`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_GaussianRationalField(K1, a, K0):
- """Convert a ``GaussianRational`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_RealField(K1, a, K0):
- """Convert a mpmath ``mpf`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_PolynomialRing(K1, a, K0):
- """Convert a ``DMP`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_FractionField(K1, a, K0):
- """Convert a ``DMF`` object to ``dtype``. """
- return K1(K0.to_sympy(a))
- def from_ExpressionDomain(K1, a, K0):
- """Convert a ``EX`` object to ``dtype``. """
- return a
- def get_ring(self):
- """Returns a ring associated with ``self``. """
- return self # XXX: EX is not a ring but we don't have much choice here.
- def get_field(self):
- """Returns a field associated with ``self``. """
- return self
- def is_positive(self, a):
- """Returns True if ``a`` is positive. """
- return a.ex.as_coeff_mul()[0].is_positive
- def is_negative(self, a):
- """Returns True if ``a`` is negative. """
- return a.ex.could_extract_minus_sign()
- def is_nonpositive(self, a):
- """Returns True if ``a`` is non-positive. """
- return a.ex.as_coeff_mul()[0].is_nonpositive
- def is_nonnegative(self, a):
- """Returns True if ``a`` is non-negative. """
- return a.ex.as_coeff_mul()[0].is_nonnegative
- def numer(self, a):
- """Returns numerator of ``a``. """
- return a.numer()
- def denom(self, a):
- """Returns denominator of ``a``. """
- return a.denom()
- def gcd(self, a, b):
- return self(1)
- def lcm(self, a, b):
- return a.lcm(b)
- EX = ExpressionDomain()
|