test_accumulationbounds.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. from sympy.core.numbers import (E, Rational, oo, pi, zoo)
  2. from sympy.core.singleton import S
  3. from sympy.core.symbol import Symbol
  4. from sympy.functions.elementary.exponential import (exp, log)
  5. from sympy.functions.elementary.miscellaneous import (Max, Min, sqrt)
  6. from sympy.functions.elementary.trigonometric import (cos, sin, tan)
  7. from sympy.calculus.accumulationbounds import AccumBounds
  8. from sympy.core import Add, Mul, Pow
  9. from sympy.core.expr import unchanged
  10. from sympy.testing.pytest import raises, XFAIL
  11. from sympy.abc import x
  12. a = Symbol('a', real=True)
  13. B = AccumBounds
  14. def test_AccumBounds():
  15. assert B(1, 2).args == (1, 2)
  16. assert B(1, 2).delta is S.One
  17. assert B(1, 2).mid == Rational(3, 2)
  18. assert B(1, 3).is_real == True
  19. assert B(1, 1) is S.One
  20. assert B(1, 2) + 1 == B(2, 3)
  21. assert 1 + B(1, 2) == B(2, 3)
  22. assert B(1, 2) + B(2, 3) == B(3, 5)
  23. assert -B(1, 2) == B(-2, -1)
  24. assert B(1, 2) - 1 == B(0, 1)
  25. assert 1 - B(1, 2) == B(-1, 0)
  26. assert B(2, 3) - B(1, 2) == B(0, 2)
  27. assert x + B(1, 2) == Add(B(1, 2), x)
  28. assert a + B(1, 2) == B(1 + a, 2 + a)
  29. assert B(1, 2) - x == Add(B(1, 2), -x)
  30. assert B(-oo, 1) + oo == B(-oo, oo)
  31. assert B(1, oo) + oo is oo
  32. assert B(1, oo) - oo == B(-oo, oo)
  33. assert (-oo - B(-1, oo)) is -oo
  34. assert B(-oo, 1) - oo is -oo
  35. assert B(1, oo) - oo == B(-oo, oo)
  36. assert B(-oo, 1) - (-oo) == B(-oo, oo)
  37. assert (oo - B(1, oo)) == B(-oo, oo)
  38. assert (-oo - B(1, oo)) is -oo
  39. assert B(1, 2)/2 == B(S.Half, 1)
  40. assert 2/B(2, 3) == B(Rational(2, 3), 1)
  41. assert 1/B(-1, 1) == B(-oo, oo)
  42. assert abs(B(1, 2)) == B(1, 2)
  43. assert abs(B(-2, -1)) == B(1, 2)
  44. assert abs(B(-2, 1)) == B(0, 2)
  45. assert abs(B(-1, 2)) == B(0, 2)
  46. c = Symbol('c')
  47. raises(ValueError, lambda: B(0, c))
  48. raises(ValueError, lambda: B(1, -1))
  49. r = Symbol('r', real=True)
  50. raises(ValueError, lambda: B(r, r - 1))
  51. def test_AccumBounds_mul():
  52. assert B(1, 2)*2 == B(2, 4)
  53. assert 2*B(1, 2) == B(2, 4)
  54. assert B(1, 2)*B(2, 3) == B(2, 6)
  55. assert B(0, 2)*B(2, oo) == B(0, oo)
  56. l, r = B(-oo, oo), B(-a, a)
  57. assert l*r == B(-oo, oo)
  58. assert r*l == B(-oo, oo)
  59. l, r = B(1, oo), B(-3, -2)
  60. assert l*r == B(-oo, -2)
  61. assert r*l == B(-oo, -2)
  62. assert B(1, 2)*0 == 0
  63. assert B(1, oo)*0 == B(0, oo)
  64. assert B(-oo, 1)*0 == B(-oo, 0)
  65. assert B(-oo, oo)*0 == B(-oo, oo)
  66. assert B(1, 2)*x == Mul(B(1, 2), x, evaluate=False)
  67. assert B(0, 2)*oo == B(0, oo)
  68. assert B(-2, 0)*oo == B(-oo, 0)
  69. assert B(0, 2)*(-oo) == B(-oo, 0)
  70. assert B(-2, 0)*(-oo) == B(0, oo)
  71. assert B(-1, 1)*oo == B(-oo, oo)
  72. assert B(-1, 1)*(-oo) == B(-oo, oo)
  73. assert B(-oo, oo)*oo == B(-oo, oo)
  74. def test_AccumBounds_div():
  75. assert B(-1, 3)/B(3, 4) == B(Rational(-1, 3), 1)
  76. assert B(-2, 4)/B(-3, 4) == B(-oo, oo)
  77. assert B(-3, -2)/B(-4, 0) == B(S.Half, oo)
  78. # these two tests can have a better answer
  79. # after Union of B is improved
  80. assert B(-3, -2)/B(-2, 1) == B(-oo, oo)
  81. assert B(2, 3)/B(-2, 2) == B(-oo, oo)
  82. assert B(-3, -2)/B(0, 4) == B(-oo, Rational(-1, 2))
  83. assert B(2, 4)/B(-3, 0) == B(-oo, Rational(-2, 3))
  84. assert B(2, 4)/B(0, 3) == B(Rational(2, 3), oo)
  85. assert B(0, 1)/B(0, 1) == B(0, oo)
  86. assert B(-1, 0)/B(0, 1) == B(-oo, 0)
  87. assert B(-1, 2)/B(-2, 2) == B(-oo, oo)
  88. assert 1/B(-1, 2) == B(-oo, oo)
  89. assert 1/B(0, 2) == B(S.Half, oo)
  90. assert (-1)/B(0, 2) == B(-oo, Rational(-1, 2))
  91. assert 1/B(-oo, 0) == B(-oo, 0)
  92. assert 1/B(-1, 0) == B(-oo, -1)
  93. assert (-2)/B(-oo, 0) == B(0, oo)
  94. assert 1/B(-oo, -1) == B(-1, 0)
  95. assert B(1, 2)/a == Mul(B(1, 2), 1/a, evaluate=False)
  96. assert B(1, 2)/0 == B(1, 2)*zoo
  97. assert B(1, oo)/oo == B(0, oo)
  98. assert B(1, oo)/(-oo) == B(-oo, 0)
  99. assert B(-oo, -1)/oo == B(-oo, 0)
  100. assert B(-oo, -1)/(-oo) == B(0, oo)
  101. assert B(-oo, oo)/oo == B(-oo, oo)
  102. assert B(-oo, oo)/(-oo) == B(-oo, oo)
  103. assert B(-1, oo)/oo == B(0, oo)
  104. assert B(-1, oo)/(-oo) == B(-oo, 0)
  105. assert B(-oo, 1)/oo == B(-oo, 0)
  106. assert B(-oo, 1)/(-oo) == B(0, oo)
  107. def test_issue_18795():
  108. r = Symbol('r', real=True)
  109. a = B(-1,1)
  110. c = B(7, oo)
  111. b = B(-oo, oo)
  112. assert c - tan(r) == B(7-tan(r), oo)
  113. assert b + tan(r) == B(-oo, oo)
  114. assert (a + r)/a == B(-oo, oo)*B(r - 1, r + 1)
  115. assert (b + a)/a == B(-oo, oo)
  116. def test_AccumBounds_func():
  117. assert (x**2 + 2*x + 1).subs(x, B(-1, 1)) == B(-1, 4)
  118. assert exp(B(0, 1)) == B(1, E)
  119. assert exp(B(-oo, oo)) == B(0, oo)
  120. assert log(B(3, 6)) == B(log(3), log(6))
  121. @XFAIL
  122. def test_AccumBounds_powf():
  123. nn = Symbol('nn', nonnegative=True)
  124. assert B(1 + nn, 2 + nn)**B(1, 2) == B(1 + nn, (2 + nn)**2)
  125. i = Symbol('i', integer=True, negative=True)
  126. assert B(1, 2)**i == B(2**i, 1)
  127. def test_AccumBounds_pow():
  128. assert B(0, 2)**2 == B(0, 4)
  129. assert B(-1, 1)**2 == B(0, 1)
  130. assert B(1, 2)**2 == B(1, 4)
  131. assert B(-1, 2)**3 == B(-1, 8)
  132. assert B(-1, 1)**0 == 1
  133. assert B(1, 2)**Rational(5, 2) == B(1, 4*sqrt(2))
  134. assert B(0, 2)**S.Half == B(0, sqrt(2))
  135. neg = Symbol('neg', negative=True)
  136. assert unchanged(Pow, B(neg, 1), S.Half)
  137. nn = Symbol('nn', nonnegative=True)
  138. assert B(nn, nn + 1)**S.Half == B(sqrt(nn), sqrt(nn + 1))
  139. assert B(nn, nn + 1)**nn == B(nn**nn, (nn + 1)**nn)
  140. assert unchanged(Pow, B(nn, nn + 1), x)
  141. i = Symbol('i', integer=True)
  142. assert B(1, 2)**i == B(Min(1, 2**i), Max(1, 2**i))
  143. i = Symbol('i', integer=True, nonnegative=True)
  144. assert B(1, 2)**i == B(1, 2**i)
  145. assert B(0, 1)**i == B(0**i, 1)
  146. assert B(1, 5)**(-2) == B(Rational(1, 25), 1)
  147. assert B(-1, 3)**(-2) == B(0, oo)
  148. assert B(0, 2)**(-3) == B(Rational(1, 8), oo)
  149. assert B(-2, 0)**(-3) == B(-oo, -Rational(1, 8))
  150. assert B(0, 2)**(-2) == B(Rational(1, 4), oo)
  151. assert B(-1, 2)**(-3) == B(-oo, oo)
  152. assert B(-3, -2)**(-3) == B(Rational(-1, 8), Rational(-1, 27))
  153. assert B(-3, -2)**(-2) == B(Rational(1, 9), Rational(1, 4))
  154. assert B(0, oo)**S.Half == B(0, oo)
  155. assert B(-oo, 0)**(-2) == B(0, oo)
  156. assert B(-2, 0)**(-2) == B(Rational(1, 4), oo)
  157. assert B(Rational(1, 3), S.Half)**oo is S.Zero
  158. assert B(0, S.Half)**oo is S.Zero
  159. assert B(S.Half, 1)**oo == B(0, oo)
  160. assert B(0, 1)**oo == B(0, oo)
  161. assert B(2, 3)**oo is oo
  162. assert B(1, 2)**oo == B(0, oo)
  163. assert B(S.Half, 3)**oo == B(0, oo)
  164. assert B(Rational(-1, 3), Rational(-1, 4))**oo is S.Zero
  165. assert B(-1, Rational(-1, 2))**oo is S.NaN
  166. assert B(-3, -2)**oo is zoo
  167. assert B(-2, -1)**oo is S.NaN
  168. assert B(-2, Rational(-1, 2))**oo is S.NaN
  169. assert B(Rational(-1, 2), S.Half)**oo is S.Zero
  170. assert B(Rational(-1, 2), 1)**oo == B(0, oo)
  171. assert B(Rational(-2, 3), 2)**oo == B(0, oo)
  172. assert B(-1, 1)**oo == B(-oo, oo)
  173. assert B(-1, S.Half)**oo == B(-oo, oo)
  174. assert B(-1, 2)**oo == B(-oo, oo)
  175. assert B(-2, S.Half)**oo == B(-oo, oo)
  176. assert B(1, 2)**x == Pow(B(1, 2), x, evaluate=False)
  177. assert B(2, 3)**(-oo) is S.Zero
  178. assert B(0, 2)**(-oo) == B(0, oo)
  179. assert B(-1, 2)**(-oo) == B(-oo, oo)
  180. assert (tan(x)**sin(2*x)).subs(x, B(0, pi/2)) == \
  181. Pow(B(-oo, oo), B(0, 1))
  182. def test_AccumBounds_exponent():
  183. # base is 0
  184. z = 0**B(a, a + S.Half)
  185. assert z.subs(a, 0) == B(0, 1)
  186. assert z.subs(a, 1) == 0
  187. p = z.subs(a, -1)
  188. assert p.is_Pow and p.args == (0, B(-1, -S.Half))
  189. # base > 0
  190. # when base is 1 the type of bounds does not matter
  191. assert 1**B(a, a + 1) == 1
  192. # otherwise we need to know if 0 is in the bounds
  193. assert S.Half**B(-2, 2) == B(S(1)/4, 4)
  194. assert 2**B(-2, 2) == B(S(1)/4, 4)
  195. # +eps may introduce +oo
  196. # if there is a negative integer exponent
  197. assert B(0, 1)**B(S(1)/2, 1) == B(0, 1)
  198. assert B(0, 1)**B(0, 1) == B(0, 1)
  199. # positive bases have positive bounds
  200. assert B(2, 3)**B(-3, -2) == B(S(1)/27, S(1)/4)
  201. assert B(2, 3)**B(-3, 2) == B(S(1)/27, 9)
  202. # bounds generating imaginary parts unevaluated
  203. assert unchanged(Pow, B(-1, 1), B(1, 2))
  204. assert B(0, S(1)/2)**B(1, oo) == B(0, S(1)/2)
  205. assert B(0, 1)**B(1, oo) == B(0, oo)
  206. assert B(0, 2)**B(1, oo) == B(0, oo)
  207. assert B(0, oo)**B(1, oo) == B(0, oo)
  208. assert B(S(1)/2, 1)**B(1, oo) == B(0, oo)
  209. assert B(S(1)/2, 1)**B(-oo, -1) == B(0, oo)
  210. assert B(S(1)/2, 1)**B(-oo, oo) == B(0, oo)
  211. assert B(S(1)/2, 2)**B(1, oo) == B(0, oo)
  212. assert B(S(1)/2, 2)**B(-oo, -1) == B(0, oo)
  213. assert B(S(1)/2, 2)**B(-oo, oo) == B(0, oo)
  214. assert B(S(1)/2, oo)**B(1, oo) == B(0, oo)
  215. assert B(S(1)/2, oo)**B(-oo, -1) == B(0, oo)
  216. assert B(S(1)/2, oo)**B(-oo, oo) == B(0, oo)
  217. assert B(1, 2)**B(1, oo) == B(0, oo)
  218. assert B(1, 2)**B(-oo, -1) == B(0, oo)
  219. assert B(1, 2)**B(-oo, oo) == B(0, oo)
  220. assert B(1, oo)**B(1, oo) == B(0, oo)
  221. assert B(1, oo)**B(-oo, -1) == B(0, oo)
  222. assert B(1, oo)**B(-oo, oo) == B(0, oo)
  223. assert B(2, oo)**B(1, oo) == B(2, oo)
  224. assert B(2, oo)**B(-oo, -1) == B(0, S(1)/2)
  225. assert B(2, oo)**B(-oo, oo) == B(0, oo)
  226. def test_comparison_AccumBounds():
  227. assert (B(1, 3) < 4) == S.true
  228. assert (B(1, 3) < -1) == S.false
  229. assert (B(1, 3) < 2).rel_op == '<'
  230. assert (B(1, 3) <= 2).rel_op == '<='
  231. assert (B(1, 3) > 4) == S.false
  232. assert (B(1, 3) > -1) == S.true
  233. assert (B(1, 3) > 2).rel_op == '>'
  234. assert (B(1, 3) >= 2).rel_op == '>='
  235. assert (B(1, 3) < B(4, 6)) == S.true
  236. assert (B(1, 3) < B(2, 4)).rel_op == '<'
  237. assert (B(1, 3) < B(-2, 0)) == S.false
  238. assert (B(1, 3) <= B(4, 6)) == S.true
  239. assert (B(1, 3) <= B(-2, 0)) == S.false
  240. assert (B(1, 3) > B(4, 6)) == S.false
  241. assert (B(1, 3) > B(-2, 0)) == S.true
  242. assert (B(1, 3) >= B(4, 6)) == S.false
  243. assert (B(1, 3) >= B(-2, 0)) == S.true
  244. # issue 13499
  245. assert (cos(x) > 0).subs(x, oo) == (B(-1, 1) > 0)
  246. c = Symbol('c')
  247. raises(TypeError, lambda: (B(0, 1) < c))
  248. raises(TypeError, lambda: (B(0, 1) <= c))
  249. raises(TypeError, lambda: (B(0, 1) > c))
  250. raises(TypeError, lambda: (B(0, 1) >= c))
  251. def test_contains_AccumBounds():
  252. assert (1 in B(1, 2)) == S.true
  253. raises(TypeError, lambda: a in B(1, 2))
  254. assert 0 in B(-1, 0)
  255. raises(TypeError, lambda:
  256. (cos(1)**2 + sin(1)**2 - 1) in B(-1, 0))
  257. assert (-oo in B(1, oo)) == S.true
  258. assert (oo in B(-oo, 0)) == S.true
  259. # issue 13159
  260. assert Mul(0, B(-1, 1)) == Mul(B(-1, 1), 0) == 0
  261. import itertools
  262. for perm in itertools.permutations([0, B(-1, 1), x]):
  263. assert Mul(*perm) == 0
  264. def test_intersection_AccumBounds():
  265. assert B(0, 3).intersection(B(1, 2)) == B(1, 2)
  266. assert B(0, 3).intersection(B(1, 4)) == B(1, 3)
  267. assert B(0, 3).intersection(B(-1, 2)) == B(0, 2)
  268. assert B(0, 3).intersection(B(-1, 4)) == B(0, 3)
  269. assert B(0, 1).intersection(B(2, 3)) == S.EmptySet
  270. raises(TypeError, lambda: B(0, 3).intersection(1))
  271. def test_union_AccumBounds():
  272. assert B(0, 3).union(B(1, 2)) == B(0, 3)
  273. assert B(0, 3).union(B(1, 4)) == B(0, 4)
  274. assert B(0, 3).union(B(-1, 2)) == B(-1, 3)
  275. assert B(0, 3).union(B(-1, 4)) == B(-1, 4)
  276. raises(TypeError, lambda: B(0, 3).union(1))