test_helper.py 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. from scipy.fft._helper import next_fast_len, _init_nd_shape_and_axes
  2. from numpy.testing import assert_equal, assert_array_equal
  3. from pytest import raises as assert_raises
  4. import pytest
  5. import numpy as np
  6. import sys
  7. _5_smooth_numbers = [
  8. 2, 3, 4, 5, 6, 8, 9, 10,
  9. 2 * 3 * 5,
  10. 2**3 * 3**5,
  11. 2**3 * 3**3 * 5**2,
  12. ]
  13. def test_next_fast_len():
  14. for n in _5_smooth_numbers:
  15. assert_equal(next_fast_len(n), n)
  16. def _assert_n_smooth(x, n):
  17. x_orig = x
  18. if n < 2:
  19. assert False
  20. while True:
  21. q, r = divmod(x, 2)
  22. if r != 0:
  23. break
  24. x = q
  25. for d in range(3, n+1, 2):
  26. while True:
  27. q, r = divmod(x, d)
  28. if r != 0:
  29. break
  30. x = q
  31. assert x == 1, \
  32. 'x={} is not {}-smooth, remainder={}'.format(x_orig, n, x)
  33. class TestNextFastLen:
  34. def test_next_fast_len(self):
  35. np.random.seed(1234)
  36. def nums():
  37. yield from range(1, 1000)
  38. yield 2**5 * 3**5 * 4**5 + 1
  39. for n in nums():
  40. m = next_fast_len(n)
  41. _assert_n_smooth(m, 11)
  42. assert m == next_fast_len(n, False)
  43. m = next_fast_len(n, True)
  44. _assert_n_smooth(m, 5)
  45. def test_np_integers(self):
  46. ITYPES = [np.int16, np.int32, np.int64, np.uint16, np.uint32, np.uint64]
  47. for ityp in ITYPES:
  48. x = ityp(12345)
  49. testN = next_fast_len(x)
  50. assert_equal(testN, next_fast_len(int(x)))
  51. def testnext_fast_len_small(self):
  52. hams = {
  53. 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 8, 8: 8, 14: 15, 15: 15,
  54. 16: 16, 17: 18, 1021: 1024, 1536: 1536, 51200000: 51200000
  55. }
  56. for x, y in hams.items():
  57. assert_equal(next_fast_len(x, True), y)
  58. @pytest.mark.xfail(sys.maxsize < 2**32,
  59. reason="Hamming Numbers too large for 32-bit",
  60. raises=ValueError, strict=True)
  61. def testnext_fast_len_big(self):
  62. hams = {
  63. 510183360: 510183360, 510183360 + 1: 512000000,
  64. 511000000: 512000000,
  65. 854296875: 854296875, 854296875 + 1: 859963392,
  66. 196608000000: 196608000000, 196608000000 + 1: 196830000000,
  67. 8789062500000: 8789062500000, 8789062500000 + 1: 8796093022208,
  68. 206391214080000: 206391214080000,
  69. 206391214080000 + 1: 206624260800000,
  70. 470184984576000: 470184984576000,
  71. 470184984576000 + 1: 470715894135000,
  72. 7222041363087360: 7222041363087360,
  73. 7222041363087360 + 1: 7230196133913600,
  74. # power of 5 5**23
  75. 11920928955078125: 11920928955078125,
  76. 11920928955078125 - 1: 11920928955078125,
  77. # power of 3 3**34
  78. 16677181699666569: 16677181699666569,
  79. 16677181699666569 - 1: 16677181699666569,
  80. # power of 2 2**54
  81. 18014398509481984: 18014398509481984,
  82. 18014398509481984 - 1: 18014398509481984,
  83. # above this, int(ceil(n)) == int(ceil(n+1))
  84. 19200000000000000: 19200000000000000,
  85. 19200000000000000 + 1: 19221679687500000,
  86. 288230376151711744: 288230376151711744,
  87. 288230376151711744 + 1: 288325195312500000,
  88. 288325195312500000 - 1: 288325195312500000,
  89. 288325195312500000: 288325195312500000,
  90. 288325195312500000 + 1: 288555831593533440,
  91. }
  92. for x, y in hams.items():
  93. assert_equal(next_fast_len(x, True), y)
  94. def test_keyword_args(self):
  95. assert next_fast_len(11, real=True) == 12
  96. assert next_fast_len(target=7, real=False) == 7
  97. class Test_init_nd_shape_and_axes:
  98. def test_py_0d_defaults(self):
  99. x = np.array(4)
  100. shape = None
  101. axes = None
  102. shape_expected = np.array([])
  103. axes_expected = np.array([])
  104. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  105. assert_equal(shape_res, shape_expected)
  106. assert_equal(axes_res, axes_expected)
  107. def test_np_0d_defaults(self):
  108. x = np.array(7.)
  109. shape = None
  110. axes = None
  111. shape_expected = np.array([])
  112. axes_expected = np.array([])
  113. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  114. assert_equal(shape_res, shape_expected)
  115. assert_equal(axes_res, axes_expected)
  116. def test_py_1d_defaults(self):
  117. x = np.array([1, 2, 3])
  118. shape = None
  119. axes = None
  120. shape_expected = np.array([3])
  121. axes_expected = np.array([0])
  122. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  123. assert_equal(shape_res, shape_expected)
  124. assert_equal(axes_res, axes_expected)
  125. def test_np_1d_defaults(self):
  126. x = np.arange(0, 1, .1)
  127. shape = None
  128. axes = None
  129. shape_expected = np.array([10])
  130. axes_expected = np.array([0])
  131. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  132. assert_equal(shape_res, shape_expected)
  133. assert_equal(axes_res, axes_expected)
  134. def test_py_2d_defaults(self):
  135. x = np.array([[1, 2, 3, 4],
  136. [5, 6, 7, 8]])
  137. shape = None
  138. axes = None
  139. shape_expected = np.array([2, 4])
  140. axes_expected = np.array([0, 1])
  141. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  142. assert_equal(shape_res, shape_expected)
  143. assert_equal(axes_res, axes_expected)
  144. def test_np_2d_defaults(self):
  145. x = np.arange(0, 1, .1).reshape(5, 2)
  146. shape = None
  147. axes = None
  148. shape_expected = np.array([5, 2])
  149. axes_expected = np.array([0, 1])
  150. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  151. assert_equal(shape_res, shape_expected)
  152. assert_equal(axes_res, axes_expected)
  153. def test_np_5d_defaults(self):
  154. x = np.zeros([6, 2, 5, 3, 4])
  155. shape = None
  156. axes = None
  157. shape_expected = np.array([6, 2, 5, 3, 4])
  158. axes_expected = np.array([0, 1, 2, 3, 4])
  159. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  160. assert_equal(shape_res, shape_expected)
  161. assert_equal(axes_res, axes_expected)
  162. def test_np_5d_set_shape(self):
  163. x = np.zeros([6, 2, 5, 3, 4])
  164. shape = [10, -1, -1, 1, 4]
  165. axes = None
  166. shape_expected = np.array([10, 2, 5, 1, 4])
  167. axes_expected = np.array([0, 1, 2, 3, 4])
  168. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  169. assert_equal(shape_res, shape_expected)
  170. assert_equal(axes_res, axes_expected)
  171. def test_np_5d_set_axes(self):
  172. x = np.zeros([6, 2, 5, 3, 4])
  173. shape = None
  174. axes = [4, 1, 2]
  175. shape_expected = np.array([4, 2, 5])
  176. axes_expected = np.array([4, 1, 2])
  177. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  178. assert_equal(shape_res, shape_expected)
  179. assert_equal(axes_res, axes_expected)
  180. def test_np_5d_set_shape_axes(self):
  181. x = np.zeros([6, 2, 5, 3, 4])
  182. shape = [10, -1, 2]
  183. axes = [1, 0, 3]
  184. shape_expected = np.array([10, 6, 2])
  185. axes_expected = np.array([1, 0, 3])
  186. shape_res, axes_res = _init_nd_shape_and_axes(x, shape, axes)
  187. assert_equal(shape_res, shape_expected)
  188. assert_equal(axes_res, axes_expected)
  189. def test_shape_axes_subset(self):
  190. x = np.zeros((2, 3, 4, 5))
  191. shape, axes = _init_nd_shape_and_axes(x, shape=(5, 5, 5), axes=None)
  192. assert_array_equal(shape, [5, 5, 5])
  193. assert_array_equal(axes, [1, 2, 3])
  194. def test_errors(self):
  195. x = np.zeros(1)
  196. with assert_raises(ValueError, match="axes must be a scalar or "
  197. "iterable of integers"):
  198. _init_nd_shape_and_axes(x, shape=None, axes=[[1, 2], [3, 4]])
  199. with assert_raises(ValueError, match="axes must be a scalar or "
  200. "iterable of integers"):
  201. _init_nd_shape_and_axes(x, shape=None, axes=[1., 2., 3., 4.])
  202. with assert_raises(ValueError,
  203. match="axes exceeds dimensionality of input"):
  204. _init_nd_shape_and_axes(x, shape=None, axes=[1])
  205. with assert_raises(ValueError,
  206. match="axes exceeds dimensionality of input"):
  207. _init_nd_shape_and_axes(x, shape=None, axes=[-2])
  208. with assert_raises(ValueError,
  209. match="all axes must be unique"):
  210. _init_nd_shape_and_axes(x, shape=None, axes=[0, 0])
  211. with assert_raises(ValueError, match="shape must be a scalar or "
  212. "iterable of integers"):
  213. _init_nd_shape_and_axes(x, shape=[[1, 2], [3, 4]], axes=None)
  214. with assert_raises(ValueError, match="shape must be a scalar or "
  215. "iterable of integers"):
  216. _init_nd_shape_and_axes(x, shape=[1., 2., 3., 4.], axes=None)
  217. with assert_raises(ValueError,
  218. match="when given, axes and shape arguments"
  219. " have to be of the same length"):
  220. _init_nd_shape_and_axes(np.zeros([1, 1, 1, 1]),
  221. shape=[1, 2, 3], axes=[1])
  222. with assert_raises(ValueError,
  223. match="invalid number of data points"
  224. r" \(\[0\]\) specified"):
  225. _init_nd_shape_and_axes(x, shape=[0], axes=None)
  226. with assert_raises(ValueError,
  227. match="invalid number of data points"
  228. r" \(\[-2\]\) specified"):
  229. _init_nd_shape_and_axes(x, shape=-2, axes=None)