test_precompute_gammainc.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. from __future__ import division, print_function, absolute_import
  2. import numpy as np
  3. import pytest
  4. from scipy.special._testutils import MissingModule, check_version
  5. from scipy.special._mptestutils import (
  6. Arg, IntArg, mp_assert_allclose, assert_mpmath_equal)
  7. from scipy.special._precompute.gammainc_asy import (
  8. compute_g, compute_alpha, compute_d)
  9. from scipy.special._precompute.gammainc_data import gammainc, gammaincc
  10. try:
  11. import sympy
  12. except ImportError:
  13. sympy = MissingModule('sympy')
  14. try:
  15. import mpmath as mp
  16. except ImportError:
  17. mp = MissingModule('mpmath')
  18. _is_32bit_platform = np.intp(0).itemsize < 8
  19. @check_version(mp, '0.19')
  20. def test_g():
  21. # Test data for the g_k. See DLMF 5.11.4.
  22. with mp.workdps(30):
  23. g = [mp.mpf(1), mp.mpf(1)/12, mp.mpf(1)/288,
  24. -mp.mpf(139)/51840, -mp.mpf(571)/2488320,
  25. mp.mpf(163879)/209018880, mp.mpf(5246819)/75246796800]
  26. mp_assert_allclose(compute_g(7), g)
  27. @pytest.mark.slow
  28. @check_version(mp, '0.19')
  29. @check_version(sympy, '0.7')
  30. @pytest.mark.xfail(condition=_is_32bit_platform, reason="rtol only 2e-11, see gh-6938")
  31. def test_alpha():
  32. # Test data for the alpha_k. See DLMF 8.12.14.
  33. with mp.workdps(30):
  34. alpha = [mp.mpf(0), mp.mpf(1), mp.mpf(1)/3, mp.mpf(1)/36,
  35. -mp.mpf(1)/270, mp.mpf(1)/4320, mp.mpf(1)/17010,
  36. -mp.mpf(139)/5443200, mp.mpf(1)/204120]
  37. mp_assert_allclose(compute_alpha(9), alpha)
  38. @pytest.mark.xslow
  39. @check_version(mp, '0.19')
  40. @check_version(sympy, '0.7')
  41. def test_d():
  42. # Compare the d_{k, n} to the results in appendix F of [1].
  43. #
  44. # Sources
  45. # -------
  46. # [1] DiDonato and Morris, Computation of the Incomplete Gamma
  47. # Function Ratios and their Inverse, ACM Transactions on
  48. # Mathematical Software, 1986.
  49. with mp.workdps(50):
  50. dataset = [(0, 0, -mp.mpf('0.333333333333333333333333333333')),
  51. (0, 12, mp.mpf('0.102618097842403080425739573227e-7')),
  52. (1, 0, -mp.mpf('0.185185185185185185185185185185e-2')),
  53. (1, 12, mp.mpf('0.119516285997781473243076536700e-7')),
  54. (2, 0, mp.mpf('0.413359788359788359788359788360e-2')),
  55. (2, 12, -mp.mpf('0.140925299108675210532930244154e-7')),
  56. (3, 0, mp.mpf('0.649434156378600823045267489712e-3')),
  57. (3, 12, -mp.mpf('0.191111684859736540606728140873e-7')),
  58. (4, 0, -mp.mpf('0.861888290916711698604702719929e-3')),
  59. (4, 12, mp.mpf('0.288658297427087836297341274604e-7')),
  60. (5, 0, -mp.mpf('0.336798553366358150308767592718e-3')),
  61. (5, 12, mp.mpf('0.482409670378941807563762631739e-7')),
  62. (6, 0, mp.mpf('0.531307936463992223165748542978e-3')),
  63. (6, 12, -mp.mpf('0.882860074633048352505085243179e-7')),
  64. (7, 0, mp.mpf('0.344367606892377671254279625109e-3')),
  65. (7, 12, -mp.mpf('0.175629733590604619378669693914e-6')),
  66. (8, 0, -mp.mpf('0.652623918595309418922034919727e-3')),
  67. (8, 12, mp.mpf('0.377358774161109793380344937299e-6')),
  68. (9, 0, -mp.mpf('0.596761290192746250124390067179e-3')),
  69. (9, 12, mp.mpf('0.870823417786464116761231237189e-6'))]
  70. d = compute_d(10, 13)
  71. res = []
  72. for k, n, std in dataset:
  73. res.append(d[k][n])
  74. std = map(lambda x: x[2], dataset)
  75. mp_assert_allclose(res, std)
  76. @check_version(mp, '0.19')
  77. def test_gammainc():
  78. # Quick check that the gammainc in
  79. # special._precompute.gammainc_data agrees with mpmath's
  80. # gammainc.
  81. assert_mpmath_equal(gammainc,
  82. lambda a, x: mp.gammainc(a, b=x, regularized=True),
  83. [Arg(0, 100, inclusive_a=False), Arg(0, 100)],
  84. nan_ok=False, rtol=1e-17, n=50, dps=50)
  85. @pytest.mark.xslow
  86. @check_version(mp, '0.19')
  87. def test_gammaincc():
  88. # Check that the gammaincc in special._precompute.gammainc_data
  89. # agrees with mpmath's gammainc.
  90. assert_mpmath_equal(lambda a, x: gammaincc(a, x, dps=1000),
  91. lambda a, x: mp.gammainc(a, a=x, regularized=True),
  92. [Arg(20, 100), Arg(20, 100)],
  93. nan_ok=False, rtol=1e-17, n=50, dps=1000)
  94. # Test the fast integer path
  95. assert_mpmath_equal(gammaincc,
  96. lambda a, x: mp.gammainc(a, a=x, regularized=True),
  97. [IntArg(1, 100), Arg(0, 100)],
  98. nan_ok=False, rtol=1e-17, n=50, dps=50)