test_ufunc.py 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159
  1. import warnings
  2. import itertools
  3. import sys
  4. import pytest
  5. import numpy as np
  6. import numpy.core._umath_tests as umt
  7. import numpy.linalg._umath_linalg as uml
  8. import numpy.core._operand_flag_tests as opflag_tests
  9. import numpy.core._rational_tests as _rational_tests
  10. from numpy.testing import (
  11. assert_, assert_equal, assert_raises, assert_array_equal,
  12. assert_almost_equal, assert_array_almost_equal, assert_no_warnings,
  13. assert_allclose, HAS_REFCOUNT,
  14. )
  15. from numpy.compat import pickle
  16. UNARY_UFUNCS = [obj for obj in np.core.umath.__dict__.values()
  17. if isinstance(obj, np.ufunc)]
  18. UNARY_OBJECT_UFUNCS = [uf for uf in UNARY_UFUNCS if "O->O" in uf.types]
  19. class TestUfuncKwargs:
  20. def test_kwarg_exact(self):
  21. assert_raises(TypeError, np.add, 1, 2, castingx='safe')
  22. assert_raises(TypeError, np.add, 1, 2, dtypex=int)
  23. assert_raises(TypeError, np.add, 1, 2, extobjx=[4096])
  24. assert_raises(TypeError, np.add, 1, 2, outx=None)
  25. assert_raises(TypeError, np.add, 1, 2, sigx='ii->i')
  26. assert_raises(TypeError, np.add, 1, 2, signaturex='ii->i')
  27. assert_raises(TypeError, np.add, 1, 2, subokx=False)
  28. assert_raises(TypeError, np.add, 1, 2, wherex=[True])
  29. def test_sig_signature(self):
  30. assert_raises(ValueError, np.add, 1, 2, sig='ii->i',
  31. signature='ii->i')
  32. def test_sig_dtype(self):
  33. assert_raises(RuntimeError, np.add, 1, 2, sig='ii->i',
  34. dtype=int)
  35. assert_raises(RuntimeError, np.add, 1, 2, signature='ii->i',
  36. dtype=int)
  37. def test_extobj_refcount(self):
  38. # Should not segfault with USE_DEBUG.
  39. assert_raises(TypeError, np.add, 1, 2, extobj=[4096], parrot=True)
  40. class TestUfuncGenericLoops:
  41. """Test generic loops.
  42. The loops to be tested are:
  43. PyUFunc_ff_f_As_dd_d
  44. PyUFunc_ff_f
  45. PyUFunc_dd_d
  46. PyUFunc_gg_g
  47. PyUFunc_FF_F_As_DD_D
  48. PyUFunc_DD_D
  49. PyUFunc_FF_F
  50. PyUFunc_GG_G
  51. PyUFunc_OO_O
  52. PyUFunc_OO_O_method
  53. PyUFunc_f_f_As_d_d
  54. PyUFunc_d_d
  55. PyUFunc_f_f
  56. PyUFunc_g_g
  57. PyUFunc_F_F_As_D_D
  58. PyUFunc_F_F
  59. PyUFunc_D_D
  60. PyUFunc_G_G
  61. PyUFunc_O_O
  62. PyUFunc_O_O_method
  63. PyUFunc_On_Om
  64. Where:
  65. f -- float
  66. d -- double
  67. g -- long double
  68. F -- complex float
  69. D -- complex double
  70. G -- complex long double
  71. O -- python object
  72. It is difficult to assure that each of these loops is entered from the
  73. Python level as the special cased loops are a moving target and the
  74. corresponding types are architecture dependent. We probably need to
  75. define C level testing ufuncs to get at them. For the time being, I've
  76. just looked at the signatures registered in the build directory to find
  77. relevant functions.
  78. """
  79. np_dtypes = [
  80. (np.single, np.single), (np.single, np.double),
  81. (np.csingle, np.csingle), (np.csingle, np.cdouble),
  82. (np.double, np.double), (np.longdouble, np.longdouble),
  83. (np.cdouble, np.cdouble), (np.clongdouble, np.clongdouble)]
  84. @pytest.mark.parametrize('input_dtype,output_dtype', np_dtypes)
  85. def test_unary_PyUFunc(self, input_dtype, output_dtype, f=np.exp, x=0, y=1):
  86. xs = np.full(10, input_dtype(x), dtype=output_dtype)
  87. ys = f(xs)[::2]
  88. assert_allclose(ys, y)
  89. assert_equal(ys.dtype, output_dtype)
  90. def f2(x, y):
  91. return x**y
  92. @pytest.mark.parametrize('input_dtype,output_dtype', np_dtypes)
  93. def test_binary_PyUFunc(self, input_dtype, output_dtype, f=f2, x=0, y=1):
  94. xs = np.full(10, input_dtype(x), dtype=output_dtype)
  95. ys = f(xs, xs)[::2]
  96. assert_allclose(ys, y)
  97. assert_equal(ys.dtype, output_dtype)
  98. # class to use in testing object method loops
  99. class foo:
  100. def conjugate(self):
  101. return np.bool_(1)
  102. def logical_xor(self, obj):
  103. return np.bool_(1)
  104. def test_unary_PyUFunc_O_O(self):
  105. x = np.ones(10, dtype=object)
  106. assert_(np.all(np.abs(x) == 1))
  107. def test_unary_PyUFunc_O_O_method_simple(self, foo=foo):
  108. x = np.full(10, foo(), dtype=object)
  109. assert_(np.all(np.conjugate(x) == True))
  110. def test_binary_PyUFunc_OO_O(self):
  111. x = np.ones(10, dtype=object)
  112. assert_(np.all(np.add(x, x) == 2))
  113. def test_binary_PyUFunc_OO_O_method(self, foo=foo):
  114. x = np.full(10, foo(), dtype=object)
  115. assert_(np.all(np.logical_xor(x, x)))
  116. def test_binary_PyUFunc_On_Om_method(self, foo=foo):
  117. x = np.full((10, 2, 3), foo(), dtype=object)
  118. assert_(np.all(np.logical_xor(x, x)))
  119. def test_python_complex_conjugate(self):
  120. # The conjugate ufunc should fall back to calling the method:
  121. arr = np.array([1+2j, 3-4j], dtype="O")
  122. assert isinstance(arr[0], complex)
  123. res = np.conjugate(arr)
  124. assert res.dtype == np.dtype("O")
  125. assert_array_equal(res, np.array([1-2j, 3+4j], dtype="O"))
  126. @pytest.mark.parametrize("ufunc", UNARY_OBJECT_UFUNCS)
  127. def test_unary_PyUFunc_O_O_method_full(self, ufunc):
  128. """Compare the result of the object loop with non-object one"""
  129. val = np.float64(np.pi/4)
  130. class MyFloat(np.float64):
  131. def __getattr__(self, attr):
  132. try:
  133. return super().__getattr__(attr)
  134. except AttributeError:
  135. return lambda: getattr(np.core.umath, attr)(val)
  136. num_arr = np.array([val], dtype=np.float64)
  137. obj_arr = np.array([MyFloat(val)], dtype="O")
  138. with np.errstate(all="raise"):
  139. try:
  140. res_num = ufunc(num_arr)
  141. except Exception as exc:
  142. with assert_raises(type(exc)):
  143. ufunc(obj_arr)
  144. else:
  145. res_obj = ufunc(obj_arr)
  146. assert_array_equal(res_num.astype("O"), res_obj)
  147. def _pickleable_module_global():
  148. pass
  149. class TestUfunc:
  150. def test_pickle(self):
  151. for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
  152. assert_(pickle.loads(pickle.dumps(np.sin,
  153. protocol=proto)) is np.sin)
  154. # Check that ufunc not defined in the top level numpy namespace
  155. # such as numpy.core._rational_tests.test_add can also be pickled
  156. res = pickle.loads(pickle.dumps(_rational_tests.test_add,
  157. protocol=proto))
  158. assert_(res is _rational_tests.test_add)
  159. def test_pickle_withstring(self):
  160. astring = (b"cnumpy.core\n_ufunc_reconstruct\np0\n"
  161. b"(S'numpy.core.umath'\np1\nS'cos'\np2\ntp3\nRp4\n.")
  162. assert_(pickle.loads(astring) is np.cos)
  163. def test_pickle_name_is_qualname(self):
  164. # This tests that a simplification of our ufunc pickle code will
  165. # lead to allowing qualnames as names. Future ufuncs should
  166. # possible add a specific qualname, or a hook into pickling instead
  167. # (dask+numba may benefit).
  168. _pickleable_module_global.ufunc = umt._pickleable_module_global_ufunc
  169. obj = pickle.loads(pickle.dumps(_pickleable_module_global.ufunc))
  170. assert obj is umt._pickleable_module_global_ufunc
  171. def test_reduceat_shifting_sum(self):
  172. L = 6
  173. x = np.arange(L)
  174. idx = np.array(list(zip(np.arange(L - 2), np.arange(L - 2) + 2))).ravel()
  175. assert_array_equal(np.add.reduceat(x, idx)[::2], [1, 3, 5, 7])
  176. def test_all_ufunc(self):
  177. """Try to check presence and results of all ufuncs.
  178. The list of ufuncs comes from generate_umath.py and is as follows:
  179. ===== ==== ============= =============== ========================
  180. done args function types notes
  181. ===== ==== ============= =============== ========================
  182. n 1 conjugate nums + O
  183. n 1 absolute nums + O complex -> real
  184. n 1 negative nums + O
  185. n 1 sign nums + O -> int
  186. n 1 invert bool + ints + O flts raise an error
  187. n 1 degrees real + M cmplx raise an error
  188. n 1 radians real + M cmplx raise an error
  189. n 1 arccos flts + M
  190. n 1 arccosh flts + M
  191. n 1 arcsin flts + M
  192. n 1 arcsinh flts + M
  193. n 1 arctan flts + M
  194. n 1 arctanh flts + M
  195. n 1 cos flts + M
  196. n 1 sin flts + M
  197. n 1 tan flts + M
  198. n 1 cosh flts + M
  199. n 1 sinh flts + M
  200. n 1 tanh flts + M
  201. n 1 exp flts + M
  202. n 1 expm1 flts + M
  203. n 1 log flts + M
  204. n 1 log10 flts + M
  205. n 1 log1p flts + M
  206. n 1 sqrt flts + M real x < 0 raises error
  207. n 1 ceil real + M
  208. n 1 trunc real + M
  209. n 1 floor real + M
  210. n 1 fabs real + M
  211. n 1 rint flts + M
  212. n 1 isnan flts -> bool
  213. n 1 isinf flts -> bool
  214. n 1 isfinite flts -> bool
  215. n 1 signbit real -> bool
  216. n 1 modf real -> (frac, int)
  217. n 1 logical_not bool + nums + M -> bool
  218. n 2 left_shift ints + O flts raise an error
  219. n 2 right_shift ints + O flts raise an error
  220. n 2 add bool + nums + O boolean + is ||
  221. n 2 subtract bool + nums + O boolean - is ^
  222. n 2 multiply bool + nums + O boolean * is &
  223. n 2 divide nums + O
  224. n 2 floor_divide nums + O
  225. n 2 true_divide nums + O bBhH -> f, iIlLqQ -> d
  226. n 2 fmod nums + M
  227. n 2 power nums + O
  228. n 2 greater bool + nums + O -> bool
  229. n 2 greater_equal bool + nums + O -> bool
  230. n 2 less bool + nums + O -> bool
  231. n 2 less_equal bool + nums + O -> bool
  232. n 2 equal bool + nums + O -> bool
  233. n 2 not_equal bool + nums + O -> bool
  234. n 2 logical_and bool + nums + M -> bool
  235. n 2 logical_or bool + nums + M -> bool
  236. n 2 logical_xor bool + nums + M -> bool
  237. n 2 maximum bool + nums + O
  238. n 2 minimum bool + nums + O
  239. n 2 bitwise_and bool + ints + O flts raise an error
  240. n 2 bitwise_or bool + ints + O flts raise an error
  241. n 2 bitwise_xor bool + ints + O flts raise an error
  242. n 2 arctan2 real + M
  243. n 2 remainder ints + real + O
  244. n 2 hypot real + M
  245. ===== ==== ============= =============== ========================
  246. Types other than those listed will be accepted, but they are cast to
  247. the smallest compatible type for which the function is defined. The
  248. casting rules are:
  249. bool -> int8 -> float32
  250. ints -> double
  251. """
  252. pass
  253. # from include/numpy/ufuncobject.h
  254. size_inferred = 2
  255. can_ignore = 4
  256. def test_signature0(self):
  257. # the arguments to test_signature are: nin, nout, core_signature
  258. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  259. 2, 1, "(i),(i)->()")
  260. assert_equal(enabled, 1)
  261. assert_equal(num_dims, (1, 1, 0))
  262. assert_equal(ixs, (0, 0))
  263. assert_equal(flags, (self.size_inferred,))
  264. assert_equal(sizes, (-1,))
  265. def test_signature1(self):
  266. # empty core signature; treat as plain ufunc (with trivial core)
  267. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  268. 2, 1, "(),()->()")
  269. assert_equal(enabled, 0)
  270. assert_equal(num_dims, (0, 0, 0))
  271. assert_equal(ixs, ())
  272. assert_equal(flags, ())
  273. assert_equal(sizes, ())
  274. def test_signature2(self):
  275. # more complicated names for variables
  276. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  277. 2, 1, "(i1,i2),(J_1)->(_kAB)")
  278. assert_equal(enabled, 1)
  279. assert_equal(num_dims, (2, 1, 1))
  280. assert_equal(ixs, (0, 1, 2, 3))
  281. assert_equal(flags, (self.size_inferred,)*4)
  282. assert_equal(sizes, (-1, -1, -1, -1))
  283. def test_signature3(self):
  284. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  285. 2, 1, u"(i1, i12), (J_1)->(i12, i2)")
  286. assert_equal(enabled, 1)
  287. assert_equal(num_dims, (2, 1, 2))
  288. assert_equal(ixs, (0, 1, 2, 1, 3))
  289. assert_equal(flags, (self.size_inferred,)*4)
  290. assert_equal(sizes, (-1, -1, -1, -1))
  291. def test_signature4(self):
  292. # matrix_multiply signature from _umath_tests
  293. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  294. 2, 1, "(n,k),(k,m)->(n,m)")
  295. assert_equal(enabled, 1)
  296. assert_equal(num_dims, (2, 2, 2))
  297. assert_equal(ixs, (0, 1, 1, 2, 0, 2))
  298. assert_equal(flags, (self.size_inferred,)*3)
  299. assert_equal(sizes, (-1, -1, -1))
  300. def test_signature5(self):
  301. # matmul signature from _umath_tests
  302. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  303. 2, 1, "(n?,k),(k,m?)->(n?,m?)")
  304. assert_equal(enabled, 1)
  305. assert_equal(num_dims, (2, 2, 2))
  306. assert_equal(ixs, (0, 1, 1, 2, 0, 2))
  307. assert_equal(flags, (self.size_inferred | self.can_ignore,
  308. self.size_inferred,
  309. self.size_inferred | self.can_ignore))
  310. assert_equal(sizes, (-1, -1, -1))
  311. def test_signature6(self):
  312. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  313. 1, 1, "(3)->()")
  314. assert_equal(enabled, 1)
  315. assert_equal(num_dims, (1, 0))
  316. assert_equal(ixs, (0,))
  317. assert_equal(flags, (0,))
  318. assert_equal(sizes, (3,))
  319. def test_signature7(self):
  320. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  321. 3, 1, "(3),(03,3),(n)->(9)")
  322. assert_equal(enabled, 1)
  323. assert_equal(num_dims, (1, 2, 1, 1))
  324. assert_equal(ixs, (0, 0, 0, 1, 2))
  325. assert_equal(flags, (0, self.size_inferred, 0))
  326. assert_equal(sizes, (3, -1, 9))
  327. def test_signature8(self):
  328. enabled, num_dims, ixs, flags, sizes = umt.test_signature(
  329. 3, 1, "(3?),(3?,3?),(n)->(9)")
  330. assert_equal(enabled, 1)
  331. assert_equal(num_dims, (1, 2, 1, 1))
  332. assert_equal(ixs, (0, 0, 0, 1, 2))
  333. assert_equal(flags, (self.can_ignore, self.size_inferred, 0))
  334. assert_equal(sizes, (3, -1, 9))
  335. def test_signature_failure_extra_parenthesis(self):
  336. with assert_raises(ValueError):
  337. umt.test_signature(2, 1, "((i)),(i)->()")
  338. def test_signature_failure_mismatching_parenthesis(self):
  339. with assert_raises(ValueError):
  340. umt.test_signature(2, 1, "(i),)i(->()")
  341. def test_signature_failure_signature_missing_input_arg(self):
  342. with assert_raises(ValueError):
  343. umt.test_signature(2, 1, "(i),->()")
  344. def test_signature_failure_signature_missing_output_arg(self):
  345. with assert_raises(ValueError):
  346. umt.test_signature(2, 2, "(i),(i)->()")
  347. def test_get_signature(self):
  348. assert_equal(umt.inner1d.signature, "(i),(i)->()")
  349. def test_forced_sig(self):
  350. a = 0.5*np.arange(3, dtype='f8')
  351. assert_equal(np.add(a, 0.5), [0.5, 1, 1.5])
  352. assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1])
  353. assert_equal(np.add(a, 0.5, sig='ii->i', casting='unsafe'), [0, 0, 1])
  354. assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'), [0, 0, 1])
  355. assert_equal(np.add(a, 0.5, sig=('i4', 'i4', 'i4'),
  356. casting='unsafe'), [0, 0, 1])
  357. b = np.zeros((3,), dtype='f8')
  358. np.add(a, 0.5, out=b)
  359. assert_equal(b, [0.5, 1, 1.5])
  360. b[:] = 0
  361. np.add(a, 0.5, sig='i', out=b, casting='unsafe')
  362. assert_equal(b, [0, 0, 1])
  363. b[:] = 0
  364. np.add(a, 0.5, sig='ii->i', out=b, casting='unsafe')
  365. assert_equal(b, [0, 0, 1])
  366. b[:] = 0
  367. np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe')
  368. assert_equal(b, [0, 0, 1])
  369. b[:] = 0
  370. np.add(a, 0.5, sig=('i4', 'i4', 'i4'), out=b, casting='unsafe')
  371. assert_equal(b, [0, 0, 1])
  372. def test_true_divide(self):
  373. a = np.array(10)
  374. b = np.array(20)
  375. tgt = np.array(0.5)
  376. for tc in 'bhilqBHILQefdgFDG':
  377. dt = np.dtype(tc)
  378. aa = a.astype(dt)
  379. bb = b.astype(dt)
  380. # Check result value and dtype.
  381. for x, y in itertools.product([aa, -aa], [bb, -bb]):
  382. # Check with no output type specified
  383. if tc in 'FDG':
  384. tgt = complex(x)/complex(y)
  385. else:
  386. tgt = float(x)/float(y)
  387. res = np.true_divide(x, y)
  388. rtol = max(np.finfo(res).resolution, 1e-15)
  389. assert_allclose(res, tgt, rtol=rtol)
  390. if tc in 'bhilqBHILQ':
  391. assert_(res.dtype.name == 'float64')
  392. else:
  393. assert_(res.dtype.name == dt.name )
  394. # Check with output type specified. This also checks for the
  395. # incorrect casts in issue gh-3484 because the unary '-' does
  396. # not change types, even for unsigned types, Hence casts in the
  397. # ufunc from signed to unsigned and vice versa will lead to
  398. # errors in the values.
  399. for tcout in 'bhilqBHILQ':
  400. dtout = np.dtype(tcout)
  401. assert_raises(TypeError, np.true_divide, x, y, dtype=dtout)
  402. for tcout in 'efdg':
  403. dtout = np.dtype(tcout)
  404. if tc in 'FDG':
  405. # Casting complex to float is not allowed
  406. assert_raises(TypeError, np.true_divide, x, y, dtype=dtout)
  407. else:
  408. tgt = float(x)/float(y)
  409. rtol = max(np.finfo(dtout).resolution, 1e-15)
  410. atol = max(np.finfo(dtout).tiny, 3e-308)
  411. # Some test values result in invalid for float16.
  412. with np.errstate(invalid='ignore'):
  413. res = np.true_divide(x, y, dtype=dtout)
  414. if not np.isfinite(res) and tcout == 'e':
  415. continue
  416. assert_allclose(res, tgt, rtol=rtol, atol=atol)
  417. assert_(res.dtype.name == dtout.name)
  418. for tcout in 'FDG':
  419. dtout = np.dtype(tcout)
  420. tgt = complex(x)/complex(y)
  421. rtol = max(np.finfo(dtout).resolution, 1e-15)
  422. atol = max(np.finfo(dtout).tiny, 3e-308)
  423. res = np.true_divide(x, y, dtype=dtout)
  424. if not np.isfinite(res):
  425. continue
  426. assert_allclose(res, tgt, rtol=rtol, atol=atol)
  427. assert_(res.dtype.name == dtout.name)
  428. # Check booleans
  429. a = np.ones((), dtype=np.bool_)
  430. res = np.true_divide(a, a)
  431. assert_(res == 1.0)
  432. assert_(res.dtype.name == 'float64')
  433. res = np.true_divide(~a, a)
  434. assert_(res == 0.0)
  435. assert_(res.dtype.name == 'float64')
  436. def test_sum_stability(self):
  437. a = np.ones(500, dtype=np.float32)
  438. assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 4)
  439. a = np.ones(500, dtype=np.float64)
  440. assert_almost_equal((a / 10.).sum() - a.size / 10., 0, 13)
  441. def test_sum(self):
  442. for dt in (int, np.float16, np.float32, np.float64, np.longdouble):
  443. for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
  444. 128, 1024, 1235):
  445. tgt = dt(v * (v + 1) / 2)
  446. d = np.arange(1, v + 1, dtype=dt)
  447. # warning if sum overflows, which it does in float16
  448. overflow = not np.isfinite(tgt)
  449. with warnings.catch_warnings(record=True) as w:
  450. warnings.simplefilter("always")
  451. assert_almost_equal(np.sum(d), tgt)
  452. assert_equal(len(w), 1 * overflow)
  453. assert_almost_equal(np.sum(d[::-1]), tgt)
  454. assert_equal(len(w), 2 * overflow)
  455. d = np.ones(500, dtype=dt)
  456. assert_almost_equal(np.sum(d[::2]), 250.)
  457. assert_almost_equal(np.sum(d[1::2]), 250.)
  458. assert_almost_equal(np.sum(d[::3]), 167.)
  459. assert_almost_equal(np.sum(d[1::3]), 167.)
  460. assert_almost_equal(np.sum(d[::-2]), 250.)
  461. assert_almost_equal(np.sum(d[-1::-2]), 250.)
  462. assert_almost_equal(np.sum(d[::-3]), 167.)
  463. assert_almost_equal(np.sum(d[-1::-3]), 167.)
  464. # sum with first reduction entry != 0
  465. d = np.ones((1,), dtype=dt)
  466. d += d
  467. assert_almost_equal(d, 2.)
  468. def test_sum_complex(self):
  469. for dt in (np.complex64, np.complex128, np.clongdouble):
  470. for v in (0, 1, 2, 7, 8, 9, 15, 16, 19, 127,
  471. 128, 1024, 1235):
  472. tgt = dt(v * (v + 1) / 2) - dt((v * (v + 1) / 2) * 1j)
  473. d = np.empty(v, dtype=dt)
  474. d.real = np.arange(1, v + 1)
  475. d.imag = -np.arange(1, v + 1)
  476. assert_almost_equal(np.sum(d), tgt)
  477. assert_almost_equal(np.sum(d[::-1]), tgt)
  478. d = np.ones(500, dtype=dt) + 1j
  479. assert_almost_equal(np.sum(d[::2]), 250. + 250j)
  480. assert_almost_equal(np.sum(d[1::2]), 250. + 250j)
  481. assert_almost_equal(np.sum(d[::3]), 167. + 167j)
  482. assert_almost_equal(np.sum(d[1::3]), 167. + 167j)
  483. assert_almost_equal(np.sum(d[::-2]), 250. + 250j)
  484. assert_almost_equal(np.sum(d[-1::-2]), 250. + 250j)
  485. assert_almost_equal(np.sum(d[::-3]), 167. + 167j)
  486. assert_almost_equal(np.sum(d[-1::-3]), 167. + 167j)
  487. # sum with first reduction entry != 0
  488. d = np.ones((1,), dtype=dt) + 1j
  489. d += d
  490. assert_almost_equal(d, 2. + 2j)
  491. def test_sum_initial(self):
  492. # Integer, single axis
  493. assert_equal(np.sum([3], initial=2), 5)
  494. # Floating point
  495. assert_almost_equal(np.sum([0.2], initial=0.1), 0.3)
  496. # Multiple non-adjacent axes
  497. assert_equal(np.sum(np.ones((2, 3, 5), dtype=np.int64), axis=(0, 2), initial=2),
  498. [12, 12, 12])
  499. def test_sum_where(self):
  500. # More extensive tests done in test_reduction_with_where.
  501. assert_equal(np.sum([[1., 2.], [3., 4.]], where=[True, False]), 4.)
  502. assert_equal(np.sum([[1., 2.], [3., 4.]], axis=0, initial=5.,
  503. where=[True, False]), [9., 5.])
  504. def test_inner1d(self):
  505. a = np.arange(6).reshape((2, 3))
  506. assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1))
  507. a = np.arange(6)
  508. assert_array_equal(umt.inner1d(a, a), np.sum(a*a))
  509. def test_broadcast(self):
  510. msg = "broadcast"
  511. a = np.arange(4).reshape((2, 1, 2))
  512. b = np.arange(4).reshape((1, 2, 2))
  513. assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
  514. msg = "extend & broadcast loop dimensions"
  515. b = np.arange(4).reshape((2, 2))
  516. assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
  517. # Broadcast in core dimensions should fail
  518. a = np.arange(8).reshape((4, 2))
  519. b = np.arange(4).reshape((4, 1))
  520. assert_raises(ValueError, umt.inner1d, a, b)
  521. # Extend core dimensions should fail
  522. a = np.arange(8).reshape((4, 2))
  523. b = np.array(7)
  524. assert_raises(ValueError, umt.inner1d, a, b)
  525. # Broadcast should fail
  526. a = np.arange(2).reshape((2, 1, 1))
  527. b = np.arange(3).reshape((3, 1, 1))
  528. assert_raises(ValueError, umt.inner1d, a, b)
  529. # Writing to a broadcasted array with overlap should warn, gh-2705
  530. a = np.arange(2)
  531. b = np.arange(4).reshape((2, 2))
  532. u, v = np.broadcast_arrays(a, b)
  533. assert_equal(u.strides[0], 0)
  534. x = u + v
  535. with warnings.catch_warnings(record=True) as w:
  536. warnings.simplefilter("always")
  537. u += v
  538. assert_equal(len(w), 1)
  539. assert_(x[0, 0] != u[0, 0])
  540. # Output reduction should not be allowed.
  541. # See gh-15139
  542. a = np.arange(6).reshape(3, 2)
  543. b = np.ones(2)
  544. out = np.empty(())
  545. assert_raises(ValueError, umt.inner1d, a, b, out)
  546. out2 = np.empty(3)
  547. c = umt.inner1d(a, b, out2)
  548. assert_(c is out2)
  549. def test_out_broadcasts(self):
  550. # For ufuncs and gufuncs (not for reductions), we currently allow
  551. # the output to cause broadcasting of the input arrays.
  552. # both along dimensions with shape 1 and dimensions which do not
  553. # exist at all in the inputs.
  554. arr = np.arange(3).reshape(1, 3)
  555. out = np.empty((5, 4, 3))
  556. np.add(arr, arr, out=out)
  557. assert (out == np.arange(3) * 2).all()
  558. # The same holds for gufuncs (gh-16484)
  559. umt.inner1d(arr, arr, out=out)
  560. # the result would be just a scalar `5`, but is broadcast fully:
  561. assert (out == 5).all()
  562. def test_type_cast(self):
  563. msg = "type cast"
  564. a = np.arange(6, dtype='short').reshape((2, 3))
  565. assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
  566. err_msg=msg)
  567. msg = "type cast on one argument"
  568. a = np.arange(6).reshape((2, 3))
  569. b = a + 0.1
  570. assert_array_almost_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1),
  571. err_msg=msg)
  572. def test_endian(self):
  573. msg = "big endian"
  574. a = np.arange(6, dtype='>i4').reshape((2, 3))
  575. assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
  576. err_msg=msg)
  577. msg = "little endian"
  578. a = np.arange(6, dtype='<i4').reshape((2, 3))
  579. assert_array_equal(umt.inner1d(a, a), np.sum(a*a, axis=-1),
  580. err_msg=msg)
  581. # Output should always be native-endian
  582. Ba = np.arange(1, dtype='>f8')
  583. La = np.arange(1, dtype='<f8')
  584. assert_equal((Ba+Ba).dtype, np.dtype('f8'))
  585. assert_equal((Ba+La).dtype, np.dtype('f8'))
  586. assert_equal((La+Ba).dtype, np.dtype('f8'))
  587. assert_equal((La+La).dtype, np.dtype('f8'))
  588. assert_equal(np.absolute(La).dtype, np.dtype('f8'))
  589. assert_equal(np.absolute(Ba).dtype, np.dtype('f8'))
  590. assert_equal(np.negative(La).dtype, np.dtype('f8'))
  591. assert_equal(np.negative(Ba).dtype, np.dtype('f8'))
  592. def test_incontiguous_array(self):
  593. msg = "incontiguous memory layout of array"
  594. x = np.arange(64).reshape((2, 2, 2, 2, 2, 2))
  595. a = x[:, 0,:, 0,:, 0]
  596. b = x[:, 1,:, 1,:, 1]
  597. a[0, 0, 0] = -1
  598. msg2 = "make sure it references to the original array"
  599. assert_equal(x[0, 0, 0, 0, 0, 0], -1, err_msg=msg2)
  600. assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
  601. x = np.arange(24).reshape(2, 3, 4)
  602. a = x.T
  603. b = x.T
  604. a[0, 0, 0] = -1
  605. assert_equal(x[0, 0, 0], -1, err_msg=msg2)
  606. assert_array_equal(umt.inner1d(a, b), np.sum(a*b, axis=-1), err_msg=msg)
  607. def test_output_argument(self):
  608. msg = "output argument"
  609. a = np.arange(12).reshape((2, 3, 2))
  610. b = np.arange(4).reshape((2, 1, 2)) + 1
  611. c = np.zeros((2, 3), dtype='int')
  612. umt.inner1d(a, b, c)
  613. assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
  614. c[:] = -1
  615. umt.inner1d(a, b, out=c)
  616. assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
  617. msg = "output argument with type cast"
  618. c = np.zeros((2, 3), dtype='int16')
  619. umt.inner1d(a, b, c)
  620. assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
  621. c[:] = -1
  622. umt.inner1d(a, b, out=c)
  623. assert_array_equal(c, np.sum(a*b, axis=-1), err_msg=msg)
  624. msg = "output argument with incontiguous layout"
  625. c = np.zeros((2, 3, 4), dtype='int16')
  626. umt.inner1d(a, b, c[..., 0])
  627. assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
  628. c[:] = -1
  629. umt.inner1d(a, b, out=c[..., 0])
  630. assert_array_equal(c[..., 0], np.sum(a*b, axis=-1), err_msg=msg)
  631. def test_axes_argument(self):
  632. # inner1d signature: '(i),(i)->()'
  633. inner1d = umt.inner1d
  634. a = np.arange(27.).reshape((3, 3, 3))
  635. b = np.arange(10., 19.).reshape((3, 1, 3))
  636. # basic tests on inputs (outputs tested below with matrix_multiply).
  637. c = inner1d(a, b)
  638. assert_array_equal(c, (a * b).sum(-1))
  639. # default
  640. c = inner1d(a, b, axes=[(-1,), (-1,), ()])
  641. assert_array_equal(c, (a * b).sum(-1))
  642. # integers ok for single axis.
  643. c = inner1d(a, b, axes=[-1, -1, ()])
  644. assert_array_equal(c, (a * b).sum(-1))
  645. # mix fine
  646. c = inner1d(a, b, axes=[(-1,), -1, ()])
  647. assert_array_equal(c, (a * b).sum(-1))
  648. # can omit last axis.
  649. c = inner1d(a, b, axes=[-1, -1])
  650. assert_array_equal(c, (a * b).sum(-1))
  651. # can pass in other types of integer (with __index__ protocol)
  652. c = inner1d(a, b, axes=[np.int8(-1), np.array(-1, dtype=np.int32)])
  653. assert_array_equal(c, (a * b).sum(-1))
  654. # swap some axes
  655. c = inner1d(a, b, axes=[0, 0])
  656. assert_array_equal(c, (a * b).sum(0))
  657. c = inner1d(a, b, axes=[0, 2])
  658. assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1))
  659. # Check errors for improperly constructed axes arguments.
  660. # should have list.
  661. assert_raises(TypeError, inner1d, a, b, axes=-1)
  662. # needs enough elements
  663. assert_raises(ValueError, inner1d, a, b, axes=[-1])
  664. # should pass in indices.
  665. assert_raises(TypeError, inner1d, a, b, axes=[-1.0, -1.0])
  666. assert_raises(TypeError, inner1d, a, b, axes=[(-1.0,), -1])
  667. assert_raises(TypeError, inner1d, a, b, axes=[None, 1])
  668. # cannot pass an index unless there is only one dimension
  669. # (output is wrong in this case)
  670. assert_raises(TypeError, inner1d, a, b, axes=[-1, -1, -1])
  671. # or pass in generally the wrong number of axes
  672. assert_raises(ValueError, inner1d, a, b, axes=[-1, -1, (-1,)])
  673. assert_raises(ValueError, inner1d, a, b, axes=[-1, (-2, -1), ()])
  674. # axes need to have same length.
  675. assert_raises(ValueError, inner1d, a, b, axes=[0, 1])
  676. # matrix_multiply signature: '(m,n),(n,p)->(m,p)'
  677. mm = umt.matrix_multiply
  678. a = np.arange(12).reshape((2, 3, 2))
  679. b = np.arange(8).reshape((2, 2, 2, 1)) + 1
  680. # Sanity check.
  681. c = mm(a, b)
  682. assert_array_equal(c, np.matmul(a, b))
  683. # Default axes.
  684. c = mm(a, b, axes=[(-2, -1), (-2, -1), (-2, -1)])
  685. assert_array_equal(c, np.matmul(a, b))
  686. # Default with explicit axes.
  687. c = mm(a, b, axes=[(1, 2), (2, 3), (2, 3)])
  688. assert_array_equal(c, np.matmul(a, b))
  689. # swap some axes.
  690. c = mm(a, b, axes=[(0, -1), (1, 2), (-2, -1)])
  691. assert_array_equal(c, np.matmul(a.transpose(1, 0, 2),
  692. b.transpose(0, 3, 1, 2)))
  693. # Default with output array.
  694. c = np.empty((2, 2, 3, 1))
  695. d = mm(a, b, out=c, axes=[(1, 2), (2, 3), (2, 3)])
  696. assert_(c is d)
  697. assert_array_equal(c, np.matmul(a, b))
  698. # Transposed output array
  699. c = np.empty((1, 2, 2, 3))
  700. d = mm(a, b, out=c, axes=[(-2, -1), (-2, -1), (3, 0)])
  701. assert_(c is d)
  702. assert_array_equal(c, np.matmul(a, b).transpose(3, 0, 1, 2))
  703. # Check errors for improperly constructed axes arguments.
  704. # wrong argument
  705. assert_raises(TypeError, mm, a, b, axis=1)
  706. # axes should be list
  707. assert_raises(TypeError, mm, a, b, axes=1)
  708. assert_raises(TypeError, mm, a, b, axes=((-2, -1), (-2, -1), (-2, -1)))
  709. # list needs to have right length
  710. assert_raises(ValueError, mm, a, b, axes=[])
  711. assert_raises(ValueError, mm, a, b, axes=[(-2, -1)])
  712. # list should contain tuples for multiple axes
  713. assert_raises(TypeError, mm, a, b, axes=[-1, -1, -1])
  714. assert_raises(TypeError, mm, a, b, axes=[(-2, -1), (-2, -1), -1])
  715. assert_raises(TypeError,
  716. mm, a, b, axes=[[-2, -1], [-2, -1], [-2, -1]])
  717. assert_raises(TypeError,
  718. mm, a, b, axes=[(-2, -1), (-2, -1), [-2, -1]])
  719. assert_raises(TypeError, mm, a, b, axes=[(-2, -1), (-2, -1), None])
  720. # tuples should not have duplicated values
  721. assert_raises(ValueError, mm, a, b, axes=[(-2, -1), (-2, -1), (-2, -2)])
  722. # arrays should have enough axes.
  723. z = np.zeros((2, 2))
  724. assert_raises(ValueError, mm, z, z[0])
  725. assert_raises(ValueError, mm, z, z, out=z[:, 0])
  726. assert_raises(ValueError, mm, z[1], z, axes=[0, 1])
  727. assert_raises(ValueError, mm, z, z, out=z[0], axes=[0, 1])
  728. # Regular ufuncs should not accept axes.
  729. assert_raises(TypeError, np.add, 1., 1., axes=[0])
  730. # should be able to deal with bad unrelated kwargs.
  731. assert_raises(TypeError, mm, z, z, axes=[0, 1], parrot=True)
  732. def test_axis_argument(self):
  733. # inner1d signature: '(i),(i)->()'
  734. inner1d = umt.inner1d
  735. a = np.arange(27.).reshape((3, 3, 3))
  736. b = np.arange(10., 19.).reshape((3, 1, 3))
  737. c = inner1d(a, b)
  738. assert_array_equal(c, (a * b).sum(-1))
  739. c = inner1d(a, b, axis=-1)
  740. assert_array_equal(c, (a * b).sum(-1))
  741. out = np.zeros_like(c)
  742. d = inner1d(a, b, axis=-1, out=out)
  743. assert_(d is out)
  744. assert_array_equal(d, c)
  745. c = inner1d(a, b, axis=0)
  746. assert_array_equal(c, (a * b).sum(0))
  747. # Sanity checks on innerwt and cumsum.
  748. a = np.arange(6).reshape((2, 3))
  749. b = np.arange(10, 16).reshape((2, 3))
  750. w = np.arange(20, 26).reshape((2, 3))
  751. assert_array_equal(umt.innerwt(a, b, w, axis=0),
  752. np.sum(a * b * w, axis=0))
  753. assert_array_equal(umt.cumsum(a, axis=0), np.cumsum(a, axis=0))
  754. assert_array_equal(umt.cumsum(a, axis=-1), np.cumsum(a, axis=-1))
  755. out = np.empty_like(a)
  756. b = umt.cumsum(a, out=out, axis=0)
  757. assert_(out is b)
  758. assert_array_equal(b, np.cumsum(a, axis=0))
  759. b = umt.cumsum(a, out=out, axis=1)
  760. assert_(out is b)
  761. assert_array_equal(b, np.cumsum(a, axis=-1))
  762. # Check errors.
  763. # Cannot pass in both axis and axes.
  764. assert_raises(TypeError, inner1d, a, b, axis=0, axes=[0, 0])
  765. # Not an integer.
  766. assert_raises(TypeError, inner1d, a, b, axis=[0])
  767. # more than 1 core dimensions.
  768. mm = umt.matrix_multiply
  769. assert_raises(TypeError, mm, a, b, axis=1)
  770. # Output wrong size in axis.
  771. out = np.empty((1, 2, 3), dtype=a.dtype)
  772. assert_raises(ValueError, umt.cumsum, a, out=out, axis=0)
  773. # Regular ufuncs should not accept axis.
  774. assert_raises(TypeError, np.add, 1., 1., axis=0)
  775. def test_keepdims_argument(self):
  776. # inner1d signature: '(i),(i)->()'
  777. inner1d = umt.inner1d
  778. a = np.arange(27.).reshape((3, 3, 3))
  779. b = np.arange(10., 19.).reshape((3, 1, 3))
  780. c = inner1d(a, b)
  781. assert_array_equal(c, (a * b).sum(-1))
  782. c = inner1d(a, b, keepdims=False)
  783. assert_array_equal(c, (a * b).sum(-1))
  784. c = inner1d(a, b, keepdims=True)
  785. assert_array_equal(c, (a * b).sum(-1, keepdims=True))
  786. out = np.zeros_like(c)
  787. d = inner1d(a, b, keepdims=True, out=out)
  788. assert_(d is out)
  789. assert_array_equal(d, c)
  790. # Now combined with axis and axes.
  791. c = inner1d(a, b, axis=-1, keepdims=False)
  792. assert_array_equal(c, (a * b).sum(-1, keepdims=False))
  793. c = inner1d(a, b, axis=-1, keepdims=True)
  794. assert_array_equal(c, (a * b).sum(-1, keepdims=True))
  795. c = inner1d(a, b, axis=0, keepdims=False)
  796. assert_array_equal(c, (a * b).sum(0, keepdims=False))
  797. c = inner1d(a, b, axis=0, keepdims=True)
  798. assert_array_equal(c, (a * b).sum(0, keepdims=True))
  799. c = inner1d(a, b, axes=[(-1,), (-1,), ()], keepdims=False)
  800. assert_array_equal(c, (a * b).sum(-1))
  801. c = inner1d(a, b, axes=[(-1,), (-1,), (-1,)], keepdims=True)
  802. assert_array_equal(c, (a * b).sum(-1, keepdims=True))
  803. c = inner1d(a, b, axes=[0, 0], keepdims=False)
  804. assert_array_equal(c, (a * b).sum(0))
  805. c = inner1d(a, b, axes=[0, 0, 0], keepdims=True)
  806. assert_array_equal(c, (a * b).sum(0, keepdims=True))
  807. c = inner1d(a, b, axes=[0, 2], keepdims=False)
  808. assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1))
  809. c = inner1d(a, b, axes=[0, 2], keepdims=True)
  810. assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1,
  811. keepdims=True))
  812. c = inner1d(a, b, axes=[0, 2, 2], keepdims=True)
  813. assert_array_equal(c, (a.transpose(1, 2, 0) * b).sum(-1,
  814. keepdims=True))
  815. c = inner1d(a, b, axes=[0, 2, 0], keepdims=True)
  816. assert_array_equal(c, (a * b.transpose(2, 0, 1)).sum(0, keepdims=True))
  817. # Hardly useful, but should work.
  818. c = inner1d(a, b, axes=[0, 2, 1], keepdims=True)
  819. assert_array_equal(c, (a.transpose(1, 0, 2) * b.transpose(0, 2, 1))
  820. .sum(1, keepdims=True))
  821. # Check with two core dimensions.
  822. a = np.eye(3) * np.arange(4.)[:, np.newaxis, np.newaxis]
  823. expected = uml.det(a)
  824. c = uml.det(a, keepdims=False)
  825. assert_array_equal(c, expected)
  826. c = uml.det(a, keepdims=True)
  827. assert_array_equal(c, expected[:, np.newaxis, np.newaxis])
  828. a = np.eye(3) * np.arange(4.)[:, np.newaxis, np.newaxis]
  829. expected_s, expected_l = uml.slogdet(a)
  830. cs, cl = uml.slogdet(a, keepdims=False)
  831. assert_array_equal(cs, expected_s)
  832. assert_array_equal(cl, expected_l)
  833. cs, cl = uml.slogdet(a, keepdims=True)
  834. assert_array_equal(cs, expected_s[:, np.newaxis, np.newaxis])
  835. assert_array_equal(cl, expected_l[:, np.newaxis, np.newaxis])
  836. # Sanity check on innerwt.
  837. a = np.arange(6).reshape((2, 3))
  838. b = np.arange(10, 16).reshape((2, 3))
  839. w = np.arange(20, 26).reshape((2, 3))
  840. assert_array_equal(umt.innerwt(a, b, w, keepdims=True),
  841. np.sum(a * b * w, axis=-1, keepdims=True))
  842. assert_array_equal(umt.innerwt(a, b, w, axis=0, keepdims=True),
  843. np.sum(a * b * w, axis=0, keepdims=True))
  844. # Check errors.
  845. # Not a boolean
  846. assert_raises(TypeError, inner1d, a, b, keepdims='true')
  847. # More than 1 core dimension, and core output dimensions.
  848. mm = umt.matrix_multiply
  849. assert_raises(TypeError, mm, a, b, keepdims=True)
  850. assert_raises(TypeError, mm, a, b, keepdims=False)
  851. # Regular ufuncs should not accept keepdims.
  852. assert_raises(TypeError, np.add, 1., 1., keepdims=False)
  853. def test_innerwt(self):
  854. a = np.arange(6).reshape((2, 3))
  855. b = np.arange(10, 16).reshape((2, 3))
  856. w = np.arange(20, 26).reshape((2, 3))
  857. assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
  858. a = np.arange(100, 124).reshape((2, 3, 4))
  859. b = np.arange(200, 224).reshape((2, 3, 4))
  860. w = np.arange(300, 324).reshape((2, 3, 4))
  861. assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
  862. def test_innerwt_empty(self):
  863. """Test generalized ufunc with zero-sized operands"""
  864. a = np.array([], dtype='f8')
  865. b = np.array([], dtype='f8')
  866. w = np.array([], dtype='f8')
  867. assert_array_equal(umt.innerwt(a, b, w), np.sum(a*b*w, axis=-1))
  868. def test_cross1d(self):
  869. """Test with fixed-sized signature."""
  870. a = np.eye(3)
  871. assert_array_equal(umt.cross1d(a, a), np.zeros((3, 3)))
  872. out = np.zeros((3, 3))
  873. result = umt.cross1d(a[0], a, out)
  874. assert_(result is out)
  875. assert_array_equal(result, np.vstack((np.zeros(3), a[2], -a[1])))
  876. assert_raises(ValueError, umt.cross1d, np.eye(4), np.eye(4))
  877. assert_raises(ValueError, umt.cross1d, a, np.arange(4.))
  878. # Wrong output core dimension.
  879. assert_raises(ValueError, umt.cross1d, a, np.arange(3.), np.zeros((3, 4)))
  880. # Wrong output broadcast dimension (see gh-15139).
  881. assert_raises(ValueError, umt.cross1d, a, np.arange(3.), np.zeros(3))
  882. def test_can_ignore_signature(self):
  883. # Comparing the effects of ? in signature:
  884. # matrix_multiply: (m,n),(n,p)->(m,p) # all must be there.
  885. # matmul: (m?,n),(n,p?)->(m?,p?) # allow missing m, p.
  886. mat = np.arange(12).reshape((2, 3, 2))
  887. single_vec = np.arange(2)
  888. col_vec = single_vec[:, np.newaxis]
  889. col_vec_array = np.arange(8).reshape((2, 2, 2, 1)) + 1
  890. # matrix @ single column vector with proper dimension
  891. mm_col_vec = umt.matrix_multiply(mat, col_vec)
  892. # matmul does the same thing
  893. matmul_col_vec = umt.matmul(mat, col_vec)
  894. assert_array_equal(matmul_col_vec, mm_col_vec)
  895. # matrix @ vector without dimension making it a column vector.
  896. # matrix multiply fails -> missing core dim.
  897. assert_raises(ValueError, umt.matrix_multiply, mat, single_vec)
  898. # matmul mimicker passes, and returns a vector.
  899. matmul_col = umt.matmul(mat, single_vec)
  900. assert_array_equal(matmul_col, mm_col_vec.squeeze())
  901. # Now with a column array: same as for column vector,
  902. # broadcasting sensibly.
  903. mm_col_vec = umt.matrix_multiply(mat, col_vec_array)
  904. matmul_col_vec = umt.matmul(mat, col_vec_array)
  905. assert_array_equal(matmul_col_vec, mm_col_vec)
  906. # As above, but for row vector
  907. single_vec = np.arange(3)
  908. row_vec = single_vec[np.newaxis, :]
  909. row_vec_array = np.arange(24).reshape((4, 2, 1, 1, 3)) + 1
  910. # row vector @ matrix
  911. mm_row_vec = umt.matrix_multiply(row_vec, mat)
  912. matmul_row_vec = umt.matmul(row_vec, mat)
  913. assert_array_equal(matmul_row_vec, mm_row_vec)
  914. # single row vector @ matrix
  915. assert_raises(ValueError, umt.matrix_multiply, single_vec, mat)
  916. matmul_row = umt.matmul(single_vec, mat)
  917. assert_array_equal(matmul_row, mm_row_vec.squeeze())
  918. # row vector array @ matrix
  919. mm_row_vec = umt.matrix_multiply(row_vec_array, mat)
  920. matmul_row_vec = umt.matmul(row_vec_array, mat)
  921. assert_array_equal(matmul_row_vec, mm_row_vec)
  922. # Now for vector combinations
  923. # row vector @ column vector
  924. col_vec = row_vec.T
  925. col_vec_array = row_vec_array.swapaxes(-2, -1)
  926. mm_row_col_vec = umt.matrix_multiply(row_vec, col_vec)
  927. matmul_row_col_vec = umt.matmul(row_vec, col_vec)
  928. assert_array_equal(matmul_row_col_vec, mm_row_col_vec)
  929. # single row vector @ single col vector
  930. assert_raises(ValueError, umt.matrix_multiply, single_vec, single_vec)
  931. matmul_row_col = umt.matmul(single_vec, single_vec)
  932. assert_array_equal(matmul_row_col, mm_row_col_vec.squeeze())
  933. # row vector array @ matrix
  934. mm_row_col_array = umt.matrix_multiply(row_vec_array, col_vec_array)
  935. matmul_row_col_array = umt.matmul(row_vec_array, col_vec_array)
  936. assert_array_equal(matmul_row_col_array, mm_row_col_array)
  937. # Finally, check that things are *not* squeezed if one gives an
  938. # output.
  939. out = np.zeros_like(mm_row_col_array)
  940. out = umt.matrix_multiply(row_vec_array, col_vec_array, out=out)
  941. assert_array_equal(out, mm_row_col_array)
  942. out[:] = 0
  943. out = umt.matmul(row_vec_array, col_vec_array, out=out)
  944. assert_array_equal(out, mm_row_col_array)
  945. # And check one cannot put missing dimensions back.
  946. out = np.zeros_like(mm_row_col_vec)
  947. assert_raises(ValueError, umt.matrix_multiply, single_vec, single_vec,
  948. out)
  949. # But fine for matmul, since it is just a broadcast.
  950. out = umt.matmul(single_vec, single_vec, out)
  951. assert_array_equal(out, mm_row_col_vec.squeeze())
  952. def test_matrix_multiply(self):
  953. self.compare_matrix_multiply_results(np.int64)
  954. self.compare_matrix_multiply_results(np.double)
  955. def test_matrix_multiply_umath_empty(self):
  956. res = umt.matrix_multiply(np.ones((0, 10)), np.ones((10, 0)))
  957. assert_array_equal(res, np.zeros((0, 0)))
  958. res = umt.matrix_multiply(np.ones((10, 0)), np.ones((0, 10)))
  959. assert_array_equal(res, np.zeros((10, 10)))
  960. def compare_matrix_multiply_results(self, tp):
  961. d1 = np.array(np.random.rand(2, 3, 4), dtype=tp)
  962. d2 = np.array(np.random.rand(2, 3, 4), dtype=tp)
  963. msg = "matrix multiply on type %s" % d1.dtype.name
  964. def permute_n(n):
  965. if n == 1:
  966. return ([0],)
  967. ret = ()
  968. base = permute_n(n-1)
  969. for perm in base:
  970. for i in range(n):
  971. new = perm + [n-1]
  972. new[n-1] = new[i]
  973. new[i] = n-1
  974. ret += (new,)
  975. return ret
  976. def slice_n(n):
  977. if n == 0:
  978. return ((),)
  979. ret = ()
  980. base = slice_n(n-1)
  981. for sl in base:
  982. ret += (sl+(slice(None),),)
  983. ret += (sl+(slice(0, 1),),)
  984. return ret
  985. def broadcastable(s1, s2):
  986. return s1 == s2 or s1 == 1 or s2 == 1
  987. permute_3 = permute_n(3)
  988. slice_3 = slice_n(3) + ((slice(None, None, -1),)*3,)
  989. ref = True
  990. for p1 in permute_3:
  991. for p2 in permute_3:
  992. for s1 in slice_3:
  993. for s2 in slice_3:
  994. a1 = d1.transpose(p1)[s1]
  995. a2 = d2.transpose(p2)[s2]
  996. ref = ref and a1.base is not None
  997. ref = ref and a2.base is not None
  998. if (a1.shape[-1] == a2.shape[-2] and
  999. broadcastable(a1.shape[0], a2.shape[0])):
  1000. assert_array_almost_equal(
  1001. umt.matrix_multiply(a1, a2),
  1002. np.sum(a2[..., np.newaxis].swapaxes(-3, -1) *
  1003. a1[..., np.newaxis,:], axis=-1),
  1004. err_msg=msg + ' %s %s' % (str(a1.shape),
  1005. str(a2.shape)))
  1006. assert_equal(ref, True, err_msg="reference check")
  1007. def test_euclidean_pdist(self):
  1008. a = np.arange(12, dtype=float).reshape(4, 3)
  1009. out = np.empty((a.shape[0] * (a.shape[0] - 1) // 2,), dtype=a.dtype)
  1010. umt.euclidean_pdist(a, out)
  1011. b = np.sqrt(np.sum((a[:, None] - a)**2, axis=-1))
  1012. b = b[~np.tri(a.shape[0], dtype=bool)]
  1013. assert_almost_equal(out, b)
  1014. # An output array is required to determine p with signature (n,d)->(p)
  1015. assert_raises(ValueError, umt.euclidean_pdist, a)
  1016. def test_cumsum(self):
  1017. a = np.arange(10)
  1018. result = umt.cumsum(a)
  1019. assert_array_equal(result, a.cumsum())
  1020. def test_object_logical(self):
  1021. a = np.array([3, None, True, False, "test", ""], dtype=object)
  1022. assert_equal(np.logical_or(a, None),
  1023. np.array([x or None for x in a], dtype=object))
  1024. assert_equal(np.logical_or(a, True),
  1025. np.array([x or True for x in a], dtype=object))
  1026. assert_equal(np.logical_or(a, 12),
  1027. np.array([x or 12 for x in a], dtype=object))
  1028. assert_equal(np.logical_or(a, "blah"),
  1029. np.array([x or "blah" for x in a], dtype=object))
  1030. assert_equal(np.logical_and(a, None),
  1031. np.array([x and None for x in a], dtype=object))
  1032. assert_equal(np.logical_and(a, True),
  1033. np.array([x and True for x in a], dtype=object))
  1034. assert_equal(np.logical_and(a, 12),
  1035. np.array([x and 12 for x in a], dtype=object))
  1036. assert_equal(np.logical_and(a, "blah"),
  1037. np.array([x and "blah" for x in a], dtype=object))
  1038. assert_equal(np.logical_not(a),
  1039. np.array([not x for x in a], dtype=object))
  1040. assert_equal(np.logical_or.reduce(a), 3)
  1041. assert_equal(np.logical_and.reduce(a), None)
  1042. def test_object_comparison(self):
  1043. class HasComparisons:
  1044. def __eq__(self, other):
  1045. return '=='
  1046. arr0d = np.array(HasComparisons())
  1047. assert_equal(arr0d == arr0d, True)
  1048. assert_equal(np.equal(arr0d, arr0d), True) # normal behavior is a cast
  1049. arr1d = np.array([HasComparisons()])
  1050. assert_equal(arr1d == arr1d, np.array([True]))
  1051. assert_equal(np.equal(arr1d, arr1d), np.array([True])) # normal behavior is a cast
  1052. assert_equal(np.equal(arr1d, arr1d, dtype=object), np.array(['==']))
  1053. def test_object_array_reduction(self):
  1054. # Reductions on object arrays
  1055. a = np.array(['a', 'b', 'c'], dtype=object)
  1056. assert_equal(np.sum(a), 'abc')
  1057. assert_equal(np.max(a), 'c')
  1058. assert_equal(np.min(a), 'a')
  1059. a = np.array([True, False, True], dtype=object)
  1060. assert_equal(np.sum(a), 2)
  1061. assert_equal(np.prod(a), 0)
  1062. assert_equal(np.any(a), True)
  1063. assert_equal(np.all(a), False)
  1064. assert_equal(np.max(a), True)
  1065. assert_equal(np.min(a), False)
  1066. assert_equal(np.array([[1]], dtype=object).sum(), 1)
  1067. assert_equal(np.array([[[1, 2]]], dtype=object).sum((0, 1)), [1, 2])
  1068. assert_equal(np.array([1], dtype=object).sum(initial=1), 2)
  1069. assert_equal(np.array([[1], [2, 3]], dtype=object)
  1070. .sum(initial=[0], where=[False, True]), [0, 2, 3])
  1071. def test_object_array_accumulate_inplace(self):
  1072. # Checks that in-place accumulates work, see also gh-7402
  1073. arr = np.ones(4, dtype=object)
  1074. arr[:] = [[1] for i in range(4)]
  1075. # Twice reproduced also for tuples:
  1076. np.add.accumulate(arr, out=arr)
  1077. np.add.accumulate(arr, out=arr)
  1078. assert_array_equal(arr,
  1079. np.array([[1]*i for i in [1, 3, 6, 10]], dtype=object),
  1080. )
  1081. # And the same if the axis argument is used
  1082. arr = np.ones((2, 4), dtype=object)
  1083. arr[0, :] = [[2] for i in range(4)]
  1084. np.add.accumulate(arr, out=arr, axis=-1)
  1085. np.add.accumulate(arr, out=arr, axis=-1)
  1086. assert_array_equal(arr[0, :],
  1087. np.array([[2]*i for i in [1, 3, 6, 10]], dtype=object),
  1088. )
  1089. def test_object_array_reduceat_inplace(self):
  1090. # Checks that in-place reduceats work, see also gh-7465
  1091. arr = np.empty(4, dtype=object)
  1092. arr[:] = [[1] for i in range(4)]
  1093. out = np.empty(4, dtype=object)
  1094. out[:] = [[1] for i in range(4)]
  1095. np.add.reduceat(arr, np.arange(4), out=arr)
  1096. np.add.reduceat(arr, np.arange(4), out=arr)
  1097. assert_array_equal(arr, out)
  1098. # And the same if the axis argument is used
  1099. arr = np.ones((2, 4), dtype=object)
  1100. arr[0, :] = [[2] for i in range(4)]
  1101. out = np.ones((2, 4), dtype=object)
  1102. out[0, :] = [[2] for i in range(4)]
  1103. np.add.reduceat(arr, np.arange(4), out=arr, axis=-1)
  1104. np.add.reduceat(arr, np.arange(4), out=arr, axis=-1)
  1105. assert_array_equal(arr, out)
  1106. def test_zerosize_reduction(self):
  1107. # Test with default dtype and object dtype
  1108. for a in [[], np.array([], dtype=object)]:
  1109. assert_equal(np.sum(a), 0)
  1110. assert_equal(np.prod(a), 1)
  1111. assert_equal(np.any(a), False)
  1112. assert_equal(np.all(a), True)
  1113. assert_raises(ValueError, np.max, a)
  1114. assert_raises(ValueError, np.min, a)
  1115. def test_axis_out_of_bounds(self):
  1116. a = np.array([False, False])
  1117. assert_raises(np.AxisError, a.all, axis=1)
  1118. a = np.array([False, False])
  1119. assert_raises(np.AxisError, a.all, axis=-2)
  1120. a = np.array([False, False])
  1121. assert_raises(np.AxisError, a.any, axis=1)
  1122. a = np.array([False, False])
  1123. assert_raises(np.AxisError, a.any, axis=-2)
  1124. def test_scalar_reduction(self):
  1125. # The functions 'sum', 'prod', etc allow specifying axis=0
  1126. # even for scalars
  1127. assert_equal(np.sum(3, axis=0), 3)
  1128. assert_equal(np.prod(3.5, axis=0), 3.5)
  1129. assert_equal(np.any(True, axis=0), True)
  1130. assert_equal(np.all(False, axis=0), False)
  1131. assert_equal(np.max(3, axis=0), 3)
  1132. assert_equal(np.min(2.5, axis=0), 2.5)
  1133. # Check scalar behaviour for ufuncs without an identity
  1134. assert_equal(np.power.reduce(3), 3)
  1135. # Make sure that scalars are coming out from this operation
  1136. assert_(type(np.prod(np.float32(2.5), axis=0)) is np.float32)
  1137. assert_(type(np.sum(np.float32(2.5), axis=0)) is np.float32)
  1138. assert_(type(np.max(np.float32(2.5), axis=0)) is np.float32)
  1139. assert_(type(np.min(np.float32(2.5), axis=0)) is np.float32)
  1140. # check if scalars/0-d arrays get cast
  1141. assert_(type(np.any(0, axis=0)) is np.bool_)
  1142. # assert that 0-d arrays get wrapped
  1143. class MyArray(np.ndarray):
  1144. pass
  1145. a = np.array(1).view(MyArray)
  1146. assert_(type(np.any(a)) is MyArray)
  1147. def test_casting_out_param(self):
  1148. # Test that it's possible to do casts on output
  1149. a = np.ones((200, 100), np.int64)
  1150. b = np.ones((200, 100), np.int64)
  1151. c = np.ones((200, 100), np.float64)
  1152. np.add(a, b, out=c)
  1153. assert_equal(c, 2)
  1154. a = np.zeros(65536)
  1155. b = np.zeros(65536, dtype=np.float32)
  1156. np.subtract(a, 0, out=b)
  1157. assert_equal(b, 0)
  1158. def test_where_param(self):
  1159. # Test that the where= ufunc parameter works with regular arrays
  1160. a = np.arange(7)
  1161. b = np.ones(7)
  1162. c = np.zeros(7)
  1163. np.add(a, b, out=c, where=(a % 2 == 1))
  1164. assert_equal(c, [0, 2, 0, 4, 0, 6, 0])
  1165. a = np.arange(4).reshape(2, 2) + 2
  1166. np.power(a, [2, 3], out=a, where=[[0, 1], [1, 0]])
  1167. assert_equal(a, [[2, 27], [16, 5]])
  1168. # Broadcasting the where= parameter
  1169. np.subtract(a, 2, out=a, where=[True, False])
  1170. assert_equal(a, [[0, 27], [14, 5]])
  1171. def test_where_param_buffer_output(self):
  1172. # This test is temporarily skipped because it requires
  1173. # adding masking features to the nditer to work properly
  1174. # With casting on output
  1175. a = np.ones(10, np.int64)
  1176. b = np.ones(10, np.int64)
  1177. c = 1.5 * np.ones(10, np.float64)
  1178. np.add(a, b, out=c, where=[1, 0, 0, 1, 0, 0, 1, 1, 1, 0])
  1179. assert_equal(c, [2, 1.5, 1.5, 2, 1.5, 1.5, 2, 2, 2, 1.5])
  1180. def test_where_param_alloc(self):
  1181. # With casting and allocated output
  1182. a = np.array([1], dtype=np.int64)
  1183. m = np.array([True], dtype=bool)
  1184. assert_equal(np.sqrt(a, where=m), [1])
  1185. # No casting and allocated output
  1186. a = np.array([1], dtype=np.float64)
  1187. m = np.array([True], dtype=bool)
  1188. assert_equal(np.sqrt(a, where=m), [1])
  1189. def test_where_with_broadcasting(self):
  1190. # See gh-17198
  1191. a = np.random.random((5000, 4))
  1192. b = np.random.random((5000, 1))
  1193. where = a > 0.3
  1194. out = np.full_like(a, 0)
  1195. np.less(a, b, where=where, out=out)
  1196. b_where = np.broadcast_to(b, a.shape)[where]
  1197. assert_array_equal((a[where] < b_where), out[where].astype(bool))
  1198. assert not out[~where].any() # outside mask, out remains all 0
  1199. def check_identityless_reduction(self, a):
  1200. # np.minimum.reduce is an identityless reduction
  1201. # Verify that it sees the zero at various positions
  1202. a[...] = 1
  1203. a[1, 0, 0] = 0
  1204. assert_equal(np.minimum.reduce(a, axis=None), 0)
  1205. assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
  1206. assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
  1207. assert_equal(np.minimum.reduce(a, axis=(1, 2)), [1, 0])
  1208. assert_equal(np.minimum.reduce(a, axis=0),
  1209. [[0, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
  1210. assert_equal(np.minimum.reduce(a, axis=1),
  1211. [[1, 1, 1, 1], [0, 1, 1, 1]])
  1212. assert_equal(np.minimum.reduce(a, axis=2),
  1213. [[1, 1, 1], [0, 1, 1]])
  1214. assert_equal(np.minimum.reduce(a, axis=()), a)
  1215. a[...] = 1
  1216. a[0, 1, 0] = 0
  1217. assert_equal(np.minimum.reduce(a, axis=None), 0)
  1218. assert_equal(np.minimum.reduce(a, axis=(0, 1)), [0, 1, 1, 1])
  1219. assert_equal(np.minimum.reduce(a, axis=(0, 2)), [1, 0, 1])
  1220. assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
  1221. assert_equal(np.minimum.reduce(a, axis=0),
  1222. [[1, 1, 1, 1], [0, 1, 1, 1], [1, 1, 1, 1]])
  1223. assert_equal(np.minimum.reduce(a, axis=1),
  1224. [[0, 1, 1, 1], [1, 1, 1, 1]])
  1225. assert_equal(np.minimum.reduce(a, axis=2),
  1226. [[1, 0, 1], [1, 1, 1]])
  1227. assert_equal(np.minimum.reduce(a, axis=()), a)
  1228. a[...] = 1
  1229. a[0, 0, 1] = 0
  1230. assert_equal(np.minimum.reduce(a, axis=None), 0)
  1231. assert_equal(np.minimum.reduce(a, axis=(0, 1)), [1, 0, 1, 1])
  1232. assert_equal(np.minimum.reduce(a, axis=(0, 2)), [0, 1, 1])
  1233. assert_equal(np.minimum.reduce(a, axis=(1, 2)), [0, 1])
  1234. assert_equal(np.minimum.reduce(a, axis=0),
  1235. [[1, 0, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]])
  1236. assert_equal(np.minimum.reduce(a, axis=1),
  1237. [[1, 0, 1, 1], [1, 1, 1, 1]])
  1238. assert_equal(np.minimum.reduce(a, axis=2),
  1239. [[0, 1, 1], [1, 1, 1]])
  1240. assert_equal(np.minimum.reduce(a, axis=()), a)
  1241. def test_identityless_reduction_corder(self):
  1242. a = np.empty((2, 3, 4), order='C')
  1243. self.check_identityless_reduction(a)
  1244. def test_identityless_reduction_forder(self):
  1245. a = np.empty((2, 3, 4), order='F')
  1246. self.check_identityless_reduction(a)
  1247. def test_identityless_reduction_otherorder(self):
  1248. a = np.empty((2, 4, 3), order='C').swapaxes(1, 2)
  1249. self.check_identityless_reduction(a)
  1250. def test_identityless_reduction_noncontig(self):
  1251. a = np.empty((3, 5, 4), order='C').swapaxes(1, 2)
  1252. a = a[1:, 1:, 1:]
  1253. self.check_identityless_reduction(a)
  1254. def test_identityless_reduction_noncontig_unaligned(self):
  1255. a = np.empty((3*4*5*8 + 1,), dtype='i1')
  1256. a = a[1:].view(dtype='f8')
  1257. a.shape = (3, 4, 5)
  1258. a = a[1:, 1:, 1:]
  1259. self.check_identityless_reduction(a)
  1260. def test_initial_reduction(self):
  1261. # np.minimum.reduce is an identityless reduction
  1262. # For cases like np.maximum(np.abs(...), initial=0)
  1263. # More generally, a supremum over non-negative numbers.
  1264. assert_equal(np.maximum.reduce([], initial=0), 0)
  1265. # For cases like reduction of an empty array over the reals.
  1266. assert_equal(np.minimum.reduce([], initial=np.inf), np.inf)
  1267. assert_equal(np.maximum.reduce([], initial=-np.inf), -np.inf)
  1268. # Random tests
  1269. assert_equal(np.minimum.reduce([5], initial=4), 4)
  1270. assert_equal(np.maximum.reduce([4], initial=5), 5)
  1271. assert_equal(np.maximum.reduce([5], initial=4), 5)
  1272. assert_equal(np.minimum.reduce([4], initial=5), 4)
  1273. # Check initial=None raises ValueError for both types of ufunc reductions
  1274. assert_raises(ValueError, np.minimum.reduce, [], initial=None)
  1275. assert_raises(ValueError, np.add.reduce, [], initial=None)
  1276. # Check that np._NoValue gives default behavior.
  1277. assert_equal(np.add.reduce([], initial=np._NoValue), 0)
  1278. # Check that initial kwarg behaves as intended for dtype=object
  1279. a = np.array([10], dtype=object)
  1280. res = np.add.reduce(a, initial=5)
  1281. assert_equal(res, 15)
  1282. @pytest.mark.parametrize('axis', (0, 1, None))
  1283. @pytest.mark.parametrize('where', (np.array([False, True, True]),
  1284. np.array([[True], [False], [True]]),
  1285. np.array([[True, False, False],
  1286. [False, True, False],
  1287. [False, True, True]])))
  1288. def test_reduction_with_where(self, axis, where):
  1289. a = np.arange(9.).reshape(3, 3)
  1290. a_copy = a.copy()
  1291. a_check = np.zeros_like(a)
  1292. np.positive(a, out=a_check, where=where)
  1293. res = np.add.reduce(a, axis=axis, where=where)
  1294. check = a_check.sum(axis)
  1295. assert_equal(res, check)
  1296. # Check we do not overwrite elements of a internally.
  1297. assert_array_equal(a, a_copy)
  1298. @pytest.mark.parametrize(('axis', 'where'),
  1299. ((0, np.array([True, False, True])),
  1300. (1, [True, True, False]),
  1301. (None, True)))
  1302. @pytest.mark.parametrize('initial', (-np.inf, 5.))
  1303. def test_reduction_with_where_and_initial(self, axis, where, initial):
  1304. a = np.arange(9.).reshape(3, 3)
  1305. a_copy = a.copy()
  1306. a_check = np.full(a.shape, -np.inf)
  1307. np.positive(a, out=a_check, where=where)
  1308. res = np.maximum.reduce(a, axis=axis, where=where, initial=initial)
  1309. check = a_check.max(axis, initial=initial)
  1310. assert_equal(res, check)
  1311. def test_reduction_where_initial_needed(self):
  1312. a = np.arange(9.).reshape(3, 3)
  1313. m = [False, True, False]
  1314. assert_raises(ValueError, np.maximum.reduce, a, where=m)
  1315. def test_identityless_reduction_nonreorderable(self):
  1316. a = np.array([[8.0, 2.0, 2.0], [1.0, 0.5, 0.25]])
  1317. res = np.divide.reduce(a, axis=0)
  1318. assert_equal(res, [8.0, 4.0, 8.0])
  1319. res = np.divide.reduce(a, axis=1)
  1320. assert_equal(res, [2.0, 8.0])
  1321. res = np.divide.reduce(a, axis=())
  1322. assert_equal(res, a)
  1323. assert_raises(ValueError, np.divide.reduce, a, axis=(0, 1))
  1324. def test_reduce_zero_axis(self):
  1325. # If we have a n x m array and do a reduction with axis=1, then we are
  1326. # doing n reductions, and each reduction takes an m-element array. For
  1327. # a reduction operation without an identity, then:
  1328. # n > 0, m > 0: fine
  1329. # n = 0, m > 0: fine, doing 0 reductions of m-element arrays
  1330. # n > 0, m = 0: can't reduce a 0-element array, ValueError
  1331. # n = 0, m = 0: can't reduce a 0-element array, ValueError (for
  1332. # consistency with the above case)
  1333. # This test doesn't actually look at return values, it just checks to
  1334. # make sure that error we get an error in exactly those cases where we
  1335. # expect one, and assumes the calculations themselves are done
  1336. # correctly.
  1337. def ok(f, *args, **kwargs):
  1338. f(*args, **kwargs)
  1339. def err(f, *args, **kwargs):
  1340. assert_raises(ValueError, f, *args, **kwargs)
  1341. def t(expect, func, n, m):
  1342. expect(func, np.zeros((n, m)), axis=1)
  1343. expect(func, np.zeros((m, n)), axis=0)
  1344. expect(func, np.zeros((n // 2, n // 2, m)), axis=2)
  1345. expect(func, np.zeros((n // 2, m, n // 2)), axis=1)
  1346. expect(func, np.zeros((n, m // 2, m // 2)), axis=(1, 2))
  1347. expect(func, np.zeros((m // 2, n, m // 2)), axis=(0, 2))
  1348. expect(func, np.zeros((m // 3, m // 3, m // 3,
  1349. n // 2, n // 2)),
  1350. axis=(0, 1, 2))
  1351. # Check what happens if the inner (resp. outer) dimensions are a
  1352. # mix of zero and non-zero:
  1353. expect(func, np.zeros((10, m, n)), axis=(0, 1))
  1354. expect(func, np.zeros((10, n, m)), axis=(0, 2))
  1355. expect(func, np.zeros((m, 10, n)), axis=0)
  1356. expect(func, np.zeros((10, m, n)), axis=1)
  1357. expect(func, np.zeros((10, n, m)), axis=2)
  1358. # np.maximum is just an arbitrary ufunc with no reduction identity
  1359. assert_equal(np.maximum.identity, None)
  1360. t(ok, np.maximum.reduce, 30, 30)
  1361. t(ok, np.maximum.reduce, 0, 30)
  1362. t(err, np.maximum.reduce, 30, 0)
  1363. t(err, np.maximum.reduce, 0, 0)
  1364. err(np.maximum.reduce, [])
  1365. np.maximum.reduce(np.zeros((0, 0)), axis=())
  1366. # all of the combinations are fine for a reduction that has an
  1367. # identity
  1368. t(ok, np.add.reduce, 30, 30)
  1369. t(ok, np.add.reduce, 0, 30)
  1370. t(ok, np.add.reduce, 30, 0)
  1371. t(ok, np.add.reduce, 0, 0)
  1372. np.add.reduce([])
  1373. np.add.reduce(np.zeros((0, 0)), axis=())
  1374. # OTOH, accumulate always makes sense for any combination of n and m,
  1375. # because it maps an m-element array to an m-element array. These
  1376. # tests are simpler because accumulate doesn't accept multiple axes.
  1377. for uf in (np.maximum, np.add):
  1378. uf.accumulate(np.zeros((30, 0)), axis=0)
  1379. uf.accumulate(np.zeros((0, 30)), axis=0)
  1380. uf.accumulate(np.zeros((30, 30)), axis=0)
  1381. uf.accumulate(np.zeros((0, 0)), axis=0)
  1382. def test_safe_casting(self):
  1383. # In old versions of numpy, in-place operations used the 'unsafe'
  1384. # casting rules. In versions >= 1.10, 'same_kind' is the
  1385. # default and an exception is raised instead of a warning.
  1386. # when 'same_kind' is not satisfied.
  1387. a = np.array([1, 2, 3], dtype=int)
  1388. # Non-in-place addition is fine
  1389. assert_array_equal(assert_no_warnings(np.add, a, 1.1),
  1390. [2.1, 3.1, 4.1])
  1391. assert_raises(TypeError, np.add, a, 1.1, out=a)
  1392. def add_inplace(a, b):
  1393. a += b
  1394. assert_raises(TypeError, add_inplace, a, 1.1)
  1395. # Make sure that explicitly overriding the exception is allowed:
  1396. assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe")
  1397. assert_array_equal(a, [2, 3, 4])
  1398. def test_ufunc_custom_out(self):
  1399. # Test ufunc with built in input types and custom output type
  1400. a = np.array([0, 1, 2], dtype='i8')
  1401. b = np.array([0, 1, 2], dtype='i8')
  1402. c = np.empty(3, dtype=_rational_tests.rational)
  1403. # Output must be specified so numpy knows what
  1404. # ufunc signature to look for
  1405. result = _rational_tests.test_add(a, b, c)
  1406. target = np.array([0, 2, 4], dtype=_rational_tests.rational)
  1407. assert_equal(result, target)
  1408. # no output type should raise TypeError
  1409. with assert_raises(TypeError):
  1410. _rational_tests.test_add(a, b)
  1411. def test_operand_flags(self):
  1412. a = np.arange(16, dtype='l').reshape(4, 4)
  1413. b = np.arange(9, dtype='l').reshape(3, 3)
  1414. opflag_tests.inplace_add(a[:-1, :-1], b)
  1415. assert_equal(a, np.array([[0, 2, 4, 3], [7, 9, 11, 7],
  1416. [14, 16, 18, 11], [12, 13, 14, 15]], dtype='l'))
  1417. a = np.array(0)
  1418. opflag_tests.inplace_add(a, 3)
  1419. assert_equal(a, 3)
  1420. opflag_tests.inplace_add(a, [3, 4])
  1421. assert_equal(a, 10)
  1422. def test_struct_ufunc(self):
  1423. import numpy.core._struct_ufunc_tests as struct_ufunc
  1424. a = np.array([(1, 2, 3)], dtype='u8,u8,u8')
  1425. b = np.array([(1, 2, 3)], dtype='u8,u8,u8')
  1426. result = struct_ufunc.add_triplet(a, b)
  1427. assert_equal(result, np.array([(2, 4, 6)], dtype='u8,u8,u8'))
  1428. assert_raises(RuntimeError, struct_ufunc.register_fail)
  1429. def test_custom_ufunc(self):
  1430. a = np.array(
  1431. [_rational_tests.rational(1, 2),
  1432. _rational_tests.rational(1, 3),
  1433. _rational_tests.rational(1, 4)],
  1434. dtype=_rational_tests.rational)
  1435. b = np.array(
  1436. [_rational_tests.rational(1, 2),
  1437. _rational_tests.rational(1, 3),
  1438. _rational_tests.rational(1, 4)],
  1439. dtype=_rational_tests.rational)
  1440. result = _rational_tests.test_add_rationals(a, b)
  1441. expected = np.array(
  1442. [_rational_tests.rational(1),
  1443. _rational_tests.rational(2, 3),
  1444. _rational_tests.rational(1, 2)],
  1445. dtype=_rational_tests.rational)
  1446. assert_equal(result, expected)
  1447. def test_custom_ufunc_forced_sig(self):
  1448. # gh-9351 - looking for a non-first userloop would previously hang
  1449. with assert_raises(TypeError):
  1450. np.multiply(_rational_tests.rational(1), 1,
  1451. signature=(_rational_tests.rational, int, None))
  1452. def test_custom_array_like(self):
  1453. class MyThing:
  1454. __array_priority__ = 1000
  1455. rmul_count = 0
  1456. getitem_count = 0
  1457. def __init__(self, shape):
  1458. self.shape = shape
  1459. def __len__(self):
  1460. return self.shape[0]
  1461. def __getitem__(self, i):
  1462. MyThing.getitem_count += 1
  1463. if not isinstance(i, tuple):
  1464. i = (i,)
  1465. if len(i) > self.ndim:
  1466. raise IndexError("boo")
  1467. return MyThing(self.shape[len(i):])
  1468. def __rmul__(self, other):
  1469. MyThing.rmul_count += 1
  1470. return self
  1471. np.float64(5)*MyThing((3, 3))
  1472. assert_(MyThing.rmul_count == 1, MyThing.rmul_count)
  1473. assert_(MyThing.getitem_count <= 2, MyThing.getitem_count)
  1474. def test_inplace_fancy_indexing(self):
  1475. a = np.arange(10)
  1476. np.add.at(a, [2, 5, 2], 1)
  1477. assert_equal(a, [0, 1, 4, 3, 4, 6, 6, 7, 8, 9])
  1478. a = np.arange(10)
  1479. b = np.array([100, 100, 100])
  1480. np.add.at(a, [2, 5, 2], b)
  1481. assert_equal(a, [0, 1, 202, 3, 4, 105, 6, 7, 8, 9])
  1482. a = np.arange(9).reshape(3, 3)
  1483. b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
  1484. np.add.at(a, (slice(None), [1, 2, 1]), b)
  1485. assert_equal(a, [[0, 201, 102], [3, 404, 205], [6, 607, 308]])
  1486. a = np.arange(27).reshape(3, 3, 3)
  1487. b = np.array([100, 200, 300])
  1488. np.add.at(a, (slice(None), slice(None), [1, 2, 1]), b)
  1489. assert_equal(a,
  1490. [[[0, 401, 202],
  1491. [3, 404, 205],
  1492. [6, 407, 208]],
  1493. [[9, 410, 211],
  1494. [12, 413, 214],
  1495. [15, 416, 217]],
  1496. [[18, 419, 220],
  1497. [21, 422, 223],
  1498. [24, 425, 226]]])
  1499. a = np.arange(9).reshape(3, 3)
  1500. b = np.array([[100, 100, 100], [200, 200, 200], [300, 300, 300]])
  1501. np.add.at(a, ([1, 2, 1], slice(None)), b)
  1502. assert_equal(a, [[0, 1, 2], [403, 404, 405], [206, 207, 208]])
  1503. a = np.arange(27).reshape(3, 3, 3)
  1504. b = np.array([100, 200, 300])
  1505. np.add.at(a, (slice(None), [1, 2, 1], slice(None)), b)
  1506. assert_equal(a,
  1507. [[[0, 1, 2],
  1508. [203, 404, 605],
  1509. [106, 207, 308]],
  1510. [[9, 10, 11],
  1511. [212, 413, 614],
  1512. [115, 216, 317]],
  1513. [[18, 19, 20],
  1514. [221, 422, 623],
  1515. [124, 225, 326]]])
  1516. a = np.arange(9).reshape(3, 3)
  1517. b = np.array([100, 200, 300])
  1518. np.add.at(a, (0, [1, 2, 1]), b)
  1519. assert_equal(a, [[0, 401, 202], [3, 4, 5], [6, 7, 8]])
  1520. a = np.arange(27).reshape(3, 3, 3)
  1521. b = np.array([100, 200, 300])
  1522. np.add.at(a, ([1, 2, 1], 0, slice(None)), b)
  1523. assert_equal(a,
  1524. [[[0, 1, 2],
  1525. [3, 4, 5],
  1526. [6, 7, 8]],
  1527. [[209, 410, 611],
  1528. [12, 13, 14],
  1529. [15, 16, 17]],
  1530. [[118, 219, 320],
  1531. [21, 22, 23],
  1532. [24, 25, 26]]])
  1533. a = np.arange(27).reshape(3, 3, 3)
  1534. b = np.array([100, 200, 300])
  1535. np.add.at(a, (slice(None), slice(None), slice(None)), b)
  1536. assert_equal(a,
  1537. [[[100, 201, 302],
  1538. [103, 204, 305],
  1539. [106, 207, 308]],
  1540. [[109, 210, 311],
  1541. [112, 213, 314],
  1542. [115, 216, 317]],
  1543. [[118, 219, 320],
  1544. [121, 222, 323],
  1545. [124, 225, 326]]])
  1546. a = np.arange(10)
  1547. np.negative.at(a, [2, 5, 2])
  1548. assert_equal(a, [0, 1, 2, 3, 4, -5, 6, 7, 8, 9])
  1549. # Test 0-dim array
  1550. a = np.array(0)
  1551. np.add.at(a, (), 1)
  1552. assert_equal(a, 1)
  1553. assert_raises(IndexError, np.add.at, a, 0, 1)
  1554. assert_raises(IndexError, np.add.at, a, [], 1)
  1555. # Test mixed dtypes
  1556. a = np.arange(10)
  1557. np.power.at(a, [1, 2, 3, 2], 3.5)
  1558. assert_equal(a, np.array([0, 1, 4414, 46, 4, 5, 6, 7, 8, 9]))
  1559. # Test boolean indexing and boolean ufuncs
  1560. a = np.arange(10)
  1561. index = a % 2 == 0
  1562. np.equal.at(a, index, [0, 2, 4, 6, 8])
  1563. assert_equal(a, [1, 1, 1, 3, 1, 5, 1, 7, 1, 9])
  1564. # Test unary operator
  1565. a = np.arange(10, dtype='u4')
  1566. np.invert.at(a, [2, 5, 2])
  1567. assert_equal(a, [0, 1, 2, 3, 4, 5 ^ 0xffffffff, 6, 7, 8, 9])
  1568. # Test empty subspace
  1569. orig = np.arange(4)
  1570. a = orig[:, None][:, 0:0]
  1571. np.add.at(a, [0, 1], 3)
  1572. assert_array_equal(orig, np.arange(4))
  1573. # Test with swapped byte order
  1574. index = np.array([1, 2, 1], np.dtype('i').newbyteorder())
  1575. values = np.array([1, 2, 3, 4], np.dtype('f').newbyteorder())
  1576. np.add.at(values, index, 3)
  1577. assert_array_equal(values, [1, 8, 6, 4])
  1578. # Test exception thrown
  1579. values = np.array(['a', 1], dtype=object)
  1580. assert_raises(TypeError, np.add.at, values, [0, 1], 1)
  1581. assert_array_equal(values, np.array(['a', 1], dtype=object))
  1582. # Test multiple output ufuncs raise error, gh-5665
  1583. assert_raises(ValueError, np.modf.at, np.arange(10), [1])
  1584. def test_reduce_arguments(self):
  1585. f = np.add.reduce
  1586. d = np.ones((5,2), dtype=int)
  1587. o = np.ones((2,), dtype=d.dtype)
  1588. r = o * 5
  1589. assert_equal(f(d), r)
  1590. # a, axis=0, dtype=None, out=None, keepdims=False
  1591. assert_equal(f(d, axis=0), r)
  1592. assert_equal(f(d, 0), r)
  1593. assert_equal(f(d, 0, dtype=None), r)
  1594. assert_equal(f(d, 0, dtype='i'), r)
  1595. assert_equal(f(d, 0, 'i'), r)
  1596. assert_equal(f(d, 0, None), r)
  1597. assert_equal(f(d, 0, None, out=None), r)
  1598. assert_equal(f(d, 0, None, out=o), r)
  1599. assert_equal(f(d, 0, None, o), r)
  1600. assert_equal(f(d, 0, None, None), r)
  1601. assert_equal(f(d, 0, None, None, keepdims=False), r)
  1602. assert_equal(f(d, 0, None, None, True), r.reshape((1,) + r.shape))
  1603. assert_equal(f(d, 0, None, None, False, 0), r)
  1604. assert_equal(f(d, 0, None, None, False, initial=0), r)
  1605. assert_equal(f(d, 0, None, None, False, 0, True), r)
  1606. assert_equal(f(d, 0, None, None, False, 0, where=True), r)
  1607. # multiple keywords
  1608. assert_equal(f(d, axis=0, dtype=None, out=None, keepdims=False), r)
  1609. assert_equal(f(d, 0, dtype=None, out=None, keepdims=False), r)
  1610. assert_equal(f(d, 0, None, out=None, keepdims=False), r)
  1611. assert_equal(f(d, 0, None, out=None, keepdims=False, initial=0,
  1612. where=True), r)
  1613. # too little
  1614. assert_raises(TypeError, f)
  1615. # too much
  1616. assert_raises(TypeError, f, d, 0, None, None, False, 0, True, 1)
  1617. # invalid axis
  1618. assert_raises(TypeError, f, d, "invalid")
  1619. assert_raises(TypeError, f, d, axis="invalid")
  1620. assert_raises(TypeError, f, d, axis="invalid", dtype=None,
  1621. keepdims=True)
  1622. # invalid dtype
  1623. assert_raises(TypeError, f, d, 0, "invalid")
  1624. assert_raises(TypeError, f, d, dtype="invalid")
  1625. assert_raises(TypeError, f, d, dtype="invalid", out=None)
  1626. # invalid out
  1627. assert_raises(TypeError, f, d, 0, None, "invalid")
  1628. assert_raises(TypeError, f, d, out="invalid")
  1629. assert_raises(TypeError, f, d, out="invalid", dtype=None)
  1630. # keepdims boolean, no invalid value
  1631. # assert_raises(TypeError, f, d, 0, None, None, "invalid")
  1632. # assert_raises(TypeError, f, d, keepdims="invalid", axis=0, dtype=None)
  1633. # invalid mix
  1634. assert_raises(TypeError, f, d, 0, keepdims="invalid", dtype="invalid",
  1635. out=None)
  1636. # invalid keyword
  1637. assert_raises(TypeError, f, d, axis=0, dtype=None, invalid=0)
  1638. assert_raises(TypeError, f, d, invalid=0)
  1639. assert_raises(TypeError, f, d, 0, keepdims=True, invalid="invalid",
  1640. out=None)
  1641. assert_raises(TypeError, f, d, axis=0, dtype=None, keepdims=True,
  1642. out=None, invalid=0)
  1643. assert_raises(TypeError, f, d, axis=0, dtype=None,
  1644. out=None, invalid=0)
  1645. def test_structured_equal(self):
  1646. # https://github.com/numpy/numpy/issues/4855
  1647. class MyA(np.ndarray):
  1648. def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
  1649. return getattr(ufunc, method)(*(input.view(np.ndarray)
  1650. for input in inputs), **kwargs)
  1651. a = np.arange(12.).reshape(4,3)
  1652. ra = a.view(dtype=('f8,f8,f8')).squeeze()
  1653. mra = ra.view(MyA)
  1654. target = np.array([ True, False, False, False], dtype=bool)
  1655. assert_equal(np.all(target == (mra == ra[0])), True)
  1656. def test_scalar_equal(self):
  1657. # Scalar comparisons should always work, without deprecation warnings.
  1658. # even when the ufunc fails.
  1659. a = np.array(0.)
  1660. b = np.array('a')
  1661. assert_(a != b)
  1662. assert_(b != a)
  1663. assert_(not (a == b))
  1664. assert_(not (b == a))
  1665. def test_NotImplemented_not_returned(self):
  1666. # See gh-5964 and gh-2091. Some of these functions are not operator
  1667. # related and were fixed for other reasons in the past.
  1668. binary_funcs = [
  1669. np.power, np.add, np.subtract, np.multiply, np.divide,
  1670. np.true_divide, np.floor_divide, np.bitwise_and, np.bitwise_or,
  1671. np.bitwise_xor, np.left_shift, np.right_shift, np.fmax,
  1672. np.fmin, np.fmod, np.hypot, np.logaddexp, np.logaddexp2,
  1673. np.logical_and, np.logical_or, np.logical_xor, np.maximum,
  1674. np.minimum, np.mod,
  1675. np.greater, np.greater_equal, np.less, np.less_equal,
  1676. np.equal, np.not_equal]
  1677. a = np.array('1')
  1678. b = 1
  1679. c = np.array([1., 2.])
  1680. for f in binary_funcs:
  1681. assert_raises(TypeError, f, a, b)
  1682. assert_raises(TypeError, f, c, a)
  1683. def test_reduce_noncontig_output(self):
  1684. # Check that reduction deals with non-contiguous output arrays
  1685. # appropriately.
  1686. #
  1687. # gh-8036
  1688. x = np.arange(7*13*8, dtype=np.int16).reshape(7, 13, 8)
  1689. x = x[4:6,1:11:6,1:5].transpose(1, 2, 0)
  1690. y_base = np.arange(4*4, dtype=np.int16).reshape(4, 4)
  1691. y = y_base[::2,:]
  1692. y_base_copy = y_base.copy()
  1693. r0 = np.add.reduce(x, out=y.copy(), axis=2)
  1694. r1 = np.add.reduce(x, out=y, axis=2)
  1695. # The results should match, and y_base shouldn't get clobbered
  1696. assert_equal(r0, r1)
  1697. assert_equal(y_base[1,:], y_base_copy[1,:])
  1698. assert_equal(y_base[3,:], y_base_copy[3,:])
  1699. @pytest.mark.parametrize('out_shape',
  1700. [(), (1,), (3,), (1, 1), (1, 3), (4, 3)])
  1701. @pytest.mark.parametrize('keepdims', [True, False])
  1702. @pytest.mark.parametrize('f_reduce', [np.add.reduce, np.minimum.reduce])
  1703. def test_reduce_wrong_dimension_output(self, f_reduce, keepdims, out_shape):
  1704. # Test that we're not incorrectly broadcasting dimensions.
  1705. # See gh-15144 (failed for np.add.reduce previously).
  1706. a = np.arange(12.).reshape(4, 3)
  1707. out = np.empty(out_shape, a.dtype)
  1708. correct_out = f_reduce(a, axis=0, keepdims=keepdims)
  1709. if out_shape != correct_out.shape:
  1710. with assert_raises(ValueError):
  1711. f_reduce(a, axis=0, out=out, keepdims=keepdims)
  1712. else:
  1713. check = f_reduce(a, axis=0, out=out, keepdims=keepdims)
  1714. assert_(check is out)
  1715. assert_array_equal(check, correct_out)
  1716. def test_reduce_output_does_not_broadcast_input(self):
  1717. # Test that the output shape cannot broadcast an input dimension
  1718. # (it never can add dimensions, but it might expand an existing one)
  1719. a = np.ones((1, 10))
  1720. out_correct = (np.empty((1, 1)))
  1721. out_incorrect = np.empty((3, 1))
  1722. np.add.reduce(a, axis=-1, out=out_correct, keepdims=True)
  1723. np.add.reduce(a, axis=-1, out=out_correct[:, 0], keepdims=False)
  1724. with assert_raises(ValueError):
  1725. np.add.reduce(a, axis=-1, out=out_incorrect, keepdims=True)
  1726. with assert_raises(ValueError):
  1727. np.add.reduce(a, axis=-1, out=out_incorrect[:, 0], keepdims=False)
  1728. def test_reduce_output_subclass_ok(self):
  1729. class MyArr(np.ndarray):
  1730. pass
  1731. out = np.empty(())
  1732. np.add.reduce(np.ones(5), out=out) # no subclass, all fine
  1733. out = out.view(MyArr)
  1734. assert np.add.reduce(np.ones(5), out=out) is out
  1735. assert type(np.add.reduce(out)) is MyArr
  1736. def test_no_doc_string(self):
  1737. # gh-9337
  1738. assert_('\n' not in umt.inner1d_no_doc.__doc__)
  1739. def test_invalid_args(self):
  1740. # gh-7961
  1741. exc = pytest.raises(TypeError, np.sqrt, None)
  1742. # minimally check the exception text
  1743. assert exc.match('loop of ufunc does not support')
  1744. @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')])
  1745. def test_nat_is_not_finite(self, nat):
  1746. try:
  1747. assert not np.isfinite(nat)
  1748. except TypeError:
  1749. pass # ok, just not implemented
  1750. @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')])
  1751. def test_nat_is_nan(self, nat):
  1752. try:
  1753. assert np.isnan(nat)
  1754. except TypeError:
  1755. pass # ok, just not implemented
  1756. @pytest.mark.parametrize('nat', [np.datetime64('nat'), np.timedelta64('nat')])
  1757. def test_nat_is_not_inf(self, nat):
  1758. try:
  1759. assert not np.isinf(nat)
  1760. except TypeError:
  1761. pass # ok, just not implemented
  1762. @pytest.mark.parametrize('ufunc', [getattr(np, x) for x in dir(np)
  1763. if isinstance(getattr(np, x), np.ufunc)])
  1764. def test_ufunc_types(ufunc):
  1765. '''
  1766. Check all ufuncs that the correct type is returned. Avoid
  1767. object and boolean types since many operations are not defined for
  1768. for them.
  1769. Choose the shape so even dot and matmul will succeed
  1770. '''
  1771. for typ in ufunc.types:
  1772. # types is a list of strings like ii->i
  1773. if 'O' in typ or '?' in typ:
  1774. continue
  1775. inp, out = typ.split('->')
  1776. args = [np.ones((3, 3), t) for t in inp]
  1777. with warnings.catch_warnings(record=True):
  1778. warnings.filterwarnings("always")
  1779. res = ufunc(*args)
  1780. if isinstance(res, tuple):
  1781. outs = tuple(out)
  1782. assert len(res) == len(outs)
  1783. for r, t in zip(res, outs):
  1784. assert r.dtype == np.dtype(t)
  1785. else:
  1786. assert res.dtype == np.dtype(out)
  1787. @pytest.mark.parametrize('ufunc', [getattr(np, x) for x in dir(np)
  1788. if isinstance(getattr(np, x), np.ufunc)])
  1789. def test_ufunc_noncontiguous(ufunc):
  1790. '''
  1791. Check that contiguous and non-contiguous calls to ufuncs
  1792. have the same results for values in range(9)
  1793. '''
  1794. for typ in ufunc.types:
  1795. # types is a list of strings like ii->i
  1796. if any(set('O?mM') & set(typ)):
  1797. # bool, object, datetime are too irregular for this simple test
  1798. continue
  1799. inp, out = typ.split('->')
  1800. args_c = [np.empty(6, t) for t in inp]
  1801. args_n = [np.empty(18, t)[::3] for t in inp]
  1802. for a in args_c:
  1803. a.flat = range(1,7)
  1804. for a in args_n:
  1805. a.flat = range(1,7)
  1806. with warnings.catch_warnings(record=True):
  1807. warnings.filterwarnings("always")
  1808. res_c = ufunc(*args_c)
  1809. res_n = ufunc(*args_n)
  1810. if len(out) == 1:
  1811. res_c = (res_c,)
  1812. res_n = (res_n,)
  1813. for c_ar, n_ar in zip(res_c, res_n):
  1814. dt = c_ar.dtype
  1815. if np.issubdtype(dt, np.floating):
  1816. # for floating point results allow a small fuss in comparisons
  1817. # since different algorithms (libm vs. intrinsics) can be used
  1818. # for different input strides
  1819. res_eps = np.finfo(dt).eps
  1820. tol = 2*res_eps
  1821. assert_allclose(res_c, res_n, atol=tol, rtol=tol)
  1822. else:
  1823. assert_equal(c_ar, n_ar)
  1824. @pytest.mark.parametrize('ufunc', [np.sign, np.equal])
  1825. def test_ufunc_warn_with_nan(ufunc):
  1826. # issue gh-15127
  1827. # test that calling certain ufuncs with a non-standard `nan` value does not
  1828. # emit a warning
  1829. # `b` holds a 64 bit signaling nan: the most significant bit of the
  1830. # significand is zero.
  1831. b = np.array([0x7ff0000000000001], 'i8').view('f8')
  1832. assert np.isnan(b)
  1833. if ufunc.nin == 1:
  1834. ufunc(b)
  1835. elif ufunc.nin == 2:
  1836. ufunc(b, b.copy())
  1837. else:
  1838. raise ValueError('ufunc with more than 2 inputs')
  1839. @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
  1840. def test_ufunc_casterrors():
  1841. # Tests that casting errors are correctly reported and buffers are
  1842. # cleared.
  1843. # The following array can be added to itself as an object array, but
  1844. # the result cannot be cast to an integer output:
  1845. value = 123 # relies on python cache (leak-check will still find it)
  1846. arr = np.array([value] * int(np.BUFSIZE * 1.5) +
  1847. ["string"] +
  1848. [value] * int(1.5 * np.BUFSIZE), dtype=object)
  1849. out = np.ones(len(arr), dtype=np.intp)
  1850. count = sys.getrefcount(value)
  1851. with pytest.raises(ValueError):
  1852. # Output casting failure:
  1853. np.add(arr, arr, out=out, casting="unsafe")
  1854. assert count == sys.getrefcount(value)
  1855. # output is unchanged after the error, this shows that the iteration
  1856. # was aborted (this is not necessarily defined behaviour)
  1857. assert out[-1] == 1
  1858. with pytest.raises(ValueError):
  1859. # Input casting failure:
  1860. np.add(arr, arr, out=out, dtype=np.intp, casting="unsafe")
  1861. assert count == sys.getrefcount(value)
  1862. # output is unchanged after the error, this shows that the iteration
  1863. # was aborted (this is not necessarily defined behaviour)
  1864. assert out[-1] == 1
  1865. @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
  1866. @pytest.mark.parametrize("offset",
  1867. [0, np.BUFSIZE//2, int(1.5*np.BUFSIZE)])
  1868. def test_reduce_casterrors(offset):
  1869. # Test reporting of casting errors in reductions, we test various
  1870. # offsets to where the casting error will occur, since these may occur
  1871. # at different places during the reduction procedure. For example
  1872. # the first item may be special.
  1873. value = 123 # relies on python cache (leak-check will still find it)
  1874. arr = np.array([value] * offset +
  1875. ["string"] +
  1876. [value] * int(1.5 * np.BUFSIZE), dtype=object)
  1877. out = np.array(-1, dtype=np.intp)
  1878. count = sys.getrefcount(value)
  1879. with pytest.raises(ValueError):
  1880. # This is an unsafe cast, but we currently always allow that:
  1881. np.add.reduce(arr, dtype=np.intp, out=out)
  1882. assert count == sys.getrefcount(value)
  1883. # If an error occurred during casting, the operation is done at most until
  1884. # the error occurs (the result of which would be `value * offset`) and -1
  1885. # if the error happened immediately.
  1886. # This does not define behaviour, the output is invalid and thus undefined
  1887. assert out[()] < value * offset