test_wrightomega.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import pytest
  2. import numpy as np
  3. from numpy.testing import assert_, assert_equal, assert_allclose
  4. import scipy.special as sc
  5. from scipy.special._testutils import assert_func_equal
  6. def test_wrightomega_nan():
  7. pts = [complex(np.nan, 0),
  8. complex(0, np.nan),
  9. complex(np.nan, np.nan),
  10. complex(np.nan, 1),
  11. complex(1, np.nan)]
  12. for p in pts:
  13. res = sc.wrightomega(p)
  14. assert_(np.isnan(res.real))
  15. assert_(np.isnan(res.imag))
  16. def test_wrightomega_inf_branch():
  17. pts = [complex(-np.inf, np.pi/4),
  18. complex(-np.inf, -np.pi/4),
  19. complex(-np.inf, 3*np.pi/4),
  20. complex(-np.inf, -3*np.pi/4)]
  21. expected_results = [complex(0.0, 0.0),
  22. complex(0.0, -0.0),
  23. complex(-0.0, 0.0),
  24. complex(-0.0, -0.0)]
  25. for p, expected in zip(pts, expected_results):
  26. res = sc.wrightomega(p)
  27. # We can't use assert_equal(res, expected) because in older versions of
  28. # numpy, assert_equal doesn't check the sign of the real and imaginary
  29. # parts when comparing complex zeros. It does check the sign when the
  30. # arguments are *real* scalars.
  31. assert_equal(res.real, expected.real)
  32. assert_equal(res.imag, expected.imag)
  33. def test_wrightomega_inf():
  34. pts = [complex(np.inf, 10),
  35. complex(-np.inf, 10),
  36. complex(10, np.inf),
  37. complex(10, -np.inf)]
  38. for p in pts:
  39. assert_equal(sc.wrightomega(p), p)
  40. def test_wrightomega_singular():
  41. pts = [complex(-1.0, np.pi),
  42. complex(-1.0, -np.pi)]
  43. for p in pts:
  44. res = sc.wrightomega(p)
  45. assert_equal(res, -1.0)
  46. assert_(np.signbit(res.imag) == False)
  47. @pytest.mark.parametrize('x, desired', [
  48. (-np.inf, 0),
  49. (np.inf, np.inf),
  50. ])
  51. def test_wrightomega_real_infinities(x, desired):
  52. assert sc.wrightomega(x) == desired
  53. def test_wrightomega_real_nan():
  54. assert np.isnan(sc.wrightomega(np.nan))
  55. def test_wrightomega_real_series_crossover():
  56. desired_error = 2 * np.finfo(float).eps
  57. crossover = 1e20
  58. x_before_crossover = np.nextafter(crossover, -np.inf)
  59. x_after_crossover = np.nextafter(crossover, np.inf)
  60. # Computed using Mpmath
  61. desired_before_crossover = 99999999999999983569.948
  62. desired_after_crossover = 100000000000000016337.948
  63. assert_allclose(
  64. sc.wrightomega(x_before_crossover),
  65. desired_before_crossover,
  66. atol=0,
  67. rtol=desired_error,
  68. )
  69. assert_allclose(
  70. sc.wrightomega(x_after_crossover),
  71. desired_after_crossover,
  72. atol=0,
  73. rtol=desired_error,
  74. )
  75. def test_wrightomega_exp_approximation_crossover():
  76. desired_error = 2 * np.finfo(float).eps
  77. crossover = -50
  78. x_before_crossover = np.nextafter(crossover, np.inf)
  79. x_after_crossover = np.nextafter(crossover, -np.inf)
  80. # Computed using Mpmath
  81. desired_before_crossover = 1.9287498479639314876e-22
  82. desired_after_crossover = 1.9287498479639040784e-22
  83. assert_allclose(
  84. sc.wrightomega(x_before_crossover),
  85. desired_before_crossover,
  86. atol=0,
  87. rtol=desired_error,
  88. )
  89. assert_allclose(
  90. sc.wrightomega(x_after_crossover),
  91. desired_after_crossover,
  92. atol=0,
  93. rtol=desired_error,
  94. )
  95. def test_wrightomega_real_versus_complex():
  96. x = np.linspace(-500, 500, 1001)
  97. results = sc.wrightomega(x + 0j).real
  98. assert_func_equal(sc.wrightomega, results, x, atol=0, rtol=1e-14)