timer_comparison.py 15 KB

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