12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253 |
- from sympy.core.logic import fuzzy_and
- from sympy.core.sympify import _sympify
- from sympy.multipledispatch import dispatch
- from sympy.testing.pytest import XFAIL, raises
- from sympy.assumptions.ask import Q
- from sympy.core.add import Add
- from sympy.core.basic import Basic
- from sympy.core.expr import Expr
- from sympy.core.function import Function
- from sympy.core.mul import Mul
- from sympy.core.numbers import (Float, I, Rational, nan, oo, pi, zoo)
- from sympy.core.power import Pow
- from sympy.core.singleton import S
- from sympy.core.symbol import (Symbol, symbols)
- from sympy.functions.elementary.exponential import (exp, exp_polar, log)
- from sympy.functions.elementary.integers import (ceiling, floor)
- from sympy.functions.elementary.miscellaneous import sqrt
- from sympy.functions.elementary.trigonometric import (cos, sin)
- from sympy.logic.boolalg import (And, Implies, Not, Or, Xor)
- from sympy.sets import Reals
- from sympy.simplify.simplify import simplify
- from sympy.simplify.trigsimp import trigsimp
- from sympy.core.relational import (Relational, Equality, Unequality,
- GreaterThan, LessThan, StrictGreaterThan,
- StrictLessThan, Rel, Eq, Lt, Le,
- Gt, Ge, Ne, is_le, is_gt, is_ge, is_lt, is_eq, is_neq)
- from sympy.sets.sets import Interval, FiniteSet
- from itertools import combinations
- x, y, z, t = symbols('x,y,z,t')
- def rel_check(a, b):
- from sympy.testing.pytest import raises
- assert a.is_number and b.is_number
- for do in range(len({type(a), type(b)})):
- if S.NaN in (a, b):
- v = [(a == b), (a != b)]
- assert len(set(v)) == 1 and v[0] == False
- assert not (a != b) and not (a == b)
- assert raises(TypeError, lambda: a < b)
- assert raises(TypeError, lambda: a <= b)
- assert raises(TypeError, lambda: a > b)
- assert raises(TypeError, lambda: a >= b)
- else:
- E = [(a == b), (a != b)]
- assert len(set(E)) == 2
- v = [
- (a < b), (a <= b), (a > b), (a >= b)]
- i = [
- [True, True, False, False],
- [False, True, False, True], # <-- i == 1
- [False, False, True, True]].index(v)
- if i == 1:
- assert E[0] or (a.is_Float != b.is_Float) # ugh
- else:
- assert E[1]
- a, b = b, a
- return True
- def test_rel_ne():
- assert Relational(x, y, '!=') == Ne(x, y)
- # issue 6116
- p = Symbol('p', positive=True)
- assert Ne(p, 0) is S.true
- def test_rel_subs():
- e = Relational(x, y, '==')
- e = e.subs(x, z)
- assert isinstance(e, Equality)
- assert e.lhs == z
- assert e.rhs == y
- e = Relational(x, y, '>=')
- e = e.subs(x, z)
- assert isinstance(e, GreaterThan)
- assert e.lhs == z
- assert e.rhs == y
- e = Relational(x, y, '<=')
- e = e.subs(x, z)
- assert isinstance(e, LessThan)
- assert e.lhs == z
- assert e.rhs == y
- e = Relational(x, y, '>')
- e = e.subs(x, z)
- assert isinstance(e, StrictGreaterThan)
- assert e.lhs == z
- assert e.rhs == y
- e = Relational(x, y, '<')
- e = e.subs(x, z)
- assert isinstance(e, StrictLessThan)
- assert e.lhs == z
- assert e.rhs == y
- e = Eq(x, 0)
- assert e.subs(x, 0) is S.true
- assert e.subs(x, 1) is S.false
- def test_wrappers():
- e = x + x**2
- res = Relational(y, e, '==')
- assert Rel(y, x + x**2, '==') == res
- assert Eq(y, x + x**2) == res
- res = Relational(y, e, '<')
- assert Lt(y, x + x**2) == res
- res = Relational(y, e, '<=')
- assert Le(y, x + x**2) == res
- res = Relational(y, e, '>')
- assert Gt(y, x + x**2) == res
- res = Relational(y, e, '>=')
- assert Ge(y, x + x**2) == res
- res = Relational(y, e, '!=')
- assert Ne(y, x + x**2) == res
- def test_Eq_Ne():
- assert Eq(x, x) # issue 5719
- # issue 6116
- p = Symbol('p', positive=True)
- assert Eq(p, 0) is S.false
- # issue 13348; 19048
- # SymPy is strict about 0 and 1 not being
- # interpreted as Booleans
- assert Eq(True, 1) is S.false
- assert Eq(False, 0) is S.false
- assert Eq(~x, 0) is S.false
- assert Eq(~x, 1) is S.false
- assert Ne(True, 1) is S.true
- assert Ne(False, 0) is S.true
- assert Ne(~x, 0) is S.true
- assert Ne(~x, 1) is S.true
- assert Eq((), 1) is S.false
- assert Ne((), 1) is S.true
- def test_as_poly():
- from sympy.polys.polytools import Poly
- # Only Eq should have an as_poly method:
- assert Eq(x, 1).as_poly() == Poly(x - 1, x, domain='ZZ')
- raises(AttributeError, lambda: Ne(x, 1).as_poly())
- raises(AttributeError, lambda: Ge(x, 1).as_poly())
- raises(AttributeError, lambda: Gt(x, 1).as_poly())
- raises(AttributeError, lambda: Le(x, 1).as_poly())
- raises(AttributeError, lambda: Lt(x, 1).as_poly())
- def test_rel_Infinity():
- # NOTE: All of these are actually handled by sympy.core.Number, and do
- # not create Relational objects.
- assert (oo > oo) is S.false
- assert (oo > -oo) is S.true
- assert (oo > 1) is S.true
- assert (oo < oo) is S.false
- assert (oo < -oo) is S.false
- assert (oo < 1) is S.false
- assert (oo >= oo) is S.true
- assert (oo >= -oo) is S.true
- assert (oo >= 1) is S.true
- assert (oo <= oo) is S.true
- assert (oo <= -oo) is S.false
- assert (oo <= 1) is S.false
- assert (-oo > oo) is S.false
- assert (-oo > -oo) is S.false
- assert (-oo > 1) is S.false
- assert (-oo < oo) is S.true
- assert (-oo < -oo) is S.false
- assert (-oo < 1) is S.true
- assert (-oo >= oo) is S.false
- assert (-oo >= -oo) is S.true
- assert (-oo >= 1) is S.false
- assert (-oo <= oo) is S.true
- assert (-oo <= -oo) is S.true
- assert (-oo <= 1) is S.true
- def test_infinite_symbol_inequalities():
- x = Symbol('x', extended_positive=True, infinite=True)
- y = Symbol('y', extended_positive=True, infinite=True)
- z = Symbol('z', extended_negative=True, infinite=True)
- w = Symbol('w', extended_negative=True, infinite=True)
- inf_set = (x, y, oo)
- ninf_set = (z, w, -oo)
- for inf1 in inf_set:
- assert (inf1 < 1) is S.false
- assert (inf1 > 1) is S.true
- assert (inf1 <= 1) is S.false
- assert (inf1 >= 1) is S.true
- for inf2 in inf_set:
- assert (inf1 < inf2) is S.false
- assert (inf1 > inf2) is S.false
- assert (inf1 <= inf2) is S.true
- assert (inf1 >= inf2) is S.true
- for ninf1 in ninf_set:
- assert (inf1 < ninf1) is S.false
- assert (inf1 > ninf1) is S.true
- assert (inf1 <= ninf1) is S.false
- assert (inf1 >= ninf1) is S.true
- assert (ninf1 < inf1) is S.true
- assert (ninf1 > inf1) is S.false
- assert (ninf1 <= inf1) is S.true
- assert (ninf1 >= inf1) is S.false
- for ninf1 in ninf_set:
- assert (ninf1 < 1) is S.true
- assert (ninf1 > 1) is S.false
- assert (ninf1 <= 1) is S.true
- assert (ninf1 >= 1) is S.false
- for ninf2 in ninf_set:
- assert (ninf1 < ninf2) is S.false
- assert (ninf1 > ninf2) is S.false
- assert (ninf1 <= ninf2) is S.true
- assert (ninf1 >= ninf2) is S.true
- def test_bool():
- assert Eq(0, 0) is S.true
- assert Eq(1, 0) is S.false
- assert Ne(0, 0) is S.false
- assert Ne(1, 0) is S.true
- assert Lt(0, 1) is S.true
- assert Lt(1, 0) is S.false
- assert Le(0, 1) is S.true
- assert Le(1, 0) is S.false
- assert Le(0, 0) is S.true
- assert Gt(1, 0) is S.true
- assert Gt(0, 1) is S.false
- assert Ge(1, 0) is S.true
- assert Ge(0, 1) is S.false
- assert Ge(1, 1) is S.true
- assert Eq(I, 2) is S.false
- assert Ne(I, 2) is S.true
- raises(TypeError, lambda: Gt(I, 2))
- raises(TypeError, lambda: Ge(I, 2))
- raises(TypeError, lambda: Lt(I, 2))
- raises(TypeError, lambda: Le(I, 2))
- a = Float('.000000000000000000001', '')
- b = Float('.0000000000000000000001', '')
- assert Eq(pi + a, pi + b) is S.false
- def test_rich_cmp():
- assert (x < y) == Lt(x, y)
- assert (x <= y) == Le(x, y)
- assert (x > y) == Gt(x, y)
- assert (x >= y) == Ge(x, y)
- def test_doit():
- from sympy.core.symbol import Symbol
- p = Symbol('p', positive=True)
- n = Symbol('n', negative=True)
- np = Symbol('np', nonpositive=True)
- nn = Symbol('nn', nonnegative=True)
- assert Gt(p, 0).doit() is S.true
- assert Gt(p, 1).doit() == Gt(p, 1)
- assert Ge(p, 0).doit() is S.true
- assert Le(p, 0).doit() is S.false
- assert Lt(n, 0).doit() is S.true
- assert Le(np, 0).doit() is S.true
- assert Gt(nn, 0).doit() == Gt(nn, 0)
- assert Lt(nn, 0).doit() is S.false
- assert Eq(x, 0).doit() == Eq(x, 0)
- def test_new_relational():
- x = Symbol('x')
- assert Eq(x, 0) == Relational(x, 0) # None ==> Equality
- assert Eq(x, 0) == Relational(x, 0, '==')
- assert Eq(x, 0) == Relational(x, 0, 'eq')
- assert Eq(x, 0) == Equality(x, 0)
- assert Eq(x, 0) != Relational(x, 1) # None ==> Equality
- assert Eq(x, 0) != Relational(x, 1, '==')
- assert Eq(x, 0) != Relational(x, 1, 'eq')
- assert Eq(x, 0) != Equality(x, 1)
- assert Eq(x, -1) == Relational(x, -1) # None ==> Equality
- assert Eq(x, -1) == Relational(x, -1, '==')
- assert Eq(x, -1) == Relational(x, -1, 'eq')
- assert Eq(x, -1) == Equality(x, -1)
- assert Eq(x, -1) != Relational(x, 1) # None ==> Equality
- assert Eq(x, -1) != Relational(x, 1, '==')
- assert Eq(x, -1) != Relational(x, 1, 'eq')
- assert Eq(x, -1) != Equality(x, 1)
- assert Ne(x, 0) == Relational(x, 0, '!=')
- assert Ne(x, 0) == Relational(x, 0, '<>')
- assert Ne(x, 0) == Relational(x, 0, 'ne')
- assert Ne(x, 0) == Unequality(x, 0)
- assert Ne(x, 0) != Relational(x, 1, '!=')
- assert Ne(x, 0) != Relational(x, 1, '<>')
- assert Ne(x, 0) != Relational(x, 1, 'ne')
- assert Ne(x, 0) != Unequality(x, 1)
- assert Ge(x, 0) == Relational(x, 0, '>=')
- assert Ge(x, 0) == Relational(x, 0, 'ge')
- assert Ge(x, 0) == GreaterThan(x, 0)
- assert Ge(x, 1) != Relational(x, 0, '>=')
- assert Ge(x, 1) != Relational(x, 0, 'ge')
- assert Ge(x, 1) != GreaterThan(x, 0)
- assert (x >= 1) == Relational(x, 1, '>=')
- assert (x >= 1) == Relational(x, 1, 'ge')
- assert (x >= 1) == GreaterThan(x, 1)
- assert (x >= 0) != Relational(x, 1, '>=')
- assert (x >= 0) != Relational(x, 1, 'ge')
- assert (x >= 0) != GreaterThan(x, 1)
- assert Le(x, 0) == Relational(x, 0, '<=')
- assert Le(x, 0) == Relational(x, 0, 'le')
- assert Le(x, 0) == LessThan(x, 0)
- assert Le(x, 1) != Relational(x, 0, '<=')
- assert Le(x, 1) != Relational(x, 0, 'le')
- assert Le(x, 1) != LessThan(x, 0)
- assert (x <= 1) == Relational(x, 1, '<=')
- assert (x <= 1) == Relational(x, 1, 'le')
- assert (x <= 1) == LessThan(x, 1)
- assert (x <= 0) != Relational(x, 1, '<=')
- assert (x <= 0) != Relational(x, 1, 'le')
- assert (x <= 0) != LessThan(x, 1)
- assert Gt(x, 0) == Relational(x, 0, '>')
- assert Gt(x, 0) == Relational(x, 0, 'gt')
- assert Gt(x, 0) == StrictGreaterThan(x, 0)
- assert Gt(x, 1) != Relational(x, 0, '>')
- assert Gt(x, 1) != Relational(x, 0, 'gt')
- assert Gt(x, 1) != StrictGreaterThan(x, 0)
- assert (x > 1) == Relational(x, 1, '>')
- assert (x > 1) == Relational(x, 1, 'gt')
- assert (x > 1) == StrictGreaterThan(x, 1)
- assert (x > 0) != Relational(x, 1, '>')
- assert (x > 0) != Relational(x, 1, 'gt')
- assert (x > 0) != StrictGreaterThan(x, 1)
- assert Lt(x, 0) == Relational(x, 0, '<')
- assert Lt(x, 0) == Relational(x, 0, 'lt')
- assert Lt(x, 0) == StrictLessThan(x, 0)
- assert Lt(x, 1) != Relational(x, 0, '<')
- assert Lt(x, 1) != Relational(x, 0, 'lt')
- assert Lt(x, 1) != StrictLessThan(x, 0)
- assert (x < 1) == Relational(x, 1, '<')
- assert (x < 1) == Relational(x, 1, 'lt')
- assert (x < 1) == StrictLessThan(x, 1)
- assert (x < 0) != Relational(x, 1, '<')
- assert (x < 0) != Relational(x, 1, 'lt')
- assert (x < 0) != StrictLessThan(x, 1)
- # finally, some fuzz testing
- from sympy.core.random import randint
- for i in range(100):
- while 1:
- strtype, length = (chr, 65535) if randint(0, 1) else (chr, 255)
- relation_type = strtype(randint(0, length))
- if randint(0, 1):
- relation_type += strtype(randint(0, length))
- if relation_type not in ('==', 'eq', '!=', '<>', 'ne', '>=', 'ge',
- '<=', 'le', '>', 'gt', '<', 'lt', ':=',
- '+=', '-=', '*=', '/=', '%='):
- break
- raises(ValueError, lambda: Relational(x, 1, relation_type))
- assert all(Relational(x, 0, op).rel_op == '==' for op in ('eq', '=='))
- assert all(Relational(x, 0, op).rel_op == '!='
- for op in ('ne', '<>', '!='))
- assert all(Relational(x, 0, op).rel_op == '>' for op in ('gt', '>'))
- assert all(Relational(x, 0, op).rel_op == '<' for op in ('lt', '<'))
- assert all(Relational(x, 0, op).rel_op == '>=' for op in ('ge', '>='))
- assert all(Relational(x, 0, op).rel_op == '<=' for op in ('le', '<='))
- def test_relational_arithmetic():
- for cls in [Eq, Ne, Le, Lt, Ge, Gt]:
- rel = cls(x, y)
- raises(TypeError, lambda: 0+rel)
- raises(TypeError, lambda: 1*rel)
- raises(TypeError, lambda: 1**rel)
- raises(TypeError, lambda: rel**1)
- raises(TypeError, lambda: Add(0, rel))
- raises(TypeError, lambda: Mul(1, rel))
- raises(TypeError, lambda: Pow(1, rel))
- raises(TypeError, lambda: Pow(rel, 1))
- def test_relational_bool_output():
- # https://github.com/sympy/sympy/issues/5931
- raises(TypeError, lambda: bool(x > 3))
- raises(TypeError, lambda: bool(x >= 3))
- raises(TypeError, lambda: bool(x < 3))
- raises(TypeError, lambda: bool(x <= 3))
- raises(TypeError, lambda: bool(Eq(x, 3)))
- raises(TypeError, lambda: bool(Ne(x, 3)))
- def test_relational_logic_symbols():
- # See issue 6204
- assert (x < y) & (z < t) == And(x < y, z < t)
- assert (x < y) | (z < t) == Or(x < y, z < t)
- assert ~(x < y) == Not(x < y)
- assert (x < y) >> (z < t) == Implies(x < y, z < t)
- assert (x < y) << (z < t) == Implies(z < t, x < y)
- assert (x < y) ^ (z < t) == Xor(x < y, z < t)
- assert isinstance((x < y) & (z < t), And)
- assert isinstance((x < y) | (z < t), Or)
- assert isinstance(~(x < y), GreaterThan)
- assert isinstance((x < y) >> (z < t), Implies)
- assert isinstance((x < y) << (z < t), Implies)
- assert isinstance((x < y) ^ (z < t), (Or, Xor))
- def test_univariate_relational_as_set():
- assert (x > 0).as_set() == Interval(0, oo, True, True)
- assert (x >= 0).as_set() == Interval(0, oo)
- assert (x < 0).as_set() == Interval(-oo, 0, True, True)
- assert (x <= 0).as_set() == Interval(-oo, 0)
- assert Eq(x, 0).as_set() == FiniteSet(0)
- assert Ne(x, 0).as_set() == Interval(-oo, 0, True, True) + \
- Interval(0, oo, True, True)
- assert (x**2 >= 4).as_set() == Interval(-oo, -2) + Interval(2, oo)
- @XFAIL
- def test_multivariate_relational_as_set():
- assert (x*y >= 0).as_set() == Interval(0, oo)*Interval(0, oo) + \
- Interval(-oo, 0)*Interval(-oo, 0)
- def test_Not():
- assert Not(Equality(x, y)) == Unequality(x, y)
- assert Not(Unequality(x, y)) == Equality(x, y)
- assert Not(StrictGreaterThan(x, y)) == LessThan(x, y)
- assert Not(StrictLessThan(x, y)) == GreaterThan(x, y)
- assert Not(GreaterThan(x, y)) == StrictLessThan(x, y)
- assert Not(LessThan(x, y)) == StrictGreaterThan(x, y)
- def test_evaluate():
- assert str(Eq(x, x, evaluate=False)) == 'Eq(x, x)'
- assert Eq(x, x, evaluate=False).doit() == S.true
- assert str(Ne(x, x, evaluate=False)) == 'Ne(x, x)'
- assert Ne(x, x, evaluate=False).doit() == S.false
- assert str(Ge(x, x, evaluate=False)) == 'x >= x'
- assert str(Le(x, x, evaluate=False)) == 'x <= x'
- assert str(Gt(x, x, evaluate=False)) == 'x > x'
- assert str(Lt(x, x, evaluate=False)) == 'x < x'
- def assert_all_ineq_raise_TypeError(a, b):
- raises(TypeError, lambda: a > b)
- raises(TypeError, lambda: a >= b)
- raises(TypeError, lambda: a < b)
- raises(TypeError, lambda: a <= b)
- raises(TypeError, lambda: b > a)
- raises(TypeError, lambda: b >= a)
- raises(TypeError, lambda: b < a)
- raises(TypeError, lambda: b <= a)
- def assert_all_ineq_give_class_Inequality(a, b):
- """All inequality operations on `a` and `b` result in class Inequality."""
- from sympy.core.relational import _Inequality as Inequality
- assert isinstance(a > b, Inequality)
- assert isinstance(a >= b, Inequality)
- assert isinstance(a < b, Inequality)
- assert isinstance(a <= b, Inequality)
- assert isinstance(b > a, Inequality)
- assert isinstance(b >= a, Inequality)
- assert isinstance(b < a, Inequality)
- assert isinstance(b <= a, Inequality)
- def test_imaginary_compare_raises_TypeError():
- # See issue #5724
- assert_all_ineq_raise_TypeError(I, x)
- def test_complex_compare_not_real():
- # two cases which are not real
- y = Symbol('y', imaginary=True)
- z = Symbol('z', complex=True, extended_real=False)
- for w in (y, z):
- assert_all_ineq_raise_TypeError(2, w)
- # some cases which should remain un-evaluated
- t = Symbol('t')
- x = Symbol('x', real=True)
- z = Symbol('z', complex=True)
- for w in (x, z, t):
- assert_all_ineq_give_class_Inequality(2, w)
- def test_imaginary_and_inf_compare_raises_TypeError():
- # See pull request #7835
- y = Symbol('y', imaginary=True)
- assert_all_ineq_raise_TypeError(oo, y)
- assert_all_ineq_raise_TypeError(-oo, y)
- def test_complex_pure_imag_not_ordered():
- raises(TypeError, lambda: 2*I < 3*I)
- # more generally
- x = Symbol('x', real=True, nonzero=True)
- y = Symbol('y', imaginary=True)
- z = Symbol('z', complex=True)
- assert_all_ineq_raise_TypeError(I, y)
- t = I*x # an imaginary number, should raise errors
- assert_all_ineq_raise_TypeError(2, t)
- t = -I*y # a real number, so no errors
- assert_all_ineq_give_class_Inequality(2, t)
- t = I*z # unknown, should be unevaluated
- assert_all_ineq_give_class_Inequality(2, t)
- def test_x_minus_y_not_same_as_x_lt_y():
- """
- A consequence of pull request #7792 is that `x - y < 0` and `x < y`
- are not synonymous.
- """
- x = I + 2
- y = I + 3
- raises(TypeError, lambda: x < y)
- assert x - y < 0
- ineq = Lt(x, y, evaluate=False)
- raises(TypeError, lambda: ineq.doit())
- assert ineq.lhs - ineq.rhs < 0
- t = Symbol('t', imaginary=True)
- x = 2 + t
- y = 3 + t
- ineq = Lt(x, y, evaluate=False)
- raises(TypeError, lambda: ineq.doit())
- assert ineq.lhs - ineq.rhs < 0
- # this one should give error either way
- x = I + 2
- y = 2*I + 3
- raises(TypeError, lambda: x < y)
- raises(TypeError, lambda: x - y < 0)
- def test_nan_equality_exceptions():
- # See issue #7774
- import random
- assert Equality(nan, nan) is S.false
- assert Unequality(nan, nan) is S.true
- # See issue #7773
- A = (x, S.Zero, S.One/3, pi, oo, -oo)
- assert Equality(nan, random.choice(A)) is S.false
- assert Equality(random.choice(A), nan) is S.false
- assert Unequality(nan, random.choice(A)) is S.true
- assert Unequality(random.choice(A), nan) is S.true
- def test_nan_inequality_raise_errors():
- # See discussion in pull request #7776. We test inequalities with
- # a set including examples of various classes.
- for q in (x, S.Zero, S(10), S.One/3, pi, S(1.3), oo, -oo, nan):
- assert_all_ineq_raise_TypeError(q, nan)
- def test_nan_complex_inequalities():
- # Comparisons of NaN with non-real raise errors, we're not too
- # fussy whether its the NaN error or complex error.
- for r in (I, zoo, Symbol('z', imaginary=True)):
- assert_all_ineq_raise_TypeError(r, nan)
- def test_complex_infinity_inequalities():
- raises(TypeError, lambda: zoo > 0)
- raises(TypeError, lambda: zoo >= 0)
- raises(TypeError, lambda: zoo < 0)
- raises(TypeError, lambda: zoo <= 0)
- def test_inequalities_symbol_name_same():
- """Using the operator and functional forms should give same results."""
- # We test all combinations from a set
- # FIXME: could replace with random selection after test passes
- A = (x, y, S.Zero, S.One/3, pi, oo, -oo)
- for a in A:
- for b in A:
- assert Gt(a, b) == (a > b)
- assert Lt(a, b) == (a < b)
- assert Ge(a, b) == (a >= b)
- assert Le(a, b) == (a <= b)
- for b in (y, S.Zero, S.One/3, pi, oo, -oo):
- assert Gt(x, b, evaluate=False) == (x > b)
- assert Lt(x, b, evaluate=False) == (x < b)
- assert Ge(x, b, evaluate=False) == (x >= b)
- assert Le(x, b, evaluate=False) == (x <= b)
- for b in (y, S.Zero, S.One/3, pi, oo, -oo):
- assert Gt(b, x, evaluate=False) == (b > x)
- assert Lt(b, x, evaluate=False) == (b < x)
- assert Ge(b, x, evaluate=False) == (b >= x)
- assert Le(b, x, evaluate=False) == (b <= x)
- def test_inequalities_symbol_name_same_complex():
- """Using the operator and functional forms should give same results.
- With complex non-real numbers, both should raise errors.
- """
- # FIXME: could replace with random selection after test passes
- for a in (x, S.Zero, S.One/3, pi, oo, Rational(1, 3)):
- raises(TypeError, lambda: Gt(a, I))
- raises(TypeError, lambda: a > I)
- raises(TypeError, lambda: Lt(a, I))
- raises(TypeError, lambda: a < I)
- raises(TypeError, lambda: Ge(a, I))
- raises(TypeError, lambda: a >= I)
- raises(TypeError, lambda: Le(a, I))
- raises(TypeError, lambda: a <= I)
- def test_inequalities_cant_sympify_other():
- # see issue 7833
- from operator import gt, lt, ge, le
- bar = "foo"
- for a in (x, S.Zero, S.One/3, pi, I, zoo, oo, -oo, nan, Rational(1, 3)):
- for op in (lt, gt, le, ge):
- raises(TypeError, lambda: op(a, bar))
- def test_ineq_avoid_wild_symbol_flip():
- # see issue #7951, we try to avoid this internally, e.g., by using
- # __lt__ instead of "<".
- from sympy.core.symbol import Wild
- p = symbols('p', cls=Wild)
- # x > p might flip, but Gt should not:
- assert Gt(x, p) == Gt(x, p, evaluate=False)
- # Previously failed as 'p > x':
- e = Lt(x, y).subs({y: p})
- assert e == Lt(x, p, evaluate=False)
- # Previously failed as 'p <= x':
- e = Ge(x, p).doit()
- assert e == Ge(x, p, evaluate=False)
- def test_issue_8245():
- a = S("6506833320952669167898688709329/5070602400912917605986812821504")
- assert rel_check(a, a.n(10))
- assert rel_check(a, a.n(20))
- assert rel_check(a, a.n())
- # prec of 31 is enough to fully capture a as mpf
- assert Float(a, 31) == Float(str(a.p), '')/Float(str(a.q), '')
- for i in range(31):
- r = Rational(Float(a, i))
- f = Float(r)
- assert (f < a) == (Rational(f) < a)
- # test sign handling
- assert (-f < -a) == (Rational(-f) < -a)
- # test equivalence handling
- isa = Float(a.p,'')/Float(a.q,'')
- assert isa <= a
- assert not isa < a
- assert isa >= a
- assert not isa > a
- assert isa > 0
- a = sqrt(2)
- r = Rational(str(a.n(30)))
- assert rel_check(a, r)
- a = sqrt(2)
- r = Rational(str(a.n(29)))
- assert rel_check(a, r)
- assert Eq(log(cos(2)**2 + sin(2)**2), 0) is S.true
- def test_issue_8449():
- p = Symbol('p', nonnegative=True)
- assert Lt(-oo, p)
- assert Ge(-oo, p) is S.false
- assert Gt(oo, -p)
- assert Le(oo, -p) is S.false
- def test_simplify_relational():
- assert simplify(x*(y + 1) - x*y - x + 1 < x) == (x > 1)
- assert simplify(x*(y + 1) - x*y - x - 1 < x) == (x > -1)
- assert simplify(x < x*(y + 1) - x*y - x + 1) == (x < 1)
- q, r = symbols("q r")
- assert (((-q + r) - (q - r)) <= 0).simplify() == (q >= r)
- root2 = sqrt(2)
- equation = ((root2 * (-q + r) - root2 * (q - r)) <= 0).simplify()
- assert equation == (q >= r)
- r = S.One < x
- # canonical operations are not the same as simplification,
- # so if there is no simplification, canonicalization will
- # be done unless the measure forbids it
- assert simplify(r) == r.canonical
- assert simplify(r, ratio=0) != r.canonical
- # this is not a random test; in _eval_simplify
- # this will simplify to S.false and that is the
- # reason for the 'if r.is_Relational' in Relational's
- # _eval_simplify routine
- assert simplify(-(2**(pi*Rational(3, 2)) + 6**pi)**(1/pi) +
- 2*(2**(pi/2) + 3**pi)**(1/pi) < 0) is S.false
- # canonical at least
- assert Eq(y, x).simplify() == Eq(x, y)
- assert Eq(x - 1, 0).simplify() == Eq(x, 1)
- assert Eq(x - 1, x).simplify() == S.false
- assert Eq(2*x - 1, x).simplify() == Eq(x, 1)
- assert Eq(2*x, 4).simplify() == Eq(x, 2)
- z = cos(1)**2 + sin(1)**2 - 1 # z.is_zero is None
- assert Eq(z*x, 0).simplify() == S.true
- assert Ne(y, x).simplify() == Ne(x, y)
- assert Ne(x - 1, 0).simplify() == Ne(x, 1)
- assert Ne(x - 1, x).simplify() == S.true
- assert Ne(2*x - 1, x).simplify() == Ne(x, 1)
- assert Ne(2*x, 4).simplify() == Ne(x, 2)
- assert Ne(z*x, 0).simplify() == S.false
- # No real-valued assumptions
- assert Ge(y, x).simplify() == Le(x, y)
- assert Ge(x - 1, 0).simplify() == Ge(x, 1)
- assert Ge(x - 1, x).simplify() == S.false
- assert Ge(2*x - 1, x).simplify() == Ge(x, 1)
- assert Ge(2*x, 4).simplify() == Ge(x, 2)
- assert Ge(z*x, 0).simplify() == S.true
- assert Ge(x, -2).simplify() == Ge(x, -2)
- assert Ge(-x, -2).simplify() == Le(x, 2)
- assert Ge(x, 2).simplify() == Ge(x, 2)
- assert Ge(-x, 2).simplify() == Le(x, -2)
- assert Le(y, x).simplify() == Ge(x, y)
- assert Le(x - 1, 0).simplify() == Le(x, 1)
- assert Le(x - 1, x).simplify() == S.true
- assert Le(2*x - 1, x).simplify() == Le(x, 1)
- assert Le(2*x, 4).simplify() == Le(x, 2)
- assert Le(z*x, 0).simplify() == S.true
- assert Le(x, -2).simplify() == Le(x, -2)
- assert Le(-x, -2).simplify() == Ge(x, 2)
- assert Le(x, 2).simplify() == Le(x, 2)
- assert Le(-x, 2).simplify() == Ge(x, -2)
- assert Gt(y, x).simplify() == Lt(x, y)
- assert Gt(x - 1, 0).simplify() == Gt(x, 1)
- assert Gt(x - 1, x).simplify() == S.false
- assert Gt(2*x - 1, x).simplify() == Gt(x, 1)
- assert Gt(2*x, 4).simplify() == Gt(x, 2)
- assert Gt(z*x, 0).simplify() == S.false
- assert Gt(x, -2).simplify() == Gt(x, -2)
- assert Gt(-x, -2).simplify() == Lt(x, 2)
- assert Gt(x, 2).simplify() == Gt(x, 2)
- assert Gt(-x, 2).simplify() == Lt(x, -2)
- assert Lt(y, x).simplify() == Gt(x, y)
- assert Lt(x - 1, 0).simplify() == Lt(x, 1)
- assert Lt(x - 1, x).simplify() == S.true
- assert Lt(2*x - 1, x).simplify() == Lt(x, 1)
- assert Lt(2*x, 4).simplify() == Lt(x, 2)
- assert Lt(z*x, 0).simplify() == S.false
- assert Lt(x, -2).simplify() == Lt(x, -2)
- assert Lt(-x, -2).simplify() == Gt(x, 2)
- assert Lt(x, 2).simplify() == Lt(x, 2)
- assert Lt(-x, 2).simplify() == Gt(x, -2)
- # Test particulat branches of _eval_simplify
- m = exp(1) - exp_polar(1)
- assert simplify(m*x > 1) is S.false
- # These two tests the same branch
- assert simplify(m*x + 2*m*y > 1) is S.false
- assert simplify(m*x + y > 1 + y) is S.false
- def test_equals():
- w, x, y, z = symbols('w:z')
- f = Function('f')
- assert Eq(x, 1).equals(Eq(x*(y + 1) - x*y - x + 1, x))
- assert Eq(x, y).equals(x < y, True) == False
- assert Eq(x, f(1)).equals(Eq(x, f(2)), True) == f(1) - f(2)
- assert Eq(f(1), y).equals(Eq(f(2), y), True) == f(1) - f(2)
- assert Eq(x, f(1)).equals(Eq(f(2), x), True) == f(1) - f(2)
- assert Eq(f(1), x).equals(Eq(x, f(2)), True) == f(1) - f(2)
- assert Eq(w, x).equals(Eq(y, z), True) == False
- assert Eq(f(1), f(2)).equals(Eq(f(3), f(4)), True) == f(1) - f(3)
- assert (x < y).equals(y > x, True) == True
- assert (x < y).equals(y >= x, True) == False
- assert (x < y).equals(z < y, True) == False
- assert (x < y).equals(x < z, True) == False
- assert (x < f(1)).equals(x < f(2), True) == f(1) - f(2)
- assert (f(1) < x).equals(f(2) < x, True) == f(1) - f(2)
- def test_reversed():
- assert (x < y).reversed == (y > x)
- assert (x <= y).reversed == (y >= x)
- assert Eq(x, y, evaluate=False).reversed == Eq(y, x, evaluate=False)
- assert Ne(x, y, evaluate=False).reversed == Ne(y, x, evaluate=False)
- assert (x >= y).reversed == (y <= x)
- assert (x > y).reversed == (y < x)
- def test_canonical():
- c = [i.canonical for i in (
- x + y < z,
- x + 2 > 3,
- x < 2,
- S(2) > x,
- x**2 > -x/y,
- Gt(3, 2, evaluate=False)
- )]
- assert [i.canonical for i in c] == c
- assert [i.reversed.canonical for i in c] == c
- assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
- c = [i.reversed.func(i.rhs, i.lhs, evaluate=False).canonical for i in c]
- assert [i.canonical for i in c] == c
- assert [i.reversed.canonical for i in c] == c
- assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
- assert Eq(y < x, x > y).canonical is S.true
- @XFAIL
- def test_issue_8444_nonworkingtests():
- x = symbols('x', real=True)
- assert (x <= oo) == (x >= -oo) == True
- x = symbols('x')
- assert x >= floor(x)
- assert (x < floor(x)) == False
- assert x <= ceiling(x)
- assert (x > ceiling(x)) == False
- def test_issue_8444_workingtests():
- x = symbols('x')
- assert Gt(x, floor(x)) == Gt(x, floor(x), evaluate=False)
- assert Ge(x, floor(x)) == Ge(x, floor(x), evaluate=False)
- assert Lt(x, ceiling(x)) == Lt(x, ceiling(x), evaluate=False)
- assert Le(x, ceiling(x)) == Le(x, ceiling(x), evaluate=False)
- i = symbols('i', integer=True)
- assert (i > floor(i)) == False
- assert (i < ceiling(i)) == False
- def test_issue_10304():
- d = cos(1)**2 + sin(1)**2 - 1
- assert d.is_comparable is False # if this fails, find a new d
- e = 1 + d*I
- assert simplify(Eq(e, 0)) is S.false
- def test_issue_18412():
- d = (Rational(1, 6) + z / 4 / y)
- assert Eq(x, pi * y**3 * d).replace(y**3, z) == Eq(x, pi * z * d)
- def test_issue_10401():
- x = symbols('x')
- fin = symbols('inf', finite=True)
- inf = symbols('inf', infinite=True)
- inf2 = symbols('inf2', infinite=True)
- infx = symbols('infx', infinite=True, extended_real=True)
- # Used in the commented tests below:
- #infx2 = symbols('infx2', infinite=True, extended_real=True)
- infnx = symbols('inf~x', infinite=True, extended_real=False)
- infnx2 = symbols('inf~x2', infinite=True, extended_real=False)
- infp = symbols('infp', infinite=True, extended_positive=True)
- infp1 = symbols('infp1', infinite=True, extended_positive=True)
- infn = symbols('infn', infinite=True, extended_negative=True)
- zero = symbols('z', zero=True)
- nonzero = symbols('nz', zero=False, finite=True)
- assert Eq(1/(1/x + 1), 1).func is Eq
- assert Eq(1/(1/x + 1), 1).subs(x, S.ComplexInfinity) is S.true
- assert Eq(1/(1/fin + 1), 1) is S.false
- T, F = S.true, S.false
- assert Eq(fin, inf) is F
- assert Eq(inf, inf2) not in (T, F) and inf != inf2
- assert Eq(1 + inf, 2 + inf2) not in (T, F) and inf != inf2
- assert Eq(infp, infp1) is T
- assert Eq(infp, infn) is F
- assert Eq(1 + I*oo, I*oo) is F
- assert Eq(I*oo, 1 + I*oo) is F
- assert Eq(1 + I*oo, 2 + I*oo) is F
- assert Eq(1 + I*oo, 2 + I*infx) is F
- assert Eq(1 + I*oo, 2 + infx) is F
- # FIXME: The test below fails because (-infx).is_extended_positive is True
- # (should be None)
- #assert Eq(1 + I*infx, 1 + I*infx2) not in (T, F) and infx != infx2
- #
- assert Eq(zoo, sqrt(2) + I*oo) is F
- assert Eq(zoo, oo) is F
- r = Symbol('r', real=True)
- i = Symbol('i', imaginary=True)
- assert Eq(i*I, r) not in (T, F)
- assert Eq(infx, infnx) is F
- assert Eq(infnx, infnx2) not in (T, F) and infnx != infnx2
- assert Eq(zoo, oo) is F
- assert Eq(inf/inf2, 0) is F
- assert Eq(inf/fin, 0) is F
- assert Eq(fin/inf, 0) is T
- assert Eq(zero/nonzero, 0) is T and ((zero/nonzero) != 0)
- # The commented out test below is incorrect because:
- assert zoo == -zoo
- assert Eq(zoo, -zoo) is T
- assert Eq(oo, -oo) is F
- assert Eq(inf, -inf) not in (T, F)
- assert Eq(fin/(fin + 1), 1) is S.false
- o = symbols('o', odd=True)
- assert Eq(o, 2*o) is S.false
- p = symbols('p', positive=True)
- assert Eq(p/(p - 1), 1) is F
- def test_issue_10633():
- assert Eq(True, False) == False
- assert Eq(False, True) == False
- assert Eq(True, True) == True
- assert Eq(False, False) == True
- def test_issue_10927():
- x = symbols('x')
- assert str(Eq(x, oo)) == 'Eq(x, oo)'
- assert str(Eq(x, -oo)) == 'Eq(x, -oo)'
- def test_issues_13081_12583_12534():
- # 13081
- r = Rational('905502432259640373/288230376151711744')
- assert (r < pi) is S.false
- assert (r > pi) is S.true
- # 12583
- v = sqrt(2)
- u = sqrt(v) + 2/sqrt(10 - 8/sqrt(2 - v) + 4*v*(1/sqrt(2 - v) - 1))
- assert (u >= 0) is S.true
- # 12534; Rational vs NumberSymbol
- # here are some precisions for which Rational forms
- # at a lower and higher precision bracket the value of pi
- # e.g. for p = 20:
- # Rational(pi.n(p + 1)).n(25) = 3.14159265358979323846 2834
- # pi.n(25) = 3.14159265358979323846 2643
- # Rational(pi.n(p )).n(25) = 3.14159265358979323846 1987
- assert [p for p in range(20, 50) if
- (Rational(pi.n(p)) < pi) and
- (pi < Rational(pi.n(p + 1)))] == [20, 24, 27, 33, 37, 43, 48]
- # pick one such precision and affirm that the reversed operation
- # gives the opposite result, i.e. if x < y is true then x > y
- # must be false
- for i in (20, 21):
- v = pi.n(i)
- assert rel_check(Rational(v), pi)
- assert rel_check(v, pi)
- assert rel_check(pi.n(20), pi.n(21))
- # Float vs Rational
- # the rational form is less than the floating representation
- # at the same precision
- assert [i for i in range(15, 50) if Rational(pi.n(i)) > pi.n(i)] == []
- # this should be the same if we reverse the relational
- assert [i for i in range(15, 50) if pi.n(i) < Rational(pi.n(i))] == []
- def test_issue_18188():
- from sympy.sets.conditionset import ConditionSet
- result1 = Eq(x*cos(x) - 3*sin(x), 0)
- assert result1.as_set() == ConditionSet(x, Eq(x*cos(x) - 3*sin(x), 0), Reals)
- result2 = Eq(x**2 + sqrt(x*2) + sin(x), 0)
- assert result2.as_set() == ConditionSet(x, Eq(sqrt(2)*sqrt(x) + x**2 + sin(x), 0), Reals)
- def test_binary_symbols():
- ans = {x}
- for f in Eq, Ne:
- for t in S.true, S.false:
- eq = f(x, S.true)
- assert eq.binary_symbols == ans
- assert eq.reversed.binary_symbols == ans
- assert f(x, 1).binary_symbols == set()
- def test_rel_args():
- # can't have Boolean args; this is automatic for True/False
- # with Python 3 and we confirm that SymPy does the same
- # for true/false
- for op in ['<', '<=', '>', '>=']:
- for b in (S.true, x < 1, And(x, y)):
- for v in (0.1, 1, 2**32, t, S.One):
- raises(TypeError, lambda: Relational(b, v, op))
- def test_Equality_rewrite_as_Add():
- eq = Eq(x + y, y - x)
- assert eq.rewrite(Add) == 2*x
- assert eq.rewrite(Add, evaluate=None).args == (x, x, y, -y)
- assert eq.rewrite(Add, evaluate=False).args == (x, y, x, -y)
- for e in (True, False, None):
- assert Eq(x, 0, evaluate=e).rewrite(Add) == x
- assert Eq(0, x, evaluate=e).rewrite(Add) == x
- def test_issue_15847():
- a = Ne(x*(x+y), x**2 + x*y)
- assert simplify(a) == False
- def test_negated_property():
- eq = Eq(x, y)
- assert eq.negated == Ne(x, y)
- eq = Ne(x, y)
- assert eq.negated == Eq(x, y)
- eq = Ge(x + y, y - x)
- assert eq.negated == Lt(x + y, y - x)
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(x, y).negated.negated == f(x, y)
- def test_reversedsign_property():
- eq = Eq(x, y)
- assert eq.reversedsign == Eq(-x, -y)
- eq = Ne(x, y)
- assert eq.reversedsign == Ne(-x, -y)
- eq = Ge(x + y, y - x)
- assert eq.reversedsign == Le(-x - y, x - y)
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(x, y).reversedsign.reversedsign == f(x, y)
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(-x, y).reversedsign.reversedsign == f(-x, y)
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(x, -y).reversedsign.reversedsign == f(x, -y)
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(-x, -y).reversedsign.reversedsign == f(-x, -y)
- def test_reversed_reversedsign_property():
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(x, y).reversed.reversedsign == f(x, y).reversedsign.reversed
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(-x, y).reversed.reversedsign == f(-x, y).reversedsign.reversed
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(x, -y).reversed.reversedsign == f(x, -y).reversedsign.reversed
- for f in (Eq, Ne, Ge, Gt, Le, Lt):
- assert f(-x, -y).reversed.reversedsign == \
- f(-x, -y).reversedsign.reversed
- def test_improved_canonical():
- def test_different_forms(listofforms):
- for form1, form2 in combinations(listofforms, 2):
- assert form1.canonical == form2.canonical
- def generate_forms(expr):
- return [expr, expr.reversed, expr.reversedsign,
- expr.reversed.reversedsign]
- test_different_forms(generate_forms(x > -y))
- test_different_forms(generate_forms(x >= -y))
- test_different_forms(generate_forms(Eq(x, -y)))
- test_different_forms(generate_forms(Ne(x, -y)))
- test_different_forms(generate_forms(pi < x))
- test_different_forms(generate_forms(pi - 5*y < -x + 2*y**2 - 7))
- assert (pi >= x).canonical == (x <= pi)
- def test_set_equality_canonical():
- a, b, c = symbols('a b c')
- A = Eq(FiniteSet(a, b, c), FiniteSet(1, 2, 3))
- B = Ne(FiniteSet(a, b, c), FiniteSet(4, 5, 6))
- assert A.canonical == A.reversed
- assert B.canonical == B.reversed
- def test_trigsimp():
- # issue 16736
- s, c = sin(2*x), cos(2*x)
- eq = Eq(s, c)
- assert trigsimp(eq) == eq # no rearrangement of sides
- # simplification of sides might result in
- # an unevaluated Eq
- changed = trigsimp(Eq(s + c, sqrt(2)))
- assert isinstance(changed, Eq)
- assert changed.subs(x, pi/8) is S.true
- # or an evaluated one
- assert trigsimp(Eq(cos(x)**2 + sin(x)**2, 1)) is S.true
- def test_polynomial_relation_simplification():
- assert Ge(3*x*(x + 1) + 4, 3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
- assert Le(-(3*x*(x + 1) + 4), -3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
- assert ((x**2+3)*(x**2-1)+3*x >= 2*x**2).simplify() in [(x**4 + 3*x >= 3), (-x**4 - 3*x <= -3)]
- def test_multivariate_linear_function_simplification():
- assert Ge(x + y, x - y).simplify() == Ge(y, 0)
- assert Le(-x + y, -x - y).simplify() == Le(y, 0)
- assert Eq(2*x + y, 2*x + y - 3).simplify() == False
- assert (2*x + y > 2*x + y - 3).simplify() == True
- assert (2*x + y < 2*x + y - 3).simplify() == False
- assert (2*x + y < 2*x + y + 3).simplify() == True
- a, b, c, d, e, f, g = symbols('a b c d e f g')
- assert Lt(a + b + c + 2*d, 3*d - f + g). simplify() == Lt(a, -b - c + d - f + g)
- def test_nonpolymonial_relations():
- assert Eq(cos(x), 0).simplify() == Eq(cos(x), 0)
- def test_18778():
- raises(TypeError, lambda: is_le(Basic(), Basic()))
- raises(TypeError, lambda: is_gt(Basic(), Basic()))
- raises(TypeError, lambda: is_ge(Basic(), Basic()))
- raises(TypeError, lambda: is_lt(Basic(), Basic()))
- def test_EvalEq():
- """
- This test exists to ensure backwards compatibility.
- The method to use is _eval_is_eq
- """
- from sympy.core.expr import Expr
- class PowTest(Expr):
- def __new__(cls, base, exp):
- return Basic.__new__(PowTest, _sympify(base), _sympify(exp))
- def _eval_Eq(lhs, rhs):
- if type(lhs) == PowTest and type(rhs) == PowTest:
- return lhs.args[0] == rhs.args[0] and lhs.args[1] == rhs.args[1]
- assert is_eq(PowTest(3, 4), PowTest(3,4))
- assert is_eq(PowTest(3, 4), _sympify(4)) is None
- assert is_neq(PowTest(3, 4), PowTest(3,7))
- def test_is_eq():
- # test assumptions
- assert is_eq(x, y, Q.infinite(x) & Q.finite(y)) is False
- assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_real(x) & ~Q.extended_real(y)) is False
- assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_positive(x) & Q.extended_negative(y)) is False
- assert is_eq(x+I, y+I, Q.infinite(x) & Q.finite(y)) is False
- assert is_eq(1+x*I, 1+y*I, Q.infinite(x) & Q.finite(y)) is False
- assert is_eq(x, S(0), assumptions=Q.zero(x))
- assert is_eq(x, S(0), assumptions=~Q.zero(x)) is False
- assert is_eq(x, S(0), assumptions=Q.nonzero(x)) is False
- assert is_neq(x, S(0), assumptions=Q.zero(x)) is False
- assert is_neq(x, S(0), assumptions=~Q.zero(x))
- assert is_neq(x, S(0), assumptions=Q.nonzero(x))
- # test registration
- class PowTest(Expr):
- def __new__(cls, base, exp):
- return Basic.__new__(cls, _sympify(base), _sympify(exp))
- @dispatch(PowTest, PowTest)
- def _eval_is_eq(lhs, rhs):
- if type(lhs) == PowTest and type(rhs) == PowTest:
- return fuzzy_and([is_eq(lhs.args[0], rhs.args[0]), is_eq(lhs.args[1], rhs.args[1])])
- assert is_eq(PowTest(3, 4), PowTest(3,4))
- assert is_eq(PowTest(3, 4), _sympify(4)) is None
- assert is_neq(PowTest(3, 4), PowTest(3,7))
- def test_is_ge_le():
- # test assumptions
- assert is_ge(x, S(0), Q.nonnegative(x)) is True
- assert is_ge(x, S(0), Q.negative(x)) is False
- # test registration
- class PowTest(Expr):
- def __new__(cls, base, exp):
- return Basic.__new__(cls, _sympify(base), _sympify(exp))
- @dispatch(PowTest, PowTest)
- def _eval_is_ge(lhs, rhs):
- if type(lhs) == PowTest and type(rhs) == PowTest:
- return fuzzy_and([is_ge(lhs.args[0], rhs.args[0]), is_ge(lhs.args[1], rhs.args[1])])
- assert is_ge(PowTest(3, 9), PowTest(3,2))
- assert is_gt(PowTest(3, 9), PowTest(3,2))
- assert is_le(PowTest(3, 2), PowTest(3,9))
- assert is_lt(PowTest(3, 2), PowTest(3,9))
- def test_weak_strict():
- for func in (Eq, Ne):
- eq = func(x, 1)
- assert eq.strict == eq.weak == eq
- eq = Gt(x, 1)
- assert eq.weak == Ge(x, 1)
- assert eq.strict == eq
- eq = Lt(x, 1)
- assert eq.weak == Le(x, 1)
- assert eq.strict == eq
- eq = Ge(x, 1)
- assert eq.strict == Gt(x, 1)
- assert eq.weak == eq
- eq = Le(x, 1)
- assert eq.strict == Lt(x, 1)
- assert eq.weak == eq
|