test_cosine_distr.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import numpy as np
  2. from numpy.testing import assert_allclose
  3. import pytest
  4. from scipy.special._ufuncs import _cosine_cdf, _cosine_invcdf
  5. # These values are (x, p) where p is the expected exact value of
  6. # _cosine_cdf(x). These values will be tested for exact agreement.
  7. _coscdf_exact = [
  8. (-4.0, 0.0),
  9. (0, 0.5),
  10. (np.pi, 1.0),
  11. (4.0, 1.0),
  12. ]
  13. @pytest.mark.parametrize("x, expected", _coscdf_exact)
  14. def test_cosine_cdf_exact(x, expected):
  15. assert _cosine_cdf(x) == expected
  16. # These values are (x, p), where p is the expected value of
  17. # _cosine_cdf(x). The expected values were computed with mpmath using
  18. # 50 digits of precision. These values will be tested for agreement
  19. # with the computed values using a very small relative tolerance.
  20. # The value at -np.pi is not 0, because -np.pi does not equal -π.
  21. _coscdf_close = [
  22. (3.1409, 0.999999999991185),
  23. (2.25, 0.9819328173287907),
  24. # -1.6 is the threshold below which the Pade approximant is used.
  25. (-1.599, 0.08641959838382553),
  26. (-1.601, 0.086110582992713),
  27. (-2.0, 0.0369709335961611),
  28. (-3.0, 7.522387241801384e-05),
  29. (-3.1415, 2.109869685443648e-14),
  30. (-3.14159, 4.956444476505336e-19),
  31. (-np.pi, 4.871934450264861e-50),
  32. ]
  33. @pytest.mark.parametrize("x, expected", _coscdf_close)
  34. def test_cosine_cdf(x, expected):
  35. assert_allclose(_cosine_cdf(x), expected, rtol=5e-15)
  36. # These values are (p, x) where x is the expected exact value of
  37. # _cosine_invcdf(p). These values will be tested for exact agreement.
  38. _cosinvcdf_exact = [
  39. (0.0, -np.pi),
  40. (0.5, 0.0),
  41. (1.0, np.pi),
  42. ]
  43. @pytest.mark.parametrize("p, expected", _cosinvcdf_exact)
  44. def test_cosine_invcdf_exact(p, expected):
  45. assert _cosine_invcdf(p) == expected
  46. def test_cosine_invcdf_invalid_p():
  47. # Check that p values outside of [0, 1] return nan.
  48. assert np.isnan(_cosine_invcdf([-0.1, 1.1])).all()
  49. # These values are (p, x), where x is the expected value of _cosine_invcdf(p).
  50. # The expected values were computed with mpmath using 50 digits of precision.
  51. _cosinvcdf_close = [
  52. (1e-50, -np.pi),
  53. (1e-14, -3.1415204137058454),
  54. (1e-08, -3.1343686589124524),
  55. (0.0018001, -2.732563923138336),
  56. (0.010, -2.41276589008678),
  57. (0.060, -1.7881244975330157),
  58. (0.125, -1.3752523669869274),
  59. (0.250, -0.831711193579736),
  60. (0.400, -0.3167954512395289),
  61. (0.419, -0.25586025626919906),
  62. (0.421, -0.24947570750445663),
  63. (0.750, 0.831711193579736),
  64. (0.940, 1.7881244975330153),
  65. (0.9999999996, 3.1391220839917167),
  66. ]
  67. @pytest.mark.parametrize("p, expected", _cosinvcdf_close)
  68. def test_cosine_invcdf(p, expected):
  69. assert_allclose(_cosine_invcdf(p), expected, rtol=1e-14)