timer_comparison.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. import timeit
  2. from functools import reduce
  3. import numpy as np
  4. from numpy import float_
  5. import numpy.core.fromnumeric as fromnumeric
  6. from numpy.testing import build_err_msg
  7. pi = np.pi
  8. class ModuleTester:
  9. def __init__(self, module):
  10. self.module = module
  11. self.allequal = module.allequal
  12. self.arange = module.arange
  13. self.array = module.array
  14. self.concatenate = module.concatenate
  15. self.count = module.count
  16. self.equal = module.equal
  17. self.filled = module.filled
  18. self.getmask = module.getmask
  19. self.getmaskarray = module.getmaskarray
  20. self.id = id
  21. self.inner = module.inner
  22. self.make_mask = module.make_mask
  23. self.masked = module.masked
  24. self.masked_array = module.masked_array
  25. self.masked_values = module.masked_values
  26. self.mask_or = module.mask_or
  27. self.nomask = module.nomask
  28. self.ones = module.ones
  29. self.outer = module.outer
  30. self.repeat = module.repeat
  31. self.resize = module.resize
  32. self.sort = module.sort
  33. self.take = module.take
  34. self.transpose = module.transpose
  35. self.zeros = module.zeros
  36. self.MaskType = module.MaskType
  37. try:
  38. self.umath = module.umath
  39. except AttributeError:
  40. self.umath = module.core.umath
  41. self.testnames = []
  42. def assert_array_compare(self, comparison, x, y, err_msg='', header='',
  43. fill_value=True):
  44. """
  45. Assert that a comparison of two masked arrays is satisfied elementwise.
  46. """
  47. xf = self.filled(x)
  48. yf = self.filled(y)
  49. m = self.mask_or(self.getmask(x), self.getmask(y))
  50. x = self.filled(self.masked_array(xf, mask=m), fill_value)
  51. y = self.filled(self.masked_array(yf, mask=m), fill_value)
  52. if (x.dtype.char != "O"):
  53. x = x.astype(float_)
  54. if isinstance(x, np.ndarray) and x.size > 1:
  55. x[np.isnan(x)] = 0
  56. elif np.isnan(x):
  57. x = 0
  58. if (y.dtype.char != "O"):
  59. y = y.astype(float_)
  60. if isinstance(y, np.ndarray) and y.size > 1:
  61. y[np.isnan(y)] = 0
  62. elif np.isnan(y):
  63. y = 0
  64. try:
  65. cond = (x.shape == () or y.shape == ()) or x.shape == y.shape
  66. if not cond:
  67. msg = build_err_msg([x, y],
  68. err_msg
  69. + f'\n(shapes {x.shape}, {y.shape} mismatch)',
  70. header=header,
  71. names=('x', 'y'))
  72. assert cond, msg
  73. val = comparison(x, y)
  74. if m is not self.nomask and fill_value:
  75. val = self.masked_array(val, mask=m)
  76. if isinstance(val, bool):
  77. cond = val
  78. reduced = [0]
  79. else:
  80. reduced = val.ravel()
  81. cond = reduced.all()
  82. reduced = reduced.tolist()
  83. if not cond:
  84. match = 100-100.0*reduced.count(1)/len(reduced)
  85. msg = build_err_msg([x, y],
  86. err_msg
  87. + '\n(mismatch %s%%)' % (match,),
  88. header=header,
  89. names=('x', 'y'))
  90. assert cond, msg
  91. except ValueError as e:
  92. msg = build_err_msg([x, y], err_msg, header=header, names=('x', 'y'))
  93. raise ValueError(msg) from e
  94. def assert_array_equal(self, x, y, err_msg=''):
  95. """
  96. Checks the elementwise equality of two masked arrays.
  97. """
  98. self.assert_array_compare(self.equal, x, y, err_msg=err_msg,
  99. header='Arrays are not equal')
  100. @np.errstate(all='ignore')
  101. def test_0(self):
  102. """
  103. Tests creation
  104. """
  105. x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
  106. m = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
  107. xm = self.masked_array(x, mask=m)
  108. xm[0]
  109. @np.errstate(all='ignore')
  110. def test_1(self):
  111. """
  112. Tests creation
  113. """
  114. x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
  115. y = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.])
  116. m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
  117. m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1]
  118. xm = self.masked_array(x, mask=m1)
  119. ym = self.masked_array(y, mask=m2)
  120. xf = np.where(m1, 1.e+20, x)
  121. xm.set_fill_value(1.e+20)
  122. assert((xm-ym).filled(0).any())
  123. s = x.shape
  124. assert(xm.size == reduce(lambda x, y:x*y, s))
  125. assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
  126. for s in [(4, 3), (6, 2)]:
  127. x.shape = s
  128. y.shape = s
  129. xm.shape = s
  130. ym.shape = s
  131. xf.shape = s
  132. assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
  133. @np.errstate(all='ignore')
  134. def test_2(self):
  135. """
  136. Tests conversions and indexing.
  137. """
  138. x1 = np.array([1, 2, 4, 3])
  139. x2 = self.array(x1, mask=[1, 0, 0, 0])
  140. x3 = self.array(x1, mask=[0, 1, 0, 1])
  141. x4 = self.array(x1)
  142. # test conversion to strings, no errors
  143. str(x2)
  144. repr(x2)
  145. # tests of indexing
  146. assert type(x2[1]) is type(x1[1])
  147. assert x1[1] == x2[1]
  148. x1[2] = 9
  149. x2[2] = 9
  150. self.assert_array_equal(x1, x2)
  151. x1[1:3] = 99
  152. x2[1:3] = 99
  153. x2[1] = self.masked
  154. x2[1:3] = self.masked
  155. x2[:] = x1
  156. x2[1] = self.masked
  157. x3[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
  158. x4[:] = self.masked_array([1, 2, 3, 4], [0, 1, 1, 0])
  159. x1 = np.arange(5)*1.0
  160. x2 = self.masked_values(x1, 3.0)
  161. x1 = self.array([1, 'hello', 2, 3], object)
  162. x2 = np.array([1, 'hello', 2, 3], object)
  163. # check that no error occurs.
  164. x1[1]
  165. x2[1]
  166. assert x1[1:1].shape == (0,)
  167. # Tests copy-size
  168. n = [0, 0, 1, 0, 0]
  169. m = self.make_mask(n)
  170. m2 = self.make_mask(m)
  171. assert(m is m2)
  172. m3 = self.make_mask(m, copy=1)
  173. assert(m is not m3)
  174. @np.errstate(all='ignore')
  175. def test_3(self):
  176. """
  177. Tests resize/repeat
  178. """
  179. x4 = self.arange(4)
  180. x4[2] = self.masked
  181. y4 = self.resize(x4, (8,))
  182. assert self.allequal(self.concatenate([x4, x4]), y4)
  183. assert self.allequal(self.getmask(y4), [0, 0, 1, 0, 0, 0, 1, 0])
  184. y5 = self.repeat(x4, (2, 2, 2, 2), axis=0)
  185. self.assert_array_equal(y5, [0, 0, 1, 1, 2, 2, 3, 3])
  186. y6 = self.repeat(x4, 2, axis=0)
  187. assert self.allequal(y5, y6)
  188. y7 = x4.repeat((2, 2, 2, 2), axis=0)
  189. assert self.allequal(y5, y7)
  190. y8 = x4.repeat(2, 0)
  191. assert self.allequal(y5, y8)
  192. @np.errstate(all='ignore')
  193. def test_4(self):
  194. """
  195. Test of take, transpose, inner, outer products.
  196. """
  197. x = self.arange(24)
  198. y = np.arange(24)
  199. x[5:6] = self.masked
  200. x = x.reshape(2, 3, 4)
  201. y = y.reshape(2, 3, 4)
  202. assert self.allequal(np.transpose(y, (2, 0, 1)), self.transpose(x, (2, 0, 1)))
  203. assert self.allequal(np.take(y, (2, 0, 1), 1), self.take(x, (2, 0, 1), 1))
  204. assert self.allequal(np.inner(self.filled(x, 0), self.filled(y, 0)),
  205. self.inner(x, y))
  206. assert self.allequal(np.outer(self.filled(x, 0), self.filled(y, 0)),
  207. self.outer(x, y))
  208. y = self.array(['abc', 1, 'def', 2, 3], object)
  209. y[2] = self.masked
  210. t = self.take(y, [0, 3, 4])
  211. assert t[0] == 'abc'
  212. assert t[1] == 2
  213. assert t[2] == 3
  214. @np.errstate(all='ignore')
  215. def test_5(self):
  216. """
  217. Tests inplace w/ scalar
  218. """
  219. x = self.arange(10)
  220. y = self.arange(10)
  221. xm = self.arange(10)
  222. xm[2] = self.masked
  223. x += 1
  224. assert self.allequal(x, y+1)
  225. xm += 1
  226. assert self.allequal(xm, y+1)
  227. x = self.arange(10)
  228. xm = self.arange(10)
  229. xm[2] = self.masked
  230. x -= 1
  231. assert self.allequal(x, y-1)
  232. xm -= 1
  233. assert self.allequal(xm, y-1)
  234. x = self.arange(10)*1.0
  235. xm = self.arange(10)*1.0
  236. xm[2] = self.masked
  237. x *= 2.0
  238. assert self.allequal(x, y*2)
  239. xm *= 2.0
  240. assert self.allequal(xm, y*2)
  241. x = self.arange(10)*2
  242. xm = self.arange(10)*2
  243. xm[2] = self.masked
  244. x /= 2
  245. assert self.allequal(x, y)
  246. xm /= 2
  247. assert self.allequal(xm, y)
  248. x = self.arange(10)*1.0
  249. xm = self.arange(10)*1.0
  250. xm[2] = self.masked
  251. x /= 2.0
  252. assert self.allequal(x, y/2.0)
  253. xm /= self.arange(10)
  254. self.assert_array_equal(xm, self.ones((10,)))
  255. x = self.arange(10).astype(float_)
  256. xm = self.arange(10)
  257. xm[2] = self.masked
  258. x += 1.
  259. assert self.allequal(x, y + 1.)
  260. @np.errstate(all='ignore')
  261. def test_6(self):
  262. """
  263. Tests inplace w/ array
  264. """
  265. x = self.arange(10, dtype=float_)
  266. y = self.arange(10)
  267. xm = self.arange(10, dtype=float_)
  268. xm[2] = self.masked
  269. m = xm.mask
  270. a = self.arange(10, dtype=float_)
  271. a[-1] = self.masked
  272. x += a
  273. xm += a
  274. assert self.allequal(x, y+a)
  275. assert self.allequal(xm, y+a)
  276. assert self.allequal(xm.mask, self.mask_or(m, a.mask))
  277. x = self.arange(10, dtype=float_)
  278. xm = self.arange(10, dtype=float_)
  279. xm[2] = self.masked
  280. m = xm.mask
  281. a = self.arange(10, dtype=float_)
  282. a[-1] = self.masked
  283. x -= a
  284. xm -= a
  285. assert self.allequal(x, y-a)
  286. assert self.allequal(xm, y-a)
  287. assert self.allequal(xm.mask, self.mask_or(m, a.mask))
  288. x = self.arange(10, dtype=float_)
  289. xm = self.arange(10, dtype=float_)
  290. xm[2] = self.masked
  291. m = xm.mask
  292. a = self.arange(10, dtype=float_)
  293. a[-1] = self.masked
  294. x *= a
  295. xm *= a
  296. assert self.allequal(x, y*a)
  297. assert self.allequal(xm, y*a)
  298. assert self.allequal(xm.mask, self.mask_or(m, a.mask))
  299. x = self.arange(10, dtype=float_)
  300. xm = self.arange(10, dtype=float_)
  301. xm[2] = self.masked
  302. m = xm.mask
  303. a = self.arange(10, dtype=float_)
  304. a[-1] = self.masked
  305. x /= a
  306. xm /= a
  307. @np.errstate(all='ignore')
  308. def test_7(self):
  309. "Tests ufunc"
  310. d = (self.array([1.0, 0, -1, pi/2]*2, mask=[0, 1]+[0]*6),
  311. self.array([1.0, 0, -1, pi/2]*2, mask=[1, 0]+[0]*6),)
  312. for f in ['sqrt', 'log', 'log10', 'exp', 'conjugate',
  313. # 'sin', 'cos', 'tan',
  314. # 'arcsin', 'arccos', 'arctan',
  315. # 'sinh', 'cosh', 'tanh',
  316. # 'arcsinh',
  317. # 'arccosh',
  318. # 'arctanh',
  319. # 'absolute', 'fabs', 'negative',
  320. # # 'nonzero', 'around',
  321. # 'floor', 'ceil',
  322. # # 'sometrue', 'alltrue',
  323. # 'logical_not',
  324. # 'add', 'subtract', 'multiply',
  325. # 'divide', 'true_divide', 'floor_divide',
  326. # 'remainder', 'fmod', 'hypot', 'arctan2',
  327. # 'equal', 'not_equal', 'less_equal', 'greater_equal',
  328. # 'less', 'greater',
  329. # 'logical_and', 'logical_or', 'logical_xor',
  330. ]:
  331. try:
  332. uf = getattr(self.umath, f)
  333. except AttributeError:
  334. uf = getattr(fromnumeric, f)
  335. mf = getattr(self.module, f)
  336. args = d[:uf.nin]
  337. ur = uf(*args)
  338. mr = mf(*args)
  339. self.assert_array_equal(ur.filled(0), mr.filled(0), f)
  340. self.assert_array_equal(ur._mask, mr._mask)
  341. @np.errstate(all='ignore')
  342. def test_99(self):
  343. # test average
  344. ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
  345. self.assert_array_equal(2.0, self.average(ott, axis=0))
  346. self.assert_array_equal(2.0, self.average(ott, weights=[1., 1., 2., 1.]))
  347. result, wts = self.average(ott, weights=[1., 1., 2., 1.], returned=1)
  348. self.assert_array_equal(2.0, result)
  349. assert(wts == 4.0)
  350. ott[:] = self.masked
  351. assert(self.average(ott, axis=0) is self.masked)
  352. ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
  353. ott = ott.reshape(2, 2)
  354. ott[:, 1] = self.masked
  355. self.assert_array_equal(self.average(ott, axis=0), [2.0, 0.0])
  356. assert(self.average(ott, axis=1)[0] is self.masked)
  357. self.assert_array_equal([2., 0.], self.average(ott, axis=0))
  358. result, wts = self.average(ott, axis=0, returned=1)
  359. self.assert_array_equal(wts, [1., 0.])
  360. w1 = [0, 1, 1, 1, 1, 0]
  361. w2 = [[0, 1, 1, 1, 1, 0], [1, 0, 0, 0, 0, 1]]
  362. x = self.arange(6)
  363. self.assert_array_equal(self.average(x, axis=0), 2.5)
  364. self.assert_array_equal(self.average(x, axis=0, weights=w1), 2.5)
  365. y = self.array([self.arange(6), 2.0*self.arange(6)])
  366. self.assert_array_equal(self.average(y, None), np.add.reduce(np.arange(6))*3./12.)
  367. self.assert_array_equal(self.average(y, axis=0), np.arange(6) * 3./2.)
  368. self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
  369. self.assert_array_equal(self.average(y, None, weights=w2), 20./6.)
  370. self.assert_array_equal(self.average(y, axis=0, weights=w2), [0., 1., 2., 3., 4., 10.])
  371. self.assert_array_equal(self.average(y, axis=1), [self.average(x, axis=0), self.average(x, axis=0) * 2.0])
  372. m1 = self.zeros(6)
  373. m2 = [0, 0, 1, 1, 0, 0]
  374. m3 = [[0, 0, 1, 1, 0, 0], [0, 1, 1, 1, 1, 0]]
  375. m4 = self.ones(6)
  376. m5 = [0, 1, 1, 1, 1, 1]
  377. self.assert_array_equal(self.average(self.masked_array(x, m1), axis=0), 2.5)
  378. self.assert_array_equal(self.average(self.masked_array(x, m2), axis=0), 2.5)
  379. self.assert_array_equal(self.average(self.masked_array(x, m5), axis=0), 0.0)
  380. self.assert_array_equal(self.count(self.average(self.masked_array(x, m4), axis=0)), 0)
  381. z = self.masked_array(y, m3)
  382. self.assert_array_equal(self.average(z, None), 20./6.)
  383. self.assert_array_equal(self.average(z, axis=0), [0., 1., 99., 99., 4.0, 7.5])
  384. self.assert_array_equal(self.average(z, axis=1), [2.5, 5.0])
  385. self.assert_array_equal(self.average(z, axis=0, weights=w2), [0., 1., 99., 99., 4.0, 10.0])
  386. @np.errstate(all='ignore')
  387. def test_A(self):
  388. x = self.arange(24)
  389. x[5:6] = self.masked
  390. x = x.reshape(2, 3, 4)
  391. if __name__ == '__main__':
  392. setup_base = ("from __main__ import ModuleTester \n"
  393. "import numpy\n"
  394. "tester = ModuleTester(module)\n")
  395. setup_cur = "import numpy.ma.core as module\n" + setup_base
  396. (nrepeat, nloop) = (10, 10)
  397. for i in range(1, 8):
  398. func = 'tester.test_%i()' % i
  399. cur = timeit.Timer(func, setup_cur).repeat(nrepeat, nloop*10)
  400. cur = np.sort(cur)
  401. print("#%i" % i + 50*'.')
  402. print(eval("ModuleTester.test_%i.__doc__" % i))
  403. print(f'core_current : {cur[0]:.3f} - {cur[1]:.3f}')