test_meijerint.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. from sympy.core.function import expand_func
  2. from sympy.core.numbers import (I, Rational, oo, pi)
  3. from sympy.core.singleton import S
  4. from sympy.core.sorting import default_sort_key
  5. from sympy.functions.elementary.complexes import Abs, arg, re, unpolarify
  6. from sympy.functions.elementary.exponential import (exp, exp_polar, log)
  7. from sympy.functions.elementary.hyperbolic import cosh, acosh
  8. from sympy.functions.elementary.miscellaneous import sqrt
  9. from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold
  10. from sympy.functions.elementary.trigonometric import (cos, sin, sinc, asin)
  11. from sympy.functions.special.error_functions import (erf, erfc)
  12. from sympy.functions.special.gamma_functions import (gamma, polygamma)
  13. from sympy.functions.special.hyper import (hyper, meijerg)
  14. from sympy.integrals.integrals import (Integral, integrate)
  15. from sympy.simplify.hyperexpand import hyperexpand
  16. from sympy.simplify.simplify import simplify
  17. from sympy.integrals.meijerint import (_rewrite_single, _rewrite1,
  18. meijerint_indefinite, _inflate_g, _create_lookup_table,
  19. meijerint_definite, meijerint_inversion)
  20. from sympy.testing.pytest import slow
  21. from sympy.core.random import (verify_numerically,
  22. random_complex_number as randcplx)
  23. from sympy.abc import x, y, a, b, c, d, s, t, z
  24. def test_rewrite_single():
  25. def t(expr, c, m):
  26. e = _rewrite_single(meijerg([a], [b], [c], [d], expr), x)
  27. assert e is not None
  28. assert isinstance(e[0][0][2], meijerg)
  29. assert e[0][0][2].argument.as_coeff_mul(x) == (c, (m,))
  30. def tn(expr):
  31. assert _rewrite_single(meijerg([a], [b], [c], [d], expr), x) is None
  32. t(x, 1, x)
  33. t(x**2, 1, x**2)
  34. t(x**2 + y*x**2, y + 1, x**2)
  35. tn(x**2 + x)
  36. tn(x**y)
  37. def u(expr, x):
  38. from sympy.core.add import Add
  39. r = _rewrite_single(expr, x)
  40. e = Add(*[res[0]*res[2] for res in r[0]]).replace(
  41. exp_polar, exp) # XXX Hack?
  42. assert verify_numerically(e, expr, x)
  43. u(exp(-x)*sin(x), x)
  44. # The following has stopped working because hyperexpand changed slightly.
  45. # It is probably not worth fixing
  46. #u(exp(-x)*sin(x)*cos(x), x)
  47. # This one cannot be done numerically, since it comes out as a g-function
  48. # of argument 4*pi
  49. # NOTE This also tests a bug in inverse mellin transform (which used to
  50. # turn exp(4*pi*I*t) into a factor of exp(4*pi*I)**t instead of
  51. # exp_polar).
  52. #u(exp(x)*sin(x), x)
  53. assert _rewrite_single(exp(x)*sin(x), x) == \
  54. ([(-sqrt(2)/(2*sqrt(pi)), 0,
  55. meijerg(((Rational(-1, 2), 0, Rational(1, 4), S.Half, Rational(3, 4)), (1,)),
  56. ((), (Rational(-1, 2), 0)), 64*exp_polar(-4*I*pi)/x**4))], True)
  57. def test_rewrite1():
  58. assert _rewrite1(x**3*meijerg([a], [b], [c], [d], x**2 + y*x**2)*5, x) == \
  59. (5, x**3, [(1, 0, meijerg([a], [b], [c], [d], x**2*(y + 1)))], True)
  60. def test_meijerint_indefinite_numerically():
  61. def t(fac, arg):
  62. g = meijerg([a], [b], [c], [d], arg)*fac
  63. subs = {a: randcplx()/10, b: randcplx()/10 + I,
  64. c: randcplx(), d: randcplx()}
  65. integral = meijerint_indefinite(g, x)
  66. assert integral is not None
  67. assert verify_numerically(g.subs(subs), integral.diff(x).subs(subs), x)
  68. t(1, x)
  69. t(2, x)
  70. t(1, 2*x)
  71. t(1, x**2)
  72. t(5, x**S('3/2'))
  73. t(x**3, x)
  74. t(3*x**S('3/2'), 4*x**S('7/3'))
  75. def test_meijerint_definite():
  76. v, b = meijerint_definite(x, x, 0, 0)
  77. assert v.is_zero and b is True
  78. v, b = meijerint_definite(x, x, oo, oo)
  79. assert v.is_zero and b is True
  80. def test_inflate():
  81. subs = {a: randcplx()/10, b: randcplx()/10 + I, c: randcplx(),
  82. d: randcplx(), y: randcplx()/10}
  83. def t(a, b, arg, n):
  84. from sympy.core.mul import Mul
  85. m1 = meijerg(a, b, arg)
  86. m2 = Mul(*_inflate_g(m1, n))
  87. # NOTE: (the random number)**9 must still be on the principal sheet.
  88. # Thus make b&d small to create random numbers of small imaginary part.
  89. return verify_numerically(m1.subs(subs), m2.subs(subs), x, b=0.1, d=-0.1)
  90. assert t([[a], [b]], [[c], [d]], x, 3)
  91. assert t([[a, y], [b]], [[c], [d]], x, 3)
  92. assert t([[a], [b]], [[c, y], [d]], 2*x**3, 3)
  93. def test_recursive():
  94. from sympy.core.symbol import symbols
  95. a, b, c = symbols('a b c', positive=True)
  96. r = exp(-(x - a)**2)*exp(-(x - b)**2)
  97. e = integrate(r, (x, 0, oo), meijerg=True)
  98. assert simplify(e.expand()) == (
  99. sqrt(2)*sqrt(pi)*(
  100. (erf(sqrt(2)*(a + b)/2) + 1)*exp(-a**2/2 + a*b - b**2/2))/4)
  101. e = integrate(exp(-(x - a)**2)*exp(-(x - b)**2)*exp(c*x), (x, 0, oo), meijerg=True)
  102. assert simplify(e) == (
  103. sqrt(2)*sqrt(pi)*(erf(sqrt(2)*(2*a + 2*b + c)/4) + 1)*exp(-a**2 - b**2
  104. + (2*a + 2*b + c)**2/8)/4)
  105. assert simplify(integrate(exp(-(x - a - b - c)**2), (x, 0, oo), meijerg=True)) == \
  106. sqrt(pi)/2*(1 + erf(a + b + c))
  107. assert simplify(integrate(exp(-(x + a + b + c)**2), (x, 0, oo), meijerg=True)) == \
  108. sqrt(pi)/2*(1 - erf(a + b + c))
  109. @slow
  110. def test_meijerint():
  111. from sympy.core.function import expand
  112. from sympy.core.symbol import symbols
  113. s, t, mu = symbols('s t mu', real=True)
  114. assert integrate(meijerg([], [], [0], [], s*t)
  115. *meijerg([], [], [mu/2], [-mu/2], t**2/4),
  116. (t, 0, oo)).is_Piecewise
  117. s = symbols('s', positive=True)
  118. assert integrate(x**s*meijerg([[], []], [[0], []], x), (x, 0, oo)) == \
  119. gamma(s + 1)
  120. assert integrate(x**s*meijerg([[], []], [[0], []], x), (x, 0, oo),
  121. meijerg=True) == gamma(s + 1)
  122. assert isinstance(integrate(x**s*meijerg([[], []], [[0], []], x),
  123. (x, 0, oo), meijerg=False),
  124. Integral)
  125. assert meijerint_indefinite(exp(x), x) == exp(x)
  126. # TODO what simplifications should be done automatically?
  127. # This tests "extra case" for antecedents_1.
  128. a, b = symbols('a b', positive=True)
  129. assert simplify(meijerint_definite(x**a, x, 0, b)[0]) == \
  130. b**(a + 1)/(a + 1)
  131. # This tests various conditions and expansions:
  132. assert meijerint_definite((x + 1)**3*exp(-x), x, 0, oo) == (16, True)
  133. # Again, how about simplifications?
  134. sigma, mu = symbols('sigma mu', positive=True)
  135. i, c = meijerint_definite(exp(-((x - mu)/(2*sigma))**2), x, 0, oo)
  136. assert simplify(i) == sqrt(pi)*sigma*(2 - erfc(mu/(2*sigma)))
  137. assert c == True
  138. i, _ = meijerint_definite(exp(-mu*x)*exp(sigma*x), x, 0, oo)
  139. # TODO it would be nice to test the condition
  140. assert simplify(i) == 1/(mu - sigma)
  141. # Test substitutions to change limits
  142. assert meijerint_definite(exp(x), x, -oo, 2) == (exp(2), True)
  143. # Note: causes a NaN in _check_antecedents
  144. assert expand(meijerint_definite(exp(x), x, 0, I)[0]) == exp(I) - 1
  145. assert expand(meijerint_definite(exp(-x), x, 0, x)[0]) == \
  146. 1 - exp(-exp(I*arg(x))*abs(x))
  147. # Test -oo to oo
  148. assert meijerint_definite(exp(-x**2), x, -oo, oo) == (sqrt(pi), True)
  149. assert meijerint_definite(exp(-abs(x)), x, -oo, oo) == (2, True)
  150. assert meijerint_definite(exp(-(2*x - 3)**2), x, -oo, oo) == \
  151. (sqrt(pi)/2, True)
  152. assert meijerint_definite(exp(-abs(2*x - 3)), x, -oo, oo) == (1, True)
  153. assert meijerint_definite(exp(-((x - mu)/sigma)**2/2)/sqrt(2*pi*sigma**2),
  154. x, -oo, oo) == (1, True)
  155. assert meijerint_definite(sinc(x)**2, x, -oo, oo) == (pi, True)
  156. # Test one of the extra conditions for 2 g-functinos
  157. assert meijerint_definite(exp(-x)*sin(x), x, 0, oo) == (S.Half, True)
  158. # Test a bug
  159. def res(n):
  160. return (1/(1 + x**2)).diff(x, n).subs(x, 1)*(-1)**n
  161. for n in range(6):
  162. assert integrate(exp(-x)*sin(x)*x**n, (x, 0, oo), meijerg=True) == \
  163. res(n)
  164. # This used to test trigexpand... now it is done by linear substitution
  165. assert simplify(integrate(exp(-x)*sin(x + a), (x, 0, oo), meijerg=True)
  166. ) == sqrt(2)*sin(a + pi/4)/2
  167. # Test the condition 14 from prudnikov.
  168. # (This is besselj*besselj in disguise, to stop the product from being
  169. # recognised in the tables.)
  170. a, b, s = symbols('a b s')
  171. assert meijerint_definite(meijerg([], [], [a/2], [-a/2], x/4)
  172. *meijerg([], [], [b/2], [-b/2], x/4)*x**(s - 1), x, 0, oo
  173. ) == (
  174. (4*2**(2*s - 2)*gamma(-2*s + 1)*gamma(a/2 + b/2 + s)
  175. /(gamma(-a/2 + b/2 - s + 1)*gamma(a/2 - b/2 - s + 1)
  176. *gamma(a/2 + b/2 - s + 1)),
  177. (re(s) < 1) & (re(s) < S(1)/2) & (re(a)/2 + re(b)/2 + re(s) > 0)))
  178. # test a bug
  179. assert integrate(sin(x**a)*sin(x**b), (x, 0, oo), meijerg=True) == \
  180. Integral(sin(x**a)*sin(x**b), (x, 0, oo))
  181. # test better hyperexpand
  182. assert integrate(exp(-x**2)*log(x), (x, 0, oo), meijerg=True) == \
  183. (sqrt(pi)*polygamma(0, S.Half)/4).expand()
  184. # Test hyperexpand bug.
  185. from sympy.functions.special.gamma_functions import lowergamma
  186. n = symbols('n', integer=True)
  187. assert simplify(integrate(exp(-x)*x**n, x, meijerg=True)) == \
  188. lowergamma(n + 1, x)
  189. # Test a bug with argument 1/x
  190. alpha = symbols('alpha', positive=True)
  191. assert meijerint_definite((2 - x)**alpha*sin(alpha/x), x, 0, 2) == \
  192. (sqrt(pi)*alpha*gamma(alpha + 1)*meijerg(((), (alpha/2 + S.Half,
  193. alpha/2 + 1)), ((0, 0, S.Half), (Rational(-1, 2),)), alpha**2/16)/4, True)
  194. # test a bug related to 3016
  195. a, s = symbols('a s', positive=True)
  196. assert simplify(integrate(x**s*exp(-a*x**2), (x, -oo, oo))) == \
  197. a**(-s/2 - S.Half)*((-1)**s + 1)*gamma(s/2 + S.Half)/2
  198. def test_bessel():
  199. from sympy.functions.special.bessel import (besseli, besselj)
  200. assert simplify(integrate(besselj(a, z)*besselj(b, z)/z, (z, 0, oo),
  201. meijerg=True, conds='none')) == \
  202. 2*sin(pi*(a/2 - b/2))/(pi*(a - b)*(a + b))
  203. assert simplify(integrate(besselj(a, z)*besselj(a, z)/z, (z, 0, oo),
  204. meijerg=True, conds='none')) == 1/(2*a)
  205. # TODO more orthogonality integrals
  206. assert simplify(integrate(sin(z*x)*(x**2 - 1)**(-(y + S.Half)),
  207. (x, 1, oo), meijerg=True, conds='none')
  208. *2/((z/2)**y*sqrt(pi)*gamma(S.Half - y))) == \
  209. besselj(y, z)
  210. # Werner Rosenheinrich
  211. # SOME INDEFINITE INTEGRALS OF BESSEL FUNCTIONS
  212. assert integrate(x*besselj(0, x), x, meijerg=True) == x*besselj(1, x)
  213. assert integrate(x*besseli(0, x), x, meijerg=True) == x*besseli(1, x)
  214. # TODO can do higher powers, but come out as high order ... should they be
  215. # reduced to order 0, 1?
  216. assert integrate(besselj(1, x), x, meijerg=True) == -besselj(0, x)
  217. assert integrate(besselj(1, x)**2/x, x, meijerg=True) == \
  218. -(besselj(0, x)**2 + besselj(1, x)**2)/2
  219. # TODO more besseli when tables are extended or recursive mellin works
  220. assert integrate(besselj(0, x)**2/x**2, x, meijerg=True) == \
  221. -2*x*besselj(0, x)**2 - 2*x*besselj(1, x)**2 \
  222. + 2*besselj(0, x)*besselj(1, x) - besselj(0, x)**2/x
  223. assert integrate(besselj(0, x)*besselj(1, x), x, meijerg=True) == \
  224. -besselj(0, x)**2/2
  225. assert integrate(x**2*besselj(0, x)*besselj(1, x), x, meijerg=True) == \
  226. x**2*besselj(1, x)**2/2
  227. assert integrate(besselj(0, x)*besselj(1, x)/x, x, meijerg=True) == \
  228. (x*besselj(0, x)**2 + x*besselj(1, x)**2 -
  229. besselj(0, x)*besselj(1, x))
  230. # TODO how does besselj(0, a*x)*besselj(0, b*x) work?
  231. # TODO how does besselj(0, x)**2*besselj(1, x)**2 work?
  232. # TODO sin(x)*besselj(0, x) etc come out a mess
  233. # TODO can x*log(x)*besselj(0, x) be done?
  234. # TODO how does besselj(1, x)*besselj(0, x+a) work?
  235. # TODO more indefinite integrals when struve functions etc are implemented
  236. # test a substitution
  237. assert integrate(besselj(1, x**2)*x, x, meijerg=True) == \
  238. -besselj(0, x**2)/2
  239. def test_inversion():
  240. from sympy.functions.special.bessel import besselj
  241. from sympy.functions.special.delta_functions import Heaviside
  242. def inv(f):
  243. return piecewise_fold(meijerint_inversion(f, s, t))
  244. assert inv(1/(s**2 + 1)) == sin(t)*Heaviside(t)
  245. assert inv(s/(s**2 + 1)) == cos(t)*Heaviside(t)
  246. assert inv(exp(-s)/s) == Heaviside(t - 1)
  247. assert inv(1/sqrt(1 + s**2)) == besselj(0, t)*Heaviside(t)
  248. # Test some antcedents checking.
  249. assert meijerint_inversion(sqrt(s)/sqrt(1 + s**2), s, t) is None
  250. assert inv(exp(s**2)) is None
  251. assert meijerint_inversion(exp(-s**2), s, t) is None
  252. def test_inversion_conditional_output():
  253. from sympy.core.symbol import Symbol
  254. from sympy.integrals.transforms import InverseLaplaceTransform
  255. a = Symbol('a', positive=True)
  256. F = sqrt(pi/a)*exp(-2*sqrt(a)*sqrt(s))
  257. f = meijerint_inversion(F, s, t)
  258. assert not f.is_Piecewise
  259. b = Symbol('b', real=True)
  260. F = F.subs(a, b)
  261. f2 = meijerint_inversion(F, s, t)
  262. assert f2.is_Piecewise
  263. # first piece is same as f
  264. assert f2.args[0][0] == f.subs(a, b)
  265. # last piece is an unevaluated transform
  266. assert f2.args[-1][1]
  267. ILT = InverseLaplaceTransform(F, s, t, None)
  268. assert f2.args[-1][0] == ILT or f2.args[-1][0] == ILT.as_integral
  269. def test_inversion_exp_real_nonreal_shift():
  270. from sympy.core.symbol import Symbol
  271. from sympy.functions.special.delta_functions import DiracDelta
  272. r = Symbol('r', real=True)
  273. c = Symbol('c', extended_real=False)
  274. a = 1 + 2*I
  275. z = Symbol('z')
  276. assert not meijerint_inversion(exp(r*s), s, t).is_Piecewise
  277. assert meijerint_inversion(exp(a*s), s, t) is None
  278. assert meijerint_inversion(exp(c*s), s, t) is None
  279. f = meijerint_inversion(exp(z*s), s, t)
  280. assert f.is_Piecewise
  281. assert isinstance(f.args[0][0], DiracDelta)
  282. @slow
  283. def test_lookup_table():
  284. from sympy.core.random import uniform, randrange
  285. from sympy.core.add import Add
  286. from sympy.integrals.meijerint import z as z_dummy
  287. table = {}
  288. _create_lookup_table(table)
  289. for _, l in table.items():
  290. for formula, terms, cond, hint in sorted(l, key=default_sort_key):
  291. subs = {}
  292. for ai in list(formula.free_symbols) + [z_dummy]:
  293. if hasattr(ai, 'properties') and ai.properties:
  294. # these Wilds match positive integers
  295. subs[ai] = randrange(1, 10)
  296. else:
  297. subs[ai] = uniform(1.5, 2.0)
  298. if not isinstance(terms, list):
  299. terms = terms(subs)
  300. # First test that hyperexpand can do this.
  301. expanded = [hyperexpand(g) for (_, g) in terms]
  302. assert all(x.is_Piecewise or not x.has(meijerg) for x in expanded)
  303. # Now test that the meijer g-function is indeed as advertised.
  304. expanded = Add(*[f*x for (f, x) in terms])
  305. a, b = formula.n(subs=subs), expanded.n(subs=subs)
  306. r = min(abs(a), abs(b))
  307. if r < 1:
  308. assert abs(a - b).n() <= 1e-10
  309. else:
  310. assert (abs(a - b)/r).n() <= 1e-10
  311. def test_branch_bug():
  312. from sympy.functions.special.gamma_functions import lowergamma
  313. from sympy.simplify.powsimp import powdenest
  314. # TODO gammasimp cannot prove that the factor is unity
  315. assert powdenest(integrate(erf(x**3), x, meijerg=True).diff(x),
  316. polar=True) == 2*erf(x**3)*gamma(Rational(2, 3))/3/gamma(Rational(5, 3))
  317. assert integrate(erf(x**3), x, meijerg=True) == \
  318. 2*x*erf(x**3)*gamma(Rational(2, 3))/(3*gamma(Rational(5, 3))) \
  319. - 2*gamma(Rational(2, 3))*lowergamma(Rational(2, 3), x**6)/(3*sqrt(pi)*gamma(Rational(5, 3)))
  320. def test_linear_subs():
  321. from sympy.functions.special.bessel import besselj
  322. assert integrate(sin(x - 1), x, meijerg=True) == -cos(1 - x)
  323. assert integrate(besselj(1, x - 1), x, meijerg=True) == -besselj(0, 1 - x)
  324. @slow
  325. def test_probability():
  326. # various integrals from probability theory
  327. from sympy.core.function import expand_mul
  328. from sympy.core.symbol import (Symbol, symbols)
  329. from sympy.simplify.gammasimp import gammasimp
  330. from sympy.simplify.powsimp import powsimp
  331. mu1, mu2 = symbols('mu1 mu2', nonzero=True)
  332. sigma1, sigma2 = symbols('sigma1 sigma2', positive=True)
  333. rate = Symbol('lambda', positive=True)
  334. def normal(x, mu, sigma):
  335. return 1/sqrt(2*pi*sigma**2)*exp(-(x - mu)**2/2/sigma**2)
  336. def exponential(x, rate):
  337. return rate*exp(-rate*x)
  338. assert integrate(normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == 1
  339. assert integrate(x*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) == \
  340. mu1
  341. assert integrate(x**2*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \
  342. == mu1**2 + sigma1**2
  343. assert integrate(x**3*normal(x, mu1, sigma1), (x, -oo, oo), meijerg=True) \
  344. == mu1**3 + 3*mu1*sigma1**2
  345. assert integrate(normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  346. (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1
  347. assert integrate(x*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  348. (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1
  349. assert integrate(y*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  350. (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu2
  351. assert integrate(x*y*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  352. (x, -oo, oo), (y, -oo, oo), meijerg=True) == mu1*mu2
  353. assert integrate((x + y + 1)*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  354. (x, -oo, oo), (y, -oo, oo), meijerg=True) == 1 + mu1 + mu2
  355. assert integrate((x + y - 1)*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  356. (x, -oo, oo), (y, -oo, oo), meijerg=True) == \
  357. -1 + mu1 + mu2
  358. i = integrate(x**2*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  359. (x, -oo, oo), (y, -oo, oo), meijerg=True)
  360. assert not i.has(Abs)
  361. assert simplify(i) == mu1**2 + sigma1**2
  362. assert integrate(y**2*normal(x, mu1, sigma1)*normal(y, mu2, sigma2),
  363. (x, -oo, oo), (y, -oo, oo), meijerg=True) == \
  364. sigma2**2 + mu2**2
  365. assert integrate(exponential(x, rate), (x, 0, oo), meijerg=True) == 1
  366. assert integrate(x*exponential(x, rate), (x, 0, oo), meijerg=True) == \
  367. 1/rate
  368. assert integrate(x**2*exponential(x, rate), (x, 0, oo), meijerg=True) == \
  369. 2/rate**2
  370. def E(expr):
  371. res1 = integrate(expr*exponential(x, rate)*normal(y, mu1, sigma1),
  372. (x, 0, oo), (y, -oo, oo), meijerg=True)
  373. res2 = integrate(expr*exponential(x, rate)*normal(y, mu1, sigma1),
  374. (y, -oo, oo), (x, 0, oo), meijerg=True)
  375. assert expand_mul(res1) == expand_mul(res2)
  376. return res1
  377. assert E(1) == 1
  378. assert E(x*y) == mu1/rate
  379. assert E(x*y**2) == mu1**2/rate + sigma1**2/rate
  380. ans = sigma1**2 + 1/rate**2
  381. assert simplify(E((x + y + 1)**2) - E(x + y + 1)**2) == ans
  382. assert simplify(E((x + y - 1)**2) - E(x + y - 1)**2) == ans
  383. assert simplify(E((x + y)**2) - E(x + y)**2) == ans
  384. # Beta' distribution
  385. alpha, beta = symbols('alpha beta', positive=True)
  386. betadist = x**(alpha - 1)*(1 + x)**(-alpha - beta)*gamma(alpha + beta) \
  387. /gamma(alpha)/gamma(beta)
  388. assert integrate(betadist, (x, 0, oo), meijerg=True) == 1
  389. i = integrate(x*betadist, (x, 0, oo), meijerg=True, conds='separate')
  390. assert (gammasimp(i[0]), i[1]) == (alpha/(beta - 1), 1 < beta)
  391. j = integrate(x**2*betadist, (x, 0, oo), meijerg=True, conds='separate')
  392. assert j[1] == (beta > 2)
  393. assert gammasimp(j[0] - i[0]**2) == (alpha + beta - 1)*alpha \
  394. /(beta - 2)/(beta - 1)**2
  395. # Beta distribution
  396. # NOTE: this is evaluated using antiderivatives. It also tests that
  397. # meijerint_indefinite returns the simplest possible answer.
  398. a, b = symbols('a b', positive=True)
  399. betadist = x**(a - 1)*(-x + 1)**(b - 1)*gamma(a + b)/(gamma(a)*gamma(b))
  400. assert simplify(integrate(betadist, (x, 0, 1), meijerg=True)) == 1
  401. assert simplify(integrate(x*betadist, (x, 0, 1), meijerg=True)) == \
  402. a/(a + b)
  403. assert simplify(integrate(x**2*betadist, (x, 0, 1), meijerg=True)) == \
  404. a*(a + 1)/(a + b)/(a + b + 1)
  405. assert simplify(integrate(x**y*betadist, (x, 0, 1), meijerg=True)) == \
  406. gamma(a + b)*gamma(a + y)/gamma(a)/gamma(a + b + y)
  407. # Chi distribution
  408. k = Symbol('k', integer=True, positive=True)
  409. chi = 2**(1 - k/2)*x**(k - 1)*exp(-x**2/2)/gamma(k/2)
  410. assert powsimp(integrate(chi, (x, 0, oo), meijerg=True)) == 1
  411. assert simplify(integrate(x*chi, (x, 0, oo), meijerg=True)) == \
  412. sqrt(2)*gamma((k + 1)/2)/gamma(k/2)
  413. assert simplify(integrate(x**2*chi, (x, 0, oo), meijerg=True)) == k
  414. # Chi^2 distribution
  415. chisquared = 2**(-k/2)/gamma(k/2)*x**(k/2 - 1)*exp(-x/2)
  416. assert powsimp(integrate(chisquared, (x, 0, oo), meijerg=True)) == 1
  417. assert simplify(integrate(x*chisquared, (x, 0, oo), meijerg=True)) == k
  418. assert simplify(integrate(x**2*chisquared, (x, 0, oo), meijerg=True)) == \
  419. k*(k + 2)
  420. assert gammasimp(integrate(((x - k)/sqrt(2*k))**3*chisquared, (x, 0, oo),
  421. meijerg=True)) == 2*sqrt(2)/sqrt(k)
  422. # Dagum distribution
  423. a, b, p = symbols('a b p', positive=True)
  424. # XXX (x/b)**a does not work
  425. dagum = a*p/x*(x/b)**(a*p)/(1 + x**a/b**a)**(p + 1)
  426. assert simplify(integrate(dagum, (x, 0, oo), meijerg=True)) == 1
  427. # XXX conditions are a mess
  428. arg = x*dagum
  429. assert simplify(integrate(arg, (x, 0, oo), meijerg=True, conds='none')
  430. ) == a*b*gamma(1 - 1/a)*gamma(p + 1 + 1/a)/(
  431. (a*p + 1)*gamma(p))
  432. assert simplify(integrate(x*arg, (x, 0, oo), meijerg=True, conds='none')
  433. ) == a*b**2*gamma(1 - 2/a)*gamma(p + 1 + 2/a)/(
  434. (a*p + 2)*gamma(p))
  435. # F-distribution
  436. d1, d2 = symbols('d1 d2', positive=True)
  437. f = sqrt(((d1*x)**d1 * d2**d2)/(d1*x + d2)**(d1 + d2))/x \
  438. /gamma(d1/2)/gamma(d2/2)*gamma((d1 + d2)/2)
  439. assert simplify(integrate(f, (x, 0, oo), meijerg=True)) == 1
  440. # TODO conditions are a mess
  441. assert simplify(integrate(x*f, (x, 0, oo), meijerg=True, conds='none')
  442. ) == d2/(d2 - 2)
  443. assert simplify(integrate(x**2*f, (x, 0, oo), meijerg=True, conds='none')
  444. ) == d2**2*(d1 + 2)/d1/(d2 - 4)/(d2 - 2)
  445. # TODO gamma, rayleigh
  446. # inverse gaussian
  447. lamda, mu = symbols('lamda mu', positive=True)
  448. dist = sqrt(lamda/2/pi)*x**(Rational(-3, 2))*exp(-lamda*(x - mu)**2/x/2/mu**2)
  449. mysimp = lambda expr: simplify(expr.rewrite(exp))
  450. assert mysimp(integrate(dist, (x, 0, oo))) == 1
  451. assert mysimp(integrate(x*dist, (x, 0, oo))) == mu
  452. assert mysimp(integrate((x - mu)**2*dist, (x, 0, oo))) == mu**3/lamda
  453. assert mysimp(integrate((x - mu)**3*dist, (x, 0, oo))) == 3*mu**5/lamda**2
  454. # Levi
  455. c = Symbol('c', positive=True)
  456. assert integrate(sqrt(c/2/pi)*exp(-c/2/(x - mu))/(x - mu)**S('3/2'),
  457. (x, mu, oo)) == 1
  458. # higher moments oo
  459. # log-logistic
  460. alpha, beta = symbols('alpha beta', positive=True)
  461. distn = (beta/alpha)*x**(beta - 1)/alpha**(beta - 1)/ \
  462. (1 + x**beta/alpha**beta)**2
  463. # FIXME: If alpha, beta are not declared as finite the line below hangs
  464. # after the changes in:
  465. # https://github.com/sympy/sympy/pull/16603
  466. assert simplify(integrate(distn, (x, 0, oo))) == 1
  467. # NOTE the conditions are a mess, but correctly state beta > 1
  468. assert simplify(integrate(x*distn, (x, 0, oo), conds='none')) == \
  469. pi*alpha/beta/sin(pi/beta)
  470. # (similar comment for conditions applies)
  471. assert simplify(integrate(x**y*distn, (x, 0, oo), conds='none')) == \
  472. pi*alpha**y*y/beta/sin(pi*y/beta)
  473. # weibull
  474. k = Symbol('k', positive=True)
  475. n = Symbol('n', positive=True)
  476. distn = k/lamda*(x/lamda)**(k - 1)*exp(-(x/lamda)**k)
  477. assert simplify(integrate(distn, (x, 0, oo))) == 1
  478. assert simplify(integrate(x**n*distn, (x, 0, oo))) == \
  479. lamda**n*gamma(1 + n/k)
  480. # rice distribution
  481. from sympy.functions.special.bessel import besseli
  482. nu, sigma = symbols('nu sigma', positive=True)
  483. rice = x/sigma**2*exp(-(x**2 + nu**2)/2/sigma**2)*besseli(0, x*nu/sigma**2)
  484. assert integrate(rice, (x, 0, oo), meijerg=True) == 1
  485. # can someone verify higher moments?
  486. # Laplace distribution
  487. mu = Symbol('mu', real=True)
  488. b = Symbol('b', positive=True)
  489. laplace = exp(-abs(x - mu)/b)/2/b
  490. assert integrate(laplace, (x, -oo, oo), meijerg=True) == 1
  491. assert integrate(x*laplace, (x, -oo, oo), meijerg=True) == mu
  492. assert integrate(x**2*laplace, (x, -oo, oo), meijerg=True) == \
  493. 2*b**2 + mu**2
  494. # TODO are there other distributions supported on (-oo, oo) that we can do?
  495. # misc tests
  496. k = Symbol('k', positive=True)
  497. assert gammasimp(expand_mul(integrate(log(x)*x**(k - 1)*exp(-x)/gamma(k),
  498. (x, 0, oo)))) == polygamma(0, k)
  499. @slow
  500. def test_expint():
  501. """ Test various exponential integrals. """
  502. from sympy.core.symbol import Symbol
  503. from sympy.functions.elementary.hyperbolic import sinh
  504. from sympy.functions.special.error_functions import (Chi, Ci, Ei, Shi, Si, expint)
  505. assert simplify(unpolarify(integrate(exp(-z*x)/x**y, (x, 1, oo),
  506. meijerg=True, conds='none'
  507. ).rewrite(expint).expand(func=True))) == expint(y, z)
  508. assert integrate(exp(-z*x)/x, (x, 1, oo), meijerg=True,
  509. conds='none').rewrite(expint).expand() == \
  510. expint(1, z)
  511. assert integrate(exp(-z*x)/x**2, (x, 1, oo), meijerg=True,
  512. conds='none').rewrite(expint).expand() == \
  513. expint(2, z).rewrite(Ei).rewrite(expint)
  514. assert integrate(exp(-z*x)/x**3, (x, 1, oo), meijerg=True,
  515. conds='none').rewrite(expint).expand() == \
  516. expint(3, z).rewrite(Ei).rewrite(expint).expand()
  517. t = Symbol('t', positive=True)
  518. assert integrate(-cos(x)/x, (x, t, oo), meijerg=True).expand() == Ci(t)
  519. assert integrate(-sin(x)/x, (x, t, oo), meijerg=True).expand() == \
  520. Si(t) - pi/2
  521. assert integrate(sin(x)/x, (x, 0, z), meijerg=True) == Si(z)
  522. assert integrate(sinh(x)/x, (x, 0, z), meijerg=True) == Shi(z)
  523. assert integrate(exp(-x)/x, x, meijerg=True).expand().rewrite(expint) == \
  524. I*pi - expint(1, x)
  525. assert integrate(exp(-x)/x**2, x, meijerg=True).rewrite(expint).expand() \
  526. == expint(1, x) - exp(-x)/x - I*pi
  527. u = Symbol('u', polar=True)
  528. assert integrate(cos(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
  529. == Ci(u)
  530. assert integrate(cosh(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
  531. == Chi(u)
  532. assert integrate(expint(1, x), x, meijerg=True
  533. ).rewrite(expint).expand() == x*expint(1, x) - exp(-x)
  534. assert integrate(expint(2, x), x, meijerg=True
  535. ).rewrite(expint).expand() == \
  536. -x**2*expint(1, x)/2 + x*exp(-x)/2 - exp(-x)/2
  537. assert simplify(unpolarify(integrate(expint(y, x), x,
  538. meijerg=True).rewrite(expint).expand(func=True))) == \
  539. -expint(y + 1, x)
  540. assert integrate(Si(x), x, meijerg=True) == x*Si(x) + cos(x)
  541. assert integrate(Ci(u), u, meijerg=True).expand() == u*Ci(u) - sin(u)
  542. assert integrate(Shi(x), x, meijerg=True) == x*Shi(x) - cosh(x)
  543. assert integrate(Chi(u), u, meijerg=True).expand() == u*Chi(u) - sinh(u)
  544. assert integrate(Si(x)*exp(-x), (x, 0, oo), meijerg=True) == pi/4
  545. assert integrate(expint(1, x)*sin(x), (x, 0, oo), meijerg=True) == log(2)/2
  546. def test_messy():
  547. from sympy.functions.elementary.hyperbolic import (acosh, acoth)
  548. from sympy.functions.elementary.trigonometric import (asin, atan)
  549. from sympy.functions.special.bessel import besselj
  550. from sympy.functions.special.error_functions import (Chi, E1, Shi, Si)
  551. from sympy.integrals.transforms import (fourier_transform, laplace_transform)
  552. assert (laplace_transform(Si(x), x, s, simplify=True) ==
  553. ((-atan(s) + pi/2)/s, 0, True))
  554. assert laplace_transform(Shi(x), x, s, simplify=True) == (
  555. acoth(s)/s, -oo, s**2 > 1)
  556. # where should the logs be simplified?
  557. assert laplace_transform(Chi(x), x, s, simplify=True) == (
  558. (log(s**(-2)) - log(1 - 1/s**2))/(2*s), -oo, s**2 > 1)
  559. # TODO maybe simplify the inequalities? when the simplification
  560. # allows for generators instead of symbols this will work
  561. assert laplace_transform(besselj(a, x), x, s)[1:] == \
  562. (0, (re(a) > -2) & (re(a) > -1))
  563. # NOTE s < 0 can be done, but argument reduction is not good enough yet
  564. ans = fourier_transform(besselj(1, x)/x, x, s, noconds=False)
  565. assert (ans[0].factor(deep=True).expand(), ans[1]) == \
  566. (Piecewise((0, (s > 1/(2*pi)) | (s < -1/(2*pi))),
  567. (2*sqrt(-4*pi**2*s**2 + 1), True)), s > 0)
  568. # TODO FT(besselj(0,x)) - conditions are messy (but for acceptable reasons)
  569. # - folding could be better
  570. assert integrate(E1(x)*besselj(0, x), (x, 0, oo), meijerg=True) == \
  571. log(1 + sqrt(2))
  572. assert integrate(E1(x)*besselj(1, x), (x, 0, oo), meijerg=True) == \
  573. log(S.Half + sqrt(2)/2)
  574. assert integrate(1/x/sqrt(1 - x**2), x, meijerg=True) == \
  575. Piecewise((-acosh(1/x), abs(x**(-2)) > 1), (I*asin(1/x), True))
  576. def test_issue_6122():
  577. assert integrate(exp(-I*x**2), (x, -oo, oo), meijerg=True) == \
  578. -I*sqrt(pi)*exp(I*pi/4)
  579. def test_issue_6252():
  580. expr = 1/x/(a + b*x)**Rational(1, 3)
  581. anti = integrate(expr, x, meijerg=True)
  582. assert not anti.has(hyper)
  583. # XXX the expression is a mess, but actually upon differentiation and
  584. # putting in numerical values seems to work...
  585. def test_issue_6348():
  586. assert integrate(exp(I*x)/(1 + x**2), (x, -oo, oo)).simplify().rewrite(exp) \
  587. == pi*exp(-1)
  588. def test_fresnel():
  589. from sympy.functions.special.error_functions import (fresnelc, fresnels)
  590. assert expand_func(integrate(sin(pi*x**2/2), x)) == fresnels(x)
  591. assert expand_func(integrate(cos(pi*x**2/2), x)) == fresnelc(x)
  592. def test_issue_6860():
  593. assert meijerint_indefinite(x**x**x, x) is None
  594. def test_issue_7337():
  595. f = meijerint_indefinite(x*sqrt(2*x + 3), x).together()
  596. assert f == sqrt(2*x + 3)*(2*x**2 + x - 3)/5
  597. assert f._eval_interval(x, S.NegativeOne, S.One) == Rational(2, 5)
  598. def test_issue_8368():
  599. assert meijerint_indefinite(cosh(x)*exp(-x*t), x) == (
  600. (-t - 1)*exp(x) + (-t + 1)*exp(-x))*exp(-t*x)/2/(t**2 - 1)
  601. def test_issue_10211():
  602. from sympy.abc import h, w
  603. assert integrate((1/sqrt((y-x)**2 + h**2)**3), (x,0,w), (y,0,w)) == \
  604. 2*sqrt(1 + w**2/h**2)/h - 2/h
  605. def test_issue_11806():
  606. from sympy.core.symbol import symbols
  607. y, L = symbols('y L', positive=True)
  608. assert integrate(1/sqrt(x**2 + y**2)**3, (x, -L, L)) == \
  609. 2*L/(y**2*sqrt(L**2 + y**2))
  610. def test_issue_10681():
  611. from sympy.polys.domains.realfield import RR
  612. from sympy.abc import R, r
  613. f = integrate(r**2*(R**2-r**2)**0.5, r, meijerg=True)
  614. g = (1.0/3)*R**1.0*r**3*hyper((-0.5, Rational(3, 2)), (Rational(5, 2),),
  615. r**2*exp_polar(2*I*pi)/R**2)
  616. assert RR.almosteq((f/g).n(), 1.0, 1e-12)
  617. def test_issue_13536():
  618. from sympy.core.symbol import Symbol
  619. a = Symbol('a', positive=True)
  620. assert integrate(1/x**2, (x, oo, a)) == -1/a
  621. def test_issue_6462():
  622. from sympy.core.symbol import Symbol
  623. x = Symbol('x')
  624. n = Symbol('n')
  625. # Not the actual issue, still wrong answer for n = 1, but that there is no
  626. # exception
  627. assert integrate(cos(x**n)/x**n, x, meijerg=True).subs(n, 2).equals(
  628. integrate(cos(x**2)/x**2, x, meijerg=True))
  629. def test_indefinite_1_bug():
  630. assert integrate((b + t)**(-a), t, meijerg=True
  631. ) == -b**(1 - a)*(1 + t/b)**(1 - a)/(a - 1)
  632. def test_pr_23583():
  633. # This result is wrong. Check whether new result is correct when this test fail.
  634. assert integrate(1/sqrt((x - I)**2-1), meijerg=True) == \
  635. Piecewise((acosh(x - I), Abs((x - I)**2) > 1), (-I*asin(x - I), True))