test_gamma_functions.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. from sympy.core.function import expand_func, Subs
  2. from sympy.core import EulerGamma
  3. from sympy.core.numbers import (I, Rational, nan, oo, pi, zoo)
  4. from sympy.core.singleton import S
  5. from sympy.core.symbol import (Dummy, Symbol)
  6. from sympy.functions.combinatorial.factorials import factorial
  7. from sympy.functions.combinatorial.numbers import harmonic
  8. from sympy.functions.elementary.complexes import (Abs, conjugate, im, re)
  9. from sympy.functions.elementary.exponential import (exp, exp_polar, log)
  10. from sympy.functions.elementary.hyperbolic import tanh
  11. from sympy.functions.elementary.miscellaneous import sqrt
  12. from sympy.functions.elementary.trigonometric import (cos, sin, atan)
  13. from sympy.functions.special.error_functions import (Ei, erf, erfc)
  14. from sympy.functions.special.gamma_functions import (digamma, gamma, loggamma, lowergamma, multigamma, polygamma, trigamma, uppergamma)
  15. from sympy.functions.special.zeta_functions import zeta
  16. from sympy.series.order import O
  17. from sympy.core.expr import unchanged
  18. from sympy.core.function import ArgumentIndexError
  19. from sympy.testing.pytest import raises
  20. from sympy.core.random import (test_derivative_numerically as td,
  21. random_complex_number as randcplx,
  22. verify_numerically as tn)
  23. x = Symbol('x')
  24. y = Symbol('y')
  25. n = Symbol('n', integer=True)
  26. w = Symbol('w', real=True)
  27. def test_gamma():
  28. assert gamma(nan) is nan
  29. assert gamma(oo) is oo
  30. assert gamma(-100) is zoo
  31. assert gamma(0) is zoo
  32. assert gamma(-100.0) is zoo
  33. assert gamma(1) == 1
  34. assert gamma(2) == 1
  35. assert gamma(3) == 2
  36. assert gamma(102) == factorial(101)
  37. assert gamma(S.Half) == sqrt(pi)
  38. assert gamma(Rational(3, 2)) == sqrt(pi)*S.Half
  39. assert gamma(Rational(5, 2)) == sqrt(pi)*Rational(3, 4)
  40. assert gamma(Rational(7, 2)) == sqrt(pi)*Rational(15, 8)
  41. assert gamma(Rational(-1, 2)) == -2*sqrt(pi)
  42. assert gamma(Rational(-3, 2)) == sqrt(pi)*Rational(4, 3)
  43. assert gamma(Rational(-5, 2)) == sqrt(pi)*Rational(-8, 15)
  44. assert gamma(Rational(-15, 2)) == sqrt(pi)*Rational(256, 2027025)
  45. assert gamma(Rational(
  46. -11, 8)).expand(func=True) == Rational(64, 33)*gamma(Rational(5, 8))
  47. assert gamma(Rational(
  48. -10, 3)).expand(func=True) == Rational(81, 280)*gamma(Rational(2, 3))
  49. assert gamma(Rational(
  50. 14, 3)).expand(func=True) == Rational(880, 81)*gamma(Rational(2, 3))
  51. assert gamma(Rational(
  52. 17, 7)).expand(func=True) == Rational(30, 49)*gamma(Rational(3, 7))
  53. assert gamma(Rational(
  54. 19, 8)).expand(func=True) == Rational(33, 64)*gamma(Rational(3, 8))
  55. assert gamma(x).diff(x) == gamma(x)*polygamma(0, x)
  56. assert gamma(x - 1).expand(func=True) == gamma(x)/(x - 1)
  57. assert gamma(x + 2).expand(func=True, mul=False) == x*(x + 1)*gamma(x)
  58. assert conjugate(gamma(x)) == gamma(conjugate(x))
  59. assert expand_func(gamma(x + Rational(3, 2))) == \
  60. (x + S.Half)*gamma(x + S.Half)
  61. assert expand_func(gamma(x - S.Half)) == \
  62. gamma(S.Half + x)/(x - S.Half)
  63. # Test a bug:
  64. assert expand_func(gamma(x + Rational(3, 4))) == gamma(x + Rational(3, 4))
  65. # XXX: Not sure about these tests. I can fix them by defining e.g.
  66. # exp_polar.is_integer but I'm not sure if that makes sense.
  67. assert gamma(3*exp_polar(I*pi)/4).is_nonnegative is False
  68. assert gamma(3*exp_polar(I*pi)/4).is_extended_nonpositive is True
  69. y = Symbol('y', nonpositive=True, integer=True)
  70. assert gamma(y).is_real == False
  71. y = Symbol('y', positive=True, noninteger=True)
  72. assert gamma(y).is_real == True
  73. assert gamma(-1.0, evaluate=False).is_real == False
  74. assert gamma(0, evaluate=False).is_real == False
  75. assert gamma(-2, evaluate=False).is_real == False
  76. def test_gamma_rewrite():
  77. assert gamma(n).rewrite(factorial) == factorial(n - 1)
  78. def test_gamma_series():
  79. assert gamma(x + 1).series(x, 0, 3) == \
  80. 1 - EulerGamma*x + x**2*(EulerGamma**2/2 + pi**2/12) + O(x**3)
  81. assert gamma(x).series(x, -1, 3) == \
  82. -1/(x + 1) + EulerGamma - 1 + (x + 1)*(-1 - pi**2/12 - EulerGamma**2/2 + \
  83. EulerGamma) + (x + 1)**2*(-1 - pi**2/12 - EulerGamma**2/2 + EulerGamma**3/6 - \
  84. polygamma(2, 1)/6 + EulerGamma*pi**2/12 + EulerGamma) + O((x + 1)**3, (x, -1))
  85. def tn_branch(s, func):
  86. from sympy.core.random import uniform
  87. c = uniform(1, 5)
  88. expr = func(s, c*exp_polar(I*pi)) - func(s, c*exp_polar(-I*pi))
  89. eps = 1e-15
  90. expr2 = func(s + eps, -c + eps*I) - func(s + eps, -c - eps*I)
  91. return abs(expr.n() - expr2.n()).n() < 1e-10
  92. def test_lowergamma():
  93. from sympy.functions.special.error_functions import expint
  94. from sympy.functions.special.hyper import meijerg
  95. assert lowergamma(x, 0) == 0
  96. assert lowergamma(x, y).diff(y) == y**(x - 1)*exp(-y)
  97. assert td(lowergamma(randcplx(), y), y)
  98. assert td(lowergamma(x, randcplx()), x)
  99. assert lowergamma(x, y).diff(x) == \
  100. gamma(x)*digamma(x) - uppergamma(x, y)*log(y) \
  101. - meijerg([], [1, 1], [0, 0, x], [], y)
  102. assert lowergamma(S.Half, x) == sqrt(pi)*erf(sqrt(x))
  103. assert not lowergamma(S.Half - 3, x).has(lowergamma)
  104. assert not lowergamma(S.Half + 3, x).has(lowergamma)
  105. assert lowergamma(S.Half, x, evaluate=False).has(lowergamma)
  106. assert tn(lowergamma(S.Half + 3, x, evaluate=False),
  107. lowergamma(S.Half + 3, x), x)
  108. assert tn(lowergamma(S.Half - 3, x, evaluate=False),
  109. lowergamma(S.Half - 3, x), x)
  110. assert tn_branch(-3, lowergamma)
  111. assert tn_branch(-4, lowergamma)
  112. assert tn_branch(Rational(1, 3), lowergamma)
  113. assert tn_branch(pi, lowergamma)
  114. assert lowergamma(3, exp_polar(4*pi*I)*x) == lowergamma(3, x)
  115. assert lowergamma(y, exp_polar(5*pi*I)*x) == \
  116. exp(4*I*pi*y)*lowergamma(y, x*exp_polar(pi*I))
  117. assert lowergamma(-2, exp_polar(5*pi*I)*x) == \
  118. lowergamma(-2, x*exp_polar(I*pi)) + 2*pi*I
  119. assert conjugate(lowergamma(x, y)) == lowergamma(conjugate(x), conjugate(y))
  120. assert conjugate(lowergamma(x, 0)) == 0
  121. assert unchanged(conjugate, lowergamma(x, -oo))
  122. assert lowergamma(0, x)._eval_is_meromorphic(x, 0) == False
  123. assert lowergamma(S(1)/3, x)._eval_is_meromorphic(x, 0) == False
  124. assert lowergamma(1, x, evaluate=False)._eval_is_meromorphic(x, 0) == True
  125. assert lowergamma(x, x)._eval_is_meromorphic(x, 0) == False
  126. assert lowergamma(x + 1, x)._eval_is_meromorphic(x, 0) == False
  127. assert lowergamma(1/x, x)._eval_is_meromorphic(x, 0) == False
  128. assert lowergamma(0, x + 1)._eval_is_meromorphic(x, 0) == False
  129. assert lowergamma(S(1)/3, x + 1)._eval_is_meromorphic(x, 0) == True
  130. assert lowergamma(1, x + 1, evaluate=False)._eval_is_meromorphic(x, 0) == True
  131. assert lowergamma(x, x + 1)._eval_is_meromorphic(x, 0) == True
  132. assert lowergamma(x + 1, x + 1)._eval_is_meromorphic(x, 0) == True
  133. assert lowergamma(1/x, x + 1)._eval_is_meromorphic(x, 0) == False
  134. assert lowergamma(0, 1/x)._eval_is_meromorphic(x, 0) == False
  135. assert lowergamma(S(1)/3, 1/x)._eval_is_meromorphic(x, 0) == False
  136. assert lowergamma(1, 1/x, evaluate=False)._eval_is_meromorphic(x, 0) == False
  137. assert lowergamma(x, 1/x)._eval_is_meromorphic(x, 0) == False
  138. assert lowergamma(x + 1, 1/x)._eval_is_meromorphic(x, 0) == False
  139. assert lowergamma(1/x, 1/x)._eval_is_meromorphic(x, 0) == False
  140. assert lowergamma(x, 2).series(x, oo, 3) == \
  141. 2**x*(1 + 2/(x + 1))*exp(-2)/x + O(exp(x*log(2))/x**3, (x, oo))
  142. assert lowergamma(
  143. x, y).rewrite(expint) == -y**x*expint(-x + 1, y) + gamma(x)
  144. k = Symbol('k', integer=True)
  145. assert lowergamma(
  146. k, y).rewrite(expint) == -y**k*expint(-k + 1, y) + gamma(k)
  147. k = Symbol('k', integer=True, positive=False)
  148. assert lowergamma(k, y).rewrite(expint) == lowergamma(k, y)
  149. assert lowergamma(x, y).rewrite(uppergamma) == gamma(x) - uppergamma(x, y)
  150. assert lowergamma(70, 6) == factorial(69) - 69035724522603011058660187038367026272747334489677105069435923032634389419656200387949342530805432320 * exp(-6)
  151. assert (lowergamma(S(77) / 2, 6) - lowergamma(S(77) / 2, 6, evaluate=False)).evalf() < 1e-16
  152. assert (lowergamma(-S(77) / 2, 6) - lowergamma(-S(77) / 2, 6, evaluate=False)).evalf() < 1e-16
  153. def test_uppergamma():
  154. from sympy.functions.special.error_functions import expint
  155. from sympy.functions.special.hyper import meijerg
  156. assert uppergamma(4, 0) == 6
  157. assert uppergamma(x, y).diff(y) == -y**(x - 1)*exp(-y)
  158. assert td(uppergamma(randcplx(), y), y)
  159. assert uppergamma(x, y).diff(x) == \
  160. uppergamma(x, y)*log(y) + meijerg([], [1, 1], [0, 0, x], [], y)
  161. assert td(uppergamma(x, randcplx()), x)
  162. p = Symbol('p', positive=True)
  163. assert uppergamma(0, p) == -Ei(-p)
  164. assert uppergamma(p, 0) == gamma(p)
  165. assert uppergamma(S.Half, x) == sqrt(pi)*erfc(sqrt(x))
  166. assert not uppergamma(S.Half - 3, x).has(uppergamma)
  167. assert not uppergamma(S.Half + 3, x).has(uppergamma)
  168. assert uppergamma(S.Half, x, evaluate=False).has(uppergamma)
  169. assert tn(uppergamma(S.Half + 3, x, evaluate=False),
  170. uppergamma(S.Half + 3, x), x)
  171. assert tn(uppergamma(S.Half - 3, x, evaluate=False),
  172. uppergamma(S.Half - 3, x), x)
  173. assert unchanged(uppergamma, x, -oo)
  174. assert unchanged(uppergamma, x, 0)
  175. assert tn_branch(-3, uppergamma)
  176. assert tn_branch(-4, uppergamma)
  177. assert tn_branch(Rational(1, 3), uppergamma)
  178. assert tn_branch(pi, uppergamma)
  179. assert uppergamma(3, exp_polar(4*pi*I)*x) == uppergamma(3, x)
  180. assert uppergamma(y, exp_polar(5*pi*I)*x) == \
  181. exp(4*I*pi*y)*uppergamma(y, x*exp_polar(pi*I)) + \
  182. gamma(y)*(1 - exp(4*pi*I*y))
  183. assert uppergamma(-2, exp_polar(5*pi*I)*x) == \
  184. uppergamma(-2, x*exp_polar(I*pi)) - 2*pi*I
  185. assert uppergamma(-2, x) == expint(3, x)/x**2
  186. assert conjugate(uppergamma(x, y)) == uppergamma(conjugate(x), conjugate(y))
  187. assert unchanged(conjugate, uppergamma(x, -oo))
  188. assert uppergamma(x, y).rewrite(expint) == y**x*expint(-x + 1, y)
  189. assert uppergamma(x, y).rewrite(lowergamma) == gamma(x) - lowergamma(x, y)
  190. assert uppergamma(70, 6) == 69035724522603011058660187038367026272747334489677105069435923032634389419656200387949342530805432320*exp(-6)
  191. assert (uppergamma(S(77) / 2, 6) - uppergamma(S(77) / 2, 6, evaluate=False)).evalf() < 1e-16
  192. assert (uppergamma(-S(77) / 2, 6) - uppergamma(-S(77) / 2, 6, evaluate=False)).evalf() < 1e-16
  193. def test_polygamma():
  194. assert polygamma(n, nan) is nan
  195. assert polygamma(0, oo) is oo
  196. assert polygamma(0, -oo) is oo
  197. assert polygamma(0, I*oo) is oo
  198. assert polygamma(0, -I*oo) is oo
  199. assert polygamma(1, oo) == 0
  200. assert polygamma(5, oo) == 0
  201. assert polygamma(0, -9) is zoo
  202. assert polygamma(0, -9) is zoo
  203. assert polygamma(0, -1) is zoo
  204. assert polygamma(Rational(3, 2), -1) is zoo
  205. assert polygamma(0, 0) is zoo
  206. assert polygamma(0, 1) == -EulerGamma
  207. assert polygamma(0, 7) == Rational(49, 20) - EulerGamma
  208. assert polygamma(1, 1) == pi**2/6
  209. assert polygamma(1, 2) == pi**2/6 - 1
  210. assert polygamma(1, 3) == pi**2/6 - Rational(5, 4)
  211. assert polygamma(3, 1) == pi**4 / 15
  212. assert polygamma(3, 5) == 6*(Rational(-22369, 20736) + pi**4/90)
  213. assert polygamma(5, 1) == 8 * pi**6 / 63
  214. assert polygamma(1, S.Half) == pi**2 / 2
  215. assert polygamma(2, S.Half) == -14*zeta(3)
  216. assert polygamma(11, S.Half) == 176896*pi**12
  217. def t(m, n):
  218. x = S(m)/n
  219. r = polygamma(0, x)
  220. if r.has(polygamma):
  221. return False
  222. return abs(polygamma(0, x.n()).n() - r.n()).n() < 1e-10
  223. assert t(1, 2)
  224. assert t(3, 2)
  225. assert t(-1, 2)
  226. assert t(1, 4)
  227. assert t(-3, 4)
  228. assert t(1, 3)
  229. assert t(4, 3)
  230. assert t(3, 4)
  231. assert t(2, 3)
  232. assert t(123, 5)
  233. assert polygamma(0, x).rewrite(zeta) == polygamma(0, x)
  234. assert polygamma(1, x).rewrite(zeta) == zeta(2, x)
  235. assert polygamma(2, x).rewrite(zeta) == -2*zeta(3, x)
  236. assert polygamma(I, 2).rewrite(zeta) == polygamma(I, 2)
  237. n1 = Symbol('n1')
  238. n2 = Symbol('n2', real=True)
  239. n3 = Symbol('n3', integer=True)
  240. n4 = Symbol('n4', positive=True)
  241. n5 = Symbol('n5', positive=True, integer=True)
  242. assert polygamma(n1, x).rewrite(zeta) == polygamma(n1, x)
  243. assert polygamma(n2, x).rewrite(zeta) == polygamma(n2, x)
  244. assert polygamma(n3, x).rewrite(zeta) == polygamma(n3, x)
  245. assert polygamma(n4, x).rewrite(zeta) == polygamma(n4, x)
  246. assert polygamma(n5, x).rewrite(zeta) == (-1)**(n5 + 1) * factorial(n5) * zeta(n5 + 1, x)
  247. assert polygamma(3, 7*x).diff(x) == 7*polygamma(4, 7*x)
  248. assert polygamma(0, x).rewrite(harmonic) == harmonic(x - 1) - EulerGamma
  249. assert polygamma(2, x).rewrite(harmonic) == 2*harmonic(x - 1, 3) - 2*zeta(3)
  250. ni = Symbol("n", integer=True)
  251. assert polygamma(ni, x).rewrite(harmonic) == (-1)**(ni + 1)*(-harmonic(x - 1, ni + 1)
  252. + zeta(ni + 1))*factorial(ni)
  253. # Polygamma of non-negative integer order is unbranched:
  254. k = Symbol('n', integer=True, nonnegative=True)
  255. assert polygamma(k, exp_polar(2*I*pi)*x) == polygamma(k, x)
  256. # but negative integers are branched!
  257. k = Symbol('n', integer=True)
  258. assert polygamma(k, exp_polar(2*I*pi)*x).args == (k, exp_polar(2*I*pi)*x)
  259. # Polygamma of order -1 is loggamma:
  260. assert polygamma(-1, x) == loggamma(x) - log(2*pi) / 2
  261. # But smaller orders are iterated integrals and don't have a special name
  262. assert polygamma(-2, x).func is polygamma
  263. # Test a bug
  264. assert polygamma(0, -x).expand(func=True) == polygamma(0, -x)
  265. assert polygamma(2, 2.5).is_positive == False
  266. assert polygamma(2, -2.5).is_positive == False
  267. assert polygamma(3, 2.5).is_positive == True
  268. assert polygamma(3, -2.5).is_positive is True
  269. assert polygamma(-2, -2.5).is_positive is None
  270. assert polygamma(-3, -2.5).is_positive is None
  271. assert polygamma(2, 2.5).is_negative == True
  272. assert polygamma(3, 2.5).is_negative == False
  273. assert polygamma(3, -2.5).is_negative == False
  274. assert polygamma(2, -2.5).is_negative is True
  275. assert polygamma(-2, -2.5).is_negative is None
  276. assert polygamma(-3, -2.5).is_negative is None
  277. assert polygamma(I, 2).is_positive is None
  278. assert polygamma(I, 3).is_negative is None
  279. # issue 17350
  280. assert (I*polygamma(I, pi)).as_real_imag() == \
  281. (-im(polygamma(I, pi)), re(polygamma(I, pi)))
  282. assert (tanh(polygamma(I, 1))).rewrite(exp) == \
  283. (exp(polygamma(I, 1)) - exp(-polygamma(I, 1)))/(exp(polygamma(I, 1)) + exp(-polygamma(I, 1)))
  284. assert (I / polygamma(I, 4)).rewrite(exp) == \
  285. I*exp(-I*atan(im(polygamma(I, 4))/re(polygamma(I, 4))))/Abs(polygamma(I, 4))
  286. # issue 12569
  287. assert unchanged(im, polygamma(0, I))
  288. assert polygamma(Symbol('a', positive=True), Symbol('b', positive=True)).is_real is True
  289. assert polygamma(0, I).is_real is None
  290. assert str(polygamma(pi, 3).evalf(n=10)) == "0.1169314564"
  291. assert str(polygamma(2.3, 1.0).evalf(n=10)) == "-3.003302909"
  292. assert str(polygamma(-1, 1).evalf(n=10)) == "-0.9189385332" # not zero
  293. assert str(polygamma(I, 1).evalf(n=10)) == "-3.109856569 + 1.89089016*I"
  294. assert str(polygamma(1, I).evalf(n=10)) == "-0.5369999034 - 0.7942335428*I"
  295. assert str(polygamma(I, I).evalf(n=10)) == "6.332362889 + 45.92828268*I"
  296. def test_polygamma_expand_func():
  297. assert polygamma(0, x).expand(func=True) == polygamma(0, x)
  298. assert polygamma(0, 2*x).expand(func=True) == \
  299. polygamma(0, x)/2 + polygamma(0, S.Half + x)/2 + log(2)
  300. assert polygamma(1, 2*x).expand(func=True) == \
  301. polygamma(1, x)/4 + polygamma(1, S.Half + x)/4
  302. assert polygamma(2, x).expand(func=True) == \
  303. polygamma(2, x)
  304. assert polygamma(0, -1 + x).expand(func=True) == \
  305. polygamma(0, x) - 1/(x - 1)
  306. assert polygamma(0, 1 + x).expand(func=True) == \
  307. 1/x + polygamma(0, x )
  308. assert polygamma(0, 2 + x).expand(func=True) == \
  309. 1/x + 1/(1 + x) + polygamma(0, x)
  310. assert polygamma(0, 3 + x).expand(func=True) == \
  311. polygamma(0, x) + 1/x + 1/(1 + x) + 1/(2 + x)
  312. assert polygamma(0, 4 + x).expand(func=True) == \
  313. polygamma(0, x) + 1/x + 1/(1 + x) + 1/(2 + x) + 1/(3 + x)
  314. assert polygamma(1, 1 + x).expand(func=True) == \
  315. polygamma(1, x) - 1/x**2
  316. assert polygamma(1, 2 + x).expand(func=True, multinomial=False) == \
  317. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2
  318. assert polygamma(1, 3 + x).expand(func=True, multinomial=False) == \
  319. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2 - 1/(2 + x)**2
  320. assert polygamma(1, 4 + x).expand(func=True, multinomial=False) == \
  321. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2 - \
  322. 1/(2 + x)**2 - 1/(3 + x)**2
  323. assert polygamma(0, x + y).expand(func=True) == \
  324. polygamma(0, x + y)
  325. assert polygamma(1, x + y).expand(func=True) == \
  326. polygamma(1, x + y)
  327. assert polygamma(1, 3 + 4*x + y).expand(func=True, multinomial=False) == \
  328. polygamma(1, y + 4*x) - 1/(y + 4*x)**2 - \
  329. 1/(1 + y + 4*x)**2 - 1/(2 + y + 4*x)**2
  330. assert polygamma(3, 3 + 4*x + y).expand(func=True, multinomial=False) == \
  331. polygamma(3, y + 4*x) - 6/(y + 4*x)**4 - \
  332. 6/(1 + y + 4*x)**4 - 6/(2 + y + 4*x)**4
  333. assert polygamma(3, 4*x + y + 1).expand(func=True, multinomial=False) == \
  334. polygamma(3, y + 4*x) - 6/(y + 4*x)**4
  335. e = polygamma(3, 4*x + y + Rational(3, 2))
  336. assert e.expand(func=True) == e
  337. e = polygamma(3, x + y + Rational(3, 4))
  338. assert e.expand(func=True, basic=False) == e
  339. assert polygamma(-1, x, evaluate=False).expand(func=True) == \
  340. loggamma(x) - log(pi)/2 - log(2)/2
  341. p2 = polygamma(-2, x).expand(func=True) + x**2/2 - x/2 + S(1)/12
  342. assert isinstance(p2, Subs)
  343. assert p2.point == (-1,)
  344. def test_digamma():
  345. assert digamma(nan) == nan
  346. assert digamma(oo) == oo
  347. assert digamma(-oo) == oo
  348. assert digamma(I*oo) == oo
  349. assert digamma(-I*oo) == oo
  350. assert digamma(-9) == zoo
  351. assert digamma(-9) == zoo
  352. assert digamma(-1) == zoo
  353. assert digamma(0) == zoo
  354. assert digamma(1) == -EulerGamma
  355. assert digamma(7) == Rational(49, 20) - EulerGamma
  356. def t(m, n):
  357. x = S(m)/n
  358. r = digamma(x)
  359. if r.has(digamma):
  360. return False
  361. return abs(digamma(x.n()).n() - r.n()).n() < 1e-10
  362. assert t(1, 2)
  363. assert t(3, 2)
  364. assert t(-1, 2)
  365. assert t(1, 4)
  366. assert t(-3, 4)
  367. assert t(1, 3)
  368. assert t(4, 3)
  369. assert t(3, 4)
  370. assert t(2, 3)
  371. assert t(123, 5)
  372. assert digamma(x).rewrite(zeta) == polygamma(0, x)
  373. assert digamma(x).rewrite(harmonic) == harmonic(x - 1) - EulerGamma
  374. assert digamma(I).is_real is None
  375. assert digamma(x,evaluate=False).fdiff() == polygamma(1, x)
  376. assert digamma(x,evaluate=False).is_real is None
  377. assert digamma(x,evaluate=False).is_positive is None
  378. assert digamma(x,evaluate=False).is_negative is None
  379. assert digamma(x,evaluate=False).rewrite(polygamma) == polygamma(0, x)
  380. def test_digamma_expand_func():
  381. assert digamma(x).expand(func=True) == polygamma(0, x)
  382. assert digamma(2*x).expand(func=True) == \
  383. polygamma(0, x)/2 + polygamma(0, Rational(1, 2) + x)/2 + log(2)
  384. assert digamma(-1 + x).expand(func=True) == \
  385. polygamma(0, x) - 1/(x - 1)
  386. assert digamma(1 + x).expand(func=True) == \
  387. 1/x + polygamma(0, x )
  388. assert digamma(2 + x).expand(func=True) == \
  389. 1/x + 1/(1 + x) + polygamma(0, x)
  390. assert digamma(3 + x).expand(func=True) == \
  391. polygamma(0, x) + 1/x + 1/(1 + x) + 1/(2 + x)
  392. assert digamma(4 + x).expand(func=True) == \
  393. polygamma(0, x) + 1/x + 1/(1 + x) + 1/(2 + x) + 1/(3 + x)
  394. assert digamma(x + y).expand(func=True) == \
  395. polygamma(0, x + y)
  396. def test_trigamma():
  397. assert trigamma(nan) == nan
  398. assert trigamma(oo) == 0
  399. assert trigamma(1) == pi**2/6
  400. assert trigamma(2) == pi**2/6 - 1
  401. assert trigamma(3) == pi**2/6 - Rational(5, 4)
  402. assert trigamma(x, evaluate=False).rewrite(zeta) == zeta(2, x)
  403. assert trigamma(x, evaluate=False).rewrite(harmonic) == \
  404. trigamma(x).rewrite(polygamma).rewrite(harmonic)
  405. assert trigamma(x,evaluate=False).fdiff() == polygamma(2, x)
  406. assert trigamma(x,evaluate=False).is_real is None
  407. assert trigamma(x,evaluate=False).is_positive is None
  408. assert trigamma(x,evaluate=False).is_negative is None
  409. assert trigamma(x,evaluate=False).rewrite(polygamma) == polygamma(1, x)
  410. def test_trigamma_expand_func():
  411. assert trigamma(2*x).expand(func=True) == \
  412. polygamma(1, x)/4 + polygamma(1, Rational(1, 2) + x)/4
  413. assert trigamma(1 + x).expand(func=True) == \
  414. polygamma(1, x) - 1/x**2
  415. assert trigamma(2 + x).expand(func=True, multinomial=False) == \
  416. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2
  417. assert trigamma(3 + x).expand(func=True, multinomial=False) == \
  418. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2 - 1/(2 + x)**2
  419. assert trigamma(4 + x).expand(func=True, multinomial=False) == \
  420. polygamma(1, x) - 1/x**2 - 1/(1 + x)**2 - \
  421. 1/(2 + x)**2 - 1/(3 + x)**2
  422. assert trigamma(x + y).expand(func=True) == \
  423. polygamma(1, x + y)
  424. assert trigamma(3 + 4*x + y).expand(func=True, multinomial=False) == \
  425. polygamma(1, y + 4*x) - 1/(y + 4*x)**2 - \
  426. 1/(1 + y + 4*x)**2 - 1/(2 + y + 4*x)**2
  427. def test_loggamma():
  428. raises(TypeError, lambda: loggamma(2, 3))
  429. raises(ArgumentIndexError, lambda: loggamma(x).fdiff(2))
  430. assert loggamma(-1) is oo
  431. assert loggamma(-2) is oo
  432. assert loggamma(0) is oo
  433. assert loggamma(1) == 0
  434. assert loggamma(2) == 0
  435. assert loggamma(3) == log(2)
  436. assert loggamma(4) == log(6)
  437. n = Symbol("n", integer=True, positive=True)
  438. assert loggamma(n) == log(gamma(n))
  439. assert loggamma(-n) is oo
  440. assert loggamma(n/2) == log(2**(-n + 1)*sqrt(pi)*gamma(n)/gamma(n/2 + S.Half))
  441. assert loggamma(oo) is oo
  442. assert loggamma(-oo) is zoo
  443. assert loggamma(I*oo) is zoo
  444. assert loggamma(-I*oo) is zoo
  445. assert loggamma(zoo) is zoo
  446. assert loggamma(nan) is nan
  447. L = loggamma(Rational(16, 3))
  448. E = -5*log(3) + loggamma(Rational(1, 3)) + log(4) + log(7) + log(10) + log(13)
  449. assert expand_func(L).doit() == E
  450. assert L.n() == E.n()
  451. L = loggamma(Rational(19, 4))
  452. E = -4*log(4) + loggamma(Rational(3, 4)) + log(3) + log(7) + log(11) + log(15)
  453. assert expand_func(L).doit() == E
  454. assert L.n() == E.n()
  455. L = loggamma(Rational(23, 7))
  456. E = -3*log(7) + log(2) + loggamma(Rational(2, 7)) + log(9) + log(16)
  457. assert expand_func(L).doit() == E
  458. assert L.n() == E.n()
  459. L = loggamma(Rational(19, 4) - 7)
  460. E = -log(9) - log(5) + loggamma(Rational(3, 4)) + 3*log(4) - 3*I*pi
  461. assert expand_func(L).doit() == E
  462. assert L.n() == E.n()
  463. L = loggamma(Rational(23, 7) - 6)
  464. E = -log(19) - log(12) - log(5) + loggamma(Rational(2, 7)) + 3*log(7) - 3*I*pi
  465. assert expand_func(L).doit() == E
  466. assert L.n() == E.n()
  467. assert loggamma(x).diff(x) == polygamma(0, x)
  468. s1 = loggamma(1/(x + sin(x)) + cos(x)).nseries(x, n=4)
  469. s2 = (-log(2*x) - 1)/(2*x) - log(x/pi)/2 + (4 - log(2*x))*x/24 + O(x**2) + \
  470. log(x)*x**2/2
  471. assert (s1 - s2).expand(force=True).removeO() == 0
  472. s1 = loggamma(1/x).series(x)
  473. s2 = (1/x - S.Half)*log(1/x) - 1/x + log(2*pi)/2 + \
  474. x/12 - x**3/360 + x**5/1260 + O(x**7)
  475. assert ((s1 - s2).expand(force=True)).removeO() == 0
  476. assert loggamma(x).rewrite('intractable') == log(gamma(x))
  477. s1 = loggamma(x).series(x).cancel()
  478. assert s1 == -log(x) - EulerGamma*x + pi**2*x**2/12 + x**3*polygamma(2, 1)/6 + \
  479. pi**4*x**4/360 + x**5*polygamma(4, 1)/120 + O(x**6)
  480. assert s1 == loggamma(x).rewrite('intractable').series(x).cancel()
  481. assert conjugate(loggamma(x)) == loggamma(conjugate(x))
  482. assert conjugate(loggamma(0)) is oo
  483. assert conjugate(loggamma(1)) == loggamma(conjugate(1))
  484. assert conjugate(loggamma(-oo)) == conjugate(zoo)
  485. assert loggamma(Symbol('v', positive=True)).is_real is True
  486. assert loggamma(Symbol('v', zero=True)).is_real is False
  487. assert loggamma(Symbol('v', negative=True)).is_real is False
  488. assert loggamma(Symbol('v', nonpositive=True)).is_real is False
  489. assert loggamma(Symbol('v', nonnegative=True)).is_real is None
  490. assert loggamma(Symbol('v', imaginary=True)).is_real is None
  491. assert loggamma(Symbol('v', real=True)).is_real is None
  492. assert loggamma(Symbol('v')).is_real is None
  493. assert loggamma(S.Half).is_real is True
  494. assert loggamma(0).is_real is False
  495. assert loggamma(Rational(-1, 2)).is_real is False
  496. assert loggamma(I).is_real is None
  497. assert loggamma(2 + 3*I).is_real is None
  498. def tN(N, M):
  499. assert loggamma(1/x)._eval_nseries(x, n=N).getn() == M
  500. tN(0, 0)
  501. tN(1, 1)
  502. tN(2, 2)
  503. tN(3, 3)
  504. tN(4, 4)
  505. tN(5, 5)
  506. def test_polygamma_expansion():
  507. # A. & S., pa. 259 and 260
  508. assert polygamma(0, 1/x).nseries(x, n=3) == \
  509. -log(x) - x/2 - x**2/12 + O(x**3)
  510. assert polygamma(1, 1/x).series(x, n=5) == \
  511. x + x**2/2 + x**3/6 + O(x**5)
  512. assert polygamma(3, 1/x).nseries(x, n=11) == \
  513. 2*x**3 + 3*x**4 + 2*x**5 - x**7 + 4*x**9/3 + O(x**11)
  514. def test_polygamma_leading_term():
  515. expr = -log(1/x) + polygamma(0, 1 + 1/x) + S.EulerGamma
  516. assert expr.as_leading_term(x, logx=-y) == S.EulerGamma
  517. def test_issue_8657():
  518. n = Symbol('n', negative=True, integer=True)
  519. m = Symbol('m', integer=True)
  520. o = Symbol('o', positive=True)
  521. p = Symbol('p', negative=True, integer=False)
  522. assert gamma(n).is_real is False
  523. assert gamma(m).is_real is None
  524. assert gamma(o).is_real is True
  525. assert gamma(p).is_real is True
  526. assert gamma(w).is_real is None
  527. def test_issue_8524():
  528. x = Symbol('x', positive=True)
  529. y = Symbol('y', negative=True)
  530. z = Symbol('z', positive=False)
  531. p = Symbol('p', negative=False)
  532. q = Symbol('q', integer=True)
  533. r = Symbol('r', integer=False)
  534. e = Symbol('e', even=True, negative=True)
  535. assert gamma(x).is_positive is True
  536. assert gamma(y).is_positive is None
  537. assert gamma(z).is_positive is None
  538. assert gamma(p).is_positive is None
  539. assert gamma(q).is_positive is None
  540. assert gamma(r).is_positive is None
  541. assert gamma(e + S.Half).is_positive is True
  542. assert gamma(e - S.Half).is_positive is False
  543. def test_issue_14450():
  544. assert uppergamma(Rational(3, 8), x).evalf() == uppergamma(Rational(3, 8), x)
  545. assert lowergamma(x, Rational(3, 8)).evalf() == lowergamma(x, Rational(3, 8))
  546. # some values from Wolfram Alpha for comparison
  547. assert abs(uppergamma(Rational(3, 8), 2).evalf() - 0.07105675881) < 1e-9
  548. assert abs(lowergamma(Rational(3, 8), 2).evalf() - 2.2993794256) < 1e-9
  549. def test_issue_14528():
  550. k = Symbol('k', integer=True, nonpositive=True)
  551. assert isinstance(gamma(k), gamma)
  552. def test_multigamma():
  553. from sympy.concrete.products import Product
  554. p = Symbol('p')
  555. _k = Dummy('_k')
  556. assert multigamma(x, p).dummy_eq(pi**(p*(p - 1)/4)*\
  557. Product(gamma(x + (1 - _k)/2), (_k, 1, p)))
  558. assert conjugate(multigamma(x, p)).dummy_eq(pi**((conjugate(p) - 1)*\
  559. conjugate(p)/4)*Product(gamma(conjugate(x) + (1-conjugate(_k))/2), (_k, 1, p)))
  560. assert conjugate(multigamma(x, 1)) == gamma(conjugate(x))
  561. p = Symbol('p', positive=True)
  562. assert conjugate(multigamma(x, p)).dummy_eq(pi**((p - 1)*p/4)*\
  563. Product(gamma(conjugate(x) + (1-conjugate(_k))/2), (_k, 1, p)))
  564. assert multigamma(nan, 1) is nan
  565. assert multigamma(oo, 1).doit() is oo
  566. assert multigamma(1, 1) == 1
  567. assert multigamma(2, 1) == 1
  568. assert multigamma(3, 1) == 2
  569. assert multigamma(102, 1) == factorial(101)
  570. assert multigamma(S.Half, 1) == sqrt(pi)
  571. assert multigamma(1, 2) == pi
  572. assert multigamma(2, 2) == pi/2
  573. assert multigamma(1, 3) is zoo
  574. assert multigamma(2, 3) == pi**2/2
  575. assert multigamma(3, 3) == 3*pi**2/2
  576. assert multigamma(x, 1).diff(x) == gamma(x)*polygamma(0, x)
  577. assert multigamma(x, 2).diff(x) == sqrt(pi)*gamma(x)*gamma(x - S.Half)*\
  578. polygamma(0, x) + sqrt(pi)*gamma(x)*gamma(x - S.Half)*polygamma(0, x - S.Half)
  579. assert multigamma(x - 1, 1).expand(func=True) == gamma(x)/(x - 1)
  580. assert multigamma(x + 2, 1).expand(func=True, mul=False) == x*(x + 1)*\
  581. gamma(x)
  582. assert multigamma(x - 1, 2).expand(func=True) == sqrt(pi)*gamma(x)*\
  583. gamma(x + S.Half)/(x**3 - 3*x**2 + x*Rational(11, 4) - Rational(3, 4))
  584. assert multigamma(x - 1, 3).expand(func=True) == pi**Rational(3, 2)*gamma(x)**2*\
  585. gamma(x + S.Half)/(x**5 - 6*x**4 + 55*x**3/4 - 15*x**2 + x*Rational(31, 4) - Rational(3, 2))
  586. assert multigamma(n, 1).rewrite(factorial) == factorial(n - 1)
  587. assert multigamma(n, 2).rewrite(factorial) == sqrt(pi)*\
  588. factorial(n - Rational(3, 2))*factorial(n - 1)
  589. assert multigamma(n, 3).rewrite(factorial) == pi**Rational(3, 2)*\
  590. factorial(n - 2)*factorial(n - Rational(3, 2))*factorial(n - 1)
  591. assert multigamma(Rational(-1, 2), 3, evaluate=False).is_real == False
  592. assert multigamma(S.Half, 3, evaluate=False).is_real == False
  593. assert multigamma(0, 1, evaluate=False).is_real == False
  594. assert multigamma(1, 3, evaluate=False).is_real == False
  595. assert multigamma(-1.0, 3, evaluate=False).is_real == False
  596. assert multigamma(0.7, 3, evaluate=False).is_real == True
  597. assert multigamma(3, 3, evaluate=False).is_real == True
  598. def test_gamma_as_leading_term():
  599. assert gamma(x).as_leading_term(x) == 1/x
  600. assert gamma(2 + x).as_leading_term(x) == S(1)
  601. assert gamma(cos(x)).as_leading_term(x) == S(1)
  602. assert gamma(sin(x)).as_leading_term(x) == 1/x