def __new__(cls, lhs, rhs=0, **options): from sympy.core.add import Add from sympy.core.logic import fuzzy_bool from sympy.core.expr import _n2 from sympy.simplify.simplify import clear_coefficients lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_evaluate[0]) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # check finiteness fin = L, R = [i.is_finite for i in (lhs, rhs)] if None not in fin: if L != R: return S.false if L is False: if lhs == -rhs: # Eq(oo, -oo) return S.false return S.true elif None in fin and False in fin: return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator infinite does not # make the original expression True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)
def __new__(cls, lhs, rhs=0, **options): from sympy.core.add import Add from sympy.core.logic import fuzzy_bool from sympy.core.expr import _n2 from sympy.simplify.simplify import clear_coefficients lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_evaluate[0]) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance( lhs, Boolean) != isinstance(rhs, Boolean)): return S.false # only Booleans can equal Booleans # check finiteness fin = L, R = [i.is_finite for i in (lhs, rhs)] if None not in fin: if L != R: return S.false if L is False: if lhs == -rhs: # Eq(oo, -oo) return S.false return S.true elif None in fin and False in fin: return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator infinite does not # make the original expression True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)
def __new__(cls, lhs, rhs=None, **options): from sympy.core.add import Add from sympy.core.containers import Tuple from sympy.core.logic import fuzzy_bool, fuzzy_xor, fuzzy_and, fuzzy_not from sympy.core.expr import _n2 from sympy.functions.elementary.complexes import arg from sympy.simplify.simplify import clear_coefficients from sympy.utilities.iterables import sift if rhs is None: SymPyDeprecationWarning(feature="Eq(expr) with rhs default to 0", useinstead="Eq(expr, 0)", issue=16587, deprecated_since_version="1.5").warn() rhs = 0 lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_parameters.evaluate) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance( lhs, Boolean) != isinstance(rhs, Boolean)): return S.false # only Booleans can equal Booleans if lhs.is_infinite or rhs.is_infinite: if fuzzy_xor([lhs.is_infinite, rhs.is_infinite]): return S.false if fuzzy_xor([lhs.is_extended_real, rhs.is_extended_real]): return S.false if fuzzy_and([lhs.is_extended_real, rhs.is_extended_real]): r = fuzzy_xor([ lhs.is_extended_positive, fuzzy_not(rhs.is_extended_positive) ]) return S(r) # Try to split real/imaginary parts and equate them I = S.ImaginaryUnit def split_real_imag(expr): real_imag = lambda t: ('real' if t.is_extended_real else 'imag' if (I * t).is_extended_real else None) return sift(Add.make_args(expr), real_imag) lhs_ri = split_real_imag(lhs) if not lhs_ri[None]: rhs_ri = split_real_imag(rhs) if not rhs_ri[None]: eq_real = Eq(Add(*lhs_ri['real']), Add(*rhs_ri['real'])) eq_imag = Eq(I * Add(*lhs_ri['imag']), I * Add(*rhs_ri['imag'])) res = fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag])) if res is not None: return S(res) # Compare e.g. zoo with 1+I*oo by comparing args arglhs = arg(lhs) argrhs = arg(rhs) # Guard against Eq(nan, nan) -> False if not (arglhs == S.NaN and argrhs == S.NaN): res = fuzzy_bool(Eq(arglhs, argrhs)) if res is not None: return S(res) return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator # infinite does not make the original expression # True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)