Spaces:
Sleeping
Sleeping
from sympy.core.numbers import (E, Rational, oo, pi, zoo) | |
from sympy.core.singleton import S | |
from sympy.core.symbol import Symbol | |
from sympy.functions.elementary.exponential import (exp, log) | |
from sympy.functions.elementary.miscellaneous import (Max, Min, sqrt) | |
from sympy.functions.elementary.trigonometric import (cos, sin, tan) | |
from sympy.calculus.accumulationbounds import AccumBounds | |
from sympy.core import Add, Mul, Pow | |
from sympy.core.expr import unchanged | |
from sympy.testing.pytest import raises, XFAIL | |
from sympy.abc import x | |
a = Symbol('a', real=True) | |
B = AccumBounds | |
def test_AccumBounds(): | |
assert B(1, 2).args == (1, 2) | |
assert B(1, 2).delta is S.One | |
assert B(1, 2).mid == Rational(3, 2) | |
assert B(1, 3).is_real == True | |
assert B(1, 1) is S.One | |
assert B(1, 2) + 1 == B(2, 3) | |
assert 1 + B(1, 2) == B(2, 3) | |
assert B(1, 2) + B(2, 3) == B(3, 5) | |
assert -B(1, 2) == B(-2, -1) | |
assert B(1, 2) - 1 == B(0, 1) | |
assert 1 - B(1, 2) == B(-1, 0) | |
assert B(2, 3) - B(1, 2) == B(0, 2) | |
assert x + B(1, 2) == Add(B(1, 2), x) | |
assert a + B(1, 2) == B(1 + a, 2 + a) | |
assert B(1, 2) - x == Add(B(1, 2), -x) | |
assert B(-oo, 1) + oo == B(-oo, oo) | |
assert B(1, oo) + oo is oo | |
assert B(1, oo) - oo == B(-oo, oo) | |
assert (-oo - B(-1, oo)) is -oo | |
assert B(-oo, 1) - oo is -oo | |
assert B(1, oo) - oo == B(-oo, oo) | |
assert B(-oo, 1) - (-oo) == B(-oo, oo) | |
assert (oo - B(1, oo)) == B(-oo, oo) | |
assert (-oo - B(1, oo)) is -oo | |
assert B(1, 2)/2 == B(S.Half, 1) | |
assert 2/B(2, 3) == B(Rational(2, 3), 1) | |
assert 1/B(-1, 1) == B(-oo, oo) | |
assert abs(B(1, 2)) == B(1, 2) | |
assert abs(B(-2, -1)) == B(1, 2) | |
assert abs(B(-2, 1)) == B(0, 2) | |
assert abs(B(-1, 2)) == B(0, 2) | |
c = Symbol('c') | |
raises(ValueError, lambda: B(0, c)) | |
raises(ValueError, lambda: B(1, -1)) | |
r = Symbol('r', real=True) | |
raises(ValueError, lambda: B(r, r - 1)) | |
def test_AccumBounds_mul(): | |
assert B(1, 2)*2 == B(2, 4) | |
assert 2*B(1, 2) == B(2, 4) | |
assert B(1, 2)*B(2, 3) == B(2, 6) | |
assert B(0, 2)*B(2, oo) == B(0, oo) | |
l, r = B(-oo, oo), B(-a, a) | |
assert l*r == B(-oo, oo) | |
assert r*l == B(-oo, oo) | |
l, r = B(1, oo), B(-3, -2) | |
assert l*r == B(-oo, -2) | |
assert r*l == B(-oo, -2) | |
assert B(1, 2)*0 == 0 | |
assert B(1, oo)*0 == B(0, oo) | |
assert B(-oo, 1)*0 == B(-oo, 0) | |
assert B(-oo, oo)*0 == B(-oo, oo) | |
assert B(1, 2)*x == Mul(B(1, 2), x, evaluate=False) | |
assert B(0, 2)*oo == B(0, oo) | |
assert B(-2, 0)*oo == B(-oo, 0) | |
assert B(0, 2)*(-oo) == B(-oo, 0) | |
assert B(-2, 0)*(-oo) == B(0, oo) | |
assert B(-1, 1)*oo == B(-oo, oo) | |
assert B(-1, 1)*(-oo) == B(-oo, oo) | |
assert B(-oo, oo)*oo == B(-oo, oo) | |
def test_AccumBounds_div(): | |
assert B(-1, 3)/B(3, 4) == B(Rational(-1, 3), 1) | |
assert B(-2, 4)/B(-3, 4) == B(-oo, oo) | |
assert B(-3, -2)/B(-4, 0) == B(S.Half, oo) | |
# these two tests can have a better answer | |
# after Union of B is improved | |
assert B(-3, -2)/B(-2, 1) == B(-oo, oo) | |
assert B(2, 3)/B(-2, 2) == B(-oo, oo) | |
assert B(-3, -2)/B(0, 4) == B(-oo, Rational(-1, 2)) | |
assert B(2, 4)/B(-3, 0) == B(-oo, Rational(-2, 3)) | |
assert B(2, 4)/B(0, 3) == B(Rational(2, 3), oo) | |
assert B(0, 1)/B(0, 1) == B(0, oo) | |
assert B(-1, 0)/B(0, 1) == B(-oo, 0) | |
assert B(-1, 2)/B(-2, 2) == B(-oo, oo) | |
assert 1/B(-1, 2) == B(-oo, oo) | |
assert 1/B(0, 2) == B(S.Half, oo) | |
assert (-1)/B(0, 2) == B(-oo, Rational(-1, 2)) | |
assert 1/B(-oo, 0) == B(-oo, 0) | |
assert 1/B(-1, 0) == B(-oo, -1) | |
assert (-2)/B(-oo, 0) == B(0, oo) | |
assert 1/B(-oo, -1) == B(-1, 0) | |
assert B(1, 2)/a == Mul(B(1, 2), 1/a, evaluate=False) | |
assert B(1, 2)/0 == B(1, 2)*zoo | |
assert B(1, oo)/oo == B(0, oo) | |
assert B(1, oo)/(-oo) == B(-oo, 0) | |
assert B(-oo, -1)/oo == B(-oo, 0) | |
assert B(-oo, -1)/(-oo) == B(0, oo) | |
assert B(-oo, oo)/oo == B(-oo, oo) | |
assert B(-oo, oo)/(-oo) == B(-oo, oo) | |
assert B(-1, oo)/oo == B(0, oo) | |
assert B(-1, oo)/(-oo) == B(-oo, 0) | |
assert B(-oo, 1)/oo == B(-oo, 0) | |
assert B(-oo, 1)/(-oo) == B(0, oo) | |
def test_issue_18795(): | |
r = Symbol('r', real=True) | |
a = B(-1,1) | |
c = B(7, oo) | |
b = B(-oo, oo) | |
assert c - tan(r) == B(7-tan(r), oo) | |
assert b + tan(r) == B(-oo, oo) | |
assert (a + r)/a == B(-oo, oo)*B(r - 1, r + 1) | |
assert (b + a)/a == B(-oo, oo) | |
def test_AccumBounds_func(): | |
assert (x**2 + 2*x + 1).subs(x, B(-1, 1)) == B(-1, 4) | |
assert exp(B(0, 1)) == B(1, E) | |
assert exp(B(-oo, oo)) == B(0, oo) | |
assert log(B(3, 6)) == B(log(3), log(6)) | |
def test_AccumBounds_powf(): | |
nn = Symbol('nn', nonnegative=True) | |
assert B(1 + nn, 2 + nn)**B(1, 2) == B(1 + nn, (2 + nn)**2) | |
i = Symbol('i', integer=True, negative=True) | |
assert B(1, 2)**i == B(2**i, 1) | |
def test_AccumBounds_pow(): | |
assert B(0, 2)**2 == B(0, 4) | |
assert B(-1, 1)**2 == B(0, 1) | |
assert B(1, 2)**2 == B(1, 4) | |
assert B(-1, 2)**3 == B(-1, 8) | |
assert B(-1, 1)**0 == 1 | |
assert B(1, 2)**Rational(5, 2) == B(1, 4*sqrt(2)) | |
assert B(0, 2)**S.Half == B(0, sqrt(2)) | |
neg = Symbol('neg', negative=True) | |
assert unchanged(Pow, B(neg, 1), S.Half) | |
nn = Symbol('nn', nonnegative=True) | |
assert B(nn, nn + 1)**S.Half == B(sqrt(nn), sqrt(nn + 1)) | |
assert B(nn, nn + 1)**nn == B(nn**nn, (nn + 1)**nn) | |
assert unchanged(Pow, B(nn, nn + 1), x) | |
i = Symbol('i', integer=True) | |
assert B(1, 2)**i == B(Min(1, 2**i), Max(1, 2**i)) | |
i = Symbol('i', integer=True, nonnegative=True) | |
assert B(1, 2)**i == B(1, 2**i) | |
assert B(0, 1)**i == B(0**i, 1) | |
assert B(1, 5)**(-2) == B(Rational(1, 25), 1) | |
assert B(-1, 3)**(-2) == B(0, oo) | |
assert B(0, 2)**(-3) == B(Rational(1, 8), oo) | |
assert B(-2, 0)**(-3) == B(-oo, -Rational(1, 8)) | |
assert B(0, 2)**(-2) == B(Rational(1, 4), oo) | |
assert B(-1, 2)**(-3) == B(-oo, oo) | |
assert B(-3, -2)**(-3) == B(Rational(-1, 8), Rational(-1, 27)) | |
assert B(-3, -2)**(-2) == B(Rational(1, 9), Rational(1, 4)) | |
assert B(0, oo)**S.Half == B(0, oo) | |
assert B(-oo, 0)**(-2) == B(0, oo) | |
assert B(-2, 0)**(-2) == B(Rational(1, 4), oo) | |
assert B(Rational(1, 3), S.Half)**oo is S.Zero | |
assert B(0, S.Half)**oo is S.Zero | |
assert B(S.Half, 1)**oo == B(0, oo) | |
assert B(0, 1)**oo == B(0, oo) | |
assert B(2, 3)**oo is oo | |
assert B(1, 2)**oo == B(0, oo) | |
assert B(S.Half, 3)**oo == B(0, oo) | |
assert B(Rational(-1, 3), Rational(-1, 4))**oo is S.Zero | |
assert B(-1, Rational(-1, 2))**oo is S.NaN | |
assert B(-3, -2)**oo is zoo | |
assert B(-2, -1)**oo is S.NaN | |
assert B(-2, Rational(-1, 2))**oo is S.NaN | |
assert B(Rational(-1, 2), S.Half)**oo is S.Zero | |
assert B(Rational(-1, 2), 1)**oo == B(0, oo) | |
assert B(Rational(-2, 3), 2)**oo == B(0, oo) | |
assert B(-1, 1)**oo == B(-oo, oo) | |
assert B(-1, S.Half)**oo == B(-oo, oo) | |
assert B(-1, 2)**oo == B(-oo, oo) | |
assert B(-2, S.Half)**oo == B(-oo, oo) | |
assert B(1, 2)**x == Pow(B(1, 2), x, evaluate=False) | |
assert B(2, 3)**(-oo) is S.Zero | |
assert B(0, 2)**(-oo) == B(0, oo) | |
assert B(-1, 2)**(-oo) == B(-oo, oo) | |
assert (tan(x)**sin(2*x)).subs(x, B(0, pi/2)) == \ | |
Pow(B(-oo, oo), B(0, 1)) | |
def test_AccumBounds_exponent(): | |
# base is 0 | |
z = 0**B(a, a + S.Half) | |
assert z.subs(a, 0) == B(0, 1) | |
assert z.subs(a, 1) == 0 | |
p = z.subs(a, -1) | |
assert p.is_Pow and p.args == (0, B(-1, -S.Half)) | |
# base > 0 | |
# when base is 1 the type of bounds does not matter | |
assert 1**B(a, a + 1) == 1 | |
# otherwise we need to know if 0 is in the bounds | |
assert S.Half**B(-2, 2) == B(S(1)/4, 4) | |
assert 2**B(-2, 2) == B(S(1)/4, 4) | |
# +eps may introduce +oo | |
# if there is a negative integer exponent | |
assert B(0, 1)**B(S(1)/2, 1) == B(0, 1) | |
assert B(0, 1)**B(0, 1) == B(0, 1) | |
# positive bases have positive bounds | |
assert B(2, 3)**B(-3, -2) == B(S(1)/27, S(1)/4) | |
assert B(2, 3)**B(-3, 2) == B(S(1)/27, 9) | |
# bounds generating imaginary parts unevaluated | |
assert unchanged(Pow, B(-1, 1), B(1, 2)) | |
assert B(0, S(1)/2)**B(1, oo) == B(0, S(1)/2) | |
assert B(0, 1)**B(1, oo) == B(0, oo) | |
assert B(0, 2)**B(1, oo) == B(0, oo) | |
assert B(0, oo)**B(1, oo) == B(0, oo) | |
assert B(S(1)/2, 1)**B(1, oo) == B(0, oo) | |
assert B(S(1)/2, 1)**B(-oo, -1) == B(0, oo) | |
assert B(S(1)/2, 1)**B(-oo, oo) == B(0, oo) | |
assert B(S(1)/2, 2)**B(1, oo) == B(0, oo) | |
assert B(S(1)/2, 2)**B(-oo, -1) == B(0, oo) | |
assert B(S(1)/2, 2)**B(-oo, oo) == B(0, oo) | |
assert B(S(1)/2, oo)**B(1, oo) == B(0, oo) | |
assert B(S(1)/2, oo)**B(-oo, -1) == B(0, oo) | |
assert B(S(1)/2, oo)**B(-oo, oo) == B(0, oo) | |
assert B(1, 2)**B(1, oo) == B(0, oo) | |
assert B(1, 2)**B(-oo, -1) == B(0, oo) | |
assert B(1, 2)**B(-oo, oo) == B(0, oo) | |
assert B(1, oo)**B(1, oo) == B(0, oo) | |
assert B(1, oo)**B(-oo, -1) == B(0, oo) | |
assert B(1, oo)**B(-oo, oo) == B(0, oo) | |
assert B(2, oo)**B(1, oo) == B(2, oo) | |
assert B(2, oo)**B(-oo, -1) == B(0, S(1)/2) | |
assert B(2, oo)**B(-oo, oo) == B(0, oo) | |
def test_comparison_AccumBounds(): | |
assert (B(1, 3) < 4) == S.true | |
assert (B(1, 3) < -1) == S.false | |
assert (B(1, 3) < 2).rel_op == '<' | |
assert (B(1, 3) <= 2).rel_op == '<=' | |
assert (B(1, 3) > 4) == S.false | |
assert (B(1, 3) > -1) == S.true | |
assert (B(1, 3) > 2).rel_op == '>' | |
assert (B(1, 3) >= 2).rel_op == '>=' | |
assert (B(1, 3) < B(4, 6)) == S.true | |
assert (B(1, 3) < B(2, 4)).rel_op == '<' | |
assert (B(1, 3) < B(-2, 0)) == S.false | |
assert (B(1, 3) <= B(4, 6)) == S.true | |
assert (B(1, 3) <= B(-2, 0)) == S.false | |
assert (B(1, 3) > B(4, 6)) == S.false | |
assert (B(1, 3) > B(-2, 0)) == S.true | |
assert (B(1, 3) >= B(4, 6)) == S.false | |
assert (B(1, 3) >= B(-2, 0)) == S.true | |
# issue 13499 | |
assert (cos(x) > 0).subs(x, oo) == (B(-1, 1) > 0) | |
c = Symbol('c') | |
raises(TypeError, lambda: (B(0, 1) < c)) | |
raises(TypeError, lambda: (B(0, 1) <= c)) | |
raises(TypeError, lambda: (B(0, 1) > c)) | |
raises(TypeError, lambda: (B(0, 1) >= c)) | |
def test_contains_AccumBounds(): | |
assert (1 in B(1, 2)) == S.true | |
raises(TypeError, lambda: a in B(1, 2)) | |
assert 0 in B(-1, 0) | |
raises(TypeError, lambda: | |
(cos(1)**2 + sin(1)**2 - 1) in B(-1, 0)) | |
assert (-oo in B(1, oo)) == S.true | |
assert (oo in B(-oo, 0)) == S.true | |
# issue 13159 | |
assert Mul(0, B(-1, 1)) == Mul(B(-1, 1), 0) == 0 | |
import itertools | |
for perm in itertools.permutations([0, B(-1, 1), x]): | |
assert Mul(*perm) == 0 | |
def test_intersection_AccumBounds(): | |
assert B(0, 3).intersection(B(1, 2)) == B(1, 2) | |
assert B(0, 3).intersection(B(1, 4)) == B(1, 3) | |
assert B(0, 3).intersection(B(-1, 2)) == B(0, 2) | |
assert B(0, 3).intersection(B(-1, 4)) == B(0, 3) | |
assert B(0, 1).intersection(B(2, 3)) == S.EmptySet | |
raises(TypeError, lambda: B(0, 3).intersection(1)) | |
def test_union_AccumBounds(): | |
assert B(0, 3).union(B(1, 2)) == B(0, 3) | |
assert B(0, 3).union(B(1, 4)) == B(0, 4) | |
assert B(0, 3).union(B(-1, 2)) == B(-1, 3) | |
assert B(0, 3).union(B(-1, 4)) == B(-1, 4) | |
raises(TypeError, lambda: B(0, 3).union(1)) | |