You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
11 KiB

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))
@XFAIL
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))