test_transforms.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. from sympy.integrals.transforms import (
  2. mellin_transform, inverse_mellin_transform,
  3. fourier_transform, inverse_fourier_transform,
  4. sine_transform, inverse_sine_transform,
  5. cosine_transform, inverse_cosine_transform,
  6. hankel_transform, inverse_hankel_transform,
  7. FourierTransform, SineTransform, CosineTransform, InverseFourierTransform,
  8. InverseSineTransform, InverseCosineTransform, IntegralTransformError)
  9. from sympy.integrals.laplace import (
  10. laplace_transform, inverse_laplace_transform)
  11. from sympy.core.function import Function, expand_mul
  12. from sympy.core import EulerGamma
  13. from sympy.core.numbers import I, Rational, oo, pi
  14. from sympy.core.singleton import S
  15. from sympy.core.symbol import Symbol, symbols
  16. from sympy.functions.combinatorial.factorials import factorial
  17. from sympy.functions.elementary.complexes import re, unpolarify
  18. from sympy.functions.elementary.exponential import exp, exp_polar, log
  19. from sympy.functions.elementary.miscellaneous import sqrt
  20. from sympy.functions.elementary.trigonometric import atan, cos, sin, tan
  21. from sympy.functions.special.bessel import besseli, besselj, besselk, bessely
  22. from sympy.functions.special.delta_functions import Heaviside
  23. from sympy.functions.special.error_functions import erf, expint
  24. from sympy.functions.special.gamma_functions import gamma
  25. from sympy.functions.special.hyper import meijerg
  26. from sympy.simplify.gammasimp import gammasimp
  27. from sympy.simplify.hyperexpand import hyperexpand
  28. from sympy.simplify.trigsimp import trigsimp
  29. from sympy.testing.pytest import XFAIL, slow, skip, raises
  30. from sympy.abc import x, s, a, b, c, d
  31. nu, beta, rho = symbols('nu beta rho')
  32. def test_undefined_function():
  33. from sympy.integrals.transforms import MellinTransform
  34. f = Function('f')
  35. assert mellin_transform(f(x), x, s) == MellinTransform(f(x), x, s)
  36. assert mellin_transform(f(x) + exp(-x), x, s) == \
  37. (MellinTransform(f(x), x, s) + gamma(s + 1)/s, (0, oo), True)
  38. def test_free_symbols():
  39. f = Function('f')
  40. assert mellin_transform(f(x), x, s).free_symbols == {s}
  41. assert mellin_transform(f(x)*a, x, s).free_symbols == {s, a}
  42. def test_as_integral():
  43. from sympy.integrals.integrals import Integral
  44. f = Function('f')
  45. assert mellin_transform(f(x), x, s).rewrite('Integral') == \
  46. Integral(x**(s - 1)*f(x), (x, 0, oo))
  47. assert fourier_transform(f(x), x, s).rewrite('Integral') == \
  48. Integral(f(x)*exp(-2*I*pi*s*x), (x, -oo, oo))
  49. assert laplace_transform(f(x), x, s, noconds=True).rewrite('Integral') == \
  50. Integral(f(x)*exp(-s*x), (x, 0, oo))
  51. assert str(2*pi*I*inverse_mellin_transform(f(s), s, x, (a, b)).rewrite('Integral')) \
  52. == "Integral(f(s)/x**s, (s, _c - oo*I, _c + oo*I))"
  53. assert str(2*pi*I*inverse_laplace_transform(f(s), s, x).rewrite('Integral')) == \
  54. "Integral(f(s)*exp(s*x), (s, _c - oo*I, _c + oo*I))"
  55. assert inverse_fourier_transform(f(s), s, x).rewrite('Integral') == \
  56. Integral(f(s)*exp(2*I*pi*s*x), (s, -oo, oo))
  57. # NOTE this is stuck in risch because meijerint cannot handle it
  58. @slow
  59. @XFAIL
  60. def test_mellin_transform_fail():
  61. skip("Risch takes forever.")
  62. MT = mellin_transform
  63. bpos = symbols('b', positive=True)
  64. # bneg = symbols('b', negative=True)
  65. expr = (sqrt(x + b**2) + b)**a/sqrt(x + b**2)
  66. # TODO does not work with bneg, argument wrong. Needs changes to matching.
  67. assert MT(expr.subs(b, -bpos), x, s) == \
  68. ((-1)**(a + 1)*2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(a + s)
  69. *gamma(1 - a - 2*s)/gamma(1 - s),
  70. (-re(a), -re(a)/2 + S.Half), True)
  71. expr = (sqrt(x + b**2) + b)**a
  72. assert MT(expr.subs(b, -bpos), x, s) == \
  73. (
  74. 2**(a + 2*s)*a*bpos**(a + 2*s)*gamma(-a - 2*
  75. s)*gamma(a + s)/gamma(-s + 1),
  76. (-re(a), -re(a)/2), True)
  77. # Test exponent 1:
  78. assert MT(expr.subs({b: -bpos, a: 1}), x, s) == \
  79. (-bpos**(2*s + 1)*gamma(s)*gamma(-s - S.Half)/(2*sqrt(pi)),
  80. (-1, Rational(-1, 2)), True)
  81. def test_mellin_transform():
  82. from sympy.functions.elementary.miscellaneous import (Max, Min)
  83. MT = mellin_transform
  84. bpos = symbols('b', positive=True)
  85. # 8.4.2
  86. assert MT(x**nu*Heaviside(x - 1), x, s) == \
  87. (-1/(nu + s), (-oo, -re(nu)), True)
  88. assert MT(x**nu*Heaviside(1 - x), x, s) == \
  89. (1/(nu + s), (-re(nu), oo), True)
  90. assert MT((1 - x)**(beta - 1)*Heaviside(1 - x), x, s) == \
  91. (gamma(beta)*gamma(s)/gamma(beta + s), (0, oo), re(beta) > 0)
  92. assert MT((x - 1)**(beta - 1)*Heaviside(x - 1), x, s) == \
  93. (gamma(beta)*gamma(1 - beta - s)/gamma(1 - s),
  94. (-oo, 1 - re(beta)), re(beta) > 0)
  95. assert MT((1 + x)**(-rho), x, s) == \
  96. (gamma(s)*gamma(rho - s)/gamma(rho), (0, re(rho)), True)
  97. assert MT(abs(1 - x)**(-rho), x, s) == (
  98. 2*sin(pi*rho/2)*gamma(1 - rho)*
  99. cos(pi*(s - rho/2))*gamma(s)*gamma(rho-s)/pi,
  100. (0, re(rho)), re(rho) < 1)
  101. mt = MT((1 - x)**(beta - 1)*Heaviside(1 - x)
  102. + a*(x - 1)**(beta - 1)*Heaviside(x - 1), x, s)
  103. assert mt[1], mt[2] == ((0, -re(beta) + 1), re(beta) > 0)
  104. assert MT((x**a - b**a)/(x - b), x, s)[0] == \
  105. pi*b**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s)))
  106. assert MT((x**a - bpos**a)/(x - bpos), x, s) == \
  107. (pi*bpos**(a + s - 1)*sin(pi*a)/(sin(pi*s)*sin(pi*(a + s))),
  108. (Max(0, -re(a)), Min(1, 1 - re(a))), True)
  109. expr = (sqrt(x + b**2) + b)**a
  110. assert MT(expr.subs(b, bpos), x, s) == \
  111. (-a*(2*bpos)**(a + 2*s)*gamma(s)*gamma(-a - 2*s)/gamma(-a - s + 1),
  112. (0, -re(a)/2), True)
  113. expr = (sqrt(x + b**2) + b)**a/sqrt(x + b**2)
  114. assert MT(expr.subs(b, bpos), x, s) == \
  115. (2**(a + 2*s)*bpos**(a + 2*s - 1)*gamma(s)
  116. *gamma(1 - a - 2*s)/gamma(1 - a - s),
  117. (0, -re(a)/2 + S.Half), True)
  118. # 8.4.2
  119. assert MT(exp(-x), x, s) == (gamma(s), (0, oo), True)
  120. assert MT(exp(-1/x), x, s) == (gamma(-s), (-oo, 0), True)
  121. # 8.4.5
  122. assert MT(log(x)**4*Heaviside(1 - x), x, s) == (24/s**5, (0, oo), True)
  123. assert MT(log(x)**3*Heaviside(x - 1), x, s) == (6/s**4, (-oo, 0), True)
  124. assert MT(log(x + 1), x, s) == (pi/(s*sin(pi*s)), (-1, 0), True)
  125. assert MT(log(1/x + 1), x, s) == (pi/(s*sin(pi*s)), (0, 1), True)
  126. assert MT(log(abs(1 - x)), x, s) == (pi/(s*tan(pi*s)), (-1, 0), True)
  127. assert MT(log(abs(1 - 1/x)), x, s) == (pi/(s*tan(pi*s)), (0, 1), True)
  128. # 8.4.14
  129. assert MT(erf(sqrt(x)), x, s) == \
  130. (-gamma(s + S.Half)/(sqrt(pi)*s), (Rational(-1, 2), 0), True)
  131. def test_mellin_transform2():
  132. MT = mellin_transform
  133. # TODO we cannot currently do these (needs summation of 3F2(-1))
  134. # this also implies that they cannot be written as a single g-function
  135. # (although this is possible)
  136. mt = MT(log(x)/(x + 1), x, s)
  137. assert mt[1:] == ((0, 1), True)
  138. assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
  139. mt = MT(log(x)**2/(x + 1), x, s)
  140. assert mt[1:] == ((0, 1), True)
  141. assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
  142. mt = MT(log(x)/(x + 1)**2, x, s)
  143. assert mt[1:] == ((0, 2), True)
  144. assert not hyperexpand(mt[0], allow_hyper=True).has(meijerg)
  145. @slow
  146. def test_mellin_transform_bessel():
  147. from sympy.functions.elementary.miscellaneous import Max
  148. MT = mellin_transform
  149. # 8.4.19
  150. assert MT(besselj(a, 2*sqrt(x)), x, s) == \
  151. (gamma(a/2 + s)/gamma(a/2 - s + 1), (-re(a)/2, Rational(3, 4)), True)
  152. assert MT(sin(sqrt(x))*besselj(a, sqrt(x)), x, s) == \
  153. (2**a*gamma(-2*s + S.Half)*gamma(a/2 + s + S.Half)/(
  154. gamma(-a/2 - s + 1)*gamma(a - 2*s + 1)), (
  155. -re(a)/2 - S.Half, Rational(1, 4)), True)
  156. assert MT(cos(sqrt(x))*besselj(a, sqrt(x)), x, s) == \
  157. (2**a*gamma(a/2 + s)*gamma(-2*s + S.Half)/(
  158. gamma(-a/2 - s + S.Half)*gamma(a - 2*s + 1)), (
  159. -re(a)/2, Rational(1, 4)), True)
  160. assert MT(besselj(a, sqrt(x))**2, x, s) == \
  161. (gamma(a + s)*gamma(S.Half - s)
  162. / (sqrt(pi)*gamma(1 - s)*gamma(1 + a - s)),
  163. (-re(a), S.Half), True)
  164. assert MT(besselj(a, sqrt(x))*besselj(-a, sqrt(x)), x, s) == \
  165. (gamma(s)*gamma(S.Half - s)
  166. / (sqrt(pi)*gamma(1 - a - s)*gamma(1 + a - s)),
  167. (0, S.Half), True)
  168. # NOTE: prudnikov gives the strip below as (1/2 - re(a), 1). As far as
  169. # I can see this is wrong (since besselj(z) ~ 1/sqrt(z) for z large)
  170. assert MT(besselj(a - 1, sqrt(x))*besselj(a, sqrt(x)), x, s) == \
  171. (gamma(1 - s)*gamma(a + s - S.Half)
  172. / (sqrt(pi)*gamma(Rational(3, 2) - s)*gamma(a - s + S.Half)),
  173. (S.Half - re(a), S.Half), True)
  174. assert MT(besselj(a, sqrt(x))*besselj(b, sqrt(x)), x, s) == \
  175. (4**s*gamma(1 - 2*s)*gamma((a + b)/2 + s)
  176. / (gamma(1 - s + (b - a)/2)*gamma(1 - s + (a - b)/2)
  177. *gamma( 1 - s + (a + b)/2)),
  178. (-(re(a) + re(b))/2, S.Half), True)
  179. assert MT(besselj(a, sqrt(x))**2 + besselj(-a, sqrt(x))**2, x, s)[1:] == \
  180. ((Max(re(a), -re(a)), S.Half), True)
  181. # Section 8.4.20
  182. assert MT(bessely(a, 2*sqrt(x)), x, s) == \
  183. (-cos(pi*(a/2 - s))*gamma(s - a/2)*gamma(s + a/2)/pi,
  184. (Max(-re(a)/2, re(a)/2), Rational(3, 4)), True)
  185. assert MT(sin(sqrt(x))*bessely(a, sqrt(x)), x, s) == \
  186. (-4**s*sin(pi*(a/2 - s))*gamma(S.Half - 2*s)
  187. * gamma((1 - a)/2 + s)*gamma((1 + a)/2 + s)
  188. / (sqrt(pi)*gamma(1 - s - a/2)*gamma(1 - s + a/2)),
  189. (Max(-(re(a) + 1)/2, (re(a) - 1)/2), Rational(1, 4)), True)
  190. assert MT(cos(sqrt(x))*bessely(a, sqrt(x)), x, s) == \
  191. (-4**s*cos(pi*(a/2 - s))*gamma(s - a/2)*gamma(s + a/2)*gamma(S.Half - 2*s)
  192. / (sqrt(pi)*gamma(S.Half - s - a/2)*gamma(S.Half - s + a/2)),
  193. (Max(-re(a)/2, re(a)/2), Rational(1, 4)), True)
  194. assert MT(besselj(a, sqrt(x))*bessely(a, sqrt(x)), x, s) == \
  195. (-cos(pi*s)*gamma(s)*gamma(a + s)*gamma(S.Half - s)
  196. / (pi**S('3/2')*gamma(1 + a - s)),
  197. (Max(-re(a), 0), S.Half), True)
  198. assert MT(besselj(a, sqrt(x))*bessely(b, sqrt(x)), x, s) == \
  199. (-4**s*cos(pi*(a/2 - b/2 + s))*gamma(1 - 2*s)
  200. * gamma(a/2 - b/2 + s)*gamma(a/2 + b/2 + s)
  201. / (pi*gamma(a/2 - b/2 - s + 1)*gamma(a/2 + b/2 - s + 1)),
  202. (Max((-re(a) + re(b))/2, (-re(a) - re(b))/2), S.Half), True)
  203. # NOTE bessely(a, sqrt(x))**2 and bessely(a, sqrt(x))*bessely(b, sqrt(x))
  204. # are a mess (no matter what way you look at it ...)
  205. assert MT(bessely(a, sqrt(x))**2, x, s)[1:] == \
  206. ((Max(-re(a), 0, re(a)), S.Half), True)
  207. # Section 8.4.22
  208. # TODO we can't do any of these (delicate cancellation)
  209. # Section 8.4.23
  210. assert MT(besselk(a, 2*sqrt(x)), x, s) == \
  211. (gamma(
  212. s - a/2)*gamma(s + a/2)/2, (Max(-re(a)/2, re(a)/2), oo), True)
  213. assert MT(besselj(a, 2*sqrt(2*sqrt(x)))*besselk(
  214. a, 2*sqrt(2*sqrt(x))), x, s) == (4**(-s)*gamma(2*s)*
  215. gamma(a/2 + s)/(2*gamma(a/2 - s + 1)), (Max(0, -re(a)/2), oo), True)
  216. # TODO bessely(a, x)*besselk(a, x) is a mess
  217. assert MT(besseli(a, sqrt(x))*besselk(a, sqrt(x)), x, s) == \
  218. (gamma(s)*gamma(
  219. a + s)*gamma(-s + S.Half)/(2*sqrt(pi)*gamma(a - s + 1)),
  220. (Max(-re(a), 0), S.Half), True)
  221. assert MT(besseli(b, sqrt(x))*besselk(a, sqrt(x)), x, s) == \
  222. (2**(2*s - 1)*gamma(-2*s + 1)*gamma(-a/2 + b/2 + s)* \
  223. gamma(a/2 + b/2 + s)/(gamma(-a/2 + b/2 - s + 1)* \
  224. gamma(a/2 + b/2 - s + 1)), (Max(-re(a)/2 - re(b)/2, \
  225. re(a)/2 - re(b)/2), S.Half), True)
  226. # TODO products of besselk are a mess
  227. mt = MT(exp(-x/2)*besselk(a, x/2), x, s)
  228. mt0 = gammasimp(trigsimp(gammasimp(mt[0].expand(func=True))))
  229. assert mt0 == 2*pi**Rational(3, 2)*cos(pi*s)*gamma(S.Half - s)/(
  230. (cos(2*pi*a) - cos(2*pi*s))*gamma(-a - s + 1)*gamma(a - s + 1))
  231. assert mt[1:] == ((Max(-re(a), re(a)), oo), True)
  232. # TODO exp(x/2)*besselk(a, x/2) [etc] cannot currently be done
  233. # TODO various strange products of special orders
  234. @slow
  235. def test_expint():
  236. from sympy.functions.elementary.miscellaneous import Max
  237. from sympy.functions.special.error_functions import Ci, E1, Si
  238. from sympy.simplify.simplify import simplify
  239. aneg = Symbol('a', negative=True)
  240. u = Symbol('u', polar=True)
  241. assert mellin_transform(E1(x), x, s) == (gamma(s)/s, (0, oo), True)
  242. assert inverse_mellin_transform(gamma(s)/s, s, x,
  243. (0, oo)).rewrite(expint).expand() == E1(x)
  244. assert mellin_transform(expint(a, x), x, s) == \
  245. (gamma(s)/(a + s - 1), (Max(1 - re(a), 0), oo), True)
  246. # XXX IMT has hickups with complicated strips ...
  247. assert simplify(unpolarify(
  248. inverse_mellin_transform(gamma(s)/(aneg + s - 1), s, x,
  249. (1 - aneg, oo)).rewrite(expint).expand(func=True))) == \
  250. expint(aneg, x)
  251. assert mellin_transform(Si(x), x, s) == \
  252. (-2**s*sqrt(pi)*gamma(s/2 + S.Half)/(
  253. 2*s*gamma(-s/2 + 1)), (-1, 0), True)
  254. assert inverse_mellin_transform(-2**s*sqrt(pi)*gamma((s + 1)/2)
  255. /(2*s*gamma(-s/2 + 1)), s, x, (-1, 0)) \
  256. == Si(x)
  257. assert mellin_transform(Ci(sqrt(x)), x, s) == \
  258. (-2**(2*s - 1)*sqrt(pi)*gamma(s)/(s*gamma(-s + S.Half)), (0, 1), True)
  259. assert inverse_mellin_transform(
  260. -4**s*sqrt(pi)*gamma(s)/(2*s*gamma(-s + S.Half)),
  261. s, u, (0, 1)).expand() == Ci(sqrt(u))
  262. @slow
  263. def test_inverse_mellin_transform():
  264. from sympy.core.function import expand
  265. from sympy.functions.elementary.miscellaneous import (Max, Min)
  266. from sympy.functions.elementary.trigonometric import cot
  267. from sympy.simplify.powsimp import powsimp
  268. from sympy.simplify.simplify import simplify
  269. IMT = inverse_mellin_transform
  270. assert IMT(gamma(s), s, x, (0, oo)) == exp(-x)
  271. assert IMT(gamma(-s), s, x, (-oo, 0)) == exp(-1/x)
  272. assert simplify(IMT(s/(2*s**2 - 2), s, x, (2, oo))) == \
  273. (x**2 + 1)*Heaviside(1 - x)/(4*x)
  274. # test passing "None"
  275. assert IMT(1/(s**2 - 1), s, x, (-1, None)) == \
  276. -x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x)
  277. assert IMT(1/(s**2 - 1), s, x, (None, 1)) == \
  278. -x*Heaviside(-x + 1)/2 - Heaviside(x - 1)/(2*x)
  279. # test expansion of sums
  280. assert IMT(gamma(s) + gamma(s - 1), s, x, (1, oo)) == (x + 1)*exp(-x)/x
  281. # test factorisation of polys
  282. r = symbols('r', real=True)
  283. assert IMT(1/(s**2 + 1), s, exp(-x), (None, oo)
  284. ).subs(x, r).rewrite(sin).simplify() \
  285. == sin(r)*Heaviside(1 - exp(-r))
  286. # test multiplicative substitution
  287. _a, _b = symbols('a b', positive=True)
  288. assert IMT(_b**(-s/_a)*factorial(s/_a)/s, s, x, (0, oo)) == exp(-_b*x**_a)
  289. assert IMT(factorial(_a/_b + s/_b)/(_a + s), s, x, (-_a, oo)) == x**_a*exp(-x**_b)
  290. def simp_pows(expr):
  291. return simplify(powsimp(expand_mul(expr, deep=False), force=True)).replace(exp_polar, exp)
  292. # Now test the inverses of all direct transforms tested above
  293. # Section 8.4.2
  294. nu = symbols('nu', real=True)
  295. assert IMT(-1/(nu + s), s, x, (-oo, None)) == x**nu*Heaviside(x - 1)
  296. assert IMT(1/(nu + s), s, x, (None, oo)) == x**nu*Heaviside(1 - x)
  297. assert simp_pows(IMT(gamma(beta)*gamma(s)/gamma(s + beta), s, x, (0, oo))) \
  298. == (1 - x)**(beta - 1)*Heaviside(1 - x)
  299. assert simp_pows(IMT(gamma(beta)*gamma(1 - beta - s)/gamma(1 - s),
  300. s, x, (-oo, None))) \
  301. == (x - 1)**(beta - 1)*Heaviside(x - 1)
  302. assert simp_pows(IMT(gamma(s)*gamma(rho - s)/gamma(rho), s, x, (0, None))) \
  303. == (1/(x + 1))**rho
  304. assert simp_pows(IMT(d**c*d**(s - 1)*sin(pi*c)
  305. *gamma(s)*gamma(s + c)*gamma(1 - s)*gamma(1 - s - c)/pi,
  306. s, x, (Max(-re(c), 0), Min(1 - re(c), 1)))) \
  307. == (x**c - d**c)/(x - d)
  308. assert simplify(IMT(1/sqrt(pi)*(-c/2)*gamma(s)*gamma((1 - c)/2 - s)
  309. *gamma(-c/2 - s)/gamma(1 - c - s),
  310. s, x, (0, -re(c)/2))) == \
  311. (1 + sqrt(x + 1))**c
  312. assert simplify(IMT(2**(a + 2*s)*b**(a + 2*s - 1)*gamma(s)*gamma(1 - a - 2*s)
  313. /gamma(1 - a - s), s, x, (0, (-re(a) + 1)/2))) == \
  314. b**(a - 1)*(b**2*(sqrt(1 + x/b**2) + 1)**a + x*(sqrt(1 + x/b**2) + 1
  315. )**(a - 1))/(b**2 + x)
  316. assert simplify(IMT(-2**(c + 2*s)*c*b**(c + 2*s)*gamma(s)*gamma(-c - 2*s)
  317. / gamma(-c - s + 1), s, x, (0, -re(c)/2))) == \
  318. b**c*(sqrt(1 + x/b**2) + 1)**c
  319. # Section 8.4.5
  320. assert IMT(24/s**5, s, x, (0, oo)) == log(x)**4*Heaviside(1 - x)
  321. assert expand(IMT(6/s**4, s, x, (-oo, 0)), force=True) == \
  322. log(x)**3*Heaviside(x - 1)
  323. assert IMT(pi/(s*sin(pi*s)), s, x, (-1, 0)) == log(x + 1)
  324. assert IMT(pi/(s*sin(pi*s/2)), s, x, (-2, 0)) == log(x**2 + 1)
  325. assert IMT(pi/(s*sin(2*pi*s)), s, x, (Rational(-1, 2), 0)) == log(sqrt(x) + 1)
  326. assert IMT(pi/(s*sin(pi*s)), s, x, (0, 1)) == log(1 + 1/x)
  327. # TODO
  328. def mysimp(expr):
  329. from sympy.core.function import expand
  330. from sympy.simplify.powsimp import powsimp
  331. from sympy.simplify.simplify import logcombine
  332. return expand(
  333. powsimp(logcombine(expr, force=True), force=True, deep=True),
  334. force=True).replace(exp_polar, exp)
  335. assert mysimp(mysimp(IMT(pi/(s*tan(pi*s)), s, x, (-1, 0)))) in [
  336. log(1 - x)*Heaviside(1 - x) + log(x - 1)*Heaviside(x - 1),
  337. log(x)*Heaviside(x - 1) + log(1 - 1/x)*Heaviside(x - 1) + log(-x +
  338. 1)*Heaviside(-x + 1)]
  339. # test passing cot
  340. assert mysimp(IMT(pi*cot(pi*s)/s, s, x, (0, 1))) in [
  341. log(1/x - 1)*Heaviside(1 - x) + log(1 - 1/x)*Heaviside(x - 1),
  342. -log(x)*Heaviside(-x + 1) + log(1 - 1/x)*Heaviside(x - 1) + log(-x +
  343. 1)*Heaviside(-x + 1), ]
  344. # 8.4.14
  345. assert IMT(-gamma(s + S.Half)/(sqrt(pi)*s), s, x, (Rational(-1, 2), 0)) == \
  346. erf(sqrt(x))
  347. # 8.4.19
  348. assert simplify(IMT(gamma(a/2 + s)/gamma(a/2 - s + 1), s, x, (-re(a)/2, Rational(3, 4)))) \
  349. == besselj(a, 2*sqrt(x))
  350. assert simplify(IMT(2**a*gamma(S.Half - 2*s)*gamma(s + (a + 1)/2)
  351. / (gamma(1 - s - a/2)*gamma(1 - 2*s + a)),
  352. s, x, (-(re(a) + 1)/2, Rational(1, 4)))) == \
  353. sin(sqrt(x))*besselj(a, sqrt(x))
  354. assert simplify(IMT(2**a*gamma(a/2 + s)*gamma(S.Half - 2*s)
  355. / (gamma(S.Half - s - a/2)*gamma(1 - 2*s + a)),
  356. s, x, (-re(a)/2, Rational(1, 4)))) == \
  357. cos(sqrt(x))*besselj(a, sqrt(x))
  358. # TODO this comes out as an amazing mess, but simplifies nicely
  359. assert simplify(IMT(gamma(a + s)*gamma(S.Half - s)
  360. / (sqrt(pi)*gamma(1 - s)*gamma(1 + a - s)),
  361. s, x, (-re(a), S.Half))) == \
  362. besselj(a, sqrt(x))**2
  363. assert simplify(IMT(gamma(s)*gamma(S.Half - s)
  364. / (sqrt(pi)*gamma(1 - s - a)*gamma(1 + a - s)),
  365. s, x, (0, S.Half))) == \
  366. besselj(-a, sqrt(x))*besselj(a, sqrt(x))
  367. assert simplify(IMT(4**s*gamma(-2*s + 1)*gamma(a/2 + b/2 + s)
  368. / (gamma(-a/2 + b/2 - s + 1)*gamma(a/2 - b/2 - s + 1)
  369. *gamma(a/2 + b/2 - s + 1)),
  370. s, x, (-(re(a) + re(b))/2, S.Half))) == \
  371. besselj(a, sqrt(x))*besselj(b, sqrt(x))
  372. # Section 8.4.20
  373. # TODO this can be further simplified!
  374. assert simplify(IMT(-2**(2*s)*cos(pi*a/2 - pi*b/2 + pi*s)*gamma(-2*s + 1) *
  375. gamma(a/2 - b/2 + s)*gamma(a/2 + b/2 + s) /
  376. (pi*gamma(a/2 - b/2 - s + 1)*gamma(a/2 + b/2 - s + 1)),
  377. s, x,
  378. (Max(-re(a)/2 - re(b)/2, -re(a)/2 + re(b)/2), S.Half))) == \
  379. besselj(a, sqrt(x))*-(besselj(-b, sqrt(x)) -
  380. besselj(b, sqrt(x))*cos(pi*b))/sin(pi*b)
  381. # TODO more
  382. # for coverage
  383. assert IMT(pi/cos(pi*s), s, x, (0, S.Half)) == sqrt(x)/(x + 1)
  384. def test_fourier_transform():
  385. from sympy.core.function import (expand, expand_complex, expand_trig)
  386. from sympy.polys.polytools import factor
  387. from sympy.simplify.simplify import simplify
  388. FT = fourier_transform
  389. IFT = inverse_fourier_transform
  390. def simp(x):
  391. return simplify(expand_trig(expand_complex(expand(x))))
  392. def sinc(x):
  393. return sin(pi*x)/(pi*x)
  394. k = symbols('k', real=True)
  395. f = Function("f")
  396. # TODO for this to work with real a, need to expand abs(a*x) to abs(a)*abs(x)
  397. a = symbols('a', positive=True)
  398. b = symbols('b', positive=True)
  399. posk = symbols('posk', positive=True)
  400. # Test unevaluated form
  401. assert fourier_transform(f(x), x, k) == FourierTransform(f(x), x, k)
  402. assert inverse_fourier_transform(
  403. f(k), k, x) == InverseFourierTransform(f(k), k, x)
  404. # basic examples from wikipedia
  405. assert simp(FT(Heaviside(1 - abs(2*a*x)), x, k)) == sinc(k/a)/a
  406. # TODO IFT is a *mess*
  407. assert simp(FT(Heaviside(1 - abs(a*x))*(1 - abs(a*x)), x, k)) == sinc(k/a)**2/a
  408. # TODO IFT
  409. assert factor(FT(exp(-a*x)*Heaviside(x), x, k), extension=I) == \
  410. 1/(a + 2*pi*I*k)
  411. # NOTE: the ift comes out in pieces
  412. assert IFT(1/(a + 2*pi*I*x), x, posk,
  413. noconds=False) == (exp(-a*posk), True)
  414. assert IFT(1/(a + 2*pi*I*x), x, -posk,
  415. noconds=False) == (0, True)
  416. assert IFT(1/(a + 2*pi*I*x), x, symbols('k', negative=True),
  417. noconds=False) == (0, True)
  418. # TODO IFT without factoring comes out as meijer g
  419. assert factor(FT(x*exp(-a*x)*Heaviside(x), x, k), extension=I) == \
  420. 1/(a + 2*pi*I*k)**2
  421. assert FT(exp(-a*x)*sin(b*x)*Heaviside(x), x, k) == \
  422. b/(b**2 + (a + 2*I*pi*k)**2)
  423. assert FT(exp(-a*x**2), x, k) == sqrt(pi)*exp(-pi**2*k**2/a)/sqrt(a)
  424. assert IFT(sqrt(pi/a)*exp(-(pi*k)**2/a), k, x) == exp(-a*x**2)
  425. assert FT(exp(-a*abs(x)), x, k) == 2*a/(a**2 + 4*pi**2*k**2)
  426. # TODO IFT (comes out as meijer G)
  427. # TODO besselj(n, x), n an integer > 0 actually can be done...
  428. # TODO are there other common transforms (no distributions!)?
  429. def test_sine_transform():
  430. t = symbols("t")
  431. w = symbols("w")
  432. a = symbols("a")
  433. f = Function("f")
  434. # Test unevaluated form
  435. assert sine_transform(f(t), t, w) == SineTransform(f(t), t, w)
  436. assert inverse_sine_transform(
  437. f(w), w, t) == InverseSineTransform(f(w), w, t)
  438. assert sine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
  439. assert inverse_sine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
  440. assert sine_transform((1/sqrt(t))**3, t, w) == 2*sqrt(w)
  441. assert sine_transform(t**(-a), t, w) == 2**(
  442. -a + S.Half)*w**(a - 1)*gamma(-a/2 + 1)/gamma((a + 1)/2)
  443. assert inverse_sine_transform(2**(-a + S(
  444. 1)/2)*w**(a - 1)*gamma(-a/2 + 1)/gamma(a/2 + S.Half), w, t) == t**(-a)
  445. assert sine_transform(
  446. exp(-a*t), t, w) == sqrt(2)*w/(sqrt(pi)*(a**2 + w**2))
  447. assert inverse_sine_transform(
  448. sqrt(2)*w/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
  449. assert sine_transform(
  450. log(t)/t, t, w) == sqrt(2)*sqrt(pi)*-(log(w**2) + 2*EulerGamma)/4
  451. assert sine_transform(
  452. t*exp(-a*t**2), t, w) == sqrt(2)*w*exp(-w**2/(4*a))/(4*a**Rational(3, 2))
  453. assert inverse_sine_transform(
  454. sqrt(2)*w*exp(-w**2/(4*a))/(4*a**Rational(3, 2)), w, t) == t*exp(-a*t**2)
  455. def test_cosine_transform():
  456. from sympy.functions.special.error_functions import (Ci, Si)
  457. t = symbols("t")
  458. w = symbols("w")
  459. a = symbols("a")
  460. f = Function("f")
  461. # Test unevaluated form
  462. assert cosine_transform(f(t), t, w) == CosineTransform(f(t), t, w)
  463. assert inverse_cosine_transform(
  464. f(w), w, t) == InverseCosineTransform(f(w), w, t)
  465. assert cosine_transform(1/sqrt(t), t, w) == 1/sqrt(w)
  466. assert inverse_cosine_transform(1/sqrt(w), w, t) == 1/sqrt(t)
  467. assert cosine_transform(1/(
  468. a**2 + t**2), t, w) == sqrt(2)*sqrt(pi)*exp(-a*w)/(2*a)
  469. assert cosine_transform(t**(
  470. -a), t, w) == 2**(-a + S.Half)*w**(a - 1)*gamma((-a + 1)/2)/gamma(a/2)
  471. assert inverse_cosine_transform(2**(-a + S(
  472. 1)/2)*w**(a - 1)*gamma(-a/2 + S.Half)/gamma(a/2), w, t) == t**(-a)
  473. assert cosine_transform(
  474. exp(-a*t), t, w) == sqrt(2)*a/(sqrt(pi)*(a**2 + w**2))
  475. assert inverse_cosine_transform(
  476. sqrt(2)*a/(sqrt(pi)*(a**2 + w**2)), w, t) == exp(-a*t)
  477. assert cosine_transform(exp(-a*sqrt(t))*cos(a*sqrt(
  478. t)), t, w) == a*exp(-a**2/(2*w))/(2*w**Rational(3, 2))
  479. assert cosine_transform(1/(a + t), t, w) == sqrt(2)*(
  480. (-2*Si(a*w) + pi)*sin(a*w)/2 - cos(a*w)*Ci(a*w))/sqrt(pi)
  481. assert inverse_cosine_transform(sqrt(2)*meijerg(((S.Half, 0), ()), (
  482. (S.Half, 0, 0), (S.Half,)), a**2*w**2/4)/(2*pi), w, t) == 1/(a + t)
  483. assert cosine_transform(1/sqrt(a**2 + t**2), t, w) == sqrt(2)*meijerg(
  484. ((S.Half,), ()), ((0, 0), (S.Half,)), a**2*w**2/4)/(2*sqrt(pi))
  485. assert inverse_cosine_transform(sqrt(2)*meijerg(((S.Half,), ()), ((0, 0), (S.Half,)), a**2*w**2/4)/(2*sqrt(pi)), w, t) == 1/(t*sqrt(a**2/t**2 + 1))
  486. def test_hankel_transform():
  487. r = Symbol("r")
  488. k = Symbol("k")
  489. nu = Symbol("nu")
  490. m = Symbol("m")
  491. a = symbols("a")
  492. assert hankel_transform(1/r, r, k, 0) == 1/k
  493. assert inverse_hankel_transform(1/k, k, r, 0) == 1/r
  494. assert hankel_transform(
  495. 1/r**m, r, k, 0) == 2**(-m + 1)*k**(m - 2)*gamma(-m/2 + 1)/gamma(m/2)
  496. assert inverse_hankel_transform(
  497. 2**(-m + 1)*k**(m - 2)*gamma(-m/2 + 1)/gamma(m/2), k, r, 0) == r**(-m)
  498. assert hankel_transform(1/r**m, r, k, nu) == (
  499. 2*2**(-m)*k**(m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2))
  500. assert inverse_hankel_transform(2**(-m + 1)*k**(
  501. m - 2)*gamma(-m/2 + nu/2 + 1)/gamma(m/2 + nu/2), k, r, nu) == r**(-m)
  502. assert hankel_transform(r**nu*exp(-a*r), r, k, nu) == \
  503. 2**(nu + 1)*a*k**(-nu - 3)*(a**2/k**2 + 1)**(-nu - S(
  504. 3)/2)*gamma(nu + Rational(3, 2))/sqrt(pi)
  505. assert inverse_hankel_transform(
  506. 2**(nu + 1)*a*k**(-nu - 3)*(a**2/k**2 + 1)**(-nu - Rational(3, 2))*gamma(
  507. nu + Rational(3, 2))/sqrt(pi), k, r, nu) == r**nu*exp(-a*r)
  508. def test_issue_7181():
  509. assert mellin_transform(1/(1 - x), x, s) != None
  510. def test_issue_8882():
  511. # This is the original test.
  512. # from sympy import diff, Integral, integrate
  513. # r = Symbol('r')
  514. # psi = 1/r*sin(r)*exp(-(a0*r))
  515. # h = -1/2*diff(psi, r, r) - 1/r*psi
  516. # f = 4*pi*psi*h*r**2
  517. # assert integrate(f, (r, -oo, 3), meijerg=True).has(Integral) == True
  518. # To save time, only the critical part is included.
  519. F = -a**(-s + 1)*(4 + 1/a**2)**(-s/2)*sqrt(1/a**2)*exp(-s*I*pi)* \
  520. sin(s*atan(sqrt(1/a**2)/2))*gamma(s)
  521. raises(IntegralTransformError, lambda:
  522. inverse_mellin_transform(F, s, x, (-1, oo),
  523. **{'as_meijerg': True, 'needeval': True}))
  524. def test_issue_12591():
  525. x, y = symbols("x y", real=True)
  526. assert fourier_transform(exp(x), x, y) == FourierTransform(exp(x), x, y)