def test_And(): assert And() is true assert And(A) == A assert And(True) is true assert And(False) is false assert And(True, True) is true assert And(True, False) is false assert And(False, False) is false assert And(True, A) == A assert And(False, A) is false assert And(True, True, True) is true assert And(True, True, A) == A assert And(True, False, A) is false assert And(1, A) == A raises(TypeError, lambda: And(2, A)) raises(TypeError, lambda: And(A < 2, A)) assert And(A < 1, A >= 1) is false e = A > 1 assert And(e, e.canonical) == e.canonical g, l, ge, le = A > B, B < A, A >= B, B <= A assert And(g, l, ge, le) == And(ge, g) assert {And(*i) for i in permutations((l, g, le, ge))} == {And(ge, g)} assert And(And(Eq(a, 0), Eq(b, 0)), And(Ne(a, 0), Eq(c, 0))) is false
def test_ITE(): A, B, C = symbols('A:C') assert ITE(True, False, True) is false assert ITE(True, True, False) is true assert ITE(False, True, False) is false assert ITE(False, False, True) is true assert isinstance(ITE(A, B, C), ITE) A = True assert ITE(A, B, C) == B A = False assert ITE(A, B, C) == C B = True assert ITE(And(A, B), B, C) == C assert ITE(Or(A, False), And(B, True), False) is false assert ITE(x, A, B) == Not(x) assert ITE(x, B, A) == x assert ITE(1, x, y) == x assert ITE(0, x, y) == y raises(TypeError, lambda: ITE(2, x, y)) raises(TypeError, lambda: ITE(1, [], y)) raises(TypeError, lambda: ITE(1, (), y)) raises(TypeError, lambda: ITE(1, y, [])) assert ITE(1, 1, 1) is S.true assert isinstance(ITE(1, 1, 1, evaluate=False), ITE) raises(TypeError, lambda: ITE(x > 1, y, x)) assert ITE(Eq(x, True), y, x) == ITE(x, y, x) assert ITE(Eq(x, False), y, x) == ITE(~x, y, x) assert ITE(Ne(x, True), y, x) == ITE(~x, y, x) assert ITE(Ne(x, False), y, x) == ITE(x, y, x) assert ITE(Eq(S.true, x), y, x) == ITE(x, y, x) assert ITE(Eq(S.false, x), y, x) == ITE(~x, y, x) assert ITE(Ne(S.true, x), y, x) == ITE(~x, y, x) assert ITE(Ne(S.false, x), y, x) == ITE(x, y, x) # 0 and 1 in the context are not treated as True/False # so the equality must always be False since dissimilar # objects cannot be equal assert ITE(Eq(x, 0), y, x) == x assert ITE(Eq(x, 1), y, x) == x assert ITE(Ne(x, 0), y, x) == y assert ITE(Ne(x, 1), y, x) == y assert ITE(Eq(x, 0), y, z).subs(x, 0) == y assert ITE(Eq(x, 0), y, z).subs(x, 1) == z raises(ValueError, lambda: ITE(x > 1, y, x, z))
def test_Piecewise(): assert refine(Piecewise((1, x < 0), (3, True)), Q.is_true(x < 0)) == 1 assert refine(Piecewise((1, x < 0), (3, True)), ~Q.is_true(x < 0)) == 3 assert refine(Piecewise((1, x < 0), (3, True)), Q.is_true(y < 0)) == Piecewise((1, x < 0), (3, True)) assert refine(Piecewise((1, x > 0), (3, True)), Q.is_true(x > 0)) == 1 assert refine(Piecewise((1, x > 0), (3, True)), ~Q.is_true(x > 0)) == 3 assert refine(Piecewise((1, x > 0), (3, True)), Q.is_true(y > 0)) == Piecewise((1, x > 0), (3, True)) assert refine(Piecewise((1, x <= 0), (3, True)), Q.is_true(x <= 0)) == 1 assert refine(Piecewise((1, x <= 0), (3, True)), ~Q.is_true(x <= 0)) == 3 assert refine(Piecewise((1, x <= 0), (3, True)), Q.is_true(y <= 0)) == Piecewise((1, x <= 0), (3, True)) assert refine(Piecewise((1, x >= 0), (3, True)), Q.is_true(x >= 0)) == 1 assert refine(Piecewise((1, x >= 0), (3, True)), ~Q.is_true(x >= 0)) == 3 assert refine(Piecewise((1, x >= 0), (3, True)), Q.is_true(y >= 0)) == Piecewise((1, x >= 0), (3, True)) assert refine(Piecewise((1, Eq(x, 0)), (3, True)), Q.is_true(Eq(x, 0))) == 1 assert refine(Piecewise((1, Eq(x, 0)), (3, True)), ~Q.is_true(Eq(x, 0))) == 3 assert refine(Piecewise((1, Eq(x, 0)), (3, True)), Q.is_true(Eq(y, 0))) == Piecewise((1, Eq(x, 0)), (3, True)) assert refine(Piecewise((1, Ne(x, 0)), (3, True)), Q.is_true(Ne(x, 0))) == 1 assert refine(Piecewise((1, Ne(x, 0)), (3, True)), ~Q.is_true(Ne(x, 0))) == 3 assert refine(Piecewise((1, Ne(x, 0)), (3, True)), Q.is_true(Ne(y, 0))) == Piecewise((1, Ne(x, 0)), (3, True))
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_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_simplification(): """ Test working of simplification methods. """ set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]] set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]] assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x)) assert Not(SOPform([x, y, z], set2)) == \ Not(Or(And(Not(x), Not(z)), And(x, z))) assert POSform([x, y, z], set1 + set2) is true assert SOPform([x, y, z], set1 + set2) is true assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]] assert ( SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, 3, 7, 11, 15] dontcares = [0, 2, 5] assert ( SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [0, [0, 0, 1, 0], 5] assert ( SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, {y: 1, z: 1}] dontcares = [0, [0, 0, 1, 0], 5] assert ( SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [{y: 1, z: 1}, 1] dontcares = [[0, 0, 0, 0]] minterms = [[0, 0, 0]] raises(ValueError, lambda: SOPform([w, x, y, z], minterms)) raises(ValueError, lambda: POSform([w, x, y, z], minterms)) raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"])) # test simplification ans = And(A, Or(B, C)) assert simplify_logic(A & (B | C)) == ans assert simplify_logic((A & B) | (A & C)) == ans assert simplify_logic(Implies(A, B)) == Or(Not(A), B) assert simplify_logic(Equivalent(A, B)) == \ Or(And(A, B), And(Not(A), Not(B))) assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C) assert simplify_logic(And(Equality(A, 2), A)) is S.false assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A) assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C) assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \ == And(Equality(A, 3), Or(B, C)) b = (~x & ~y & ~z) | (~x & ~y & z) e = And(A, b) assert simplify_logic(e) == A & ~x & ~y raises(ValueError, lambda: simplify_logic(A & (B | C), form='blabla')) # Check that expressions with nine variables or more are not simplified # (without the force-flag) a, b, c, d, e, f, g, h, j = symbols('a b c d e f g h j') expr = a & b & c & d & e & f & g & h & j | \ a & b & c & d & e & f & g & h & ~j # This expression can be simplified to get rid of the j variables assert simplify_logic(expr) == expr # check input ans = SOPform([x, y], [[1, 0]]) assert SOPform([x, y], [[1, 0]]) == ans assert POSform([x, y], [[1, 0]]) == ans raises(ValueError, lambda: SOPform([x], [[1]], [[1]])) assert SOPform([x], [[1]], [[0]]) is true assert SOPform([x], [[0]], [[1]]) is true assert SOPform([x], [], []) is false raises(ValueError, lambda: POSform([x], [[1]], [[1]])) assert POSform([x], [[1]], [[0]]) is true assert POSform([x], [[0]], [[1]]) is true assert POSform([x], [], []) is false # check working of simplify assert simplify((A & B) | (A & C)) == And(A, Or(B, C)) assert simplify(And(x, Not(x))) == False assert simplify(Or(x, Not(x))) == True assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0)) assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1)) assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y)) assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1)) assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify( ) == And(Eq(x, 1), Eq(y, -1), Eq(z, 2)) assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1) assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1) assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify( ) == And(Ne(x, 1), Ne(x, 0))
def test_PoissonProcess(): X = PoissonProcess("X", 3) assert X.state_space == S.Naturals0 assert X.index_set == Interval(0, oo) assert X.lamda == 3 t, d, x, y = symbols('t d x y', positive=True) assert isinstance(X(t), RandomIndexedSymbol) assert X.distribution(t) == PoissonDistribution(3 * t) raises(ValueError, lambda: PoissonProcess("X", -1)) raises(NotImplementedError, lambda: X[t]) raises(IndexError, lambda: X(-5)) assert X.joint_distribution(X(2), X(3)) == JointDistributionHandmade( Lambda((X(2), X(3)), 6**X(2) * 9**X(3) * exp(-15) / (factorial(X(2)) * factorial(X(3))))) assert X.joint_distribution(4, 6) == JointDistributionHandmade( Lambda((X(4), X(6)), 12**X(4) * 18**X(6) * exp(-30) / (factorial(X(4)) * factorial(X(6))))) assert P(X(t) < 1) == exp(-3 * t) assert P(Eq(X(t), 0), Contains(t, Interval.Lopen(3, 5))) == exp(-6) # exp(-2*lamda) res = P(Eq(X(t), 1), Contains(t, Interval.Lopen(3, 4))) assert res == 3 * exp(-3) # Equivalent to P(Eq(X(t), 1))**4 because of non-overlapping intervals assert P( Eq(X(t), 1) & Eq(X(d), 1) & Eq(X(x), 1) & Eq(X(y), 1), Contains(t, Interval.Lopen(0, 1)) & Contains(d, Interval.Lopen(1, 2)) & Contains(x, Interval.Lopen(2, 3)) & Contains(y, Interval.Lopen(3, 4))) == res**4 # Return Probability because of overlapping intervals assert P(Eq(X(t), 2) & Eq(X(d), 3), Contains(t, Interval.Lopen(0, 2)) & Contains(d, Interval.Ropen(2, 4))) == \ Probability(Eq(X(d), 3) & Eq(X(t), 2), Contains(t, Interval.Lopen(0, 2)) & Contains(d, Interval.Ropen(2, 4))) raises(ValueError, lambda: P( Eq(X(t), 2) & Eq(X(d), 3), Contains(t, Interval.Lopen(0, 4)) & Contains(d, Interval.Lopen(3, oo))) ) # no bound on d assert P(Eq(X(3), 2)) == 81 * exp(-9) / 2 assert P(Eq(X(t), 2), Contains(t, Interval.Lopen(0, 5))) == 225 * exp(-15) / 2 # Check that probability works correctly by adding it to 1 res1 = P(X(t) <= 3, Contains(t, Interval.Lopen(0, 5))) res2 = P(X(t) > 3, Contains(t, Interval.Lopen(0, 5))) assert res1 == 691 * exp(-15) assert (res1 + res2).simplify() == 1 # Check Not and Or assert P(Not(Eq(X(t), 2) & (X(d) > 3)), Contains(t, Interval.Ropen(2, 4)) & \ Contains(d, Interval.Lopen(7, 8))).simplify() == -18*exp(-6) + 234*exp(-9) + 1 assert P(Eq(X(t), 2) | Ne(X(t), 4), Contains(t, Interval.Ropen(2, 4))) == 1 - 36 * exp(-6) raises(ValueError, lambda: P(X(t) > 2, X(t) + X(d))) assert E( X(t)) == 3 * t # property of the distribution at a given timestamp assert E( X(t)**2 + X(d) * 2 + X(y)**3, Contains(t, Interval.Lopen(0, 1)) & Contains(d, Interval.Lopen(1, 2)) & Contains(y, Interval.Ropen(3, 4))) == 75 assert E(X(t)**2, Contains(t, Interval.Lopen(0, 1))) == 12 assert E(x*(X(t) + X(d))*(X(t)**2+X(d)**2), Contains(t, Interval.Lopen(0, 1)) & Contains(d, Interval.Ropen(1, 2))) == \ Expectation(x*(X(d) + X(t))*(X(d)**2 + X(t)**2), Contains(t, Interval.Lopen(0, 1)) & Contains(d, Interval.Ropen(1, 2))) # Value Error because of infinite time bound raises(ValueError, lambda: E(X(t)**3, Contains(t, Interval.Lopen(1, oo)))) # Equivalent to E(X(t)**2) - E(X(d)**2) == E(X(1)**2) - E(X(1)**2) == 0 assert E((X(t) + X(d)) * (X(t) - X(d)), Contains(t, Interval.Lopen(0, 1)) & Contains(d, Interval.Lopen(1, 2))) == 0 assert E(X(2) + x * E(X(5))) == 15 * x + 6 assert E(x * X(1) + y) == 3 * x + y assert P(Eq(X(1), 2) & Eq(X(t), 3), Contains(t, Interval.Lopen(1, 2))) == 81 * exp(-6) / 4 Y = PoissonProcess("Y", 6) Z = X + Y assert Z.lamda == X.lamda + Y.lamda == 9 raises(ValueError, lambda: X + 5) # should be added be only PoissonProcess instance N, M = Z.split(4, 5) assert N.lamda == 4 assert M.lamda == 5 raises(ValueError, lambda: Z.split(3, 2)) # 2+3 != 9 raises( ValueError, lambda: P(Eq(X(t), 0), Contains(t, Interval.Lopen(1, 3)) & Eq(X(1), 0))) # check if it handles queries with two random variables in one args res1 = P(Eq(N(3), N(5))) assert res1 == P(Eq(N(t), 0), Contains(t, Interval(3, 5))) res2 = P(N(3) > N(1)) assert res2 == P((N(t) > 0), Contains(t, Interval(1, 3))) assert P(N(3) < N(1)) == 0 # condition is not possible res3 = P(N(3) <= N(1)) # holds only for Eq(N(3), N(1)) assert res3 == P(Eq(N(t), 0), Contains(t, Interval(1, 3))) # tests from https://www.probabilitycourse.com/chapter11/11_1_2_basic_concepts_of_the_poisson_process.php X = PoissonProcess('X', 10) # 11.1 assert P(Eq(X(S(1) / 3), 3) & Eq(X(1), 10)) == exp(-10) * Rational(8000000000, 11160261) assert P(Eq(X(1), 1), Eq(X(S(1) / 3), 3)) == 0 assert P(Eq(X(1), 10), Eq(X(S(1) / 3), 3)) == P(Eq(X(S(2) / 3), 7)) X = PoissonProcess('X', 2) # 11.2 assert P(X(S(1) / 2) < 1) == exp(-1) assert P(X(3) < 1, Eq(X(1), 0)) == exp(-4) assert P(Eq(X(4), 3), Eq(X(2), 3)) == exp(-4) X = PoissonProcess('X', 3) assert P(Eq(X(2), 5) & Eq(X(1), 2)) == Rational(81, 4) * exp(-6) # check few properties assert P( X(2) <= 3, X(1) >= 1) == 3 * P(Eq(X(1), 0)) + 2 * P(Eq(X(1), 1)) + P(Eq(X(1), 2)) assert P(X(2) <= 3, X(1) > 1) == 2 * P(Eq(X(1), 0)) + 1 * P(Eq(X(1), 1)) assert P(Eq(X(2), 5) & Eq(X(1), 2)) == P(Eq(X(1), 3)) * P(Eq(X(1), 2)) assert P(Eq(X(3), 4), Eq(X(1), 3)) == P(Eq(X(2), 1)) #test issue 20078 assert (2 * X(t) + 3 * X(t)).simplify() == 5 * X(t) assert (2 * X(t) - 3 * X(t)).simplify() == -X(t) assert (2 * (0.25 * X(t))).simplify() == 0.5 * X(t) assert (2 * X(t) * 0.25 * X(t)).simplify() == 0.5 * X(t)**2 assert (X(t)**2 + X(t)**3).simplify() == (X(t) + 1) * X(t)**2
def test_DiscreteMarkovChain(): # pass only the name X = DiscreteMarkovChain("X") assert isinstance(X.state_space, Range) assert X.index_set == S.Naturals0 assert isinstance(X.transition_probabilities, MatrixSymbol) t = symbols('t', positive=True, integer=True) assert isinstance(X[t], RandomIndexedSymbol) assert E(X[0]) == Expectation(X[0]) raises(TypeError, lambda: DiscreteMarkovChain(1)) raises(NotImplementedError, lambda: X(t)) raises(NotImplementedError, lambda: X.communication_classes()) raises(NotImplementedError, lambda: X.canonical_form()) raises(NotImplementedError, lambda: X.decompose()) nz = Symbol('n', integer=True) TZ = MatrixSymbol('M', nz, nz) SZ = Range(nz) YZ = DiscreteMarkovChain('Y', SZ, TZ) assert P(Eq(YZ[2], 1), Eq(YZ[1], 0)) == TZ[0, 1] raises(ValueError, lambda: sample_stochastic_process(t)) raises(ValueError, lambda: next(sample_stochastic_process(X))) # pass name and state_space # any hashable object should be a valid state # states should be valid as a tuple/set/list/Tuple/Range sym, rainy, cloudy, sunny = symbols('a Rainy Cloudy Sunny', real=True) state_spaces = [(1, 2, 3), [Str('Hello'), sym, DiscreteMarkovChain], Tuple(S(1), exp(sym), Str('World'), sympify=False), Range(-1, 5, 2), [rainy, cloudy, sunny]] chains = [ DiscreteMarkovChain("Y", state_space) for state_space in state_spaces ] for i, Y in enumerate(chains): assert isinstance(Y.transition_probabilities, MatrixSymbol) assert Y.state_space == state_spaces[i] or Y.state_space == FiniteSet( *state_spaces[i]) assert Y.number_of_states == 3 with ignore_warnings( UserWarning): # TODO: Restore tests once warnings are removed assert P(Eq(Y[2], 1), Eq(Y[0], 2), evaluate=False) == Probability(Eq(Y[2], 1), Eq(Y[0], 2)) assert E(Y[0]) == Expectation(Y[0]) raises(ValueError, lambda: next(sample_stochastic_process(Y))) raises(TypeError, lambda: DiscreteMarkovChain("Y", dict((1, 1)))) Y = DiscreteMarkovChain("Y", Range(1, t, 2)) assert Y.number_of_states == ceiling((t - 1) / 2) # pass name and transition_probabilities chains = [ DiscreteMarkovChain("Y", trans_probs=Matrix([[]])), DiscreteMarkovChain("Y", trans_probs=Matrix([[0, 1], [1, 0]])), DiscreteMarkovChain("Y", trans_probs=Matrix([[pi, 1 - pi], [sym, 1 - sym]])) ] for Z in chains: assert Z.number_of_states == Z.transition_probabilities.shape[0] assert isinstance(Z.transition_probabilities, ImmutableMatrix) # pass name, state_space and transition_probabilities T = Matrix([[0.5, 0.2, 0.3], [0.2, 0.5, 0.3], [0.2, 0.3, 0.5]]) TS = MatrixSymbol('T', 3, 3) Y = DiscreteMarkovChain("Y", [0, 1, 2], T) YS = DiscreteMarkovChain("Y", ['One', 'Two', 3], TS) assert Y.joint_distribution(1, Y[2], 3) == JointDistribution(Y[1], Y[2], Y[3]) raises(ValueError, lambda: Y.joint_distribution(Y[1].symbol, Y[2].symbol)) assert P(Eq(Y[3], 2), Eq(Y[1], 1)).round(2) == Float(0.36, 2) assert (P(Eq(YS[3], 2), Eq(YS[1], 1)) - (TS[0, 2] * TS[1, 0] + TS[1, 1] * TS[1, 2] + TS[1, 2] * TS[2, 2])).simplify() == 0 assert P(Eq(YS[1], 1), Eq(YS[2], 2)) == Probability(Eq(YS[1], 1)) assert P(Eq(YS[3], 3), Eq( YS[1], 1)) == TS[0, 2] * TS[1, 0] + TS[1, 1] * TS[1, 2] + TS[1, 2] * TS[2, 2] TO = Matrix([[0.25, 0.75, 0], [0, 0.25, 0.75], [0.75, 0, 0.25]]) assert P(Eq(Y[3], 2), Eq(Y[1], 1) & TransitionMatrixOf(Y, TO)).round(3) == Float( 0.375, 3) with ignore_warnings( UserWarning): ### TODO: Restore tests once warnings are removed assert E(Y[3], evaluate=False) == Expectation(Y[3]) assert E(Y[3], Eq(Y[2], 1)).round(2) == Float(1.1, 3) TSO = MatrixSymbol('T', 4, 4) raises( ValueError, lambda: str(P(Eq(YS[3], 2), Eq(YS[1], 1) & TransitionMatrixOf(YS, TSO)))) raises(TypeError, lambda: DiscreteMarkovChain("Z", [0, 1, 2], symbols('M'))) raises( ValueError, lambda: DiscreteMarkovChain("Z", [0, 1, 2], MatrixSymbol('T', 3, 4))) raises(ValueError, lambda: E(Y[3], Eq(Y[2], 6))) raises(ValueError, lambda: E(Y[2], Eq(Y[3], 1))) # extended tests for probability queries TO1 = Matrix([[Rational(1, 4), Rational(3, 4), 0], [Rational(1, 3), Rational(1, 3), Rational(1, 3)], [0, Rational(1, 4), Rational(3, 4)]]) assert P( And(Eq(Y[2], 1), Eq(Y[1], 1), Eq(Y[0], 0)), Eq(Probability(Eq(Y[0], 0)), Rational(1, 4)) & TransitionMatrixOf(Y, TO1)) == Rational(1, 16) assert P(And(Eq(Y[2], 1), Eq(Y[1], 1), Eq(Y[0], 0)), TransitionMatrixOf(Y, TO1)) == \ Probability(Eq(Y[0], 0))/4 assert P( Lt(X[1], 2) & Gt(X[1], 0), Eq(X[0], 2) & StochasticStateSpaceOf(X, [0, 1, 2]) & TransitionMatrixOf(X, TO1)) == Rational(1, 4) assert P( Lt(X[1], 2) & Gt(X[1], 0), Eq(X[0], 2) & StochasticStateSpaceOf(X, [None, 'None', 1]) & TransitionMatrixOf(X, TO1)) == Rational(1, 4) assert P( Ne(X[1], 2) & Ne(X[1], 1), Eq(X[0], 2) & StochasticStateSpaceOf(X, [0, 1, 2]) & TransitionMatrixOf(X, TO1)) is S.Zero assert P( Ne(X[1], 2) & Ne(X[1], 1), Eq(X[0], 2) & StochasticStateSpaceOf(X, [None, 'None', 1]) & TransitionMatrixOf(X, TO1)) is S.Zero assert P(And(Eq(Y[2], 1), Eq(Y[1], 1), Eq(Y[0], 0)), Eq(Y[1], 1)) == 0.1 * Probability(Eq(Y[0], 0)) # testing properties of Markov chain TO2 = Matrix([[S.One, 0, 0], [Rational(1, 3), Rational(1, 3), Rational(1, 3)], [0, Rational(1, 4), Rational(3, 4)]]) TO3 = Matrix([[Rational(1, 4), Rational(3, 4), 0], [Rational(1, 3), Rational(1, 3), Rational(1, 3)], [0, Rational(1, 4), Rational(3, 4)]]) Y2 = DiscreteMarkovChain('Y', trans_probs=TO2) Y3 = DiscreteMarkovChain('Y', trans_probs=TO3) assert Y3.fundamental_matrix() == ImmutableMatrix( [[176, 81, -132], [36, 141, -52], [-44, -39, 208]]) / 125 assert Y2.is_absorbing_chain() == True assert Y3.is_absorbing_chain() == False assert Y2.canonical_form() == ([0, 1, 2], TO2) assert Y3.canonical_form() == ([0, 1, 2], TO3) assert Y2.decompose() == ([0, 1, 2], TO2[0:1, 0:1], TO2[1:3, 0:1], TO2[1:3, 1:3]) assert Y3.decompose() == ([0, 1, 2], TO3, Matrix(0, 3, []), Matrix(0, 0, [])) TO4 = Matrix([[Rational(1, 5), Rational(2, 5), Rational(2, 5)], [Rational(1, 10), S.Half, Rational(2, 5)], [Rational(3, 5), Rational(3, 10), Rational(1, 10)]]) Y4 = DiscreteMarkovChain('Y', trans_probs=TO4) w = ImmutableMatrix([[Rational(11, 39), Rational(16, 39), Rational(4, 13)]]) assert Y4.limiting_distribution == w assert Y4.is_regular() == True assert Y4.is_ergodic() == True TS1 = MatrixSymbol('T', 3, 3) Y5 = DiscreteMarkovChain('Y', trans_probs=TS1) assert Y5.limiting_distribution(w, TO4).doit() == True assert Y5.stationary_distribution(condition_set=True).subs( TS1, TO4).contains(w).doit() == S.true TO6 = Matrix([[S.One, 0, 0, 0, 0], [S.Half, 0, S.Half, 0, 0], [0, S.Half, 0, S.Half, 0], [0, 0, S.Half, 0, S.Half], [0, 0, 0, 0, 1]]) Y6 = DiscreteMarkovChain('Y', trans_probs=TO6) assert Y6.fundamental_matrix() == ImmutableMatrix( [[Rational(3, 2), S.One, S.Half], [S.One, S(2), S.One], [S.Half, S.One, Rational(3, 2)]]) assert Y6.absorbing_probabilities() == ImmutableMatrix( [[Rational(3, 4), Rational(1, 4)], [S.Half, S.Half], [Rational(1, 4), Rational(3, 4)]]) TO7 = Matrix([[Rational(1, 2), Rational(1, 4), Rational(1, 4)], [Rational(1, 2), 0, Rational(1, 2)], [Rational(1, 4), Rational(1, 4), Rational(1, 2)]]) Y7 = DiscreteMarkovChain('Y', trans_probs=TO7) assert Y7.is_absorbing_chain() == False assert Y7.fundamental_matrix() == ImmutableMatrix( [[Rational(86, 75), Rational(1, 25), Rational(-14, 75)], [Rational(2, 25), Rational(21, 25), Rational(2, 25)], [Rational(-14, 75), Rational(1, 25), Rational(86, 75)]]) # test for zero-sized matrix functionality X = DiscreteMarkovChain('X', trans_probs=Matrix([[]])) assert X.number_of_states == 0 assert X.stationary_distribution() == Matrix([[]]) assert X.communication_classes() == [] assert X.canonical_form() == ([], Matrix([[]])) assert X.decompose() == ([], Matrix([[]]), Matrix([[]]), Matrix([[]])) assert X.is_regular() == False assert X.is_ergodic() == False # test communication_class # see https://drive.google.com/drive/folders/1HbxLlwwn2b3U8Lj7eb_ASIUb5vYaNIjg?usp=sharing # tutorial 2.pdf TO7 = Matrix([[0, 5, 5, 0, 0], [0, 0, 0, 10, 0], [5, 0, 5, 0, 0], [0, 10, 0, 0, 0], [0, 3, 0, 3, 4]]) / 10 Y7 = DiscreteMarkovChain('Y', trans_probs=TO7) tuples = Y7.communication_classes() classes, recurrence, periods = list(zip(*tuples)) assert classes == ([1, 3], [0, 2], [4]) assert recurrence == (True, False, False) assert periods == (2, 1, 1) TO8 = Matrix([[0, 0, 0, 10, 0, 0], [5, 0, 5, 0, 0, 0], [0, 4, 0, 0, 0, 6], [10, 0, 0, 0, 0, 0], [0, 10, 0, 0, 0, 0], [0, 0, 0, 5, 5, 0] ]) / 10 Y8 = DiscreteMarkovChain('Y', trans_probs=TO8) tuples = Y8.communication_classes() classes, recurrence, periods = list(zip(*tuples)) assert classes == ([0, 3], [1, 2, 5, 4]) assert recurrence == (True, False) assert periods == (2, 2) TO9 = Matrix( [[2, 0, 0, 3, 0, 0, 3, 2, 0, 0], [0, 10, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 0, 0, 0, 0, 0, 3, 3], [0, 0, 0, 3, 0, 0, 6, 1, 0, 0], [0, 0, 0, 0, 5, 5, 0, 0, 0, 0], [0, 0, 0, 0, 0, 10, 0, 0, 0, 0], [4, 0, 0, 5, 0, 0, 1, 0, 0, 0], [2, 0, 0, 4, 0, 0, 2, 2, 0, 0], [3, 0, 1, 0, 0, 0, 0, 0, 4, 2], [0, 0, 4, 0, 0, 0, 0, 0, 3, 3]]) / 10 Y9 = DiscreteMarkovChain('Y', trans_probs=TO9) tuples = Y9.communication_classes() classes, recurrence, periods = list(zip(*tuples)) assert classes == ([0, 3, 6, 7], [1], [2, 8, 9], [5], [4]) assert recurrence == (True, True, False, True, False) assert periods == (1, 1, 1, 1, 1) # test canonical form # see https://www.dartmouth.edu/~chance/teaching_aids/books_articles/probability_book/Chapter11.pdf # example 11.13 T = Matrix([[1, 0, 0, 0, 0], [S(1) / 2, 0, S(1) / 2, 0, 0], [0, S(1) / 2, 0, S(1) / 2, 0], [0, 0, S(1) / 2, 0, S(1) / 2], [0, 0, 0, 0, S(1)]]) DW = DiscreteMarkovChain('DW', [0, 1, 2, 3, 4], T) states, A, B, C = DW.decompose() assert states == [0, 4, 1, 2, 3] assert A == Matrix([[1, 0], [0, 1]]) assert B == Matrix([[S(1) / 2, 0], [0, 0], [0, S(1) / 2]]) assert C == Matrix([[0, S(1) / 2, 0], [S(1) / 2, 0, S(1) / 2], [0, S(1) / 2, 0]]) states, new_matrix = DW.canonical_form() assert states == [0, 4, 1, 2, 3] assert new_matrix == Matrix([[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [S(1) / 2, 0, 0, S(1) / 2, 0], [0, 0, S(1) / 2, 0, S(1) / 2], [0, S(1) / 2, 0, S(1) / 2, 0]]) # test regular and ergodic # https://www.dartmouth.edu/~chance/teaching_aids/books_articles/probability_book/Chapter11.pdf T = Matrix([[0, 4, 0, 0, 0], [1, 0, 3, 0, 0], [0, 2, 0, 2, 0], [0, 0, 3, 0, 1], [0, 0, 0, 4, 0]]) / 4 X = DiscreteMarkovChain('X', trans_probs=T) assert not X.is_regular() assert X.is_ergodic() T = Matrix([[0, 1], [1, 0]]) X = DiscreteMarkovChain('X', trans_probs=T) assert not X.is_regular() assert X.is_ergodic() # http://www.math.wisc.edu/~valko/courses/331/MC2.pdf T = Matrix([[2, 1, 1], [2, 0, 2], [1, 1, 2]]) / 4 X = DiscreteMarkovChain('X', trans_probs=T) assert X.is_regular() assert X.is_ergodic() # https://docs.ufpr.br/~lucambio/CE222/1S2014/Kemeny-Snell1976.pdf T = Matrix([[1, 1], [1, 1]]) / 2 X = DiscreteMarkovChain('X', trans_probs=T) assert X.is_regular() assert X.is_ergodic() # test is_absorbing_chain T = Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]]) X = DiscreteMarkovChain('X', trans_probs=T) assert not X.is_absorbing_chain() # https://en.wikipedia.org/wiki/Absorbing_Markov_chain T = Matrix([[1, 1, 0, 0], [0, 1, 1, 0], [1, 0, 0, 1], [0, 0, 0, 2]]) / 2 X = DiscreteMarkovChain('X', trans_probs=T) assert X.is_absorbing_chain() T = Matrix([[2, 0, 0, 0, 0], [1, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 0, 2]]) / 2 X = DiscreteMarkovChain('X', trans_probs=T) assert X.is_absorbing_chain() # test custom state space Y10 = DiscreteMarkovChain('Y', [1, 2, 3], TO2) tuples = Y10.communication_classes() classes, recurrence, periods = list(zip(*tuples)) assert classes == ([1], [2, 3]) assert recurrence == (True, False) assert periods == (1, 1) assert Y10.canonical_form() == ([1, 2, 3], TO2) assert Y10.decompose() == ([1, 2, 3], TO2[0:1, 0:1], TO2[1:3, 0:1], TO2[1:3, 1:3]) # testing miscellaneous queries T = Matrix([[S.Half, Rational(1, 4), Rational(1, 4)], [Rational(1, 3), 0, Rational(2, 3)], [S.Half, S.Half, 0]]) X = DiscreteMarkovChain('X', [0, 1, 2], T) assert P( Eq(X[1], 2) & Eq(X[2], 1) & Eq(X[3], 0), Eq(P(Eq(X[1], 0)), Rational(1, 4)) & Eq(P(Eq(X[1], 1)), Rational(1, 4))) == Rational(1, 12) assert P(Eq(X[2], 1) | Eq(X[2], 2), Eq(X[1], 1)) == Rational(2, 3) assert P(Eq(X[2], 1) & Eq(X[2], 2), Eq(X[1], 1)) is S.Zero assert P(Ne(X[2], 2), Eq(X[1], 1)) == Rational(1, 3) assert E(X[1]**2, Eq(X[0], 1)) == Rational(8, 3) assert variance(X[1], Eq(X[0], 1)) == Rational(8, 9) raises(ValueError, lambda: E(X[1], Eq(X[2], 1))) raises(ValueError, lambda: DiscreteMarkovChain('X', [0, 1], T)) # testing miscellaneous queries with different state space X = DiscreteMarkovChain('X', ['A', 'B', 'C'], T) assert P( Eq(X[1], 2) & Eq(X[2], 1) & Eq(X[3], 0), Eq(P(Eq(X[1], 0)), Rational(1, 4)) & Eq(P(Eq(X[1], 1)), Rational(1, 4))) == Rational(1, 12) assert P(Eq(X[2], 1) | Eq(X[2], 2), Eq(X[1], 1)) == Rational(2, 3) assert P(Eq(X[2], 1) & Eq(X[2], 2), Eq(X[1], 1)) is S.Zero assert P(Ne(X[2], 2), Eq(X[1], 1)) == Rational(1, 3) a = X.state_space.args[0] c = X.state_space.args[2] assert (E(X[1]**2, Eq(X[0], 1)) - (a**2 / 3 + 2 * c**2 / 3)).simplify() == 0 assert (variance(X[1], Eq(X[0], 1)) - (2 * (-a / 3 + c / 3)**2 / 3 + (2 * a / 3 - 2 * c / 3)**2 / 3)).simplify() == 0 raises(ValueError, lambda: E(X[1], Eq(X[2], 1))) #testing queries with multiple RandomIndexedSymbols T = Matrix([[Rational(5, 10), Rational(3, 10), Rational(2, 10)], [Rational(2, 10), Rational(7, 10), Rational(1, 10)], [Rational(3, 10), Rational(3, 10), Rational(4, 10)]]) Y = DiscreteMarkovChain("Y", [0, 1, 2], T) assert P(Eq(Y[7], Y[5]), Eq(Y[2], 0)).round(5) == Float(0.44428, 5) assert P(Gt(Y[3], Y[1]), Eq(Y[0], 0)).round(2) == Float(0.36, 2) assert P(Le(Y[5], Y[10]), Eq(Y[4], 2)).round(6) == Float(0.583120, 6) assert Float(P(Eq(Y[10], Y[5]), Eq(Y[4], 1)), 14) == Float(1 - P(Ne(Y[10], Y[5]), Eq(Y[4], 1)), 14) assert Float(P(Gt(Y[8], Y[9]), Eq(Y[3], 2)), 14) == Float(1 - P(Le(Y[8], Y[9]), Eq(Y[3], 2)), 14) assert Float(P(Lt(Y[1], Y[4]), Eq(Y[0], 0)), 14) == Float(1 - P(Ge(Y[1], Y[4]), Eq(Y[0], 0)), 14) assert P(Eq(Y[5], Y[10]), Eq(Y[2], 1)) == P(Eq(Y[10], Y[5]), Eq(Y[2], 1)) assert P(Gt(Y[1], Y[2]), Eq(Y[0], 1)) == P(Lt(Y[2], Y[1]), Eq(Y[0], 1)) assert P(Ge(Y[7], Y[6]), Eq(Y[4], 1)) == P(Le(Y[6], Y[7]), Eq(Y[4], 1)) #test symbolic queries a, b, c, d = symbols('a b c d') T = Matrix([[Rational(1, 10), Rational(4, 10), Rational(5, 10)], [Rational(3, 10), Rational(4, 10), Rational(3, 10)], [Rational(7, 10), Rational(2, 10), Rational(1, 10)]]) Y = DiscreteMarkovChain("Y", [0, 1, 2], T) query = P(Eq(Y[a], b), Eq(Y[c], d)) assert query.subs({ a: 10, b: 2, c: 5, d: 1 }).evalf().round(4) == P(Eq(Y[10], 2), Eq(Y[5], 1)).round(4) assert query.subs({ a: 15, b: 0, c: 10, d: 1 }).evalf().round(4) == P(Eq(Y[15], 0), Eq(Y[10], 1)).round(4) query_gt = P(Gt(Y[a], b), Eq(Y[c], d)) query_le = P(Le(Y[a], b), Eq(Y[c], d)) assert query_gt.subs({ a: 5, b: 2, c: 1, d: 0 }).evalf() + query_le.subs({ a: 5, b: 2, c: 1, d: 0 }).evalf() == 1 query_ge = P(Ge(Y[a], b), Eq(Y[c], d)) query_lt = P(Lt(Y[a], b), Eq(Y[c], d)) assert query_ge.subs({ a: 4, b: 1, c: 0, d: 2 }).evalf() + query_lt.subs({ a: 4, b: 1, c: 0, d: 2 }).evalf() == 1 #test issue 20078 assert (2 * Y[1] + 3 * Y[1]).simplify() == 5 * Y[1] assert (2 * Y[1] - 3 * Y[1]).simplify() == -Y[1] assert (2 * (0.25 * Y[1])).simplify() == 0.5 * Y[1] assert ((2 * Y[1]) * (0.25 * Y[1])).simplify() == 0.5 * Y[1]**2 assert (Y[1]**2 + Y[1]**3).simplify() == (Y[1] + 1) * Y[1]**2
def test_Relational(): assert str(Rel(x, y, "<")) == "x < y" assert str(Rel(x + y, y, "==")) == "Eq(x + y, y)" assert str(Rel(x, y, "!=")) == "Ne(x, y)" assert str(Eq(x, 1) | Eq(x, 2)) == "Eq(x, 1) | Eq(x, 2)" assert str(Ne(x, 1) & Ne(x, 2)) == "Ne(x, 1) & Ne(x, 2)"
def test_Complement_as_relational(): x = Symbol('x') expr = Complement(Interval(0, 1), FiniteSet(2), evaluate=False) assert expr.as_relational(x) == \ And(Le(0, x), Le(x, 1), Ne(x, 2))
def test_issue_12251(): assert manualintegrate(x**y, x) == Piecewise( (x**(y + 1) / (y + 1), Ne(y, -1)), (log(x), True))
def test_manualintegrate_inversetrig(): # atan assert manualintegrate(exp(x) / (1 + exp(2 * x)), x) == atan(exp(x)) assert manualintegrate(1 / (4 + 9 * x**2), x) == atan(3 * x / 2) / 6 assert manualintegrate(1 / (16 + 16 * x**2), x) == atan(x) / 16 assert manualintegrate(1 / (4 + x**2), x) == atan(x / 2) / 2 assert manualintegrate(1 / (1 + 4 * x**2), x) == atan(2 * x) / 2 ra = Symbol('a', real=True) rb = Symbol('b', real=True) assert manualintegrate(1/(ra + rb*x**2), x) == \ Piecewise((atan(x/sqrt(ra/rb))/(rb*sqrt(ra/rb)), ra/rb > 0), (-acoth(x/sqrt(-ra/rb))/(rb*sqrt(-ra/rb)), And(ra/rb < 0, x**2 > -ra/rb)), (-atanh(x/sqrt(-ra/rb))/(rb*sqrt(-ra/rb)), And(ra/rb < 0, x**2 < -ra/rb))) assert manualintegrate(1/(4 + rb*x**2), x) == \ Piecewise((atan(x/(2*sqrt(1/rb)))/(2*rb*sqrt(1/rb)), 4/rb > 0), (-acoth(x/(2*sqrt(-1/rb)))/(2*rb*sqrt(-1/rb)), And(4/rb < 0, x**2 > -4/rb)), (-atanh(x/(2*sqrt(-1/rb)))/(2*rb*sqrt(-1/rb)), And(4/rb < 0, x**2 < -4/rb))) assert manualintegrate(1/(ra + 4*x**2), x) == \ Piecewise((atan(2*x/sqrt(ra))/(2*sqrt(ra)), ra/4 > 0), (-acoth(2*x/sqrt(-ra))/(2*sqrt(-ra)), And(ra/4 < 0, x**2 > -ra/4)), (-atanh(2*x/sqrt(-ra))/(2*sqrt(-ra)), And(ra/4 < 0, x**2 < -ra/4))) assert manualintegrate(1 / (4 + 4 * x**2), x) == atan(x) / 4 assert manualintegrate(1 / (a + b * x**2), x) == atan(x / sqrt(a / b)) / (b * sqrt(a / b)) # asin assert manualintegrate(1 / sqrt(1 - x**2), x) == asin(x) assert manualintegrate(1 / sqrt(4 - 4 * x**2), x) == asin(x) / 2 assert manualintegrate(3 / sqrt(1 - 9 * x**2), x) == asin(3 * x) assert manualintegrate(1 / sqrt(4 - 9 * x**2), x) == asin(x * Rational(3, 2)) / 3 # asinh assert manualintegrate(1/sqrt(x**2 + 1), x) == \ asinh(x) assert manualintegrate(1/sqrt(x**2 + 4), x) == \ asinh(x/2) assert manualintegrate(1/sqrt(4*x**2 + 4), x) == \ asinh(x)/2 assert manualintegrate(1/sqrt(4*x**2 + 1), x) == \ asinh(2*x)/2 assert manualintegrate(1/sqrt(ra*x**2 + 1), x) == \ Piecewise((asin(x*sqrt(-ra))/sqrt(-ra), ra < 0), (asinh(sqrt(ra)*x)/sqrt(ra), ra > 0)) assert manualintegrate(1/sqrt(ra + x**2), x) == \ Piecewise((asinh(x*sqrt(1/ra)), ra > 0), (acosh(x*sqrt(-1/ra)), ra < 0)) # acosh assert manualintegrate(1/sqrt(x**2 - 1), x) == \ acosh(x) assert manualintegrate(1/sqrt(x**2 - 4), x) == \ acosh(x/2) assert manualintegrate(1/sqrt(4*x**2 - 4), x) == \ acosh(x)/2 assert manualintegrate(1/sqrt(9*x**2 - 1), x) == \ acosh(3*x)/3 assert manualintegrate(1/sqrt(ra*x**2 - 4), x) == \ Piecewise((acosh(sqrt(ra)*x/2)/sqrt(ra), ra > 0)) assert manualintegrate(1/sqrt(-ra + 4*x**2), x) == \ Piecewise((asinh(2*x*sqrt(-1/ra))/2, -ra > 0), (acosh(2*x*sqrt(1/ra))/2, -ra < 0)) # From https://www.wikiwand.com/en/List_of_integrals_of_inverse_trigonometric_functions # asin assert manualintegrate(asin(x), x) == x * asin(x) + sqrt(1 - x**2) assert manualintegrate(asin(a * x), x) == Piecewise( ((a * x * asin(a * x) + sqrt(-a**2 * x**2 + 1)) / a, Ne(a, 0)), (0, True)) assert manualintegrate(x * asin(a * x), x) == -a * Integral( x**2 / sqrt(-a**2 * x**2 + 1), x) / 2 + x**2 * asin(a * x) / 2 # acos assert manualintegrate(acos(x), x) == x * acos(x) - sqrt(1 - x**2) assert manualintegrate(acos(a * x), x) == Piecewise( ((a * x * acos(a * x) - sqrt(-a**2 * x**2 + 1)) / a, Ne(a, 0)), (pi * x / 2, True)) assert manualintegrate(x * acos(a * x), x) == a * Integral( x**2 / sqrt(-a**2 * x**2 + 1), x) / 2 + x**2 * acos(a * x) / 2 # atan assert manualintegrate(atan(x), x) == x * atan(x) - log(x**2 + 1) / 2 assert manualintegrate(atan(a * x), x) == Piecewise( ((a * x * atan(a * x) - log(a**2 * x**2 + 1) / 2) / a, Ne(a, 0)), (0, True)) assert manualintegrate( x * atan(a * x), x) == -a * (x / a**2 - atan(x / sqrt(a**(-2))) / (a**4 * sqrt(a**(-2)))) / 2 + x**2 * atan(a * x) / 2 # acsc assert manualintegrate( acsc(x), x) == x * acsc(x) + Integral(1 / (x * sqrt(1 - 1 / x**2)), x) assert manualintegrate( acsc(a * x), x) == x * acsc(a * x) + Integral(1 / (x * sqrt(1 - 1 / (a**2 * x**2))), x) / a assert manualintegrate(x * acsc(a * x), x) == x**2 * acsc(a * x) / 2 + Integral( 1 / sqrt(1 - 1 / (a**2 * x**2)), x) / (2 * a) # asec assert manualintegrate( asec(x), x) == x * asec(x) - Integral(1 / (x * sqrt(1 - 1 / x**2)), x) assert manualintegrate( asec(a * x), x) == x * asec(a * x) - Integral(1 / (x * sqrt(1 - 1 / (a**2 * x**2))), x) / a assert manualintegrate(x * asec(a * x), x) == x**2 * asec(a * x) / 2 - Integral( 1 / sqrt(1 - 1 / (a**2 * x**2)), x) / (2 * a) # acot assert manualintegrate(acot(x), x) == x * acot(x) + log(x**2 + 1) / 2 assert manualintegrate(acot(a * x), x) == Piecewise( ((a * x * acot(a * x) + log(a**2 * x**2 + 1) / 2) / a, Ne(a, 0)), (pi * x / 2, True)) assert manualintegrate( x * acot(a * x), x) == a * (x / a**2 - atan(x / sqrt(a**(-2))) / (a**4 * sqrt(a**(-2)))) / 2 + x**2 * acot(a * x) / 2 # piecewise assert manualintegrate(1/sqrt(ra-rb*x**2), x) == \ Piecewise((asin(x*sqrt(rb/ra))/sqrt(rb), And(-rb < 0, ra > 0)), (asinh(x*sqrt(-rb/ra))/sqrt(-rb), And(-rb > 0, ra > 0)), (acosh(x*sqrt(rb/ra))/sqrt(-rb), And(-rb > 0, ra < 0))) assert manualintegrate(1/sqrt(ra + rb*x**2), x) == \ Piecewise((asin(x*sqrt(-rb/ra))/sqrt(-rb), And(ra > 0, rb < 0)), (asinh(x*sqrt(rb/ra))/sqrt(rb), And(ra > 0, rb > 0)), (acosh(x*sqrt(-rb/ra))/sqrt(rb), And(ra < 0, rb > 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 random import randint from sympy.core.compatibility import unichr for i in range(100): while 1: strtype, length = (unichr, 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_reduce_poly_inequalities_real_interval(): assert reduce_rational_inequalities( [[Eq(x**2, 0)]], x, relational=False) == FiniteSet(0) assert reduce_rational_inequalities( [[Le(x**2, 0)]], x, relational=False) == FiniteSet(0) assert reduce_rational_inequalities( [[Lt(x**2, 0)]], x, relational=False) == S.EmptySet assert reduce_rational_inequalities( [[Ge(x**2, 0)]], x, relational=False) == \ S.Reals if x.is_real else Interval(-oo, oo) assert reduce_rational_inequalities( [[Gt(x**2, 0)]], x, relational=False) == \ FiniteSet(0).complement(S.Reals) assert reduce_rational_inequalities( [[Ne(x**2, 0)]], x, relational=False) == \ FiniteSet(0).complement(S.Reals) assert reduce_rational_inequalities( [[Eq(x**2, 1)]], x, relational=False) == FiniteSet(-1, 1) assert reduce_rational_inequalities( [[Le(x**2, 1)]], x, relational=False) == Interval(-1, 1) assert reduce_rational_inequalities( [[Lt(x**2, 1)]], x, relational=False) == Interval(-1, 1, True, True) assert reduce_rational_inequalities( [[Ge(x**2, 1)]], x, relational=False) == \ Union(Interval(-oo, -1), Interval(1, oo)) assert reduce_rational_inequalities( [[Gt(x**2, 1)]], x, relational=False) == \ Interval(-1, 1).complement(S.Reals) assert reduce_rational_inequalities( [[Ne(x**2, 1)]], x, relational=False) == \ FiniteSet(-1, 1).complement(S.Reals) assert reduce_rational_inequalities([[Eq( x**2, 1.0)]], x, relational=False) == FiniteSet(-1.0, 1.0).evalf() assert reduce_rational_inequalities( [[Le(x**2, 1.0)]], x, relational=False) == Interval(-1.0, 1.0) assert reduce_rational_inequalities([[Lt( x**2, 1.0)]], x, relational=False) == Interval(-1.0, 1.0, True, True) assert reduce_rational_inequalities( [[Ge(x**2, 1.0)]], x, relational=False) == \ Union(Interval(-inf, -1.0), Interval(1.0, inf)) assert reduce_rational_inequalities( [[Gt(x**2, 1.0)]], x, relational=False) == \ Union(Interval(-inf, -1.0, right_open=True), Interval(1.0, inf, left_open=True)) assert reduce_rational_inequalities([[Ne( x**2, 1.0)]], x, relational=False) == \ FiniteSet(-1.0, 1.0).complement(S.Reals) s = sqrt(2) assert reduce_rational_inequalities([[Lt( x**2 - 1, 0), Gt(x**2 - 1, 0)]], x, relational=False) == S.EmptySet assert reduce_rational_inequalities([[Le(x**2 - 1, 0), Ge( x**2 - 1, 0)]], x, relational=False) == FiniteSet(-1, 1) assert reduce_rational_inequalities( [[Le(x**2 - 2, 0), Ge(x**2 - 1, 0)]], x, relational=False ) == Union(Interval(-s, -1, False, False), Interval(1, s, False, False)) assert reduce_rational_inequalities( [[Le(x**2 - 2, 0), Gt(x**2 - 1, 0)]], x, relational=False ) == Union(Interval(-s, -1, False, True), Interval(1, s, True, False)) assert reduce_rational_inequalities( [[Lt(x**2 - 2, 0), Ge(x**2 - 1, 0)]], x, relational=False ) == Union(Interval(-s, -1, True, False), Interval(1, s, False, True)) assert reduce_rational_inequalities( [[Lt(x**2 - 2, 0), Gt(x**2 - 1, 0)]], x, relational=False ) == Union(Interval(-s, -1, True, True), Interval(1, s, True, True)) assert reduce_rational_inequalities( [[Lt(x**2 - 2, 0), Ne(x**2 - 1, 0)]], x, relational=False ) == Union(Interval(-s, -1, True, True), Interval(-1, 1, True, True), Interval(1, s, True, True)) assert reduce_rational_inequalities([[Lt(x**2, -1.)]], x) is S.false
def test__solve_inequalities(): assert reduce_inequalities(x + y < 1, symbols=[x]) == (x < 1 - y) assert reduce_inequalities(x + y >= 1, symbols=[x]) == (x < oo) & (x >= -y + 1) assert reduce_inequalities(Eq(0, x - y), symbols=[x]) == Eq(x, y) assert reduce_inequalities(Ne(0, x - y), symbols=[x]) == Ne(x, y)
(r"a \div b", a / b), (r"a + b", a + b), (r"a + b - a", _Add(a + b, -a)), (r"a^2 + b^2 = c^2", Eq(a**2 + b**2, c**2)), (r"(x + y) z", _Mul(_Add(x, y), z)), (r"\left(x + y\right) z", _Mul(_Add(x, y), z)), (r"\left( x + y\right ) z", _Mul(_Add(x, y), z)), (r"\left( x + y\right ) z", _Mul(_Add(x, y), z)), (r"\left[x + y\right] z", _Mul(_Add(x, y), z)), (r"\left\{x + y\right\} z", _Mul(_Add(x, y), z)), (r"1+1", _Add(1, 1)), (r"0+1", _Add(0, 1)), (r"1*2", _Mul(1, 2)), (r"0*1", _Mul(0, 1)), (r"x = y", Eq(x, y)), (r"x \neq y", Ne(x, y)), (r"x < y", Lt(x, y)), (r"x > y", Gt(x, y)), (r"x \leq y", Le(x, y)), (r"x \geq y", Ge(x, y)), (r"x \le y", Le(x, y)), (r"x \ge y", Ge(x, y)), (r"\lfloor x \rfloor", floor(x)), (r"\lceil x \rceil", ceiling(x)), (r"\langle x |", Bra('x')), (r"| x \rangle", Ket('x')), (r"\sin \theta", sin(theta)), (r"\sin(\theta)", sin(theta)), (r"\sin^{-1} a", asin(a)), (r"\sin a \cos b", _Mul(sin(a), cos(b))), (r"\sin \cos \theta", sin(cos(theta))),
def test_rel_ne(): assert Relational(x, y, '!=') == Ne(x, y)
def test_simplification(): """ Test working of simplification methods. """ set1 = [[0, 0, 1], [0, 1, 1], [1, 0, 0], [1, 1, 0]] set2 = [[0, 0, 0], [0, 1, 0], [1, 0, 1], [1, 1, 1]] assert SOPform([x, y, z], set1) == Or(And(Not(x), z), And(Not(z), x)) assert Not(SOPform([x, y, z], set2)) == Not(Or(And(Not(x), Not(z)), And(x, z))) assert POSform([x, y, z], set1 + set2) is true assert SOPform([x, y, z], set1 + set2) is true assert SOPform([Dummy(), Dummy(), Dummy()], set1 + set2) is true minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 1]] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, 3, 7, 11, 15] dontcares = [0, 2, 5] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [1, [0, 0, 1, 1], 7, [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [0, [0, 0, 1, 0], 5] assert (SOPform([w, x, y, z], minterms, dontcares) == Or(And(Not(w), z), And(y, z))) assert POSform([w, x, y, z], minterms, dontcares) == And(Or(Not(w), y), z) minterms = [{y: 1, z: 1}, 1] dontcares = [[0, 0, 0, 0]] minterms = [[0, 0, 0]] raises(ValueError, lambda: SOPform([w, x, y, z], minterms)) raises(ValueError, lambda: POSform([w, x, y, z], minterms)) raises(TypeError, lambda: POSform([w, x, y, z], ["abcdefg"])) # test simplification ans = And(A, Or(B, C)) assert simplify_logic(A & (B | C)) == ans assert simplify_logic((A & B) | (A & C)) == ans assert simplify_logic(Implies(A, B)) == Or(Not(A), B) assert simplify_logic(Equivalent(A, B)) == \ Or(And(A, B), And(Not(A), Not(B))) assert simplify_logic(And(Equality(A, 2), C)) == And(Equality(A, 2), C) assert simplify_logic(And(Equality(A, 2), A)) is S.false assert simplify_logic(And(Equality(A, 2), A)) == And(Equality(A, 2), A) assert simplify_logic(And(Equality(A, B), C)) == And(Equality(A, B), C) assert simplify_logic(Or(And(Equality(A, 3), B), And(Equality(A, 3), C))) \ == And(Equality(A, 3), Or(B, C)) b = (~x & ~y & ~z) | (~x & ~y & z) e = And(A, b) assert simplify_logic(e) == A & ~x & ~y # check input ans = SOPform([x, y], [[1, 0]]) assert SOPform([x, y], [[1, 0]]) == ans assert POSform([x, y], [[1, 0]]) == ans raises(ValueError, lambda: SOPform([x], [[1]], [[1]])) assert SOPform([x], [[1]], [[0]]) is true assert SOPform([x], [[0]], [[1]]) is true assert SOPform([x], [], []) is false raises(ValueError, lambda: POSform([x], [[1]], [[1]])) assert POSform([x], [[1]], [[0]]) is true assert POSform([x], [[0]], [[1]]) is true assert POSform([x], [], []) is false # check working of simplify assert simplify((A & B) | (A & C)) == And(A, Or(B, C)) assert simplify(And(x, Not(x))) == False assert simplify(Or(x, Not(x))) == True assert simplify(And(Eq(x, 0), Eq(x, y))) == And(Eq(x, 0), Eq(y, 0)) assert And(Eq(x - 1, 0), Eq(x, y)).simplify() == And(Eq(x, 1), Eq(y, 1)) assert And(Ne(x - 1, 0), Ne(x, y)).simplify() == And(Ne(x, 1), Ne(x, y)) assert And(Eq(x - 1, 0), Ne(x, y)).simplify() == And(Eq(x, 1), Ne(y, 1)) assert And(Eq(x - 1, 0), Eq(x, z + y), Eq(y + x, 0)).simplify() == And(Eq(x, 1), Eq(y, -1), Eq(z, 2)) assert And(Eq(x - 1, 0), Eq(x + 2, 3)).simplify() == Eq(x, 1) assert And(Ne(x - 1, 0), Ne(x + 2, 3)).simplify() == Ne(x, 1) assert And(Eq(x - 1, 0), Eq(x + 2, 2)).simplify() == False assert And(Ne(x - 1, 0), Ne(x + 2, 2)).simplify() == And(Ne(x, 1), Ne(x, 0))
def _eval_rewrite_as_Piecewise(self, *args, **kwargs): from sympy.functions.elementary.piecewise import Piecewise from sympy.core.relational import Ne i, j = args return Piecewise((0, Ne(i, j)), (1, True))
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) 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)
def test_ContinuousMarkovChain(): T1 = Matrix([[S(-2), S(2), S.Zero], [S.Zero, S.NegativeOne, S.One], [Rational(3, 2), Rational(3, 2), S(-3)]]) C1 = ContinuousMarkovChain('C', [0, 1, 2], T1) assert C1.limiting_distribution() == ImmutableMatrix( [[Rational(3, 19), Rational(12, 19), Rational(4, 19)]]) T2 = Matrix([[-S.One, S.One, S.Zero], [S.One, -S.One, S.Zero], [S.Zero, S.One, -S.One]]) C2 = ContinuousMarkovChain('C', [0, 1, 2], T2) A, t = C2.generator_matrix, symbols('t', positive=True) assert C2.transition_probabilities(A)(t) == Matrix( [[S.Half + exp(-2 * t) / 2, S.Half - exp(-2 * t) / 2, 0], [S.Half - exp(-2 * t) / 2, S.Half + exp(-2 * t) / 2, 0], [ S.Half - exp(-t) + exp(-2 * t) / 2, S.Half - exp(-2 * t) / 2, exp(-t) ]]) with ignore_warnings( UserWarning): ### TODO: Restore tests once warnings are removed assert P(Eq(C2(1), 1), Eq(C2(0), 1), evaluate=False) == Probability(Eq(C2(1), 1), Eq(C2(0), 1)) assert P(Eq(C2(1), 1), Eq(C2(0), 1)) == exp(-2) / 2 + S.Half assert P( Eq(C2(1), 0) & Eq(C2(2), 1) & Eq(C2(3), 1), Eq(P(Eq(C2(1), 0)), S.Half)) == (Rational(1, 4) - exp(-2) / 4) * (exp(-2) / 2 + S.Half) assert P( Not(Eq(C2(1), 0) & Eq(C2(2), 1) & Eq(C2(3), 2)) | (Eq(C2(1), 0) & Eq(C2(2), 1) & Eq(C2(3), 2)), Eq(P(Eq(C2(1), 0)), Rational(1, 4)) & Eq(P(Eq(C2(1), 1)), Rational(1, 4))) is S.One assert E(C2(Rational(3, 2)), Eq(C2(0), 2)) == -exp(-3) / 2 + 2 * exp(Rational(-3, 2)) + S.Half assert variance(C2(Rational(3, 2)), Eq( C2(0), 1)) == ((S.Half - exp(-3) / 2)**2 * (exp(-3) / 2 + S.Half) + (Rational(-1, 2) - exp(-3) / 2)**2 * (S.Half - exp(-3) / 2)) raises(KeyError, lambda: P(Eq(C2(1), 0), Eq(P(Eq(C2(1), 1)), S.Half))) assert P(Eq(C2(1), 0), Eq(P(Eq(C2(5), 1)), S.Half)) == Probability(Eq(C2(1), 0)) TS1 = MatrixSymbol('G', 3, 3) CS1 = ContinuousMarkovChain('C', [0, 1, 2], TS1) A = CS1.generator_matrix assert CS1.transition_probabilities(A)(t) == exp(t * A) C3 = ContinuousMarkovChain( 'C', [Symbol('0'), Symbol('1'), Symbol('2')], T2) assert P(Eq(C3(1), 1), Eq(C3(0), 1)) == exp(-2) / 2 + S.Half assert P(Eq(C3(1), Symbol('1')), Eq(C3(0), Symbol('1'))) == exp(-2) / 2 + S.Half #test probability queries G = Matrix([[-S(1), Rational(1, 10), Rational(9, 10)], [Rational(2, 5), -S(1), Rational(3, 5)], [Rational(1, 2), Rational(1, 2), -S(1)]]) C = ContinuousMarkovChain('C', state_space=[0, 1, 2], gen_mat=G) assert P(Eq(C(7.385), C(3.19)), Eq(C(0.862), 0)).round(5) == Float(0.35469, 5) assert P(Gt(C(98.715), C(19.807)), Eq(C(11.314), 2)).round(5) == Float(0.32452, 5) assert P(Le(C(5.9), C(10.112)), Eq(C(4), 1)).round(6) == Float(0.675214, 6) assert Float(P(Eq(C(7.32), C(2.91)), Eq(C(2.63), 1)), 14) == Float(1 - P(Ne(C(7.32), C(2.91)), Eq(C(2.63), 1)), 14) assert Float(P(Gt(C(3.36), C(1.101)), Eq(C(0.8), 2)), 14) == Float(1 - P(Le(C(3.36), C(1.101)), Eq(C(0.8), 2)), 14) assert Float(P(Lt(C(4.9), C(2.79)), Eq(C(1.61), 0)), 14) == Float(1 - P(Ge(C(4.9), C(2.79)), Eq(C(1.61), 0)), 14) assert P(Eq(C(5.243), C(10.912)), Eq(C(2.174), 1)) == P(Eq(C(10.912), C(5.243)), Eq(C(2.174), 1)) assert P(Gt(C(2.344), C(9.9)), Eq(C(1.102), 1)) == P(Lt(C(9.9), C(2.344)), Eq(C(1.102), 1)) assert P(Ge(C(7.87), C(1.008)), Eq(C(0.153), 1)) == P(Le(C(1.008), C(7.87)), Eq(C(0.153), 1)) #test symbolic queries a, b, c, d = symbols('a b c d') query = P(Eq(C(a), b), Eq(C(c), d)) assert query.subs({ a: 3.65, b: 2, c: 1.78, d: 1 }).evalf().round(10) == P(Eq(C(3.65), 2), Eq(C(1.78), 1)).round(10) query_gt = P(Gt(C(a), b), Eq(C(c), d)) query_le = P(Le(C(a), b), Eq(C(c), d)) assert query_gt.subs({ a: 13.2, b: 0, c: 3.29, d: 2 }).evalf() + query_le.subs({ a: 13.2, b: 0, c: 3.29, d: 2 }).evalf() == 1 query_ge = P(Ge(C(a), b), Eq(C(c), d)) query_lt = P(Lt(C(a), b), Eq(C(c), d)) assert query_ge.subs({ a: 7.43, b: 1, c: 1.45, d: 0 }).evalf() + query_lt.subs({ a: 7.43, b: 1, c: 1.45, d: 0 }).evalf() == 1 #test issue 20078 assert (2 * C(1) + 3 * C(1)).simplify() == 5 * C(1) assert (2 * C(1) - 3 * C(1)).simplify() == -C(1) assert (2 * (0.25 * C(1))).simplify() == 0.5 * C(1) assert (2 * C(1) * 0.25 * C(1)).simplify() == 0.5 * C(1)**2 assert (C(1)**2 + C(1)**3).simplify() == (C(1) + 1) * C(1)**2
def test_relational_simplification(): w, x, y, z = symbols('w x y z', real=True) d, e = symbols('d e', real=False) # Test all combinations or sign and order assert Or(x >= y, x < y).simplify() == S.true assert Or(x >= y, y > x).simplify() == S.true assert Or(x >= y, -x > -y).simplify() == S.true assert Or(x >= y, -y < -x).simplify() == S.true assert Or(-x <= -y, x < y).simplify() == S.true assert Or(-x <= -y, -x > -y).simplify() == S.true assert Or(-x <= -y, y > x).simplify() == S.true assert Or(-x <= -y, -y < -x).simplify() == S.true assert Or(y <= x, x < y).simplify() == S.true assert Or(y <= x, y > x).simplify() == S.true assert Or(y <= x, -x > -y).simplify() == S.true assert Or(y <= x, -y < -x).simplify() == S.true assert Or(-y >= -x, x < y).simplify() == S.true assert Or(-y >= -x, y > x).simplify() == S.true assert Or(-y >= -x, -x > -y).simplify() == S.true assert Or(-y >= -x, -y < -x).simplify() == S.true assert Or(x < y, x >= y).simplify() == S.true assert Or(y > x, x >= y).simplify() == S.true assert Or(-x > -y, x >= y).simplify() == S.true assert Or(-y < -x, x >= y).simplify() == S.true assert Or(x < y, -x <= -y).simplify() == S.true assert Or(-x > -y, -x <= -y).simplify() == S.true assert Or(y > x, -x <= -y).simplify() == S.true assert Or(-y < -x, -x <= -y).simplify() == S.true assert Or(x < y, y <= x).simplify() == S.true assert Or(y > x, y <= x).simplify() == S.true assert Or(-x > -y, y <= x).simplify() == S.true assert Or(-y < -x, y <= x).simplify() == S.true assert Or(x < y, -y >= -x).simplify() == S.true assert Or(y > x, -y >= -x).simplify() == S.true assert Or(-x > -y, -y >= -x).simplify() == S.true assert Or(-y < -x, -y >= -x).simplify() == S.true # Some other tests assert Or(x >= y, w < z, x <= y).simplify() == S.true assert And(x >= y, x < y).simplify() == S.false assert Or(x >= y, Eq(y, x)).simplify() == (x >= y) assert And(x >= y, Eq(y, x)).simplify() == Eq(x, y) assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \ (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z)) assert Or(Eq(x, y), x >= y, w < y, z < y).simplify() == \ (x >= y) | (y > z) | (w < y) assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify() == \ Eq(x, y) & (y > z) & (w < y) # assert And(Eq(x, y), x >= y, w < y, y >= z, z < y).simplify(relational_minmax=True) == \ # And(Eq(x, y), y > Max(w, z)) # assert Or(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify(relational_minmax=True) == \ # (Eq(x, y) | (x >= 1) | (y > Min(2, z))) assert And(Eq(x, y), x >= 1, 2 < y, y >= 5, z < y).simplify() == \ (Eq(x, y) & (x >= 1) & (y >= 5) & (y > z)) assert (Eq(x, y) & Eq(d, e) & (x >= y) & (d >= e)).simplify() == \ (Eq(x, y) & Eq(d, e) & (d >= e)) assert And(Eq(x, y), Eq(x, -y)).simplify() == And(Eq(x, 0), Eq(y, 0)) assert Xor(x >= y, x <= y).simplify() == Ne(x, y) assert And(x > 1, x < -1, Eq(x, y)).simplify() == S.false # From #16690 assert And(x >= y, Eq(y, 0)).simplify() == And(x >= 0, Eq(y, 0))
def test_issue_9778(): assert solveset(x**3 + 1, x, S.Reals) == FiniteSet(-1) assert solveset(x**(S(3) / 5) + 1, x, S.Reals) == S.EmptySet assert solveset(x**3 + y, x, S.Reals) == Intersection(Interval(-oo, oo), \ FiniteSet((-y)**(S(1)/3)*Piecewise((1, Ne(-im(y), 0)), ((-1)**(S(2)/3), -y < 0), (1, True))))
def test_frac(): assert isinstance(frac(x), frac) assert frac(oo) == AccumBounds(0, 1) assert frac(-oo) == AccumBounds(0, 1) assert frac(zoo) is nan assert frac(n) == 0 assert frac(nan) is nan assert frac(Rational(4, 3)) == Rational(1, 3) assert frac(-Rational(4, 3)) == Rational(2, 3) assert frac(Rational(-4, 3)) == Rational(2, 3) r = Symbol('r', real=True) assert frac(I*r) == I*frac(r) assert frac(1 + I*r) == I*frac(r) assert frac(0.5 + I*r) == 0.5 + I*frac(r) assert frac(n + I*r) == I*frac(r) assert frac(n + I*k) == 0 assert unchanged(frac, x + I*x) assert frac(x + I*n) == frac(x) assert frac(x).rewrite(floor) == x - floor(x) assert frac(x).rewrite(ceiling) == x + ceiling(-x) assert frac(y).rewrite(floor).subs(y, pi) == frac(pi) assert frac(y).rewrite(floor).subs(y, -E) == frac(-E) assert frac(y).rewrite(ceiling).subs(y, -pi) == frac(-pi) assert frac(y).rewrite(ceiling).subs(y, E) == frac(E) assert Eq(frac(y), y - floor(y)) assert Eq(frac(y), y + ceiling(-y)) r = Symbol('r', real=True) p_i = Symbol('p_i', integer=True, positive=True) n_i = Symbol('p_i', integer=True, negative=True) np_i = Symbol('np_i', integer=True, nonpositive=True) nn_i = Symbol('nn_i', integer=True, nonnegative=True) p_r = Symbol('p_r', positive=True) n_r = Symbol('n_r', negative=True) np_r = Symbol('np_r', real=True, nonpositive=True) nn_r = Symbol('nn_r', real=True, nonnegative=True) # Real frac argument, integer rhs assert frac(r) <= p_i assert not frac(r) <= n_i assert (frac(r) <= np_i).has(Le) assert (frac(r) <= nn_i).has(Le) assert frac(r) < p_i assert not frac(r) < n_i assert not frac(r) < np_i assert (frac(r) < nn_i).has(Lt) assert not frac(r) >= p_i assert frac(r) >= n_i assert frac(r) >= np_i assert (frac(r) >= nn_i).has(Ge) assert not frac(r) > p_i assert frac(r) > n_i assert (frac(r) > np_i).has(Gt) assert (frac(r) > nn_i).has(Gt) assert not Eq(frac(r), p_i) assert not Eq(frac(r), n_i) assert Eq(frac(r), np_i).has(Eq) assert Eq(frac(r), nn_i).has(Eq) assert Ne(frac(r), p_i) assert Ne(frac(r), n_i) assert Ne(frac(r), np_i).has(Ne) assert Ne(frac(r), nn_i).has(Ne) # Real frac argument, real rhs assert (frac(r) <= p_r).has(Le) assert not frac(r) <= n_r assert (frac(r) <= np_r).has(Le) assert (frac(r) <= nn_r).has(Le) assert (frac(r) < p_r).has(Lt) assert not frac(r) < n_r assert not frac(r) < np_r assert (frac(r) < nn_r).has(Lt) assert (frac(r) >= p_r).has(Ge) assert frac(r) >= n_r assert frac(r) >= np_r assert (frac(r) >= nn_r).has(Ge) assert (frac(r) > p_r).has(Gt) assert frac(r) > n_r assert (frac(r) > np_r).has(Gt) assert (frac(r) > nn_r).has(Gt) assert not Eq(frac(r), n_r) assert Eq(frac(r), p_r).has(Eq) assert Eq(frac(r), np_r).has(Eq) assert Eq(frac(r), nn_r).has(Eq) assert Ne(frac(r), p_r).has(Ne) assert Ne(frac(r), n_r) assert Ne(frac(r), np_r).has(Ne) assert Ne(frac(r), nn_r).has(Ne) # Real frac argument, +/- oo rhs assert frac(r) < oo assert frac(r) <= oo assert not frac(r) > oo assert not frac(r) >= oo assert not frac(r) < -oo assert not frac(r) <= -oo assert frac(r) > -oo assert frac(r) >= -oo assert frac(r) < 1 assert frac(r) <= 1 assert not frac(r) > 1 assert not frac(r) >= 1 assert not frac(r) < 0 assert (frac(r) <= 0).has(Le) assert (frac(r) > 0).has(Gt) assert frac(r) >= 0 # Some test for numbers assert frac(r) <= sqrt(2) assert (frac(r) <= sqrt(3) - sqrt(2)).has(Le) assert not frac(r) <= sqrt(2) - sqrt(3) assert not frac(r) >= sqrt(2) assert (frac(r) >= sqrt(3) - sqrt(2)).has(Ge) assert frac(r) >= sqrt(2) - sqrt(3) assert not Eq(frac(r), sqrt(2)) assert Eq(frac(r), sqrt(3) - sqrt(2)).has(Eq) assert not Eq(frac(r), sqrt(2) - sqrt(3)) assert Ne(frac(r), sqrt(2)) assert Ne(frac(r), sqrt(3) - sqrt(2)).has(Ne) assert Ne(frac(r), sqrt(2) - sqrt(3)) assert frac(p_i, evaluate=False).is_zero assert frac(p_i, evaluate=False).is_finite assert frac(p_i, evaluate=False).is_integer assert frac(p_i, evaluate=False).is_real assert frac(r).is_finite assert frac(r).is_real assert frac(r).is_zero is None assert frac(r).is_integer is None assert frac(oo).is_finite assert frac(oo).is_real
def test_issue_15847(): a = Ne(x * (x + y), x**2 + x * y) assert simplify(a) == False
("a \\div b", a / b), ("a + b", a + b), ("a + b - a", _Add(a + b, -a)), ("a^2 + b^2 = c^2", Eq(a**2 + b**2, c**2)), ("(x + y) z", _Mul(_Add(x, y), z)), ("\\left(x + y\\right) z", _Mul(_Add(x, y), z)), ("\\left( x + y\\right ) z", _Mul(_Add(x, y), z)), ("\\left( x + y\\right ) z", _Mul(_Add(x, y), z)), ("\\left[x + y\\right] z", _Mul(_Add(x, y), z)), ("\\left\\{x + y\\right\\} z", _Mul(_Add(x, y), z)), ("1+1", Add(1, 1, evaluate=False)), ("0+1", Add(0, 1, evaluate=False)), ("1*2", Mul(1, 2, evaluate=False)), ("0*1", Mul(0, 1, evaluate=False)), ("x = y", Eq(x, y)), ("x \\neq y", Ne(x, y)), ("x < y", Lt(x, y)), ("x > y", Gt(x, y)), ("x \\leq y", Le(x, y)), ("x \\geq y", Ge(x, y)), ("x \\le y", Le(x, y)), ("x \\ge y", Ge(x, y)), ("\\lfloor x \\rfloor", floor(x)), ("\\lceil x \\rceil", ceiling(x)), ("\\langle x |", Bra('x')), ("| x \\rangle", Ket('x')), ("\\sin \\theta", sin(theta)), ("\\sin(\\theta)", sin(theta)), ("\\sin^{-1} a", asin(a)), ("\\sin a \\cos b", _Mul(sin(a), cos(b))), ("\\sin \\cos \\theta", sin(cos(theta))),
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 _solve_inequality(ie, s, linear=False): """Return the inequality with s isolated on the left, if possible. If the relationship is non-linear, a solution involving And or Or may be returned. False or True are returned if the relationship is never True or always True, respectively. If `linear` is True (default is False) an `s`-dependent expression will be isoloated on the left, if possible but it will not be solved for `s` unless the expression is linear in `s`. Furthermore, only "safe" operations which don't change the sense of the relationship are applied: no division by an unsigned value is attempted unless the relationship involves Eq or Ne and no division by a value not known to be nonzero is ever attempted. Examples ======== >>> from sympy import Eq, Symbol >>> from sympy.solvers.inequalities import _solve_inequality as f >>> from sympy.abc import x, y For linear expressions, the symbol can be isolated: >>> f(x - 2 < 0, x) x < 2 >>> f(-x - 6 < x, x) x > -3 Sometimes nonlinear relationships will be False >>> f(x**2 + 4 < 0, x) False Or they may involve more than one region of values: >>> f(x**2 - 4 < 0, x) (-2 < x) & (x < 2) To restrict the solution to a relational, set linear=True and only the x-dependent portion will be isolated on the left: >>> f(x**2 - 4 < 0, x, linear=True) x**2 < 4 Division of only nonzero quantities is allowed, so x cannot be isolated by dividing by y: >>> y.is_nonzero is None # it is unknown whether it is 0 or not True >>> f(x*y < 1, x) x*y < 1 And while an equality (or unequality) still holds after dividing by a non-zero quantity >>> nz = Symbol('nz', nonzero=True) >>> f(Eq(x*nz, 1), x) Eq(x, 1/nz) the sign must be known for other inequalities involving > or <: >>> f(x*nz <= 1, x) nz*x <= 1 >>> p = Symbol('p', positive=True) >>> f(x*p <= 1, x) x <= 1/p When there are denominators in the original expression that are removed by expansion, conditions for them will be returned as part of the result: >>> f(x < x*(2/x - 1), x) (x < 1) & Ne(x, 0) """ from sympy.solvers.solvers import denoms if s not in ie.free_symbols: return ie if ie.rhs == s: ie = ie.reversed if ie.lhs == s and s not in ie.rhs.free_symbols: return ie expr = ie.lhs - ie.rhs rv = None try: p = Poly(expr, s) if p.degree() == 0: rv = ie.func(p.as_expr(), 0) elif not linear and p.degree() > 1: # handle in except clause raise NotImplementedError except (PolynomialError, NotImplementedError): if not linear: try: return reduce_rational_inequalities([[ie]], s) except PolynomialError: return solve_univariate_inequality(ie, s) else: p = Poly(expr) e = expanded = p.as_expr() # this is in exanded form if rv is None: # Do a safe inversion of e, moving non-s terms # to the rhs and dividing by a nonzero factor if # the relational is Eq/Ne; for other relationals # the sign must also be positive or negative rhs = 0 b, ax = e.as_independent(s, as_Add=True) e -= b rhs -= b ef = factor_terms(e) a, e = ef.as_independent(s, as_Add=False) if (a.is_zero != False or # don't divide by potential 0 a.is_negative == a.is_positive == None and # if sign is not known then ie.rel_op not in ('!=', '==')): # reject if not Eq/Ne e = ef a = S.One rhs /= a if a.is_positive: rv = ie.func(e, rhs) else: rv = ie.reversed.func(e, rhs) # return conditions under which the value is # valid, too. conds = [rv] beginning_denoms = denoms(ie.lhs) | denoms(ie.rhs) current_denoms = denoms(expanded) for d in beginning_denoms - current_denoms: conds.append(_solve_inequality(Ne(d, 0), s, linear=linear)) return And(*conds)
def heurisch_wrapper(f, x, rewrite=False, hints=None, mappings=None, retries=3, degree_offset=0, unnecessary_permutations=None, _try_heurisch=None): """ A wrapper around the heurisch integration algorithm. Explanation =========== This method takes the result from heurisch and checks for poles in the denominator. For each of these poles, the integral is reevaluated, and the final integration result is given in terms of a Piecewise. Examples ======== >>> from sympy import cos, symbols >>> from sympy.integrals.heurisch import heurisch, heurisch_wrapper >>> n, x = symbols('n x') >>> heurisch(cos(n*x), x) sin(n*x)/n >>> heurisch_wrapper(cos(n*x), x) Piecewise((sin(n*x)/n, Ne(n, 0)), (x, True)) See Also ======== heurisch """ from sympy.solvers.solvers import solve, denoms f = sympify(f) if not f.has_free(x): return f*x res = heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch) if not isinstance(res, Basic): return res # We consider each denominator in the expression, and try to find # cases where one or more symbolic denominator might be zero. The # conditions for these cases are stored in the list slns. slns = [] for d in denoms(res): try: slns += solve(d, dict=True, exclude=(x,)) except NotImplementedError: pass if not slns: return res slns = list(uniq(slns)) # Remove the solutions corresponding to poles in the original expression. slns0 = [] for d in denoms(f): try: slns0 += solve(d, dict=True, exclude=(x,)) except NotImplementedError: pass slns = [s for s in slns if s not in slns0] if not slns: return res if len(slns) > 1: eqs = [] for sub_dict in slns: eqs.extend([Eq(key, value) for key, value in sub_dict.items()]) slns = solve(eqs, dict=True, exclude=(x,)) + slns # For each case listed in the list slns, we reevaluate the integral. pairs = [] for sub_dict in slns: expr = heurisch(f.subs(sub_dict), x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch) cond = And(*[Eq(key, value) for key, value in sub_dict.items()]) generic = Or(*[Ne(key, value) for key, value in sub_dict.items()]) if expr is None: expr = integrate(f.subs(sub_dict),x) pairs.append((expr, cond)) # If there is one condition, put the generic case first. Otherwise, # doing so may lead to longer Piecewise formulas if len(pairs) == 1: pairs = [(heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch), generic), (pairs[0][0], True)] else: pairs.append((heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch), True)) return Piecewise(*pairs)
def test_new_relational(): x = Symbol('x') assert Eq(x) == Relational(x, 0) # None ==> Equality assert Eq(x) == Relational(x, 0, '==') assert Eq(x) == Relational(x, 0, 'eq') assert Eq(x) == Equality(x, 0) 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) != Relational(x, 1) # None ==> Equality assert Eq(x) != Relational(x, 1, '==') assert Eq(x) != Relational(x, 1, 'eq') assert Eq(x) != 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 random import randint for i in range(100): while 1: if sys.version_info[0] >= 3: strtype, length = (chr, 65535) if randint(0, 1) else (chr, 255) else: strtype, length = (unichr, 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))