test_exprtools.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. """Tests for tools for manipulating of large commutative expressions. """
  2. from sympy.concrete.summations import Sum
  3. from sympy.core.add import Add
  4. from sympy.core.basic import Basic
  5. from sympy.core.containers import (Dict, Tuple)
  6. from sympy.core.function import Function
  7. from sympy.core.mul import Mul
  8. from sympy.core.numbers import (I, Rational, oo)
  9. from sympy.core.singleton import S
  10. from sympy.core.symbol import (Dummy, Symbol, symbols)
  11. from sympy.functions.elementary.exponential import (exp, log)
  12. from sympy.functions.elementary.miscellaneous import (root, sqrt)
  13. from sympy.functions.elementary.trigonometric import (cos, sin)
  14. from sympy.integrals.integrals import Integral
  15. from sympy.series.order import O
  16. from sympy.sets.sets import Interval
  17. from sympy.simplify.radsimp import collect
  18. from sympy.simplify.simplify import simplify
  19. from sympy.core.exprtools import (decompose_power, Factors, Term, _gcd_terms,
  20. gcd_terms, factor_terms, factor_nc, _mask_nc,
  21. _monotonic_sign)
  22. from sympy.core.mul import _keep_coeff as _keep_coeff
  23. from sympy.simplify.cse_opts import sub_pre
  24. from sympy.testing.pytest import raises
  25. from sympy.abc import a, b, t, x, y, z
  26. def test_decompose_power():
  27. assert decompose_power(x) == (x, 1)
  28. assert decompose_power(x**2) == (x, 2)
  29. assert decompose_power(x**(2*y)) == (x**y, 2)
  30. assert decompose_power(x**(2*y/3)) == (x**(y/3), 2)
  31. assert decompose_power(x**(y*Rational(2, 3))) == (x**(y/3), 2)
  32. def test_Factors():
  33. assert Factors() == Factors({}) == Factors(S.One)
  34. assert Factors().as_expr() is S.One
  35. assert Factors({x: 2, y: 3, sin(x): 4}).as_expr() == x**2*y**3*sin(x)**4
  36. assert Factors(S.Infinity) == Factors({oo: 1})
  37. assert Factors(S.NegativeInfinity) == Factors({oo: 1, -1: 1})
  38. # issue #18059:
  39. assert Factors((x**2)**S.Half).as_expr() == (x**2)**S.Half
  40. a = Factors({x: 5, y: 3, z: 7})
  41. b = Factors({ y: 4, z: 3, t: 10})
  42. assert a.mul(b) == a*b == Factors({x: 5, y: 7, z: 10, t: 10})
  43. assert a.div(b) == divmod(a, b) == \
  44. (Factors({x: 5, z: 4}), Factors({y: 1, t: 10}))
  45. assert a.quo(b) == a/b == Factors({x: 5, z: 4})
  46. assert a.rem(b) == a % b == Factors({y: 1, t: 10})
  47. assert a.pow(3) == a**3 == Factors({x: 15, y: 9, z: 21})
  48. assert b.pow(3) == b**3 == Factors({y: 12, z: 9, t: 30})
  49. assert a.gcd(b) == Factors({y: 3, z: 3})
  50. assert a.lcm(b) == Factors({x: 5, y: 4, z: 7, t: 10})
  51. a = Factors({x: 4, y: 7, t: 7})
  52. b = Factors({z: 1, t: 3})
  53. assert a.normal(b) == (Factors({x: 4, y: 7, t: 4}), Factors({z: 1}))
  54. assert Factors(sqrt(2)*x).as_expr() == sqrt(2)*x
  55. assert Factors(-I)*I == Factors()
  56. assert Factors({S.NegativeOne: S(3)})*Factors({S.NegativeOne: S.One, I: S(5)}) == \
  57. Factors(I)
  58. assert Factors(sqrt(I)*I) == Factors(I**(S(3)/2)) == Factors({I: S(3)/2})
  59. assert Factors({I: S(3)/2}).as_expr() == I**(S(3)/2)
  60. assert Factors(S(2)**x).div(S(3)**x) == \
  61. (Factors({S(2): x}), Factors({S(3): x}))
  62. assert Factors(2**(2*x + 2)).div(S(8)) == \
  63. (Factors({S(2): 2*x + 2}), Factors({S(8): S.One}))
  64. # coverage
  65. # /!\ things break if this is not True
  66. assert Factors({S.NegativeOne: Rational(3, 2)}) == Factors({I: S.One, S.NegativeOne: S.One})
  67. assert Factors({I: S.One, S.NegativeOne: Rational(1, 3)}).as_expr() == I*(-1)**Rational(1, 3)
  68. assert Factors(-1.) == Factors({S.NegativeOne: S.One, S(1.): 1})
  69. assert Factors(-2.) == Factors({S.NegativeOne: S.One, S(2.): 1})
  70. assert Factors((-2.)**x) == Factors({S(-2.): x})
  71. assert Factors(S(-2)) == Factors({S.NegativeOne: S.One, S(2): 1})
  72. assert Factors(S.Half) == Factors({S(2): -S.One})
  73. assert Factors(Rational(3, 2)) == Factors({S(3): S.One, S(2): S.NegativeOne})
  74. assert Factors({I: S.One}) == Factors(I)
  75. assert Factors({-1.0: 2, I: 1}) == Factors({S(1.0): 1, I: 1})
  76. assert Factors({S.NegativeOne: Rational(-3, 2)}).as_expr() == I
  77. A = symbols('A', commutative=False)
  78. assert Factors(2*A**2) == Factors({S(2): 1, A**2: 1})
  79. assert Factors(I) == Factors({I: S.One})
  80. assert Factors(x).normal(S(2)) == (Factors(x), Factors(S(2)))
  81. assert Factors(x).normal(S.Zero) == (Factors(), Factors(S.Zero))
  82. raises(ZeroDivisionError, lambda: Factors(x).div(S.Zero))
  83. assert Factors(x).mul(S(2)) == Factors(2*x)
  84. assert Factors(x).mul(S.Zero).is_zero
  85. assert Factors(x).mul(1/x).is_one
  86. assert Factors(x**sqrt(2)**3).as_expr() == x**(2*sqrt(2))
  87. assert Factors(x)**Factors(S(2)) == Factors(x**2)
  88. assert Factors(x).gcd(S.Zero) == Factors(x)
  89. assert Factors(x).lcm(S.Zero).is_zero
  90. assert Factors(S.Zero).div(x) == (Factors(S.Zero), Factors())
  91. assert Factors(x).div(x) == (Factors(), Factors())
  92. assert Factors({x: .2})/Factors({x: .2}) == Factors()
  93. assert Factors(x) != Factors()
  94. assert Factors(S.Zero).normal(x) == (Factors(S.Zero), Factors())
  95. n, d = x**(2 + y), x**2
  96. f = Factors(n)
  97. assert f.div(d) == f.normal(d) == (Factors(x**y), Factors())
  98. assert f.gcd(d) == Factors()
  99. d = x**y
  100. assert f.div(d) == f.normal(d) == (Factors(x**2), Factors())
  101. assert f.gcd(d) == Factors(d)
  102. n = d = 2**x
  103. f = Factors(n)
  104. assert f.div(d) == f.normal(d) == (Factors(), Factors())
  105. assert f.gcd(d) == Factors(d)
  106. n, d = 2**x, 2**y
  107. f = Factors(n)
  108. assert f.div(d) == f.normal(d) == (Factors({S(2): x}), Factors({S(2): y}))
  109. assert f.gcd(d) == Factors()
  110. # extraction of constant only
  111. n = x**(x + 3)
  112. assert Factors(n).normal(x**-3) == (Factors({x: x + 6}), Factors({}))
  113. assert Factors(n).normal(x**3) == (Factors({x: x}), Factors({}))
  114. assert Factors(n).normal(x**4) == (Factors({x: x}), Factors({x: 1}))
  115. assert Factors(n).normal(x**(y - 3)) == \
  116. (Factors({x: x + 6}), Factors({x: y}))
  117. assert Factors(n).normal(x**(y + 3)) == (Factors({x: x}), Factors({x: y}))
  118. assert Factors(n).normal(x**(y + 4)) == \
  119. (Factors({x: x}), Factors({x: y + 1}))
  120. assert Factors(n).div(x**-3) == (Factors({x: x + 6}), Factors({}))
  121. assert Factors(n).div(x**3) == (Factors({x: x}), Factors({}))
  122. assert Factors(n).div(x**4) == (Factors({x: x}), Factors({x: 1}))
  123. assert Factors(n).div(x**(y - 3)) == \
  124. (Factors({x: x + 6}), Factors({x: y}))
  125. assert Factors(n).div(x**(y + 3)) == (Factors({x: x}), Factors({x: y}))
  126. assert Factors(n).div(x**(y + 4)) == \
  127. (Factors({x: x}), Factors({x: y + 1}))
  128. assert Factors(3 * x / 2) == Factors({3: 1, 2: -1, x: 1})
  129. assert Factors(x * x / y) == Factors({x: 2, y: -1})
  130. assert Factors(27 * x / y**9) == Factors({27: 1, x: 1, y: -9})
  131. def test_Term():
  132. a = Term(4*x*y**2/z/t**3)
  133. b = Term(2*x**3*y**5/t**3)
  134. assert a == Term(4, Factors({x: 1, y: 2}), Factors({z: 1, t: 3}))
  135. assert b == Term(2, Factors({x: 3, y: 5}), Factors({t: 3}))
  136. assert a.as_expr() == 4*x*y**2/z/t**3
  137. assert b.as_expr() == 2*x**3*y**5/t**3
  138. assert a.inv() == \
  139. Term(S.One/4, Factors({z: 1, t: 3}), Factors({x: 1, y: 2}))
  140. assert b.inv() == Term(S.Half, Factors({t: 3}), Factors({x: 3, y: 5}))
  141. assert a.mul(b) == a*b == \
  142. Term(8, Factors({x: 4, y: 7}), Factors({z: 1, t: 6}))
  143. assert a.quo(b) == a/b == Term(2, Factors({}), Factors({x: 2, y: 3, z: 1}))
  144. assert a.pow(3) == a**3 == \
  145. Term(64, Factors({x: 3, y: 6}), Factors({z: 3, t: 9}))
  146. assert b.pow(3) == b**3 == Term(8, Factors({x: 9, y: 15}), Factors({t: 9}))
  147. assert a.pow(-3) == a**(-3) == \
  148. Term(S.One/64, Factors({z: 3, t: 9}), Factors({x: 3, y: 6}))
  149. assert b.pow(-3) == b**(-3) == \
  150. Term(S.One/8, Factors({t: 9}), Factors({x: 9, y: 15}))
  151. assert a.gcd(b) == Term(2, Factors({x: 1, y: 2}), Factors({t: 3}))
  152. assert a.lcm(b) == Term(4, Factors({x: 3, y: 5}), Factors({z: 1, t: 3}))
  153. a = Term(4*x*y**2/z/t**3)
  154. b = Term(2*x**3*y**5*t**7)
  155. assert a.mul(b) == Term(8, Factors({x: 4, y: 7, t: 4}), Factors({z: 1}))
  156. assert Term((2*x + 2)**3) == Term(8, Factors({x + 1: 3}), Factors({}))
  157. assert Term((2*x + 2)*(3*x + 6)**2) == \
  158. Term(18, Factors({x + 1: 1, x + 2: 2}), Factors({}))
  159. def test_gcd_terms():
  160. f = 2*(x + 1)*(x + 4)/(5*x**2 + 5) + (2*x + 2)*(x + 5)/(x**2 + 1)/5 + \
  161. (2*x + 2)*(x + 6)/(5*x**2 + 5)
  162. assert _gcd_terms(f) == ((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1)
  163. assert _gcd_terms(Add.make_args(f)) == \
  164. ((Rational(6, 5))*((1 + x)/(1 + x**2)), 5 + x, 1)
  165. newf = (Rational(6, 5))*((1 + x)*(5 + x)/(1 + x**2))
  166. assert gcd_terms(f) == newf
  167. args = Add.make_args(f)
  168. # non-Basic sequences of terms treated as terms of Add
  169. assert gcd_terms(list(args)) == newf
  170. assert gcd_terms(tuple(args)) == newf
  171. assert gcd_terms(set(args)) == newf
  172. # but a Basic sequence is treated as a container
  173. assert gcd_terms(Tuple(*args)) != newf
  174. assert gcd_terms(Basic(Tuple(S(1), 3*y + 3*x*y), Tuple(S(1), S(3)))) == \
  175. Basic(Tuple(S(1), 3*y*(x + 1)), Tuple(S(1), S(3)))
  176. # but we shouldn't change keys of a dictionary or some may be lost
  177. assert gcd_terms(Dict((x*(1 + y), S(2)), (x + x*y, y + x*y))) == \
  178. Dict({x*(y + 1): S(2), x + x*y: y*(1 + x)})
  179. assert gcd_terms((2*x + 2)**3 + (2*x + 2)**2) == 4*(x + 1)**2*(2*x + 3)
  180. assert gcd_terms(0) == 0
  181. assert gcd_terms(1) == 1
  182. assert gcd_terms(x) == x
  183. assert gcd_terms(2 + 2*x) == Mul(2, 1 + x, evaluate=False)
  184. arg = x*(2*x + 4*y)
  185. garg = 2*x*(x + 2*y)
  186. assert gcd_terms(arg) == garg
  187. assert gcd_terms(sin(arg)) == sin(garg)
  188. # issue 6139-like
  189. alpha, alpha1, alpha2, alpha3 = symbols('alpha:4')
  190. a = alpha**2 - alpha*x**2 + alpha + x**3 - x*(alpha + 1)
  191. rep = (alpha, (1 + sqrt(5))/2 + alpha1*x + alpha2*x**2 + alpha3*x**3)
  192. s = (a/(x - alpha)).subs(*rep).series(x, 0, 1)
  193. assert simplify(collect(s, x)) == -sqrt(5)/2 - Rational(3, 2) + O(x)
  194. # issue 5917
  195. assert _gcd_terms([S.Zero, S.Zero]) == (0, 0, 1)
  196. assert _gcd_terms([2*x + 4]) == (2, x + 2, 1)
  197. eq = x/(x + 1/x)
  198. assert gcd_terms(eq, fraction=False) == eq
  199. eq = x/2/y + 1/x/y
  200. assert gcd_terms(eq, fraction=True, clear=True) == \
  201. (x**2 + 2)/(2*x*y)
  202. assert gcd_terms(eq, fraction=True, clear=False) == \
  203. (x**2/2 + 1)/(x*y)
  204. assert gcd_terms(eq, fraction=False, clear=True) == \
  205. (x + 2/x)/(2*y)
  206. assert gcd_terms(eq, fraction=False, clear=False) == \
  207. (x/2 + 1/x)/y
  208. def test_factor_terms():
  209. A = Symbol('A', commutative=False)
  210. assert factor_terms(9*(x + x*y + 1) + (3*x + 3)**(2 + 2*x)) == \
  211. 9*x*y + 9*x + _keep_coeff(S(3), x + 1)**_keep_coeff(S(2), x + 1) + 9
  212. assert factor_terms(9*(x + x*y + 1) + (3)**(2 + 2*x)) == \
  213. _keep_coeff(S(9), 3**(2*x) + x*y + x + 1)
  214. assert factor_terms(3**(2 + 2*x) + a*3**(2 + 2*x)) == \
  215. 9*3**(2*x)*(a + 1)
  216. assert factor_terms(x + x*A) == \
  217. x*(1 + A)
  218. assert factor_terms(sin(x + x*A)) == \
  219. sin(x*(1 + A))
  220. assert factor_terms((3*x + 3)**((2 + 2*x)/3)) == \
  221. _keep_coeff(S(3), x + 1)**_keep_coeff(Rational(2, 3), x + 1)
  222. assert factor_terms(x + (x*y + x)**(3*x + 3)) == \
  223. x + (x*(y + 1))**_keep_coeff(S(3), x + 1)
  224. assert factor_terms(a*(x + x*y) + b*(x*2 + y*x*2)) == \
  225. x*(a + 2*b)*(y + 1)
  226. i = Integral(x, (x, 0, oo))
  227. assert factor_terms(i) == i
  228. assert factor_terms(x/2 + y) == x/2 + y
  229. # fraction doesn't apply to integer denominators
  230. assert factor_terms(x/2 + y, fraction=True) == x/2 + y
  231. # clear *does* apply to the integer denominators
  232. assert factor_terms(x/2 + y, clear=True) == Mul(S.Half, x + 2*y, evaluate=False)
  233. # check radical extraction
  234. eq = sqrt(2) + sqrt(10)
  235. assert factor_terms(eq) == eq
  236. assert factor_terms(eq, radical=True) == sqrt(2)*(1 + sqrt(5))
  237. eq = root(-6, 3) + root(6, 3)
  238. assert factor_terms(eq, radical=True) == 6**(S.One/3)*(1 + (-1)**(S.One/3))
  239. eq = [x + x*y]
  240. ans = [x*(y + 1)]
  241. for c in [list, tuple, set]:
  242. assert factor_terms(c(eq)) == c(ans)
  243. assert factor_terms(Tuple(x + x*y)) == Tuple(x*(y + 1))
  244. assert factor_terms(Interval(0, 1)) == Interval(0, 1)
  245. e = 1/sqrt(a/2 + 1)
  246. assert factor_terms(e, clear=False) == 1/sqrt(a/2 + 1)
  247. assert factor_terms(e, clear=True) == sqrt(2)/sqrt(a + 2)
  248. eq = x/(x + 1/x) + 1/(x**2 + 1)
  249. assert factor_terms(eq, fraction=False) == eq
  250. assert factor_terms(eq, fraction=True) == 1
  251. assert factor_terms((1/(x**3 + x**2) + 2/x**2)*y) == \
  252. y*(2 + 1/(x + 1))/x**2
  253. # if not True, then processesing for this in factor_terms is not necessary
  254. assert gcd_terms(-x - y) == -x - y
  255. assert factor_terms(-x - y) == Mul(-1, x + y, evaluate=False)
  256. # if not True, then "special" processesing in factor_terms is not necessary
  257. assert gcd_terms(exp(Mul(-1, x + 1))) == exp(-x - 1)
  258. e = exp(-x - 2) + x
  259. assert factor_terms(e) == exp(Mul(-1, x + 2, evaluate=False)) + x
  260. assert factor_terms(e, sign=False) == e
  261. assert factor_terms(exp(-4*x - 2) - x) == -x + exp(Mul(-2, 2*x + 1, evaluate=False))
  262. # sum/integral tests
  263. for F in (Sum, Integral):
  264. assert factor_terms(F(x, (y, 1, 10))) == x * F(1, (y, 1, 10))
  265. assert factor_terms(F(x, (y, 1, 10)) + x) == x * (1 + F(1, (y, 1, 10)))
  266. assert factor_terms(F(x*y + x*y**2, (y, 1, 10))) == x*F(y*(y + 1), (y, 1, 10))
  267. # expressions involving Pow terms with base 0
  268. assert factor_terms(0**(x - 2) - 1) == 0**(x - 2) - 1
  269. assert factor_terms(0**(x + 2) - 1) == 0**(x + 2) - 1
  270. assert factor_terms((0**(x + 2) - 1).subs(x,-2)) == 0
  271. def test_xreplace():
  272. e = Mul(2, 1 + x, evaluate=False)
  273. assert e.xreplace({}) == e
  274. assert e.xreplace({y: x}) == e
  275. def test_factor_nc():
  276. x, y = symbols('x,y')
  277. k = symbols('k', integer=True)
  278. n, m, o = symbols('n,m,o', commutative=False)
  279. # mul and multinomial expansion is needed
  280. from sympy.core.function import _mexpand
  281. e = x*(1 + y)**2
  282. assert _mexpand(e) == x + x*2*y + x*y**2
  283. def factor_nc_test(e):
  284. ex = _mexpand(e)
  285. assert ex.is_Add
  286. f = factor_nc(ex)
  287. assert not f.is_Add and _mexpand(f) == ex
  288. factor_nc_test(x*(1 + y))
  289. factor_nc_test(n*(x + 1))
  290. factor_nc_test(n*(x + m))
  291. factor_nc_test((x + m)*n)
  292. factor_nc_test(n*m*(x*o + n*o*m)*n)
  293. s = Sum(x, (x, 1, 2))
  294. factor_nc_test(x*(1 + s))
  295. factor_nc_test(x*(1 + s)*s)
  296. factor_nc_test(x*(1 + sin(s)))
  297. factor_nc_test((1 + n)**2)
  298. factor_nc_test((x + n)*(x + m)*(x + y))
  299. factor_nc_test(x*(n*m + 1))
  300. factor_nc_test(x*(n*m + x))
  301. factor_nc_test(x*(x*n*m + 1))
  302. factor_nc_test(n*(m/x + o))
  303. factor_nc_test(m*(n + o/2))
  304. factor_nc_test(x*n*(x*m + 1))
  305. factor_nc_test(x*(m*n + x*n*m))
  306. factor_nc_test(n*(1 - m)*n**2)
  307. factor_nc_test((n + m)**2)
  308. factor_nc_test((n - m)*(n + m)**2)
  309. factor_nc_test((n + m)**2*(n - m))
  310. factor_nc_test((m - n)*(n + m)**2*(n - m))
  311. assert factor_nc(n*(n + n*m)) == n**2*(1 + m)
  312. assert factor_nc(m*(m*n + n*m*n**2)) == m*(m + n*m*n)*n
  313. eq = m*sin(n) - sin(n)*m
  314. assert factor_nc(eq) == eq
  315. # for coverage:
  316. from sympy.physics.secondquant import Commutator
  317. from sympy.polys.polytools import factor
  318. eq = 1 + x*Commutator(m, n)
  319. assert factor_nc(eq) == eq
  320. eq = x*Commutator(m, n) + x*Commutator(m, o)*Commutator(m, n)
  321. assert factor(eq) == x*(1 + Commutator(m, o))*Commutator(m, n)
  322. # issue 6534
  323. assert (2*n + 2*m).factor() == 2*(n + m)
  324. # issue 6701
  325. _n = symbols('nz', zero=False, commutative=False)
  326. assert factor_nc(_n**k + _n**(k + 1)) == _n**k*(1 + _n)
  327. assert factor_nc((m*n)**k + (m*n)**(k + 1)) == (1 + m*n)*(m*n)**k
  328. # issue 6918
  329. assert factor_nc(-n*(2*x**2 + 2*x)) == -2*n*x*(x + 1)
  330. def test_issue_6360():
  331. a, b = symbols("a b")
  332. apb = a + b
  333. eq = apb + apb**2*(-2*a - 2*b)
  334. assert factor_terms(sub_pre(eq)) == a + b - 2*(a + b)**3
  335. def test_issue_7903():
  336. a = symbols(r'a', real=True)
  337. t = exp(I*cos(a)) + exp(-I*sin(a))
  338. assert t.simplify()
  339. def test_issue_8263():
  340. F, G = symbols('F, G', commutative=False, cls=Function)
  341. x, y = symbols('x, y')
  342. expr, dummies, _ = _mask_nc(F(x)*G(y) - G(y)*F(x))
  343. for v in dummies.values():
  344. assert not v.is_commutative
  345. assert not expr.is_zero
  346. def test_monotonic_sign():
  347. F = _monotonic_sign
  348. x = symbols('x')
  349. assert F(x) is None
  350. assert F(-x) is None
  351. assert F(Dummy(prime=True)) == 2
  352. assert F(Dummy(prime=True, odd=True)) == 3
  353. assert F(Dummy(composite=True)) == 4
  354. assert F(Dummy(composite=True, odd=True)) == 9
  355. assert F(Dummy(positive=True, integer=True)) == 1
  356. assert F(Dummy(positive=True, even=True)) == 2
  357. assert F(Dummy(positive=True, even=True, prime=False)) == 4
  358. assert F(Dummy(negative=True, integer=True)) == -1
  359. assert F(Dummy(negative=True, even=True)) == -2
  360. assert F(Dummy(zero=True)) == 0
  361. assert F(Dummy(nonnegative=True)) == 0
  362. assert F(Dummy(nonpositive=True)) == 0
  363. assert F(Dummy(positive=True) + 1).is_positive
  364. assert F(Dummy(positive=True, integer=True) - 1).is_nonnegative
  365. assert F(Dummy(positive=True) - 1) is None
  366. assert F(Dummy(negative=True) + 1) is None
  367. assert F(Dummy(negative=True, integer=True) - 1).is_nonpositive
  368. assert F(Dummy(negative=True) - 1).is_negative
  369. assert F(-Dummy(positive=True) + 1) is None
  370. assert F(-Dummy(positive=True, integer=True) - 1).is_negative
  371. assert F(-Dummy(positive=True) - 1).is_negative
  372. assert F(-Dummy(negative=True) + 1).is_positive
  373. assert F(-Dummy(negative=True, integer=True) - 1).is_nonnegative
  374. assert F(-Dummy(negative=True) - 1) is None
  375. x = Dummy(negative=True)
  376. assert F(x**3).is_nonpositive
  377. assert F(x**3 + log(2)*x - 1).is_negative
  378. x = Dummy(positive=True)
  379. assert F(-x**3).is_nonpositive
  380. p = Dummy(positive=True)
  381. assert F(1/p).is_positive
  382. assert F(p/(p + 1)).is_positive
  383. p = Dummy(nonnegative=True)
  384. assert F(p/(p + 1)).is_nonnegative
  385. p = Dummy(positive=True)
  386. assert F(-1/p).is_negative
  387. p = Dummy(nonpositive=True)
  388. assert F(p/(-p + 1)).is_nonpositive
  389. p = Dummy(positive=True, integer=True)
  390. q = Dummy(positive=True, integer=True)
  391. assert F(-2/p/q).is_negative
  392. assert F(-2/(p - 1)/q) is None
  393. assert F((p - 1)*q + 1).is_positive
  394. assert F(-(p - 1)*q - 1).is_negative
  395. def test_issue_17256():
  396. from sympy.sets.fancysets import Range
  397. x = Symbol('x')
  398. s1 = Sum(x + 1, (x, 1, 9))
  399. s2 = Sum(x + 1, (x, Range(1, 10)))
  400. a = Symbol('a')
  401. r1 = s1.xreplace({x:a})
  402. r2 = s2.xreplace({x:a})
  403. assert r1.doit() == r2.doit()
  404. s1 = Sum(x + 1, (x, 0, 9))
  405. s2 = Sum(x + 1, (x, Range(10)))
  406. a = Symbol('a')
  407. r1 = s1.xreplace({x:a})
  408. r2 = s2.xreplace({x:a})
  409. assert r1 == r2
  410. def test_issue_21623():
  411. from sympy.matrices.expressions.matexpr import MatrixSymbol
  412. M = MatrixSymbol('X', 2, 2)
  413. assert gcd_terms(M[0,0], 1) == M[0,0]