@@ -0,0 +1,8471 @@
1+import collections.abc
2+import tempfile
3+import sys
4+import shutil
5+import warnings
6+import operator
7+import io
8+import itertools
9+import functools
10+import ctypes
11+import os
12+import gc
13+import weakref
14+import pytest
15+from contextlib import contextmanager
16+
17+from numpy.compat import pickle
18+
19+import pathlib
20+import builtins
21+from decimal import Decimal
22+
23+import numpy as np
24+from numpy.compat import strchar
25+import numpy.core._multiarray_tests as _multiarray_tests
26+from numpy.testing import (
27+ assert_, assert_raises, assert_warns, assert_equal, assert_almost_equal,
28+ assert_array_equal, assert_raises_regex, assert_array_almost_equal,
29+ assert_allclose, IS_PYPY, HAS_REFCOUNT, assert_array_less, runstring,
30+ temppath, suppress_warnings, break_cycles,
31+ )
32+from numpy.testing._private.utils import _no_tracing
33+from numpy.core.tests._locales import CommaDecimalPointLocale
34+
35+# Need to test an object that does not fully implement math interface
36+from datetime import timedelta, datetime
37+
38+
39+def _aligned_zeros(shape, dtype=float, order="C", align=None):
40+ """
41+ Allocate a new ndarray with aligned memory.
42+
43+ The ndarray is guaranteed *not* aligned to twice the requested alignment.
44+ Eg, if align=4, guarantees it is not aligned to 8. If align=None uses
45+ dtype.alignment."""
46+ dtype = np.dtype(dtype)
47+ if dtype == np.dtype(object):
48+ # Can't do this, fall back to standard allocation (which
49+ # should always be sufficiently aligned)
50+ if align is not None:
51+ raise ValueError("object array alignment not supported")
52+ return np.zeros(shape, dtype=dtype, order=order)
53+ if align is None:
54+ align = dtype.alignment
55+ if not hasattr(shape, '__len__'):
56+ shape = (shape,)
57+ size = functools.reduce(operator.mul, shape) * dtype.itemsize
58+ buf = np.empty(size + 2*align + 1, np.uint8)
59+
60+ ptr = buf.__array_interface__['data'][0]
61+ offset = ptr % align
62+ if offset != 0:
63+ offset = align - offset
64+ if (ptr % (2*align)) == 0:
65+ offset += align
66+
67+ # Note: slices producing 0-size arrays do not necessarily change
68+ # data pointer --- so we use and allocate size+1
69+ buf = buf[offset:offset+size+1][:-1]
70+ data = np.ndarray(shape, dtype, buf, order=order)
71+ data.fill(0)
72+ return data
73+
74+
75+class TestFlags:
76+ def setup(self):
77+ self.a = np.arange(10)
78+
79+ def test_writeable(self):
80+ mydict = locals()
81+ self.a.flags.writeable = False
82+ assert_raises(ValueError, runstring, 'self.a[0] = 3', mydict)
83+ assert_raises(ValueError, runstring, 'self.a[0:1].itemset(3)', mydict)
84+ self.a.flags.writeable = True
85+ self.a[0] = 5
86+ self.a[0] = 0
87+
88+ def test_writeable_any_base(self):
89+ # Ensure that any base being writeable is sufficient to change flag;
90+ # this is especially interesting for arrays from an array interface.
91+ arr = np.arange(10)
92+
93+ class subclass(np.ndarray):
94+ pass
95+
96+ # Create subclass so base will not be collapsed, this is OK to change
97+ view1 = arr.view(subclass)
98+ view2 = view1[...]
99+ arr.flags.writeable = False
100+ view2.flags.writeable = False
101+ view2.flags.writeable = True # Can be set to True again.
102+
103+ arr = np.arange(10)
104+
105+ class frominterface:
106+ def __init__(self, arr):
107+ self.arr = arr
108+ self.__array_interface__ = arr.__array_interface__
109+
110+ view1 = np.asarray(frominterface)
111+ view2 = view1[...]
112+ view2.flags.writeable = False
113+ view2.flags.writeable = True
114+
115+ view1.flags.writeable = False
116+ view2.flags.writeable = False
117+ with assert_raises(ValueError):
118+ # Must assume not writeable, since only base is not:
119+ view2.flags.writeable = True
120+
121+ def test_writeable_from_readonly(self):
122+ # gh-9440 - make sure fromstring, from buffer on readonly buffers
123+ # set writeable False
124+ data = b'\x00' * 100
125+ vals = np.frombuffer(data, 'B')
126+ assert_raises(ValueError, vals.setflags, write=True)
127+ types = np.dtype( [('vals', 'u1'), ('res3', 'S4')] )
128+ values = np.core.records.fromstring(data, types)
129+ vals = values['vals']
130+ assert_raises(ValueError, vals.setflags, write=True)
131+
132+ def test_writeable_from_buffer(self):
133+ data = bytearray(b'\x00' * 100)
134+ vals = np.frombuffer(data, 'B')
135+ assert_(vals.flags.writeable)
136+ vals.setflags(write=False)
137+ assert_(vals.flags.writeable is False)
138+ vals.setflags(write=True)
139+ assert_(vals.flags.writeable)
140+ types = np.dtype( [('vals', 'u1'), ('res3', 'S4')] )
141+ values = np.core.records.fromstring(data, types)
142+ vals = values['vals']
143+ assert_(vals.flags.writeable)
144+ vals.setflags(write=False)
145+ assert_(vals.flags.writeable is False)
146+ vals.setflags(write=True)
147+ assert_(vals.flags.writeable)
148+
149+ @pytest.mark.skipif(IS_PYPY, reason="PyPy always copies")
150+ def test_writeable_pickle(self):
151+ import pickle
152+ # Small arrays will be copied without setting base.
153+ # See condition for using PyArray_SetBaseObject in
154+ # array_setstate.
155+ a = np.arange(1000)
156+ for v in range(pickle.HIGHEST_PROTOCOL):
157+ vals = pickle.loads(pickle.dumps(a, v))
158+ assert_(vals.flags.writeable)
159+ assert_(isinstance(vals.base, bytes))
160+
161+ def test_writeable_from_c_data(self):
162+ # Test that the writeable flag can be changed for an array wrapping
163+ # low level C-data, but not owning its data.
164+ # Also see that this is deprecated to change from python.
165+ from numpy.core._multiarray_tests import get_c_wrapping_array
166+
167+ arr_writeable = get_c_wrapping_array(True)
168+ assert not arr_writeable.flags.owndata
169+ assert arr_writeable.flags.writeable
170+ view = arr_writeable[...]
171+
172+ # Toggling the writeable flag works on the view:
173+ view.flags.writeable = False
174+ assert not view.flags.writeable
175+ view.flags.writeable = True
176+ assert view.flags.writeable
177+ # Flag can be unset on the arr_writeable:
178+ arr_writeable.flags.writeable = False
179+
180+ arr_readonly = get_c_wrapping_array(False)
181+ assert not arr_readonly.flags.owndata
182+ assert not arr_readonly.flags.writeable
183+
184+ for arr in [arr_writeable, arr_readonly]:
185+ view = arr[...]
186+ view.flags.writeable = False # make sure it is readonly
187+ arr.flags.writeable = False
188+ assert not arr.flags.writeable
189+
190+ with assert_raises(ValueError):
191+ view.flags.writeable = True
192+
193+ with warnings.catch_warnings():
194+ warnings.simplefilter("error", DeprecationWarning)
195+ with assert_raises(DeprecationWarning):
196+ arr.flags.writeable = True
197+
198+ with assert_warns(DeprecationWarning):
199+ arr.flags.writeable = True
200+
201+ def test_warnonwrite(self):
202+ a = np.arange(10)
203+ a.flags._warn_on_write = True
204+ with warnings.catch_warnings(record=True) as w:
205+ warnings.filterwarnings('always')
206+ a[1] = 10
207+ a[2] = 10
208+ # only warn once
209+ assert_(len(w) == 1)
210+
211+ def test_otherflags(self):
212+ assert_equal(self.a.flags.carray, True)
213+ assert_equal(self.a.flags['C'], True)
214+ assert_equal(self.a.flags.farray, False)
215+ assert_equal(self.a.flags.behaved, True)
216+ assert_equal(self.a.flags.fnc, False)
217+ assert_equal(self.a.flags.forc, True)
218+ assert_equal(self.a.flags.owndata, True)
219+ assert_equal(self.a.flags.writeable, True)
220+ assert_equal(self.a.flags.aligned, True)
221+ with assert_warns(DeprecationWarning):
222+ assert_equal(self.a.flags.updateifcopy, False)
223+ with assert_warns(DeprecationWarning):
224+ assert_equal(self.a.flags['U'], False)
225+ assert_equal(self.a.flags['UPDATEIFCOPY'], False)
226+ assert_equal(self.a.flags.writebackifcopy, False)
227+ assert_equal(self.a.flags['X'], False)
228+ assert_equal(self.a.flags['WRITEBACKIFCOPY'], False)
229+
230+ def test_string_align(self):
231+ a = np.zeros(4, dtype=np.dtype('|S4'))
232+ assert_(a.flags.aligned)
233+ # not power of two are accessed byte-wise and thus considered aligned
234+ a = np.zeros(5, dtype=np.dtype('|S4'))
235+ assert_(a.flags.aligned)
236+
237+ def test_void_align(self):
238+ a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")]))
239+ assert_(a.flags.aligned)
240+
241+
242+class TestHash:
243+ # see #3793
244+ def test_int(self):
245+ for st, ut, s in [(np.int8, np.uint8, 8),
246+ (np.int16, np.uint16, 16),
247+ (np.int32, np.uint32, 32),
248+ (np.int64, np.uint64, 64)]:
249+ for i in range(1, s):
250+ assert_equal(hash(st(-2**i)), hash(-2**i),
251+ err_msg="%r: -2**%d" % (st, i))
252+ assert_equal(hash(st(2**(i - 1))), hash(2**(i - 1)),
253+ err_msg="%r: 2**%d" % (st, i - 1))
254+ assert_equal(hash(st(2**i - 1)), hash(2**i - 1),
255+ err_msg="%r: 2**%d - 1" % (st, i))
256+
257+ i = max(i - 1, 1)
258+ assert_equal(hash(ut(2**(i - 1))), hash(2**(i - 1)),
259+ err_msg="%r: 2**%d" % (ut, i - 1))
260+ assert_equal(hash(ut(2**i - 1)), hash(2**i - 1),
261+ err_msg="%r: 2**%d - 1" % (ut, i))
262+
263+
264+class TestAttributes:
265+ def setup(self):
266+ self.one = np.arange(10)
267+ self.two = np.arange(20).reshape(4, 5)
268+ self.three = np.arange(60, dtype=np.float64).reshape(2, 5, 6)
269+
270+ def test_attributes(self):
271+ assert_equal(self.one.shape, (10,))
272+ assert_equal(self.two.shape, (4, 5))
273+ assert_equal(self.three.shape, (2, 5, 6))
274+ self.three.shape = (10, 3, 2)
275+ assert_equal(self.three.shape, (10, 3, 2))
276+ self.three.shape = (2, 5, 6)
277+ assert_equal(self.one.strides, (self.one.itemsize,))
278+ num = self.two.itemsize
279+ assert_equal(self.two.strides, (5*num, num))
280+ num = self.three.itemsize
281+ assert_equal(self.three.strides, (30*num, 6*num, num))
282+ assert_equal(self.one.ndim, 1)
283+ assert_equal(self.two.ndim, 2)
284+ assert_equal(self.three.ndim, 3)
285+ num = self.two.itemsize
286+ assert_equal(self.two.size, 20)
287+ assert_equal(self.two.nbytes, 20*num)
288+ assert_equal(self.two.itemsize, self.two.dtype.itemsize)
289+ assert_equal(self.two.base, np.arange(20))
290+
291+ def test_dtypeattr(self):
292+ assert_equal(self.one.dtype, np.dtype(np.int_))
293+ assert_equal(self.three.dtype, np.dtype(np.float_))
294+ assert_equal(self.one.dtype.char, 'l')
295+ assert_equal(self.three.dtype.char, 'd')
296+ assert_(self.three.dtype.str[0] in '<>')
297+ assert_equal(self.one.dtype.str[1], 'i')
298+ assert_equal(self.three.dtype.str[1], 'f')
299+
300+ def test_int_subclassing(self):
301+ # Regression test for https://github.com/numpy/numpy/pull/3526
302+
303+ numpy_int = np.int_(0)
304+
305+ # int_ doesn't inherit from Python int, because it's not fixed-width
306+ assert_(not isinstance(numpy_int, int))
307+
308+ def test_stridesattr(self):
309+ x = self.one
310+
311+ def make_array(size, offset, strides):
312+ return np.ndarray(size, buffer=x, dtype=int,
313+ offset=offset*x.itemsize,
314+ strides=strides*x.itemsize)
315+
316+ assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
317+ assert_raises(ValueError, make_array, 4, 4, -2)
318+ assert_raises(ValueError, make_array, 4, 2, -1)
319+ assert_raises(ValueError, make_array, 8, 3, 1)
320+ assert_equal(make_array(8, 3, 0), np.array([3]*8))
321+ # Check behavior reported in gh-2503:
322+ assert_raises(ValueError, make_array, (2, 3), 5, np.array([-2, -3]))
323+ make_array(0, 0, 10)
324+
325+ def test_set_stridesattr(self):
326+ x = self.one
327+
328+ def make_array(size, offset, strides):
329+ try:
330+ r = np.ndarray([size], dtype=int, buffer=x,
331+ offset=offset*x.itemsize)
332+ except Exception as e:
333+ raise RuntimeError(e)
334+ r.strides = strides = strides*x.itemsize
335+ return r
336+
337+ assert_equal(make_array(4, 4, -1), np.array([4, 3, 2, 1]))
338+ assert_equal(make_array(7, 3, 1), np.array([3, 4, 5, 6, 7, 8, 9]))
339+ assert_raises(ValueError, make_array, 4, 4, -2)
340+ assert_raises(ValueError, make_array, 4, 2, -1)
341+ assert_raises(RuntimeError, make_array, 8, 3, 1)
342+ # Check that the true extent of the array is used.
343+ # Test relies on as_strided base not exposing a buffer.
344+ x = np.lib.stride_tricks.as_strided(np.arange(1), (10, 10), (0, 0))
345+
346+ def set_strides(arr, strides):
347+ arr.strides = strides
348+
349+ assert_raises(ValueError, set_strides, x, (10*x.itemsize, x.itemsize))
350+
351+ # Test for offset calculations:
352+ x = np.lib.stride_tricks.as_strided(np.arange(10, dtype=np.int8)[-1],
353+ shape=(10,), strides=(-1,))
354+ assert_raises(ValueError, set_strides, x[::-1], -1)
355+ a = x[::-1]
356+ a.strides = 1
357+ a[::2].strides = 2
358+
359+ # test 0d
360+ arr_0d = np.array(0)
361+ arr_0d.strides = ()
362+ assert_raises(TypeError, set_strides, arr_0d, None)
363+
364+ def test_fill(self):
365+ for t in "?bhilqpBHILQPfdgFDGO":
366+ x = np.empty((3, 2, 1), t)
367+ y = np.empty((3, 2, 1), t)
368+ x.fill(1)
369+ y[...] = 1
370+ assert_equal(x, y)
371+
372+ def test_fill_max_uint64(self):
373+ x = np.empty((3, 2, 1), dtype=np.uint64)
374+ y = np.empty((3, 2, 1), dtype=np.uint64)
375+ value = 2**64 - 1
376+ y[...] = value
377+ x.fill(value)
378+ assert_array_equal(x, y)
379+
380+ def test_fill_struct_array(self):
381+ # Filling from a scalar
382+ x = np.array([(0, 0.0), (1, 1.0)], dtype='i4,f8')
383+ x.fill(x[0])
384+ assert_equal(x['f1'][1], x['f1'][0])
385+ # Filling from a tuple that can be converted
386+ # to a scalar
387+ x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')])
388+ x.fill((3.5, -2))
389+ assert_array_equal(x['a'], [3.5, 3.5])
390+ assert_array_equal(x['b'], [-2, -2])
391+
392+
393+class TestArrayConstruction:
394+ def test_array(self):
395+ d = np.ones(6)
396+ r = np.array([d, d])
397+ assert_equal(r, np.ones((2, 6)))
398+
399+ d = np.ones(6)
400+ tgt = np.ones((2, 6))
401+ r = np.array([d, d])
402+ assert_equal(r, tgt)
403+ tgt[1] = 2
404+ r = np.array([d, d + 1])
405+ assert_equal(r, tgt)
406+
407+ d = np.ones(6)
408+ r = np.array([[d, d]])
409+ assert_equal(r, np.ones((1, 2, 6)))
410+
411+ d = np.ones(6)
412+ r = np.array([[d, d], [d, d]])
413+ assert_equal(r, np.ones((2, 2, 6)))
414+
415+ d = np.ones((6, 6))
416+ r = np.array([d, d])
417+ assert_equal(r, np.ones((2, 6, 6)))
418+
419+ d = np.ones((6, ))
420+ r = np.array([[d, d + 1], d + 2], dtype=object)
421+ assert_equal(len(r), 2)
422+ assert_equal(r[0], [d, d + 1])
423+ assert_equal(r[1], d + 2)
424+
425+ tgt = np.ones((2, 3), dtype=bool)
426+ tgt[0, 2] = False
427+ tgt[1, 0:2] = False
428+ r = np.array([[True, True, False], [False, False, True]])
429+ assert_equal(r, tgt)
430+ r = np.array([[True, False], [True, False], [False, True]])
431+ assert_equal(r, tgt.T)
432+
433+ def test_array_empty(self):
434+ assert_raises(TypeError, np.array)
435+
436+ def test_array_copy_false(self):
437+ d = np.array([1, 2, 3])
438+ e = np.array(d, copy=False)
439+ d[1] = 3
440+ assert_array_equal(e, [1, 3, 3])
441+ e = np.array(d, copy=False, order='F')
442+ d[1] = 4
443+ assert_array_equal(e, [1, 4, 3])
444+ e[2] = 7
445+ assert_array_equal(d, [1, 4, 7])
446+
447+ def test_array_copy_true(self):
448+ d = np.array([[1,2,3], [1, 2, 3]])
449+ e = np.array(d, copy=True)
450+ d[0, 1] = 3
451+ e[0, 2] = -7
452+ assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
453+ assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
454+ e = np.array(d, copy=True, order='F')
455+ d[0, 1] = 5
456+ e[0, 2] = 7
457+ assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
458+ assert_array_equal(d, [[1, 5, 3], [1,2,3]])
459+
460+ def test_array_cont(self):
461+ d = np.ones(10)[::2]
462+ assert_(np.ascontiguousarray(d).flags.c_contiguous)
463+ assert_(np.ascontiguousarray(d).flags.f_contiguous)
464+ assert_(np.asfortranarray(d).flags.c_contiguous)
465+ assert_(np.asfortranarray(d).flags.f_contiguous)
466+ d = np.ones((10, 10))[::2,::2]
467+ assert_(np.ascontiguousarray(d).flags.c_contiguous)
468+ assert_(np.asfortranarray(d).flags.f_contiguous)
469+
470+
471+class TestAssignment:
472+ def test_assignment_broadcasting(self):
473+ a = np.arange(6).reshape(2, 3)
474+
475+ # Broadcasting the input to the output
476+ a[...] = np.arange(3)
477+ assert_equal(a, [[0, 1, 2], [0, 1, 2]])
478+ a[...] = np.arange(2).reshape(2, 1)
479+ assert_equal(a, [[0, 0, 0], [1, 1, 1]])
480+
481+ # For compatibility with <= 1.5, a limited version of broadcasting
482+ # the output to the input.
483+ #
484+ # This behavior is inconsistent with NumPy broadcasting
485+ # in general, because it only uses one of the two broadcasting
486+ # rules (adding a new "1" dimension to the left of the shape),
487+ # applied to the output instead of an input. In NumPy 2.0, this kind
488+ # of broadcasting assignment will likely be disallowed.
489+ a[...] = np.arange(6)[::-1].reshape(1, 2, 3)
490+ assert_equal(a, [[5, 4, 3], [2, 1, 0]])
491+ # The other type of broadcasting would require a reduction operation.
492+
493+ def assign(a, b):
494+ a[...] = b
495+
496+ assert_raises(ValueError, assign, a, np.arange(12).reshape(2, 2, 3))
497+
498+ def test_assignment_errors(self):
499+ # Address issue #2276
500+ class C:
501+ pass
502+ a = np.zeros(1)
503+
504+ def assign(v):
505+ a[0] = v
506+
507+ assert_raises((AttributeError, TypeError), assign, C())
508+ assert_raises(ValueError, assign, [1])
509+
510+ def test_unicode_assignment(self):
511+ # gh-5049
512+ from numpy.core.numeric import set_string_function
513+
514+ @contextmanager
515+ def inject_str(s):
516+ """ replace ndarray.__str__ temporarily """
517+ set_string_function(lambda x: s, repr=False)
518+ try:
519+ yield
520+ finally:
521+ set_string_function(None, repr=False)
522+
523+ a1d = np.array([u'test'])
524+ a0d = np.array(u'done')
525+ with inject_str(u'bad'):
526+ a1d[0] = a0d # previously this would invoke __str__
527+ assert_equal(a1d[0], u'done')
528+
529+ # this would crash for the same reason
530+ np.array([np.array(u'\xe5\xe4\xf6')])
531+
532+ def test_stringlike_empty_list(self):
533+ # gh-8902
534+ u = np.array([u'done'])
535+ b = np.array([b'done'])
536+
537+ class bad_sequence:
538+ def __getitem__(self): pass
539+ def __len__(self): raise RuntimeError
540+
541+ assert_raises(ValueError, operator.setitem, u, 0, [])
542+ assert_raises(ValueError, operator.setitem, b, 0, [])
543+
544+ assert_raises(ValueError, operator.setitem, u, 0, bad_sequence())
545+ assert_raises(ValueError, operator.setitem, b, 0, bad_sequence())
546+
547+ def test_longdouble_assignment(self):
548+ # only relevant if longdouble is larger than float
549+ # we're looking for loss of precision
550+
551+ for dtype in (np.longdouble, np.longcomplex):
552+ # gh-8902
553+ tinyb = np.nextafter(np.longdouble(0), 1).astype(dtype)
554+ tinya = np.nextafter(np.longdouble(0), -1).astype(dtype)
555+
556+ # construction
557+ tiny1d = np.array([tinya])
558+ assert_equal(tiny1d[0], tinya)
559+
560+ # scalar = scalar
561+ tiny1d[0] = tinyb
562+ assert_equal(tiny1d[0], tinyb)
563+
564+ # 0d = scalar
565+ tiny1d[0, ...] = tinya
566+ assert_equal(tiny1d[0], tinya)
567+
568+ # 0d = 0d
569+ tiny1d[0, ...] = tinyb[...]
570+ assert_equal(tiny1d[0], tinyb)
571+
572+ # scalar = 0d
573+ tiny1d[0] = tinyb[...]
574+ assert_equal(tiny1d[0], tinyb)
575+
576+ arr = np.array([np.array(tinya)])
577+ assert_equal(arr[0], tinya)
578+
579+ def test_cast_to_string(self):
580+ # cast to str should do "str(scalar)", not "str(scalar.item())"
581+ # Example: In python2, str(float) is truncated, so we want to avoid
582+ # str(np.float64(...).item()) as this would incorrectly truncate.
583+ a = np.zeros(1, dtype='S20')
584+ a[:] = np.array(['1.12345678901234567890'], dtype='f8')
585+ assert_equal(a[0], b"1.1234567890123457")
586+
587+
588+class TestDtypedescr:
589+ def test_construction(self):
590+ d1 = np.dtype('i4')
591+ assert_equal(d1, np.dtype(np.int32))
592+ d2 = np.dtype('f8')
593+ assert_equal(d2, np.dtype(np.float64))
594+
595+ def test_byteorders(self):
596+ assert_(np.dtype('<i4') != np.dtype('>i4'))
597+ assert_(np.dtype([('a', '<i4')]) != np.dtype([('a', '>i4')]))
598+
599+ def test_structured_non_void(self):
600+ fields = [('a', '<i2'), ('b', '<i2')]
601+ dt_int = np.dtype(('i4', fields))
602+ assert_equal(str(dt_int), "(numpy.int32, [('a', '<i2'), ('b', '<i2')])")
603+
604+ # gh-9821
605+ arr_int = np.zeros(4, dt_int)
606+ assert_equal(repr(arr_int),
607+ "array([0, 0, 0, 0], dtype=(numpy.int32, [('a', '<i2'), ('b', '<i2')]))")
608+
609+
610+class TestZeroRank:
611+ def setup(self):
612+ self.d = np.array(0), np.array('x', object)
613+
614+ def test_ellipsis_subscript(self):
615+ a, b = self.d
616+ assert_equal(a[...], 0)
617+ assert_equal(b[...], 'x')
618+ assert_(a[...].base is a) # `a[...] is a` in numpy <1.9.
619+ assert_(b[...].base is b) # `b[...] is b` in numpy <1.9.
620+
621+ def test_empty_subscript(self):
622+ a, b = self.d
623+ assert_equal(a[()], 0)
624+ assert_equal(b[()], 'x')
625+ assert_(type(a[()]) is a.dtype.type)
626+ assert_(type(b[()]) is str)
627+
628+ def test_invalid_subscript(self):
629+ a, b = self.d
630+ assert_raises(IndexError, lambda x: x[0], a)
631+ assert_raises(IndexError, lambda x: x[0], b)
632+ assert_raises(IndexError, lambda x: x[np.array([], int)], a)
633+ assert_raises(IndexError, lambda x: x[np.array([], int)], b)
634+
635+ def test_ellipsis_subscript_assignment(self):
636+ a, b = self.d
637+ a[...] = 42
638+ assert_equal(a, 42)
639+ b[...] = ''
640+ assert_equal(b.item(), '')
641+
642+ def test_empty_subscript_assignment(self):
643+ a, b = self.d
644+ a[()] = 42
645+ assert_equal(a, 42)
646+ b[()] = ''
647+ assert_equal(b.item(), '')
648+
649+ def test_invalid_subscript_assignment(self):
650+ a, b = self.d
651+
652+ def assign(x, i, v):
653+ x[i] = v
654+
655+ assert_raises(IndexError, assign, a, 0, 42)
656+ assert_raises(IndexError, assign, b, 0, '')
657+ assert_raises(ValueError, assign, a, (), '')
658+
659+ def test_newaxis(self):
660+ a, b = self.d
661+ assert_equal(a[np.newaxis].shape, (1,))
662+ assert_equal(a[..., np.newaxis].shape, (1,))
663+ assert_equal(a[np.newaxis, ...].shape, (1,))
664+ assert_equal(a[..., np.newaxis].shape, (1,))
665+ assert_equal(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
666+ assert_equal(a[..., np.newaxis, np.newaxis].shape, (1, 1))
667+ assert_equal(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
668+ assert_equal(a[(np.newaxis,)*10].shape, (1,)*10)
669+
670+ def test_invalid_newaxis(self):
671+ a, b = self.d
672+
673+ def subscript(x, i):
674+ x[i]
675+
676+ assert_raises(IndexError, subscript, a, (np.newaxis, 0))
677+ assert_raises(IndexError, subscript, a, (np.newaxis,)*50)
678+
679+ def test_constructor(self):
680+ x = np.ndarray(())
681+ x[()] = 5
682+ assert_equal(x[()], 5)
683+ y = np.ndarray((), buffer=x)
684+ y[()] = 6
685+ assert_equal(x[()], 6)
686+
687+ # strides and shape must be the same length
688+ with pytest.raises(ValueError):
689+ np.ndarray((2,), strides=())
690+ with pytest.raises(ValueError):
691+ np.ndarray((), strides=(2,))
692+
693+ def test_output(self):
694+ x = np.array(2)
695+ assert_raises(ValueError, np.add, x, [1], x)
696+
697+ def test_real_imag(self):
698+ # contiguity checks are for gh-11245
699+ x = np.array(1j)
700+ xr = x.real
701+ xi = x.imag
702+
703+ assert_equal(xr, np.array(0))
704+ assert_(type(xr) is np.ndarray)
705+ assert_equal(xr.flags.contiguous, True)
706+ assert_equal(xr.flags.f_contiguous, True)
707+
708+ assert_equal(xi, np.array(1))
709+ assert_(type(xi) is np.ndarray)
710+ assert_equal(xi.flags.contiguous, True)
711+ assert_equal(xi.flags.f_contiguous, True)
712+
713+
714+class TestScalarIndexing:
715+ def setup(self):
716+ self.d = np.array([0, 1])[0]
717+
718+ def test_ellipsis_subscript(self):
719+ a = self.d
720+ assert_equal(a[...], 0)
721+ assert_equal(a[...].shape, ())
722+
723+ def test_empty_subscript(self):
724+ a = self.d
725+ assert_equal(a[()], 0)
726+ assert_equal(a[()].shape, ())
727+
728+ def test_invalid_subscript(self):
729+ a = self.d
730+ assert_raises(IndexError, lambda x: x[0], a)
731+ assert_raises(IndexError, lambda x: x[np.array([], int)], a)
732+
733+ def test_invalid_subscript_assignment(self):
734+ a = self.d
735+
736+ def assign(x, i, v):
737+ x[i] = v
738+
739+ assert_raises(TypeError, assign, a, 0, 42)
740+
741+ def test_newaxis(self):
742+ a = self.d
743+ assert_equal(a[np.newaxis].shape, (1,))
744+ assert_equal(a[..., np.newaxis].shape, (1,))
745+ assert_equal(a[np.newaxis, ...].shape, (1,))
746+ assert_equal(a[..., np.newaxis].shape, (1,))
747+ assert_equal(a[np.newaxis, ..., np.newaxis].shape, (1, 1))
748+ assert_equal(a[..., np.newaxis, np.newaxis].shape, (1, 1))
749+ assert_equal(a[np.newaxis, np.newaxis, ...].shape, (1, 1))
750+ assert_equal(a[(np.newaxis,)*10].shape, (1,)*10)
751+
752+ def test_invalid_newaxis(self):
753+ a = self.d
754+
755+ def subscript(x, i):
756+ x[i]
757+
758+ assert_raises(IndexError, subscript, a, (np.newaxis, 0))
759+ assert_raises(IndexError, subscript, a, (np.newaxis,)*50)
760+
761+ def test_overlapping_assignment(self):
762+ # With positive strides
763+ a = np.arange(4)
764+ a[:-1] = a[1:]
765+ assert_equal(a, [1, 2, 3, 3])
766+
767+ a = np.arange(4)
768+ a[1:] = a[:-1]
769+ assert_equal(a, [0, 0, 1, 2])
770+
771+ # With positive and negative strides
772+ a = np.arange(4)
773+ a[:] = a[::-1]
774+ assert_equal(a, [3, 2, 1, 0])
775+
776+ a = np.arange(6).reshape(2, 3)
777+ a[::-1,:] = a[:, ::-1]
778+ assert_equal(a, [[5, 4, 3], [2, 1, 0]])
779+
780+ a = np.arange(6).reshape(2, 3)
781+ a[::-1, ::-1] = a[:, ::-1]
782+ assert_equal(a, [[3, 4, 5], [0, 1, 2]])
783+
784+ # With just one element overlapping
785+ a = np.arange(5)
786+ a[:3] = a[2:]
787+ assert_equal(a, [2, 3, 4, 3, 4])
788+
789+ a = np.arange(5)
790+ a[2:] = a[:3]
791+ assert_equal(a, [0, 1, 0, 1, 2])
792+
793+ a = np.arange(5)
794+ a[2::-1] = a[2:]
795+ assert_equal(a, [4, 3, 2, 3, 4])
796+
797+ a = np.arange(5)
798+ a[2:] = a[2::-1]
799+ assert_equal(a, [0, 1, 2, 1, 0])
800+
801+ a = np.arange(5)
802+ a[2::-1] = a[:1:-1]
803+ assert_equal(a, [2, 3, 4, 3, 4])
804+
805+ a = np.arange(5)
806+ a[:1:-1] = a[2::-1]
807+ assert_equal(a, [0, 1, 0, 1, 2])
808+
809+
810+class TestCreation:
811+ """
812+ Test the np.array constructor
813+ """
814+ def test_from_attribute(self):
815+ class x:
816+ def __array__(self, dtype=None):
817+ pass
818+
819+ assert_raises(ValueError, np.array, x())
820+
821+ def test_from_string(self):
822+ types = np.typecodes['AllInteger'] + np.typecodes['Float']
823+ nstr = ['123', '123']
824+ result = np.array([123, 123], dtype=int)
825+ for type in types:
826+ msg = 'String conversion for %s' % type
827+ assert_equal(np.array(nstr, dtype=type), result, err_msg=msg)
828+
829+ def test_void(self):
830+ arr = np.array([], dtype='V')
831+ assert_equal(arr.dtype.kind, 'V')
832+
833+ def test_too_big_error(self):
834+ # 45341 is the smallest integer greater than sqrt(2**31 - 1).
835+ # 3037000500 is the smallest integer greater than sqrt(2**63 - 1).
836+ # We want to make sure that the square byte array with those dimensions
837+ # is too big on 32 or 64 bit systems respectively.
838+ if np.iinfo('intp').max == 2**31 - 1:
839+ shape = (46341, 46341)
840+ elif np.iinfo('intp').max == 2**63 - 1:
841+ shape = (3037000500, 3037000500)
842+ else:
843+ return
844+ assert_raises(ValueError, np.empty, shape, dtype=np.int8)
845+ assert_raises(ValueError, np.zeros, shape, dtype=np.int8)
846+ assert_raises(ValueError, np.ones, shape, dtype=np.int8)
847+
848+ @pytest.mark.skipif(np.dtype(np.intp).itemsize != 8,
849+ reason="malloc may not fail on 32 bit systems")
850+ def test_malloc_fails(self):
851+ # This test is guaranteed to fail due to a too large allocation
852+ with assert_raises(np.core._exceptions._ArrayMemoryError):
853+ np.empty(np.iinfo(np.intp).max, dtype=np.uint8)
854+
855+ def test_zeros(self):
856+ types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
857+ for dt in types:
858+ d = np.zeros((13,), dtype=dt)
859+ assert_equal(np.count_nonzero(d), 0)
860+ # true for ieee floats
861+ assert_equal(d.sum(), 0)
862+ assert_(not d.any())
863+
864+ d = np.zeros(2, dtype='(2,4)i4')
865+ assert_equal(np.count_nonzero(d), 0)
866+ assert_equal(d.sum(), 0)
867+ assert_(not d.any())
868+
869+ d = np.zeros(2, dtype='4i4')
870+ assert_equal(np.count_nonzero(d), 0)
871+ assert_equal(d.sum(), 0)
872+ assert_(not d.any())
873+
874+ d = np.zeros(2, dtype='(2,4)i4, (2,4)i4')
875+ assert_equal(np.count_nonzero(d), 0)
876+
877+ @pytest.mark.slow
878+ def test_zeros_big(self):
879+ # test big array as they might be allocated different by the system
880+ types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
881+ for dt in types:
882+ d = np.zeros((30 * 1024**2,), dtype=dt)
883+ assert_(not d.any())
884+ # This test can fail on 32-bit systems due to insufficient
885+ # contiguous memory. Deallocating the previous array increases the
886+ # chance of success.
887+ del(d)
888+
889+ def test_zeros_obj(self):
890+ # test initialization from PyLong(0)
891+ d = np.zeros((13,), dtype=object)
892+ assert_array_equal(d, [0] * 13)
893+ assert_equal(np.count_nonzero(d), 0)
894+
895+ def test_zeros_obj_obj(self):
896+ d = np.zeros(10, dtype=[('k', object, 2)])
897+ assert_array_equal(d['k'], 0)
898+
899+ def test_zeros_like_like_zeros(self):
900+ # test zeros_like returns the same as zeros
901+ for c in np.typecodes['All']:
902+ if c == 'V':
903+ continue
904+ d = np.zeros((3,3), dtype=c)
905+ assert_array_equal(np.zeros_like(d), d)
906+ assert_equal(np.zeros_like(d).dtype, d.dtype)
907+ # explicitly check some special cases
908+ d = np.zeros((3,3), dtype='S5')
909+ assert_array_equal(np.zeros_like(d), d)
910+ assert_equal(np.zeros_like(d).dtype, d.dtype)
911+ d = np.zeros((3,3), dtype='U5')
912+ assert_array_equal(np.zeros_like(d), d)
913+ assert_equal(np.zeros_like(d).dtype, d.dtype)
914+
915+ d = np.zeros((3,3), dtype='<i4')
916+ assert_array_equal(np.zeros_like(d), d)
917+ assert_equal(np.zeros_like(d).dtype, d.dtype)
918+ d = np.zeros((3,3), dtype='>i4')
919+ assert_array_equal(np.zeros_like(d), d)
920+ assert_equal(np.zeros_like(d).dtype, d.dtype)
921+
922+ d = np.zeros((3,3), dtype='<M8[s]')
923+ assert_array_equal(np.zeros_like(d), d)
924+ assert_equal(np.zeros_like(d).dtype, d.dtype)
925+ d = np.zeros((3,3), dtype='>M8[s]')
926+ assert_array_equal(np.zeros_like(d), d)
927+ assert_equal(np.zeros_like(d).dtype, d.dtype)
928+
929+ d = np.zeros((3,3), dtype='f4,f4')
930+ assert_array_equal(np.zeros_like(d), d)
931+ assert_equal(np.zeros_like(d).dtype, d.dtype)
932+
933+ def test_empty_unicode(self):
934+ # don't throw decode errors on garbage memory
935+ for i in range(5, 100, 5):
936+ d = np.empty(i, dtype='U')
937+ str(d)
938+
939+ def test_sequence_non_homogenous(self):
940+ assert_equal(np.array([4, 2**80]).dtype, object)
941+ assert_equal(np.array([4, 2**80, 4]).dtype, object)
942+ assert_equal(np.array([2**80, 4]).dtype, object)
943+ assert_equal(np.array([2**80] * 3).dtype, object)
944+ assert_equal(np.array([[1, 1],[1j, 1j]]).dtype, complex)
945+ assert_equal(np.array([[1j, 1j],[1, 1]]).dtype, complex)
946+ assert_equal(np.array([[1, 1, 1],[1, 1j, 1.], [1, 1, 1]]).dtype, complex)
947+
948+ def test_non_sequence_sequence(self):
949+ """Should not segfault.
950+
951+ Class Fail breaks the sequence protocol for new style classes, i.e.,
952+ those derived from object. Class Map is a mapping type indicated by
953+ raising a ValueError. At some point we may raise a warning instead
954+ of an error in the Fail case.
955+
956+ """
957+ class Fail:
958+ def __len__(self):
959+ return 1
960+
961+ def __getitem__(self, index):
962+ raise ValueError()
963+
964+ class Map:
965+ def __len__(self):
966+ return 1
967+
968+ def __getitem__(self, index):
969+ raise KeyError()
970+
971+ a = np.array([Map()])
972+ assert_(a.shape == (1,))
973+ assert_(a.dtype == np.dtype(object))
974+ assert_raises(ValueError, np.array, [Fail()])
975+
976+ def test_no_len_object_type(self):
977+ # gh-5100, want object array from iterable object without len()
978+ class Point2:
979+ def __init__(self):
980+ pass
981+
982+ def __getitem__(self, ind):
983+ if ind in [0, 1]:
984+ return ind
985+ else:
986+ raise IndexError()
987+ d = np.array([Point2(), Point2(), Point2()])
988+ assert_equal(d.dtype, np.dtype(object))
989+
990+ def test_false_len_sequence(self):
991+ # gh-7264, segfault for this example
992+ class C:
993+ def __getitem__(self, i):
994+ raise IndexError
995+ def __len__(self):
996+ return 42
997+
998+ a = np.array(C()) # segfault?
999+ assert_equal(len(a), 0)
1000+
1001+ def test_false_len_iterable(self):
1002+ # Special case where a bad __getitem__ makes us fall back on __iter__:
1003+ class C:
1004+ def __getitem__(self, x):
1005+ raise Exception
1006+ def __iter__(self):
1007+ return iter(())
1008+ def __len__(self):
1009+ return 2
1010+
1011+ a = np.empty(2)
1012+ with assert_raises(ValueError):
1013+ a[:] = C() # Segfault!
1014+
1015+ def test_failed_len_sequence(self):
1016+ # gh-7393
1017+ class A:
1018+ def __init__(self, data):
1019+ self._data = data
1020+ def __getitem__(self, item):
1021+ return type(self)(self._data[item])
1022+ def __len__(self):
1023+ return len(self._data)
1024+
1025+ # len(d) should give 3, but len(d[0]) will fail
1026+ d = A([1,2,3])
1027+ assert_equal(len(np.array(d)), 3)
1028+
1029+ def test_array_too_big(self):
1030+ # Test that array creation succeeds for arrays addressable by intp
1031+ # on the byte level and fails for too large arrays.
1032+ buf = np.zeros(100)
1033+
1034+ max_bytes = np.iinfo(np.intp).max
1035+ for dtype in ["intp", "S20", "b"]:
1036+ dtype = np.dtype(dtype)
1037+ itemsize = dtype.itemsize
1038+
1039+ np.ndarray(buffer=buf, strides=(0,),
1040+ shape=(max_bytes//itemsize,), dtype=dtype)
1041+ assert_raises(ValueError, np.ndarray, buffer=buf, strides=(0,),
1042+ shape=(max_bytes//itemsize + 1,), dtype=dtype)
1043+
1044+ def _ragged_creation(self, seq):
1045+ # without dtype=object, the ragged object should raise
1046+ with assert_warns(np.VisibleDeprecationWarning):
1047+ a = np.array(seq)
1048+ b = np.array(seq, dtype=object)
1049+ assert_equal(a, b)
1050+ return b
1051+
1052+ def test_ragged_ndim_object(self):
1053+ # Lists of mismatching depths are treated as object arrays
1054+ a = self._ragged_creation([[1], 2, 3])
1055+ assert_equal(a.shape, (3,))
1056+ assert_equal(a.dtype, object)
1057+
1058+ a = self._ragged_creation([1, [2], 3])
1059+ assert_equal(a.shape, (3,))
1060+ assert_equal(a.dtype, object)
1061+
1062+ a = self._ragged_creation([1, 2, [3]])
1063+ assert_equal(a.shape, (3,))
1064+ assert_equal(a.dtype, object)
1065+
1066+ def test_ragged_shape_object(self):
1067+ # The ragged dimension of a list is turned into an object array
1068+ a = self._ragged_creation([[1, 1], [2], [3]])
1069+ assert_equal(a.shape, (3,))
1070+ assert_equal(a.dtype, object)
1071+
1072+ a = self._ragged_creation([[1], [2, 2], [3]])
1073+ assert_equal(a.shape, (3,))
1074+ assert_equal(a.dtype, object)
1075+
1076+ a = self._ragged_creation([[1], [2], [3, 3]])
1077+ assert a.shape == (3,)
1078+ assert a.dtype == object
1079+
1080+ def test_array_of_ragged_array(self):
1081+ outer = np.array([None, None])
1082+ outer[0] = outer[1] = np.array([1, 2, 3])
1083+ assert np.array(outer).shape == (2,)
1084+ assert np.array([outer]).shape == (1, 2)
1085+
1086+ outer_ragged = np.array([None, None])
1087+ outer_ragged[0] = np.array([1, 2, 3])
1088+ outer_ragged[1] = np.array([1, 2, 3, 4])
1089+ # should both of these emit deprecation warnings?
1090+ assert np.array(outer_ragged).shape == (2,)
1091+ assert np.array([outer_ragged]).shape == (1, 2,)
1092+
1093+ def test_deep_nonragged_object(self):
1094+ # None of these should raise, even though they are missing dtype=object
1095+ a = np.array([[[Decimal(1)]]])
1096+ a = np.array([1, Decimal(1)])
1097+ a = np.array([[1], [Decimal(1)]])
1098+
1099+class TestStructured:
1100+ def test_subarray_field_access(self):
1101+ a = np.zeros((3, 5), dtype=[('a', ('i4', (2, 2)))])
1102+ a['a'] = np.arange(60).reshape(3, 5, 2, 2)
1103+
1104+ # Since the subarray is always in C-order, a transpose
1105+ # does not swap the subarray:
1106+ assert_array_equal(a.T['a'], a['a'].transpose(1, 0, 2, 3))
1107+
1108+ # In Fortran order, the subarray gets appended
1109+ # like in all other cases, not prepended as a special case
1110+ b = a.copy(order='F')
1111+ assert_equal(a['a'].shape, b['a'].shape)
1112+ assert_equal(a.T['a'].shape, a.T.copy()['a'].shape)
1113+
1114+ def test_subarray_comparison(self):
1115+ # Check that comparisons between record arrays with
1116+ # multi-dimensional field types work properly
1117+ a = np.rec.fromrecords(
1118+ [([1, 2, 3], 'a', [[1, 2], [3, 4]]), ([3, 3, 3], 'b', [[0, 0], [0, 0]])],
1119+ dtype=[('a', ('f4', 3)), ('b', object), ('c', ('i4', (2, 2)))])
1120+ b = a.copy()
1121+ assert_equal(a == b, [True, True])
1122+ assert_equal(a != b, [False, False])
1123+ b[1].b = 'c'
1124+ assert_equal(a == b, [True, False])
1125+ assert_equal(a != b, [False, True])
1126+ for i in range(3):
1127+ b[0].a = a[0].a
1128+ b[0].a[i] = 5
1129+ assert_equal(a == b, [False, False])
1130+ assert_equal(a != b, [True, True])
1131+ for i in range(2):
1132+ for j in range(2):
1133+ b = a.copy()
1134+ b[0].c[i, j] = 10
1135+ assert_equal(a == b, [False, True])
1136+ assert_equal(a != b, [True, False])
1137+
1138+ # Check that broadcasting with a subarray works
1139+ a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8')])
1140+ b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8')])
1141+ assert_equal(a == b, [[True, True, False], [False, False, True]])
1142+ assert_equal(b == a, [[True, True, False], [False, False, True]])
1143+ a = np.array([[(0,)], [(1,)]], dtype=[('a', 'f8', (1,))])
1144+ b = np.array([(0,), (0,), (1,)], dtype=[('a', 'f8', (1,))])
1145+ assert_equal(a == b, [[True, True, False], [False, False, True]])
1146+ assert_equal(b == a, [[True, True, False], [False, False, True]])
1147+ a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))])
1148+ b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
1149+ assert_equal(a == b, [[True, False, False], [False, False, True]])
1150+ assert_equal(b == a, [[True, False, False], [False, False, True]])
1151+
1152+ # Check that broadcasting Fortran-style arrays with a subarray work
1153+ a = np.array([[([0, 0],)], [([1, 1],)]], dtype=[('a', 'f8', (2,))], order='F')
1154+ b = np.array([([0, 0],), ([0, 1],), ([1, 1],)], dtype=[('a', 'f8', (2,))])
1155+ assert_equal(a == b, [[True, False, False], [False, False, True]])
1156+ assert_equal(b == a, [[True, False, False], [False, False, True]])
1157+
1158+ # Check that incompatible sub-array shapes don't result to broadcasting
1159+ x = np.zeros((1,), dtype=[('a', ('f4', (1, 2))), ('b', 'i1')])
1160+ y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
1161+ # This comparison invokes deprecated behaviour, and will probably
1162+ # start raising an error eventually. What we really care about in this
1163+ # test is just that it doesn't return True.
1164+ with suppress_warnings() as sup:
1165+ sup.filter(FutureWarning, "elementwise == comparison failed")
1166+ assert_equal(x == y, False)
1167+
1168+ x = np.zeros((1,), dtype=[('a', ('f4', (2, 1))), ('b', 'i1')])
1169+ y = np.zeros((1,), dtype=[('a', ('f4', (2,))), ('b', 'i1')])
1170+ # This comparison invokes deprecated behaviour, and will probably
1171+ # start raising an error eventually. What we really care about in this
1172+ # test is just that it doesn't return True.
1173+ with suppress_warnings() as sup:
1174+ sup.filter(FutureWarning, "elementwise == comparison failed")
1175+ assert_equal(x == y, False)
1176+
1177+ # Check that structured arrays that are different only in
1178+ # byte-order work
1179+ a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i8'), ('b', '<f8')])
1180+ b = np.array([(5, 43), (10, 1)], dtype=[('a', '<i8'), ('b', '>f8')])
1181+ assert_equal(a == b, [False, True])
1182+
1183+ def test_casting(self):
1184+ # Check that casting a structured array to change its byte order
1185+ # works
1186+ a = np.array([(1,)], dtype=[('a', '<i4')])
1187+ assert_(np.can_cast(a.dtype, [('a', '>i4')], casting='unsafe'))
1188+ b = a.astype([('a', '>i4')])
1189+ assert_equal(b, a.byteswap().newbyteorder())
1190+ assert_equal(a['a'][0], b['a'][0])
1191+
1192+ # Check that equality comparison works on structured arrays if
1193+ # they are 'equiv'-castable
1194+ a = np.array([(5, 42), (10, 1)], dtype=[('a', '>i4'), ('b', '<f8')])
1195+ b = np.array([(5, 42), (10, 1)], dtype=[('a', '<i4'), ('b', '>f8')])
1196+ assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
1197+ assert_equal(a == b, [True, True])
1198+
1199+ # Check that 'equiv' casting can change byte order
1200+ assert_(np.can_cast(a.dtype, b.dtype, casting='equiv'))
1201+ c = a.astype(b.dtype, casting='equiv')
1202+ assert_equal(a == c, [True, True])
1203+
1204+ # Check that 'safe' casting can change byte order and up-cast
1205+ # fields
1206+ t = [('a', '<i8'), ('b', '>f8')]
1207+ assert_(np.can_cast(a.dtype, t, casting='safe'))
1208+ c = a.astype(t, casting='safe')
1209+ assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
1210+ [True, True])
1211+
1212+ # Check that 'same_kind' casting can change byte order and
1213+ # change field widths within a "kind"
1214+ t = [('a', '<i4'), ('b', '>f4')]
1215+ assert_(np.can_cast(a.dtype, t, casting='same_kind'))
1216+ c = a.astype(t, casting='same_kind')
1217+ assert_equal((c == np.array([(5, 42), (10, 1)], dtype=t)),
1218+ [True, True])
1219+
1220+ # Check that casting fails if the casting rule should fail on
1221+ # any of the fields
1222+ t = [('a', '>i8'), ('b', '<f4')]
1223+ assert_(not np.can_cast(a.dtype, t, casting='safe'))
1224+ assert_raises(TypeError, a.astype, t, casting='safe')
1225+ t = [('a', '>i2'), ('b', '<f8')]
1226+ assert_(not np.can_cast(a.dtype, t, casting='equiv'))
1227+ assert_raises(TypeError, a.astype, t, casting='equiv')
1228+ t = [('a', '>i8'), ('b', '<i2')]
1229+ assert_(not np.can_cast(a.dtype, t, casting='same_kind'))
1230+ assert_raises(TypeError, a.astype, t, casting='same_kind')
1231+ assert_(not np.can_cast(a.dtype, b.dtype, casting='no'))
1232+ assert_raises(TypeError, a.astype, b.dtype, casting='no')
1233+
1234+ # Check that non-'unsafe' casting can't change the set of field names
1235+ for casting in ['no', 'safe', 'equiv', 'same_kind']:
1236+ t = [('a', '>i4')]
1237+ assert_(not np.can_cast(a.dtype, t, casting=casting))
1238+ t = [('a', '>i4'), ('b', '<f8'), ('c', 'i4')]
1239+ assert_(not np.can_cast(a.dtype, t, casting=casting))
1240+
1241+ def test_objview(self):
1242+ # https://github.com/numpy/numpy/issues/3286
1243+ a = np.array([], dtype=[('a', 'f'), ('b', 'f'), ('c', 'O')])
1244+ a[['a', 'b']] # TypeError?
1245+
1246+ # https://github.com/numpy/numpy/issues/3253
1247+ dat2 = np.zeros(3, [('A', 'i'), ('B', '|O')])
1248+ dat2[['B', 'A']] # TypeError?
1249+
1250+ def test_setfield(self):
1251+ # https://github.com/numpy/numpy/issues/3126
1252+ struct_dt = np.dtype([('elem', 'i4', 5),])
1253+ dt = np.dtype([('field', 'i4', 10),('struct', struct_dt)])
1254+ x = np.zeros(1, dt)
1255+ x[0]['field'] = np.ones(10, dtype='i4')
1256+ x[0]['struct'] = np.ones(1, dtype=struct_dt)
1257+ assert_equal(x[0]['field'], np.ones(10, dtype='i4'))
1258+
1259+ def test_setfield_object(self):
1260+ # make sure object field assignment with ndarray value
1261+ # on void scalar mimics setitem behavior
1262+ b = np.zeros(1, dtype=[('x', 'O')])
1263+ # next line should work identically to b['x'][0] = np.arange(3)
1264+ b[0]['x'] = np.arange(3)
1265+ assert_equal(b[0]['x'], np.arange(3))
1266+
1267+ # check that broadcasting check still works
1268+ c = np.zeros(1, dtype=[('x', 'O', 5)])
1269+
1270+ def testassign():
1271+ c[0]['x'] = np.arange(3)
1272+
1273+ assert_raises(ValueError, testassign)
1274+
1275+ def test_zero_width_string(self):
1276+ # Test for PR #6430 / issues #473, #4955, #2585
1277+
1278+ dt = np.dtype([('I', int), ('S', 'S0')])
1279+
1280+ x = np.zeros(4, dtype=dt)
1281+
1282+ assert_equal(x['S'], [b'', b'', b'', b''])
1283+ assert_equal(x['S'].itemsize, 0)
1284+
1285+ x['S'] = ['a', 'b', 'c', 'd']
1286+ assert_equal(x['S'], [b'', b'', b'', b''])
1287+ assert_equal(x['I'], [0, 0, 0, 0])
1288+
1289+ # Variation on test case from #4955
1290+ x['S'][x['I'] == 0] = 'hello'
1291+ assert_equal(x['S'], [b'', b'', b'', b''])
1292+ assert_equal(x['I'], [0, 0, 0, 0])
1293+
1294+ # Variation on test case from #2585
1295+ x['S'] = 'A'
1296+ assert_equal(x['S'], [b'', b'', b'', b''])
1297+ assert_equal(x['I'], [0, 0, 0, 0])
1298+
1299+ # Allow zero-width dtypes in ndarray constructor
1300+ y = np.ndarray(4, dtype=x['S'].dtype)
1301+ assert_equal(y.itemsize, 0)
1302+ assert_equal(x['S'], y)
1303+
1304+ # More tests for indexing an array with zero-width fields
1305+ assert_equal(np.zeros(4, dtype=[('a', 'S0,S0'),
1306+ ('b', 'u1')])['a'].itemsize, 0)
1307+ assert_equal(np.empty(3, dtype='S0,S0').itemsize, 0)
1308+ assert_equal(np.zeros(4, dtype='S0,u1')['f0'].itemsize, 0)
1309+
1310+ xx = x['S'].reshape((2, 2))
1311+ assert_equal(xx.itemsize, 0)
1312+ assert_equal(xx, [[b'', b''], [b'', b'']])
1313+ # check for no uninitialized memory due to viewing S0 array
1314+ assert_equal(xx[:].dtype, xx.dtype)
1315+ assert_array_equal(eval(repr(xx), dict(array=np.array)), xx)
1316+
1317+ b = io.BytesIO()
1318+ np.save(b, xx)
1319+
1320+ b.seek(0)
1321+ yy = np.load(b)
1322+ assert_equal(yy.itemsize, 0)
1323+ assert_equal(xx, yy)
1324+
1325+ with temppath(suffix='.npy') as tmp:
1326+ np.save(tmp, xx)
1327+ yy = np.load(tmp)
1328+ assert_equal(yy.itemsize, 0)
1329+ assert_equal(xx, yy)
1330+
1331+ def test_base_attr(self):
1332+ a = np.zeros(3, dtype='i4,f4')
1333+ b = a[0]
1334+ assert_(b.base is a)
1335+
1336+ def test_assignment(self):
1337+ def testassign(arr, v):
1338+ c = arr.copy()
1339+ c[0] = v # assign using setitem
1340+ c[1:] = v # assign using "dtype_transfer" code paths
1341+ return c
1342+
1343+ dt = np.dtype([('foo', 'i8'), ('bar', 'i8')])
1344+ arr = np.ones(2, dt)
1345+ v1 = np.array([(2,3)], dtype=[('foo', 'i8'), ('bar', 'i8')])
1346+ v2 = np.array([(2,3)], dtype=[('bar', 'i8'), ('foo', 'i8')])
1347+ v3 = np.array([(2,3)], dtype=[('bar', 'i8'), ('baz', 'i8')])
1348+ v4 = np.array([(2,)], dtype=[('bar', 'i8')])
1349+ v5 = np.array([(2,3)], dtype=[('foo', 'f8'), ('bar', 'f8')])
1350+ w = arr.view({'names': ['bar'], 'formats': ['i8'], 'offsets': [8]})
1351+
1352+ ans = np.array([(2,3),(2,3)], dtype=dt)
1353+ assert_equal(testassign(arr, v1), ans)
1354+ assert_equal(testassign(arr, v2), ans)
1355+ assert_equal(testassign(arr, v3), ans)
1356+ assert_raises(ValueError, lambda: testassign(arr, v4))
1357+ assert_equal(testassign(arr, v5), ans)
1358+ w[:] = 4
1359+ assert_equal(arr, np.array([(1,4),(1,4)], dtype=dt))
1360+
1361+ # test field-reordering, assignment by position, and self-assignment
1362+ a = np.array([(1,2,3)],
1363+ dtype=[('foo', 'i8'), ('bar', 'i8'), ('baz', 'f4')])
1364+ a[['foo', 'bar']] = a[['bar', 'foo']]
1365+ assert_equal(a[0].item(), (2,1,3))
1366+
1367+ # test that this works even for 'simple_unaligned' structs
1368+ # (ie, that PyArray_EquivTypes cares about field order too)
1369+ a = np.array([(1,2)], dtype=[('a', 'i4'), ('b', 'i4')])
1370+ a[['a', 'b']] = a[['b', 'a']]
1371+ assert_equal(a[0].item(), (2,1))
1372+
1373+ def test_scalar_assignment(self):
1374+ with assert_raises(ValueError):
1375+ arr = np.arange(25).reshape(5, 5)
1376+ arr.itemset(3)
1377+
1378+ def test_structuredscalar_indexing(self):
1379+ # test gh-7262
1380+ x = np.empty(shape=1, dtype="(2)3S,(2)3U")
1381+ assert_equal(x[["f0","f1"]][0], x[0][["f0","f1"]])
1382+ assert_equal(x[0], x[0][()])
1383+
1384+ def test_multiindex_titles(self):
1385+ a = np.zeros(4, dtype=[(('a', 'b'), 'i'), ('c', 'i'), ('d', 'i')])
1386+ assert_raises(KeyError, lambda : a[['a','c']])
1387+ assert_raises(KeyError, lambda : a[['a','a']])
1388+ assert_raises(ValueError, lambda : a[['b','b']]) # field exists, but repeated
1389+ a[['b','c']] # no exception
1390+
1391+
1392+class TestBool:
1393+ def test_test_interning(self):
1394+ a0 = np.bool_(0)
1395+ b0 = np.bool_(False)
1396+ assert_(a0 is b0)
1397+ a1 = np.bool_(1)
1398+ b1 = np.bool_(True)
1399+ assert_(a1 is b1)
1400+ assert_(np.array([True])[0] is a1)
1401+ assert_(np.array(True)[()] is a1)
1402+
1403+ def test_sum(self):
1404+ d = np.ones(101, dtype=bool)
1405+ assert_equal(d.sum(), d.size)
1406+ assert_equal(d[::2].sum(), d[::2].size)
1407+ assert_equal(d[::-2].sum(), d[::-2].size)
1408+
1409+ d = np.frombuffer(b'\xff\xff' * 100, dtype=bool)
1410+ assert_equal(d.sum(), d.size)
1411+ assert_equal(d[::2].sum(), d[::2].size)
1412+ assert_equal(d[::-2].sum(), d[::-2].size)
1413+
1414+ def check_count_nonzero(self, power, length):
1415+ powers = [2 ** i for i in range(length)]
1416+ for i in range(2**power):
1417+ l = [(i & x) != 0 for x in powers]
1418+ a = np.array(l, dtype=bool)
1419+ c = builtins.sum(l)
1420+ assert_equal(np.count_nonzero(a), c)
1421+ av = a.view(np.uint8)
1422+ av *= 3
1423+ assert_equal(np.count_nonzero(a), c)
1424+ av *= 4
1425+ assert_equal(np.count_nonzero(a), c)
1426+ av[av != 0] = 0xFF
1427+ assert_equal(np.count_nonzero(a), c)
1428+
1429+ def test_count_nonzero(self):
1430+ # check all 12 bit combinations in a length 17 array
1431+ # covers most cases of the 16 byte unrolled code
1432+ self.check_count_nonzero(12, 17)
1433+
1434+ @pytest.mark.slow
1435+ def test_count_nonzero_all(self):
1436+ # check all combinations in a length 17 array
1437+ # covers all cases of the 16 byte unrolled code
1438+ self.check_count_nonzero(17, 17)
1439+
1440+ def test_count_nonzero_unaligned(self):
1441+ # prevent mistakes as e.g. gh-4060
1442+ for o in range(7):
1443+ a = np.zeros((18,), dtype=bool)[o+1:]
1444+ a[:o] = True
1445+ assert_equal(np.count_nonzero(a), builtins.sum(a.tolist()))
1446+ a = np.ones((18,), dtype=bool)[o+1:]
1447+ a[:o] = False
1448+ assert_equal(np.count_nonzero(a), builtins.sum(a.tolist()))
1449+
1450+ def _test_cast_from_flexible(self, dtype):
1451+ # empty string -> false
1452+ for n in range(3):
1453+ v = np.array(b'', (dtype, n))
1454+ assert_equal(bool(v), False)
1455+ assert_equal(bool(v[()]), False)
1456+ assert_equal(v.astype(bool), False)
1457+ assert_(isinstance(v.astype(bool), np.ndarray))
1458+ assert_(v[()].astype(bool) is np.False_)
1459+
1460+ # anything else -> true
1461+ for n in range(1, 4):
1462+ for val in [b'a', b'0', b' ']:
1463+ v = np.array(val, (dtype, n))
1464+ assert_equal(bool(v), True)
1465+ assert_equal(bool(v[()]), True)
1466+ assert_equal(v.astype(bool), True)
1467+ assert_(isinstance(v.astype(bool), np.ndarray))
1468+ assert_(v[()].astype(bool) is np.True_)
1469+
1470+ def test_cast_from_void(self):
1471+ self._test_cast_from_flexible(np.void)
1472+
1473+ @pytest.mark.xfail(reason="See gh-9847")
1474+ def test_cast_from_unicode(self):
1475+ self._test_cast_from_flexible(np.unicode_)
1476+
1477+ @pytest.mark.xfail(reason="See gh-9847")
1478+ def test_cast_from_bytes(self):
1479+ self._test_cast_from_flexible(np.bytes_)
1480+
1481+
1482+class TestZeroSizeFlexible:
1483+ @staticmethod
1484+ def _zeros(shape, dtype=str):
1485+ dtype = np.dtype(dtype)
1486+ if dtype == np.void:
1487+ return np.zeros(shape, dtype=(dtype, 0))
1488+
1489+ # not constructable directly
1490+ dtype = np.dtype([('x', dtype, 0)])
1491+ return np.zeros(shape, dtype=dtype)['x']
1492+
1493+ def test_create(self):
1494+ zs = self._zeros(10, bytes)
1495+ assert_equal(zs.itemsize, 0)
1496+ zs = self._zeros(10, np.void)
1497+ assert_equal(zs.itemsize, 0)
1498+ zs = self._zeros(10, str)
1499+ assert_equal(zs.itemsize, 0)
1500+
1501+ def _test_sort_partition(self, name, kinds, **kwargs):
1502+ # Previously, these would all hang
1503+ for dt in [bytes, np.void, str]:
1504+ zs = self._zeros(10, dt)
1505+ sort_method = getattr(zs, name)
1506+ sort_func = getattr(np, name)
1507+ for kind in kinds:
1508+ sort_method(kind=kind, **kwargs)
1509+ sort_func(zs, kind=kind, **kwargs)
1510+
1511+ def test_sort(self):
1512+ self._test_sort_partition('sort', kinds='qhs')
1513+
1514+ def test_argsort(self):
1515+ self._test_sort_partition('argsort', kinds='qhs')
1516+
1517+ def test_partition(self):
1518+ self._test_sort_partition('partition', kinds=['introselect'], kth=2)
1519+
1520+ def test_argpartition(self):
1521+ self._test_sort_partition('argpartition', kinds=['introselect'], kth=2)
1522+
1523+ def test_resize(self):
1524+ # previously an error
1525+ for dt in [bytes, np.void, str]:
1526+ zs = self._zeros(10, dt)
1527+ zs.resize(25)
1528+ zs.resize((10, 10))
1529+
1530+ def test_view(self):
1531+ for dt in [bytes, np.void, str]:
1532+ zs = self._zeros(10, dt)
1533+
1534+ # viewing as itself should be allowed
1535+ assert_equal(zs.view(dt).dtype, np.dtype(dt))
1536+
1537+ # viewing as any non-empty type gives an empty result
1538+ assert_equal(zs.view((dt, 1)).shape, (0,))
1539+
1540+ def test_dumps(self):
1541+ zs = self._zeros(10, int)
1542+ assert_equal(zs, pickle.loads(zs.dumps()))
1543+
1544+ def test_pickle(self):
1545+ for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
1546+ for dt in [bytes, np.void, str]:
1547+ zs = self._zeros(10, dt)
1548+ p = pickle.dumps(zs, protocol=proto)
1549+ zs2 = pickle.loads(p)
1550+
1551+ assert_equal(zs.dtype, zs2.dtype)
1552+
1553+ @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL < 5,
1554+ reason="requires pickle protocol 5")
1555+ def test_pickle_with_buffercallback(self):
1556+ array = np.arange(10)
1557+ buffers = []
1558+ bytes_string = pickle.dumps(array, buffer_callback=buffers.append,
1559+ protocol=5)
1560+ array_from_buffer = pickle.loads(bytes_string, buffers=buffers)
1561+ # when using pickle protocol 5 with buffer callbacks,
1562+ # array_from_buffer is reconstructed from a buffer holding a view
1563+ # to the initial array's data, so modifying an element in array
1564+ # should modify it in array_from_buffer too.
1565+ array[0] = -1
1566+ assert array_from_buffer[0] == -1, array_from_buffer[0]
1567+
1568+
1569+class TestMethods:
1570+
1571+ sort_kinds = ['quicksort', 'heapsort', 'stable']
1572+
1573+ def test_compress(self):
1574+ tgt = [[5, 6, 7, 8, 9]]
1575+ arr = np.arange(10).reshape(2, 5)
1576+ out = arr.compress([0, 1], axis=0)
1577+ assert_equal(out, tgt)
1578+
1579+ tgt = [[1, 3], [6, 8]]
1580+ out = arr.compress([0, 1, 0, 1, 0], axis=1)
1581+ assert_equal(out, tgt)
1582+
1583+ tgt = [[1], [6]]
1584+ arr = np.arange(10).reshape(2, 5)
1585+ out = arr.compress([0, 1], axis=1)
1586+ assert_equal(out, tgt)
1587+
1588+ arr = np.arange(10).reshape(2, 5)
1589+ out = arr.compress([0, 1])
1590+ assert_equal(out, 1)
1591+
1592+ def test_choose(self):
1593+ x = 2*np.ones((3,), dtype=int)
1594+ y = 3*np.ones((3,), dtype=int)
1595+ x2 = 2*np.ones((2, 3), dtype=int)
1596+ y2 = 3*np.ones((2, 3), dtype=int)
1597+ ind = np.array([0, 0, 1])
1598+
1599+ A = ind.choose((x, y))
1600+ assert_equal(A, [2, 2, 3])
1601+
1602+ A = ind.choose((x2, y2))
1603+ assert_equal(A, [[2, 2, 3], [2, 2, 3]])
1604+
1605+ A = ind.choose((x, y2))
1606+ assert_equal(A, [[2, 2, 3], [2, 2, 3]])
1607+
1608+ oned = np.ones(1)
1609+ # gh-12031, caused SEGFAULT
1610+ assert_raises(TypeError, oned.choose,np.void(0), [oned])
1611+
1612+ # gh-6272 check overlap on out
1613+ x = np.arange(5)
1614+ y = np.choose([0,0,0], [x[:3], x[:3], x[:3]], out=x[1:4], mode='wrap')
1615+ assert_equal(y, np.array([0, 1, 2]))
1616+
1617+ def test_prod(self):
1618+ ba = [1, 2, 10, 11, 6, 5, 4]
1619+ ba2 = [[1, 2, 3, 4], [5, 6, 7, 9], [10, 3, 4, 5]]
1620+
1621+ for ctype in [np.int16, np.uint16, np.int32, np.uint32,
1622+ np.float32, np.float64, np.complex64, np.complex128]:
1623+ a = np.array(ba, ctype)
1624+ a2 = np.array(ba2, ctype)
1625+ if ctype in ['1', 'b']:
1626+ assert_raises(ArithmeticError, a.prod)
1627+ assert_raises(ArithmeticError, a2.prod, axis=1)
1628+ else:
1629+ assert_equal(a.prod(axis=0), 26400)
1630+ assert_array_equal(a2.prod(axis=0),
1631+ np.array([50, 36, 84, 180], ctype))
1632+ assert_array_equal(a2.prod(axis=-1),
1633+ np.array([24, 1890, 600], ctype))
1634+
1635+ def test_repeat(self):
1636+ m = np.array([1, 2, 3, 4, 5, 6])
1637+ m_rect = m.reshape((2, 3))
1638+
1639+ A = m.repeat([1, 3, 2, 1, 1, 2])
1640+ assert_equal(A, [1, 2, 2, 2, 3,
1641+ 3, 4, 5, 6, 6])
1642+
1643+ A = m.repeat(2)
1644+ assert_equal(A, [1, 1, 2, 2, 3, 3,
1645+ 4, 4, 5, 5, 6, 6])
1646+
1647+ A = m_rect.repeat([2, 1], axis=0)
1648+ assert_equal(A, [[1, 2, 3],
1649+ [1, 2, 3],
1650+ [4, 5, 6]])
1651+
1652+ A = m_rect.repeat([1, 3, 2], axis=1)
1653+ assert_equal(A, [[1, 2, 2, 2, 3, 3],
1654+ [4, 5, 5, 5, 6, 6]])
1655+
1656+ A = m_rect.repeat(2, axis=0)
1657+ assert_equal(A, [[1, 2, 3],
1658+ [1, 2, 3],
1659+ [4, 5, 6],
1660+ [4, 5, 6]])
1661+
1662+ A = m_rect.repeat(2, axis=1)
1663+ assert_equal(A, [[1, 1, 2, 2, 3, 3],
1664+ [4, 4, 5, 5, 6, 6]])
1665+
1666+ def test_reshape(self):
1667+ arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
1668+
1669+ tgt = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
1670+ assert_equal(arr.reshape(2, 6), tgt)
1671+
1672+ tgt = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
1673+ assert_equal(arr.reshape(3, 4), tgt)
1674+
1675+ tgt = [[1, 10, 8, 6], [4, 2, 11, 9], [7, 5, 3, 12]]
1676+ assert_equal(arr.reshape((3, 4), order='F'), tgt)
1677+
1678+ tgt = [[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
1679+ assert_equal(arr.T.reshape((3, 4), order='C'), tgt)
1680+
1681+ def test_round(self):
1682+ def check_round(arr, expected, *round_args):
1683+ assert_equal(arr.round(*round_args), expected)
1684+ # With output array
1685+ out = np.zeros_like(arr)
1686+ res = arr.round(*round_args, out=out)
1687+ assert_equal(out, expected)
1688+ assert_equal(out, res)
1689+
1690+ check_round(np.array([1.2, 1.5]), [1, 2])
1691+ check_round(np.array(1.5), 2)
1692+ check_round(np.array([12.2, 15.5]), [10, 20], -1)
1693+ check_round(np.array([12.15, 15.51]), [12.2, 15.5], 1)
1694+ # Complex rounding
1695+ check_round(np.array([4.5 + 1.5j]), [4 + 2j])
1696+ check_round(np.array([12.5 + 15.5j]), [10 + 20j], -1)
1697+
1698+ def test_squeeze(self):
1699+ a = np.array([[[1], [2], [3]]])
1700+ assert_equal(a.squeeze(), [1, 2, 3])
1701+ assert_equal(a.squeeze(axis=(0,)), [[1], [2], [3]])
1702+ assert_raises(ValueError, a.squeeze, axis=(1,))
1703+ assert_equal(a.squeeze(axis=(2,)), [[1, 2, 3]])
1704+
1705+ def test_transpose(self):
1706+ a = np.array([[1, 2], [3, 4]])
1707+ assert_equal(a.transpose(), [[1, 3], [2, 4]])
1708+ assert_raises(ValueError, lambda: a.transpose(0))
1709+ assert_raises(ValueError, lambda: a.transpose(0, 0))
1710+ assert_raises(ValueError, lambda: a.transpose(0, 1, 2))
1711+
1712+ def test_sort(self):
1713+ # test ordering for floats and complex containing nans. It is only
1714+ # necessary to check the less-than comparison, so sorts that
1715+ # only follow the insertion sort path are sufficient. We only
1716+ # test doubles and complex doubles as the logic is the same.
1717+
1718+ # check doubles
1719+ msg = "Test real sort order with nans"
1720+ a = np.array([np.nan, 1, 0])
1721+ b = np.sort(a)
1722+ assert_equal(b, a[::-1], msg)
1723+ # check complex
1724+ msg = "Test complex sort order with nans"
1725+ a = np.zeros(9, dtype=np.complex128)
1726+ a.real += [np.nan, np.nan, np.nan, 1, 0, 1, 1, 0, 0]
1727+ a.imag += [np.nan, 1, 0, np.nan, np.nan, 1, 0, 1, 0]
1728+ b = np.sort(a)
1729+ assert_equal(b, a[::-1], msg)
1730+
1731+ # all c scalar sorts use the same code with different types
1732+ # so it suffices to run a quick check with one type. The number
1733+ # of sorted items must be greater than ~50 to check the actual
1734+ # algorithm because quick and merge sort fall over to insertion
1735+ # sort for small arrays.
1736+
1737+ @pytest.mark.parametrize('dtype', [np.uint8, np.uint16, np.uint32, np.uint64,
1738+ np.float16, np.float32, np.float64,
1739+ np.longdouble])
1740+ def test_sort_unsigned(self, dtype):
1741+ a = np.arange(101, dtype=dtype)
1742+ b = a[::-1].copy()
1743+ for kind in self.sort_kinds:
1744+ msg = "scalar sort, kind=%s" % kind
1745+ c = a.copy()
1746+ c.sort(kind=kind)
1747+ assert_equal(c, a, msg)
1748+ c = b.copy()
1749+ c.sort(kind=kind)
1750+ assert_equal(c, a, msg)
1751+
1752+ @pytest.mark.parametrize('dtype',
1753+ [np.int8, np.int16, np.int32, np.int64, np.float16,
1754+ np.float32, np.float64, np.longdouble])
1755+ def test_sort_signed(self, dtype):
1756+ a = np.arange(-50, 51, dtype=dtype)
1757+ b = a[::-1].copy()
1758+ for kind in self.sort_kinds:
1759+ msg = "scalar sort, kind=%s" % (kind)
1760+ c = a.copy()
1761+ c.sort(kind=kind)
1762+ assert_equal(c, a, msg)
1763+ c = b.copy()
1764+ c.sort(kind=kind)
1765+ assert_equal(c, a, msg)
1766+
1767+ @pytest.mark.parametrize('dtype', [np.float32, np.float64, np.longdouble])
1768+ @pytest.mark.parametrize('part', ['real', 'imag'])
1769+ def test_sort_complex(self, part, dtype):
1770+ # test complex sorts. These use the same code as the scalars
1771+ # but the compare function differs.
1772+ cdtype = {
1773+ np.single: np.csingle,
1774+ np.double: np.cdouble,
1775+ np.longdouble: np.clongdouble,
1776+ }[dtype]
1777+ a = np.arange(-50, 51, dtype=dtype)
1778+ b = a[::-1].copy()
1779+ ai = (a * (1+1j)).astype(cdtype)
1780+ bi = (b * (1+1j)).astype(cdtype)
1781+ setattr(ai, part, 1)
1782+ setattr(bi, part, 1)
1783+ for kind in self.sort_kinds:
1784+ msg = "complex sort, %s part == 1, kind=%s" % (part, kind)
1785+ c = ai.copy()
1786+ c.sort(kind=kind)
1787+ assert_equal(c, ai, msg)
1788+ c = bi.copy()
1789+ c.sort(kind=kind)
1790+ assert_equal(c, ai, msg)
1791+
1792+ def test_sort_complex_byte_swapping(self):
1793+ # test sorting of complex arrays requiring byte-swapping, gh-5441
1794+ for endianness in '<>':
1795+ for dt in np.typecodes['Complex']:
1796+ arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianness + dt)
1797+ c = arr.copy()
1798+ c.sort()
1799+ msg = 'byte-swapped complex sort, dtype={0}'.format(dt)
1800+ assert_equal(c, arr, msg)
1801+
1802+ @pytest.mark.parametrize('dtype', [np.bytes_, np.unicode_])
1803+ def test_sort_string(self, dtype):
1804+ # np.array will perform the encoding to bytes for us in the bytes test
1805+ a = np.array(['aaaaaaaa' + chr(i) for i in range(101)], dtype=dtype)
1806+ b = a[::-1].copy()
1807+ for kind in self.sort_kinds:
1808+ msg = "kind=%s" % kind
1809+ c = a.copy()
1810+ c.sort(kind=kind)
1811+ assert_equal(c, a, msg)
1812+ c = b.copy()
1813+ c.sort(kind=kind)
1814+ assert_equal(c, a, msg)
1815+
1816+ def test_sort_object(self):
1817+ # test object array sorts.
1818+ a = np.empty((101,), dtype=object)
1819+ a[:] = list(range(101))
1820+ b = a[::-1]
1821+ for kind in ['q', 'h', 'm']:
1822+ msg = "kind=%s" % kind
1823+ c = a.copy()
1824+ c.sort(kind=kind)
1825+ assert_equal(c, a, msg)
1826+ c = b.copy()
1827+ c.sort(kind=kind)
1828+ assert_equal(c, a, msg)
1829+
1830+ def test_sort_structured(self):
1831+ # test record array sorts.
1832+ dt = np.dtype([('f', float), ('i', int)])
1833+ a = np.array([(i, i) for i in range(101)], dtype=dt)
1834+ b = a[::-1]
1835+ for kind in ['q', 'h', 'm']:
1836+ msg = "kind=%s" % kind
1837+ c = a.copy()
1838+ c.sort(kind=kind)
1839+ assert_equal(c, a, msg)
1840+ c = b.copy()
1841+ c.sort(kind=kind)
1842+ assert_equal(c, a, msg)
1843+
1844+ @pytest.mark.parametrize('dtype', ['datetime64[D]', 'timedelta64[D]'])
1845+ def test_sort_time(self, dtype):
1846+ # test datetime64 and timedelta64 sorts.
1847+ a = np.arange(0, 101, dtype=dtype)
1848+ b = a[::-1]
1849+ for kind in ['q', 'h', 'm']:
1850+ msg = "kind=%s" % kind
1851+ c = a.copy()
1852+ c.sort(kind=kind)
1853+ assert_equal(c, a, msg)
1854+ c = b.copy()
1855+ c.sort(kind=kind)
1856+ assert_equal(c, a, msg)
1857+
1858+ def test_sort_axis(self):
1859+ # check axis handling. This should be the same for all type
1860+ # specific sorts, so we only check it for one type and one kind
1861+ a = np.array([[3, 2], [1, 0]])
1862+ b = np.array([[1, 0], [3, 2]])
1863+ c = np.array([[2, 3], [0, 1]])
1864+ d = a.copy()
1865+ d.sort(axis=0)
1866+ assert_equal(d, b, "test sort with axis=0")
1867+ d = a.copy()
1868+ d.sort(axis=1)
1869+ assert_equal(d, c, "test sort with axis=1")
1870+ d = a.copy()
1871+ d.sort()
1872+ assert_equal(d, c, "test sort with default axis")
1873+
1874+ def test_sort_size_0(self):
1875+ # check axis handling for multidimensional empty arrays
1876+ a = np.array([])
1877+ a.shape = (3, 2, 1, 0)
1878+ for axis in range(-a.ndim, a.ndim):
1879+ msg = 'test empty array sort with axis={0}'.format(axis)
1880+ assert_equal(np.sort(a, axis=axis), a, msg)
1881+ msg = 'test empty array sort with axis=None'
1882+ assert_equal(np.sort(a, axis=None), a.ravel(), msg)
1883+
1884+ def test_sort_bad_ordering(self):
1885+ # test generic class with bogus ordering,
1886+ # should not segfault.
1887+ class Boom:
1888+ def __lt__(self, other):
1889+ return True
1890+
1891+ a = np.array([Boom()] * 100, dtype=object)
1892+ for kind in self.sort_kinds:
1893+ msg = "kind=%s" % kind
1894+ c = a.copy()
1895+ c.sort(kind=kind)
1896+ assert_equal(c, a, msg)
1897+
1898+ def test_void_sort(self):
1899+ # gh-8210 - previously segfaulted
1900+ for i in range(4):
1901+ rand = np.random.randint(256, size=4000, dtype=np.uint8)
1902+ arr = rand.view('V4')
1903+ arr[::-1].sort()
1904+
1905+ dt = np.dtype([('val', 'i4', (1,))])
1906+ for i in range(4):
1907+ rand = np.random.randint(256, size=4000, dtype=np.uint8)
1908+ arr = rand.view(dt)
1909+ arr[::-1].sort()
1910+
1911+ def test_sort_raises(self):
1912+ #gh-9404
1913+ arr = np.array([0, datetime.now(), 1], dtype=object)
1914+ for kind in self.sort_kinds:
1915+ assert_raises(TypeError, arr.sort, kind=kind)
1916+ #gh-3879
1917+ class Raiser:
1918+ def raises_anything(*args, **kwargs):
1919+ raise TypeError("SOMETHING ERRORED")
1920+ __eq__ = __ne__ = __lt__ = __gt__ = __ge__ = __le__ = raises_anything
1921+ arr = np.array([[Raiser(), n] for n in range(10)]).reshape(-1)
1922+ np.random.shuffle(arr)
1923+ for kind in self.sort_kinds:
1924+ assert_raises(TypeError, arr.sort, kind=kind)
1925+
1926+ def test_sort_degraded(self):
1927+ # test degraded dataset would take minutes to run with normal qsort
1928+ d = np.arange(1000000)
1929+ do = d.copy()
1930+ x = d
1931+ # create a median of 3 killer where each median is the sorted second
1932+ # last element of the quicksort partition
1933+ while x.size > 3:
1934+ mid = x.size // 2
1935+ x[mid], x[-2] = x[-2], x[mid]
1936+ x = x[:-2]
1937+
1938+ assert_equal(np.sort(d), do)
1939+ assert_equal(d[np.argsort(d)], do)
1940+
1941+ def test_copy(self):
1942+ def assert_fortran(arr):
1943+ assert_(arr.flags.fortran)
1944+ assert_(arr.flags.f_contiguous)
1945+ assert_(not arr.flags.c_contiguous)
1946+
1947+ def assert_c(arr):
1948+ assert_(not arr.flags.fortran)
1949+ assert_(not arr.flags.f_contiguous)
1950+ assert_(arr.flags.c_contiguous)
1951+
1952+ a = np.empty((2, 2), order='F')
1953+ # Test copying a Fortran array
1954+ assert_c(a.copy())
1955+ assert_c(a.copy('C'))
1956+ assert_fortran(a.copy('F'))
1957+ assert_fortran(a.copy('A'))
1958+
1959+ # Now test starting with a C array.
1960+ a = np.empty((2, 2), order='C')
1961+ assert_c(a.copy())
1962+ assert_c(a.copy('C'))
1963+ assert_fortran(a.copy('F'))
1964+ assert_c(a.copy('A'))
1965+
1966+ def test_sort_order(self):
1967+ # Test sorting an array with fields
1968+ x1 = np.array([21, 32, 14])
1969+ x2 = np.array(['my', 'first', 'name'])
1970+ x3 = np.array([3.1, 4.5, 6.2])
1971+ r = np.rec.fromarrays([x1, x2, x3], names='id,word,number')
1972+
1973+ r.sort(order=['id'])
1974+ assert_equal(r.id, np.array([14, 21, 32]))
1975+ assert_equal(r.word, np.array(['name', 'my', 'first']))
1976+ assert_equal(r.number, np.array([6.2, 3.1, 4.5]))
1977+
1978+ r.sort(order=['word'])
1979+ assert_equal(r.id, np.array([32, 21, 14]))
1980+ assert_equal(r.word, np.array(['first', 'my', 'name']))
1981+ assert_equal(r.number, np.array([4.5, 3.1, 6.2]))
1982+
1983+ r.sort(order=['number'])
1984+ assert_equal(r.id, np.array([21, 32, 14]))
1985+ assert_equal(r.word, np.array(['my', 'first', 'name']))
1986+ assert_equal(r.number, np.array([3.1, 4.5, 6.2]))
1987+
1988+ assert_raises_regex(ValueError, 'duplicate',
1989+ lambda: r.sort(order=['id', 'id']))
1990+
1991+ if sys.byteorder == 'little':
1992+ strtype = '>i2'
1993+ else:
1994+ strtype = '<i2'
1995+ mydtype = [('name', strchar + '5'), ('col2', strtype)]
1996+ r = np.array([('a', 1), ('b', 255), ('c', 3), ('d', 258)],
1997+ dtype=mydtype)
1998+ r.sort(order='col2')
1999+ assert_equal(r['col2'], [1, 3, 255, 258])
2000+ assert_equal(r, np.array([('a', 1), ('c', 3), ('b', 255), ('d', 258)],
2001+ dtype=mydtype))
2002+
2003+ def test_argsort(self):
2004+ # all c scalar argsorts use the same code with different types
2005+ # so it suffices to run a quick check with one type. The number
2006+ # of sorted items must be greater than ~50 to check the actual
2007+ # algorithm because quick and merge sort fall over to insertion
2008+ # sort for small arrays.
2009+
2010+ for dtype in [np.int32, np.uint32, np.float32]:
2011+ a = np.arange(101, dtype=dtype)
2012+ b = a[::-1].copy()
2013+ for kind in self.sort_kinds:
2014+ msg = "scalar argsort, kind=%s, dtype=%s" % (kind, dtype)
2015+ assert_equal(a.copy().argsort(kind=kind), a, msg)
2016+ assert_equal(b.copy().argsort(kind=kind), b, msg)
2017+
2018+ # test complex argsorts. These use the same code as the scalars
2019+ # but the compare function differs.
2020+ ai = a*1j + 1
2021+ bi = b*1j + 1
2022+ for kind in self.sort_kinds:
2023+ msg = "complex argsort, kind=%s" % kind
2024+ assert_equal(ai.copy().argsort(kind=kind), a, msg)
2025+ assert_equal(bi.copy().argsort(kind=kind), b, msg)
2026+ ai = a + 1j
2027+ bi = b + 1j
2028+ for kind in self.sort_kinds:
2029+ msg = "complex argsort, kind=%s" % kind
2030+ assert_equal(ai.copy().argsort(kind=kind), a, msg)
2031+ assert_equal(bi.copy().argsort(kind=kind), b, msg)
2032+
2033+ # test argsort of complex arrays requiring byte-swapping, gh-5441
2034+ for endianness in '<>':
2035+ for dt in np.typecodes['Complex']:
2036+ arr = np.array([1+3.j, 2+2.j, 3+1.j], dtype=endianness + dt)
2037+ msg = 'byte-swapped complex argsort, dtype={0}'.format(dt)
2038+ assert_equal(arr.argsort(),
2039+ np.arange(len(arr), dtype=np.intp), msg)
2040+
2041+ # test string argsorts.
2042+ s = 'aaaaaaaa'
2043+ a = np.array([s + chr(i) for i in range(101)])
2044+ b = a[::-1].copy()
2045+ r = np.arange(101)
2046+ rr = r[::-1]
2047+ for kind in self.sort_kinds:
2048+ msg = "string argsort, kind=%s" % kind
2049+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2050+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2051+
2052+ # test unicode argsorts.
2053+ s = 'aaaaaaaa'
2054+ a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode_)
2055+ b = a[::-1]
2056+ r = np.arange(101)
2057+ rr = r[::-1]
2058+ for kind in self.sort_kinds:
2059+ msg = "unicode argsort, kind=%s" % kind
2060+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2061+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2062+
2063+ # test object array argsorts.
2064+ a = np.empty((101,), dtype=object)
2065+ a[:] = list(range(101))
2066+ b = a[::-1]
2067+ r = np.arange(101)
2068+ rr = r[::-1]
2069+ for kind in self.sort_kinds:
2070+ msg = "object argsort, kind=%s" % kind
2071+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2072+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2073+
2074+ # test structured array argsorts.
2075+ dt = np.dtype([('f', float), ('i', int)])
2076+ a = np.array([(i, i) for i in range(101)], dtype=dt)
2077+ b = a[::-1]
2078+ r = np.arange(101)
2079+ rr = r[::-1]
2080+ for kind in self.sort_kinds:
2081+ msg = "structured array argsort, kind=%s" % kind
2082+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2083+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2084+
2085+ # test datetime64 argsorts.
2086+ a = np.arange(0, 101, dtype='datetime64[D]')
2087+ b = a[::-1]
2088+ r = np.arange(101)
2089+ rr = r[::-1]
2090+ for kind in ['q', 'h', 'm']:
2091+ msg = "datetime64 argsort, kind=%s" % kind
2092+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2093+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2094+
2095+ # test timedelta64 argsorts.
2096+ a = np.arange(0, 101, dtype='timedelta64[D]')
2097+ b = a[::-1]
2098+ r = np.arange(101)
2099+ rr = r[::-1]
2100+ for kind in ['q', 'h', 'm']:
2101+ msg = "timedelta64 argsort, kind=%s" % kind
2102+ assert_equal(a.copy().argsort(kind=kind), r, msg)
2103+ assert_equal(b.copy().argsort(kind=kind), rr, msg)
2104+
2105+ # check axis handling. This should be the same for all type
2106+ # specific argsorts, so we only check it for one type and one kind
2107+ a = np.array([[3, 2], [1, 0]])
2108+ b = np.array([[1, 1], [0, 0]])
2109+ c = np.array([[1, 0], [1, 0]])
2110+ assert_equal(a.copy().argsort(axis=0), b)
2111+ assert_equal(a.copy().argsort(axis=1), c)
2112+ assert_equal(a.copy().argsort(), c)
2113+
2114+ # check axis handling for multidimensional empty arrays
2115+ a = np.array([])
2116+ a.shape = (3, 2, 1, 0)
2117+ for axis in range(-a.ndim, a.ndim):
2118+ msg = 'test empty array argsort with axis={0}'.format(axis)
2119+ assert_equal(np.argsort(a, axis=axis),
2120+ np.zeros_like(a, dtype=np.intp), msg)
2121+ msg = 'test empty array argsort with axis=None'
2122+ assert_equal(np.argsort(a, axis=None),
2123+ np.zeros_like(a.ravel(), dtype=np.intp), msg)
2124+
2125+ # check that stable argsorts are stable
2126+ r = np.arange(100)
2127+ # scalars
2128+ a = np.zeros(100)
2129+ assert_equal(a.argsort(kind='m'), r)
2130+ # complex
2131+ a = np.zeros(100, dtype=complex)
2132+ assert_equal(a.argsort(kind='m'), r)
2133+ # string
2134+ a = np.array(['aaaaaaaaa' for i in range(100)])
2135+ assert_equal(a.argsort(kind='m'), r)
2136+ # unicode
2137+ a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode_)
2138+ assert_equal(a.argsort(kind='m'), r)
2139+
2140+ def test_sort_unicode_kind(self):
2141+ d = np.arange(10)
2142+ k = b'\xc3\xa4'.decode("UTF8")
2143+ assert_raises(ValueError, d.sort, kind=k)
2144+ assert_raises(ValueError, d.argsort, kind=k)
2145+
2146+ def test_searchsorted(self):
2147+ # test for floats and complex containing nans. The logic is the
2148+ # same for all float types so only test double types for now.
2149+ # The search sorted routines use the compare functions for the
2150+ # array type, so this checks if that is consistent with the sort
2151+ # order.
2152+
2153+ # check double
2154+ a = np.array([0, 1, np.nan])
2155+ msg = "Test real searchsorted with nans, side='l'"
2156+ b = a.searchsorted(a, side='l')
2157+ assert_equal(b, np.arange(3), msg)
2158+ msg = "Test real searchsorted with nans, side='r'"
2159+ b = a.searchsorted(a, side='r')
2160+ assert_equal(b, np.arange(1, 4), msg)
2161+ # check keyword arguments
2162+ a.searchsorted(v=1)
2163+ # check double complex
2164+ a = np.zeros(9, dtype=np.complex128)
2165+ a.real += [0, 0, 1, 1, 0, 1, np.nan, np.nan, np.nan]
2166+ a.imag += [0, 1, 0, 1, np.nan, np.nan, 0, 1, np.nan]
2167+ msg = "Test complex searchsorted with nans, side='l'"
2168+ b = a.searchsorted(a, side='l')
2169+ assert_equal(b, np.arange(9), msg)
2170+ msg = "Test complex searchsorted with nans, side='r'"
2171+ b = a.searchsorted(a, side='r')
2172+ assert_equal(b, np.arange(1, 10), msg)
2173+ msg = "Test searchsorted with little endian, side='l'"
2174+ a = np.array([0, 128], dtype='<i4')
2175+ b = a.searchsorted(np.array(128, dtype='<i4'))
2176+ assert_equal(b, 1, msg)
2177+ msg = "Test searchsorted with big endian, side='l'"
2178+ a = np.array([0, 128], dtype='>i4')
2179+ b = a.searchsorted(np.array(128, dtype='>i4'))
2180+ assert_equal(b, 1, msg)
2181+
2182+ # Check 0 elements
2183+ a = np.ones(0)
2184+ b = a.searchsorted([0, 1, 2], 'l')
2185+ assert_equal(b, [0, 0, 0])
2186+ b = a.searchsorted([0, 1, 2], 'r')
2187+ assert_equal(b, [0, 0, 0])
2188+ a = np.ones(1)
2189+ # Check 1 element
2190+ b = a.searchsorted([0, 1, 2], 'l')
2191+ assert_equal(b, [0, 0, 1])
2192+ b = a.searchsorted([0, 1, 2], 'r')
2193+ assert_equal(b, [0, 1, 1])
2194+ # Check all elements equal
2195+ a = np.ones(2)
2196+ b = a.searchsorted([0, 1, 2], 'l')
2197+ assert_equal(b, [0, 0, 2])
2198+ b = a.searchsorted([0, 1, 2], 'r')
2199+ assert_equal(b, [0, 2, 2])
2200+
2201+ # Test searching unaligned array
2202+ a = np.arange(10)
2203+ aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
2204+ unaligned = aligned[1:].view(a.dtype)
2205+ unaligned[:] = a
2206+ # Test searching unaligned array
2207+ b = unaligned.searchsorted(a, 'l')
2208+ assert_equal(b, a)
2209+ b = unaligned.searchsorted(a, 'r')
2210+ assert_equal(b, a + 1)
2211+ # Test searching for unaligned keys
2212+ b = a.searchsorted(unaligned, 'l')
2213+ assert_equal(b, a)
2214+ b = a.searchsorted(unaligned, 'r')
2215+ assert_equal(b, a + 1)
2216+
2217+ # Test smart resetting of binsearch indices
2218+ a = np.arange(5)
2219+ b = a.searchsorted([6, 5, 4], 'l')
2220+ assert_equal(b, [5, 5, 4])
2221+ b = a.searchsorted([6, 5, 4], 'r')
2222+ assert_equal(b, [5, 5, 5])
2223+
2224+ # Test all type specific binary search functions
2225+ types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
2226+ np.typecodes['Datetime'], '?O'))
2227+ for dt in types:
2228+ if dt == 'M':
2229+ dt = 'M8[D]'
2230+ if dt == '?':
2231+ a = np.arange(2, dtype=dt)
2232+ out = np.arange(2)
2233+ else:
2234+ a = np.arange(0, 5, dtype=dt)
2235+ out = np.arange(5)
2236+ b = a.searchsorted(a, 'l')
2237+ assert_equal(b, out)
2238+ b = a.searchsorted(a, 'r')
2239+ assert_equal(b, out + 1)
2240+ # Test empty array, use a fresh array to get warnings in
2241+ # valgrind if access happens.
2242+ e = np.ndarray(shape=0, buffer=b'', dtype=dt)
2243+ b = e.searchsorted(a, 'l')
2244+ assert_array_equal(b, np.zeros(len(a), dtype=np.intp))
2245+ b = a.searchsorted(e, 'l')
2246+ assert_array_equal(b, np.zeros(0, dtype=np.intp))
2247+
2248+ def test_searchsorted_unicode(self):
2249+ # Test searchsorted on unicode strings.
2250+
2251+ # 1.6.1 contained a string length miscalculation in
2252+ # arraytypes.c.src:UNICODE_compare() which manifested as
2253+ # incorrect/inconsistent results from searchsorted.
2254+ a = np.array(['P:\\20x_dapi_cy3\\20x_dapi_cy3_20100185_1',
2255+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100186_1',
2256+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100187_1',
2257+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100189_1',
2258+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100190_1',
2259+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100191_1',
2260+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100192_1',
2261+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100193_1',
2262+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100194_1',
2263+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100195_1',
2264+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100196_1',
2265+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1',
2266+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1',
2267+ 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'],
2268+ dtype=np.unicode_)
2269+ ind = np.arange(len(a))
2270+ assert_equal([a.searchsorted(v, 'left') for v in a], ind)
2271+ assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1)
2272+ assert_equal([a.searchsorted(a[i], 'left') for i in ind], ind)
2273+ assert_equal([a.searchsorted(a[i], 'right') for i in ind], ind + 1)
2274+
2275+ def test_searchsorted_with_invalid_sorter(self):
2276+ a = np.array([5, 2, 1, 3, 4])
2277+ s = np.argsort(a)
2278+ assert_raises(TypeError, np.searchsorted, a, 0,
2279+ sorter=np.array((1, (2, 3)), dtype=object))
2280+ assert_raises(TypeError, np.searchsorted, a, 0, sorter=[1.1])
2281+ assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4])
2282+ assert_raises(ValueError, np.searchsorted, a, 0, sorter=[1, 2, 3, 4, 5, 6])
2283+
2284+ # bounds check
2285+ assert_raises(ValueError, np.searchsorted, a, 4, sorter=[0, 1, 2, 3, 5])
2286+ assert_raises(ValueError, np.searchsorted, a, 0, sorter=[-1, 0, 1, 2, 3])
2287+ assert_raises(ValueError, np.searchsorted, a, 0, sorter=[4, 0, -1, 2, 3])
2288+
2289+ def test_searchsorted_with_sorter(self):
2290+ a = np.random.rand(300)
2291+ s = a.argsort()
2292+ b = np.sort(a)
2293+ k = np.linspace(0, 1, 20)
2294+ assert_equal(b.searchsorted(k), a.searchsorted(k, sorter=s))
2295+
2296+ a = np.array([0, 1, 2, 3, 5]*20)
2297+ s = a.argsort()
2298+ k = [0, 1, 2, 3, 5]
2299+ expected = [0, 20, 40, 60, 80]
2300+ assert_equal(a.searchsorted(k, side='l', sorter=s), expected)
2301+ expected = [20, 40, 60, 80, 100]
2302+ assert_equal(a.searchsorted(k, side='r', sorter=s), expected)
2303+
2304+ # Test searching unaligned array
2305+ keys = np.arange(10)
2306+ a = keys.copy()
2307+ np.random.shuffle(s)
2308+ s = a.argsort()
2309+ aligned = np.empty(a.itemsize * a.size + 1, 'uint8')
2310+ unaligned = aligned[1:].view(a.dtype)
2311+ # Test searching unaligned array
2312+ unaligned[:] = a
2313+ b = unaligned.searchsorted(keys, 'l', s)
2314+ assert_equal(b, keys)
2315+ b = unaligned.searchsorted(keys, 'r', s)
2316+ assert_equal(b, keys + 1)
2317+ # Test searching for unaligned keys
2318+ unaligned[:] = keys
2319+ b = a.searchsorted(unaligned, 'l', s)
2320+ assert_equal(b, keys)
2321+ b = a.searchsorted(unaligned, 'r', s)
2322+ assert_equal(b, keys + 1)
2323+
2324+ # Test all type specific indirect binary search functions
2325+ types = ''.join((np.typecodes['AllInteger'], np.typecodes['AllFloat'],
2326+ np.typecodes['Datetime'], '?O'))
2327+ for dt in types:
2328+ if dt == 'M':
2329+ dt = 'M8[D]'
2330+ if dt == '?':
2331+ a = np.array([1, 0], dtype=dt)
2332+ # We want the sorter array to be of a type that is different
2333+ # from np.intp in all platforms, to check for #4698
2334+ s = np.array([1, 0], dtype=np.int16)
2335+ out = np.array([1, 0])
2336+ else:
2337+ a = np.array([3, 4, 1, 2, 0], dtype=dt)
2338+ # We want the sorter array to be of a type that is different
2339+ # from np.intp in all platforms, to check for #4698
2340+ s = np.array([4, 2, 3, 0, 1], dtype=np.int16)
2341+ out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
2342+ b = a.searchsorted(a, 'l', s)
2343+ assert_equal(b, out)
2344+ b = a.searchsorted(a, 'r', s)
2345+ assert_equal(b, out + 1)
2346+ # Test empty array, use a fresh array to get warnings in
2347+ # valgrind if access happens.
2348+ e = np.ndarray(shape=0, buffer=b'', dtype=dt)
2349+ b = e.searchsorted(a, 'l', s[:0])
2350+ assert_array_equal(b, np.zeros(len(a), dtype=np.intp))
2351+ b = a.searchsorted(e, 'l', s)
2352+ assert_array_equal(b, np.zeros(0, dtype=np.intp))
2353+
2354+ # Test non-contiguous sorter array
2355+ a = np.array([3, 4, 1, 2, 0])
2356+ srt = np.empty((10,), dtype=np.intp)
2357+ srt[1::2] = -1
2358+ srt[::2] = [4, 2, 3, 0, 1]
2359+ s = srt[::2]
2360+ out = np.array([3, 4, 1, 2, 0], dtype=np.intp)
2361+ b = a.searchsorted(a, 'l', s)
2362+ assert_equal(b, out)
2363+ b = a.searchsorted(a, 'r', s)
2364+ assert_equal(b, out + 1)
2365+
2366+ def test_searchsorted_return_type(self):
2367+ # Functions returning indices should always return base ndarrays
2368+ class A(np.ndarray):
2369+ pass
2370+ a = np.arange(5).view(A)
2371+ b = np.arange(1, 3).view(A)
2372+ s = np.arange(5).view(A)
2373+ assert_(not isinstance(a.searchsorted(b, 'l'), A))
2374+ assert_(not isinstance(a.searchsorted(b, 'r'), A))
2375+ assert_(not isinstance(a.searchsorted(b, 'l', s), A))
2376+ assert_(not isinstance(a.searchsorted(b, 'r', s), A))
2377+
2378+ def test_argpartition_out_of_range(self):
2379+ # Test out of range values in kth raise an error, gh-5469
2380+ d = np.arange(10)
2381+ assert_raises(ValueError, d.argpartition, 10)
2382+ assert_raises(ValueError, d.argpartition, -11)
2383+ # Test also for generic type argpartition, which uses sorting
2384+ # and used to not bound check kth
2385+ d_obj = np.arange(10, dtype=object)
2386+ assert_raises(ValueError, d_obj.argpartition, 10)
2387+ assert_raises(ValueError, d_obj.argpartition, -11)
2388+
2389+ def test_partition_out_of_range(self):
2390+ # Test out of range values in kth raise an error, gh-5469
2391+ d = np.arange(10)
2392+ assert_raises(ValueError, d.partition, 10)
2393+ assert_raises(ValueError, d.partition, -11)
2394+ # Test also for generic type partition, which uses sorting
2395+ # and used to not bound check kth
2396+ d_obj = np.arange(10, dtype=object)
2397+ assert_raises(ValueError, d_obj.partition, 10)
2398+ assert_raises(ValueError, d_obj.partition, -11)
2399+
2400+ def test_argpartition_integer(self):
2401+ # Test non-integer values in kth raise an error/
2402+ d = np.arange(10)
2403+ assert_raises(TypeError, d.argpartition, 9.)
2404+ # Test also for generic type argpartition, which uses sorting
2405+ # and used to not bound check kth
2406+ d_obj = np.arange(10, dtype=object)
2407+ assert_raises(TypeError, d_obj.argpartition, 9.)
2408+
2409+ def test_partition_integer(self):
2410+ # Test out of range values in kth raise an error, gh-5469
2411+ d = np.arange(10)
2412+ assert_raises(TypeError, d.partition, 9.)
2413+ # Test also for generic type partition, which uses sorting
2414+ # and used to not bound check kth
2415+ d_obj = np.arange(10, dtype=object)
2416+ assert_raises(TypeError, d_obj.partition, 9.)
2417+
2418+ def test_partition_empty_array(self):
2419+ # check axis handling for multidimensional empty arrays
2420+ a = np.array([])
2421+ a.shape = (3, 2, 1, 0)
2422+ for axis in range(-a.ndim, a.ndim):
2423+ msg = 'test empty array partition with axis={0}'.format(axis)
2424+ assert_equal(np.partition(a, 0, axis=axis), a, msg)
2425+ msg = 'test empty array partition with axis=None'
2426+ assert_equal(np.partition(a, 0, axis=None), a.ravel(), msg)
2427+
2428+ def test_argpartition_empty_array(self):
2429+ # check axis handling for multidimensional empty arrays
2430+ a = np.array([])
2431+ a.shape = (3, 2, 1, 0)
2432+ for axis in range(-a.ndim, a.ndim):
2433+ msg = 'test empty array argpartition with axis={0}'.format(axis)
2434+ assert_equal(np.partition(a, 0, axis=axis),
2435+ np.zeros_like(a, dtype=np.intp), msg)
2436+ msg = 'test empty array argpartition with axis=None'
2437+ assert_equal(np.partition(a, 0, axis=None),
2438+ np.zeros_like(a.ravel(), dtype=np.intp), msg)
2439+
2440+ def test_partition(self):
2441+ d = np.arange(10)
2442+ assert_raises(TypeError, np.partition, d, 2, kind=1)
2443+ assert_raises(ValueError, np.partition, d, 2, kind="nonsense")
2444+ assert_raises(ValueError, np.argpartition, d, 2, kind="nonsense")
2445+ assert_raises(ValueError, d.partition, 2, axis=0, kind="nonsense")
2446+ assert_raises(ValueError, d.argpartition, 2, axis=0, kind="nonsense")
2447+ for k in ("introselect",):
2448+ d = np.array([])
2449+ assert_array_equal(np.partition(d, 0, kind=k), d)
2450+ assert_array_equal(np.argpartition(d, 0, kind=k), d)
2451+ d = np.ones(1)
2452+ assert_array_equal(np.partition(d, 0, kind=k)[0], d)
2453+ assert_array_equal(d[np.argpartition(d, 0, kind=k)],
2454+ np.partition(d, 0, kind=k))
2455+
2456+ # kth not modified
2457+ kth = np.array([30, 15, 5])
2458+ okth = kth.copy()
2459+ np.partition(np.arange(40), kth)
2460+ assert_array_equal(kth, okth)
2461+
2462+ for r in ([2, 1], [1, 2], [1, 1]):
2463+ d = np.array(r)
2464+ tgt = np.sort(d)
2465+ assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
2466+ assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
2467+ assert_array_equal(d[np.argpartition(d, 0, kind=k)],
2468+ np.partition(d, 0, kind=k))
2469+ assert_array_equal(d[np.argpartition(d, 1, kind=k)],
2470+ np.partition(d, 1, kind=k))
2471+ for i in range(d.size):
2472+ d[i:].partition(0, kind=k)
2473+ assert_array_equal(d, tgt)
2474+
2475+ for r in ([3, 2, 1], [1, 2, 3], [2, 1, 3], [2, 3, 1],
2476+ [1, 1, 1], [1, 2, 2], [2, 2, 1], [1, 2, 1]):
2477+ d = np.array(r)
2478+ tgt = np.sort(d)
2479+ assert_array_equal(np.partition(d, 0, kind=k)[0], tgt[0])
2480+ assert_array_equal(np.partition(d, 1, kind=k)[1], tgt[1])
2481+ assert_array_equal(np.partition(d, 2, kind=k)[2], tgt[2])
2482+ assert_array_equal(d[np.argpartition(d, 0, kind=k)],
2483+ np.partition(d, 0, kind=k))
2484+ assert_array_equal(d[np.argpartition(d, 1, kind=k)],
2485+ np.partition(d, 1, kind=k))
2486+ assert_array_equal(d[np.argpartition(d, 2, kind=k)],
2487+ np.partition(d, 2, kind=k))
2488+ for i in range(d.size):
2489+ d[i:].partition(0, kind=k)
2490+ assert_array_equal(d, tgt)
2491+
2492+ d = np.ones(50)
2493+ assert_array_equal(np.partition(d, 0, kind=k), d)
2494+ assert_array_equal(d[np.argpartition(d, 0, kind=k)],
2495+ np.partition(d, 0, kind=k))
2496+
2497+ # sorted
2498+ d = np.arange(49)
2499+ assert_equal(np.partition(d, 5, kind=k)[5], 5)
2500+ assert_equal(np.partition(d, 15, kind=k)[15], 15)
2501+ assert_array_equal(d[np.argpartition(d, 5, kind=k)],
2502+ np.partition(d, 5, kind=k))
2503+ assert_array_equal(d[np.argpartition(d, 15, kind=k)],
2504+ np.partition(d, 15, kind=k))
2505+
2506+ # rsorted
2507+ d = np.arange(47)[::-1]
2508+ assert_equal(np.partition(d, 6, kind=k)[6], 6)
2509+ assert_equal(np.partition(d, 16, kind=k)[16], 16)
2510+ assert_array_equal(d[np.argpartition(d, 6, kind=k)],
2511+ np.partition(d, 6, kind=k))
2512+ assert_array_equal(d[np.argpartition(d, 16, kind=k)],
2513+ np.partition(d, 16, kind=k))
2514+
2515+ assert_array_equal(np.partition(d, -6, kind=k),
2516+ np.partition(d, 41, kind=k))
2517+ assert_array_equal(np.partition(d, -16, kind=k),
2518+ np.partition(d, 31, kind=k))
2519+ assert_array_equal(d[np.argpartition(d, -6, kind=k)],
2520+ np.partition(d, 41, kind=k))
2521+
2522+ # median of 3 killer, O(n^2) on pure median 3 pivot quickselect
2523+ # exercises the median of median of 5 code used to keep O(n)
2524+ d = np.arange(1000000)
2525+ x = np.roll(d, d.size // 2)
2526+ mid = x.size // 2 + 1
2527+ assert_equal(np.partition(x, mid)[mid], mid)
2528+ d = np.arange(1000001)
2529+ x = np.roll(d, d.size // 2 + 1)
2530+ mid = x.size // 2 + 1
2531+ assert_equal(np.partition(x, mid)[mid], mid)
2532+
2533+ # max
2534+ d = np.ones(10)
2535+ d[1] = 4
2536+ assert_equal(np.partition(d, (2, -1))[-1], 4)
2537+ assert_equal(np.partition(d, (2, -1))[2], 1)
2538+ assert_equal(d[np.argpartition(d, (2, -1))][-1], 4)
2539+ assert_equal(d[np.argpartition(d, (2, -1))][2], 1)
2540+ d[1] = np.nan
2541+ assert_(np.isnan(d[np.argpartition(d, (2, -1))][-1]))
2542+ assert_(np.isnan(np.partition(d, (2, -1))[-1]))
2543+
2544+ # equal elements
2545+ d = np.arange(47) % 7
2546+ tgt = np.sort(np.arange(47) % 7)
2547+ np.random.shuffle(d)
2548+ for i in range(d.size):
2549+ assert_equal(np.partition(d, i, kind=k)[i], tgt[i])
2550+ assert_array_equal(d[np.argpartition(d, 6, kind=k)],
2551+ np.partition(d, 6, kind=k))
2552+ assert_array_equal(d[np.argpartition(d, 16, kind=k)],
2553+ np.partition(d, 16, kind=k))
2554+ for i in range(d.size):
2555+ d[i:].partition(0, kind=k)
2556+ assert_array_equal(d, tgt)
2557+
2558+ d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2559+ 7, 7, 7, 7, 7, 9])
2560+ kth = [0, 3, 19, 20]
2561+ assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
2562+ assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
2563+
2564+ d = np.array([2, 1])
2565+ d.partition(0, kind=k)
2566+ assert_raises(ValueError, d.partition, 2)
2567+ assert_raises(np.AxisError, d.partition, 3, axis=1)
2568+ assert_raises(ValueError, np.partition, d, 2)
2569+ assert_raises(np.AxisError, np.partition, d, 2, axis=1)
2570+ assert_raises(ValueError, d.argpartition, 2)
2571+ assert_raises(np.AxisError, d.argpartition, 3, axis=1)
2572+ assert_raises(ValueError, np.argpartition, d, 2)
2573+ assert_raises(np.AxisError, np.argpartition, d, 2, axis=1)
2574+ d = np.arange(10).reshape((2, 5))
2575+ d.partition(1, axis=0, kind=k)
2576+ d.partition(4, axis=1, kind=k)
2577+ np.partition(d, 1, axis=0, kind=k)
2578+ np.partition(d, 4, axis=1, kind=k)
2579+ np.partition(d, 1, axis=None, kind=k)
2580+ np.partition(d, 9, axis=None, kind=k)
2581+ d.argpartition(1, axis=0, kind=k)
2582+ d.argpartition(4, axis=1, kind=k)
2583+ np.argpartition(d, 1, axis=0, kind=k)
2584+ np.argpartition(d, 4, axis=1, kind=k)
2585+ np.argpartition(d, 1, axis=None, kind=k)
2586+ np.argpartition(d, 9, axis=None, kind=k)
2587+ assert_raises(ValueError, d.partition, 2, axis=0)
2588+ assert_raises(ValueError, d.partition, 11, axis=1)
2589+ assert_raises(TypeError, d.partition, 2, axis=None)
2590+ assert_raises(ValueError, np.partition, d, 9, axis=1)
2591+ assert_raises(ValueError, np.partition, d, 11, axis=None)
2592+ assert_raises(ValueError, d.argpartition, 2, axis=0)
2593+ assert_raises(ValueError, d.argpartition, 11, axis=1)
2594+ assert_raises(ValueError, np.argpartition, d, 9, axis=1)
2595+ assert_raises(ValueError, np.argpartition, d, 11, axis=None)
2596+
2597+ td = [(dt, s) for dt in [np.int32, np.float32, np.complex64]
2598+ for s in (9, 16)]
2599+ for dt, s in td:
2600+ aae = assert_array_equal
2601+ at = assert_
2602+
2603+ d = np.arange(s, dtype=dt)
2604+ np.random.shuffle(d)
2605+ d1 = np.tile(np.arange(s, dtype=dt), (4, 1))
2606+ map(np.random.shuffle, d1)
2607+ d0 = np.transpose(d1)
2608+ for i in range(d.size):
2609+ p = np.partition(d, i, kind=k)
2610+ assert_equal(p[i], i)
2611+ # all before are smaller
2612+ assert_array_less(p[:i], p[i])
2613+ # all after are larger
2614+ assert_array_less(p[i], p[i + 1:])
2615+ aae(p, d[np.argpartition(d, i, kind=k)])
2616+
2617+ p = np.partition(d1, i, axis=1, kind=k)
2618+ aae(p[:, i], np.array([i] * d1.shape[0], dtype=dt))
2619+ # array_less does not seem to work right
2620+ at((p[:, :i].T <= p[:, i]).all(),
2621+ msg="%d: %r <= %r" % (i, p[:, i], p[:, :i].T))
2622+ at((p[:, i + 1:].T > p[:, i]).all(),
2623+ msg="%d: %r < %r" % (i, p[:, i], p[:, i + 1:].T))
2624+ aae(p, d1[np.arange(d1.shape[0])[:, None],
2625+ np.argpartition(d1, i, axis=1, kind=k)])
2626+
2627+ p = np.partition(d0, i, axis=0, kind=k)
2628+ aae(p[i, :], np.array([i] * d1.shape[0], dtype=dt))
2629+ # array_less does not seem to work right
2630+ at((p[:i, :] <= p[i, :]).all(),
2631+ msg="%d: %r <= %r" % (i, p[i, :], p[:i, :]))
2632+ at((p[i + 1:, :] > p[i, :]).all(),
2633+ msg="%d: %r < %r" % (i, p[i, :], p[:, i + 1:]))
2634+ aae(p, d0[np.argpartition(d0, i, axis=0, kind=k),
2635+ np.arange(d0.shape[1])[None, :]])
2636+
2637+ # check inplace
2638+ dc = d.copy()
2639+ dc.partition(i, kind=k)
2640+ assert_equal(dc, np.partition(d, i, kind=k))
2641+ dc = d0.copy()
2642+ dc.partition(i, axis=0, kind=k)
2643+ assert_equal(dc, np.partition(d0, i, axis=0, kind=k))
2644+ dc = d1.copy()
2645+ dc.partition(i, axis=1, kind=k)
2646+ assert_equal(dc, np.partition(d1, i, axis=1, kind=k))
2647+
2648+ def assert_partitioned(self, d, kth):
2649+ prev = 0
2650+ for k in np.sort(kth):
2651+ assert_array_less(d[prev:k], d[k], err_msg='kth %d' % k)
2652+ assert_((d[k:] >= d[k]).all(),
2653+ msg="kth %d, %r not greater equal %d" % (k, d[k:], d[k]))
2654+ prev = k + 1
2655+
2656+ def test_partition_iterative(self):
2657+ d = np.arange(17)
2658+ kth = (0, 1, 2, 429, 231)
2659+ assert_raises(ValueError, d.partition, kth)
2660+ assert_raises(ValueError, d.argpartition, kth)
2661+ d = np.arange(10).reshape((2, 5))
2662+ assert_raises(ValueError, d.partition, kth, axis=0)
2663+ assert_raises(ValueError, d.partition, kth, axis=1)
2664+ assert_raises(ValueError, np.partition, d, kth, axis=1)
2665+ assert_raises(ValueError, np.partition, d, kth, axis=None)
2666+
2667+ d = np.array([3, 4, 2, 1])
2668+ p = np.partition(d, (0, 3))
2669+ self.assert_partitioned(p, (0, 3))
2670+ self.assert_partitioned(d[np.argpartition(d, (0, 3))], (0, 3))
2671+
2672+ assert_array_equal(p, np.partition(d, (-3, -1)))
2673+ assert_array_equal(p, d[np.argpartition(d, (-3, -1))])
2674+
2675+ d = np.arange(17)
2676+ np.random.shuffle(d)
2677+ d.partition(range(d.size))
2678+ assert_array_equal(np.arange(17), d)
2679+ np.random.shuffle(d)
2680+ assert_array_equal(np.arange(17), d[d.argpartition(range(d.size))])
2681+
2682+ # test unsorted kth
2683+ d = np.arange(17)
2684+ np.random.shuffle(d)
2685+ keys = np.array([1, 3, 8, -2])
2686+ np.random.shuffle(d)
2687+ p = np.partition(d, keys)
2688+ self.assert_partitioned(p, keys)
2689+ p = d[np.argpartition(d, keys)]
2690+ self.assert_partitioned(p, keys)
2691+ np.random.shuffle(keys)
2692+ assert_array_equal(np.partition(d, keys), p)
2693+ assert_array_equal(d[np.argpartition(d, keys)], p)
2694+
2695+ # equal kth
2696+ d = np.arange(20)[::-1]
2697+ self.assert_partitioned(np.partition(d, [5]*4), [5])
2698+ self.assert_partitioned(np.partition(d, [5]*4 + [6, 13]),
2699+ [5]*4 + [6, 13])
2700+ self.assert_partitioned(d[np.argpartition(d, [5]*4)], [5])
2701+ self.assert_partitioned(d[np.argpartition(d, [5]*4 + [6, 13])],
2702+ [5]*4 + [6, 13])
2703+
2704+ d = np.arange(12)
2705+ np.random.shuffle(d)
2706+ d1 = np.tile(np.arange(12), (4, 1))
2707+ map(np.random.shuffle, d1)
2708+ d0 = np.transpose(d1)
2709+
2710+ kth = (1, 6, 7, -1)
2711+ p = np.partition(d1, kth, axis=1)
2712+ pa = d1[np.arange(d1.shape[0])[:, None],
2713+ d1.argpartition(kth, axis=1)]
2714+ assert_array_equal(p, pa)
2715+ for i in range(d1.shape[0]):
2716+ self.assert_partitioned(p[i,:], kth)
2717+ p = np.partition(d0, kth, axis=0)
2718+ pa = d0[np.argpartition(d0, kth, axis=0),
2719+ np.arange(d0.shape[1])[None,:]]
2720+ assert_array_equal(p, pa)
2721+ for i in range(d0.shape[1]):
2722+ self.assert_partitioned(p[:, i], kth)
2723+
2724+ def test_partition_cdtype(self):
2725+ d = np.array([('Galahad', 1.7, 38), ('Arthur', 1.8, 41),
2726+ ('Lancelot', 1.9, 38)],
2727+ dtype=[('name', '|S10'), ('height', '<f8'), ('age', '<i4')])
2728+
2729+ tgt = np.sort(d, order=['age', 'height'])
2730+ assert_array_equal(np.partition(d, range(d.size),
2731+ order=['age', 'height']),
2732+ tgt)
2733+ assert_array_equal(d[np.argpartition(d, range(d.size),
2734+ order=['age', 'height'])],
2735+ tgt)
2736+ for k in range(d.size):
2737+ assert_equal(np.partition(d, k, order=['age', 'height'])[k],
2738+ tgt[k])
2739+ assert_equal(d[np.argpartition(d, k, order=['age', 'height'])][k],
2740+ tgt[k])
2741+
2742+ d = np.array(['Galahad', 'Arthur', 'zebra', 'Lancelot'])
2743+ tgt = np.sort(d)
2744+ assert_array_equal(np.partition(d, range(d.size)), tgt)
2745+ for k in range(d.size):
2746+ assert_equal(np.partition(d, k)[k], tgt[k])
2747+ assert_equal(d[np.argpartition(d, k)][k], tgt[k])
2748+
2749+ def test_partition_unicode_kind(self):
2750+ d = np.arange(10)
2751+ k = b'\xc3\xa4'.decode("UTF8")
2752+ assert_raises(ValueError, d.partition, 2, kind=k)
2753+ assert_raises(ValueError, d.argpartition, 2, kind=k)
2754+
2755+ def test_partition_fuzz(self):
2756+ # a few rounds of random data testing
2757+ for j in range(10, 30):
2758+ for i in range(1, j - 2):
2759+ d = np.arange(j)
2760+ np.random.shuffle(d)
2761+ d = d % np.random.randint(2, 30)
2762+ idx = np.random.randint(d.size)
2763+ kth = [0, idx, i, i + 1]
2764+ tgt = np.sort(d)[kth]
2765+ assert_array_equal(np.partition(d, kth)[kth], tgt,
2766+ err_msg="data: %r\n kth: %r" % (d, kth))
2767+
2768+ def test_argpartition_gh5524(self):
2769+ # A test for functionality of argpartition on lists.
2770+ d = [6,7,3,2,9,0]
2771+ p = np.argpartition(d,1)
2772+ self.assert_partitioned(np.array(d)[p],[1])
2773+
2774+ def test_flatten(self):
2775+ x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
2776+ x1 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], np.int32)
2777+ y0 = np.array([1, 2, 3, 4, 5, 6], np.int32)
2778+ y0f = np.array([1, 4, 2, 5, 3, 6], np.int32)
2779+ y1 = np.array([1, 2, 3, 4, 5, 6, 7, 8], np.int32)
2780+ y1f = np.array([1, 5, 3, 7, 2, 6, 4, 8], np.int32)
2781+ assert_equal(x0.flatten(), y0)
2782+ assert_equal(x0.flatten('F'), y0f)
2783+ assert_equal(x0.flatten('F'), x0.T.flatten())
2784+ assert_equal(x1.flatten(), y1)
2785+ assert_equal(x1.flatten('F'), y1f)
2786+ assert_equal(x1.flatten('F'), x1.T.flatten())
2787+
2788+
2789+ @pytest.mark.parametrize('func', (np.dot, np.matmul))
2790+ def test_arr_mult(self, func):
2791+ a = np.array([[1, 0], [0, 1]])
2792+ b = np.array([[0, 1], [1, 0]])
2793+ c = np.array([[9, 1], [1, -9]])
2794+ d = np.arange(24).reshape(4, 6)
2795+ ddt = np.array(
2796+ [[ 55, 145, 235, 325],
2797+ [ 145, 451, 757, 1063],
2798+ [ 235, 757, 1279, 1801],
2799+ [ 325, 1063, 1801, 2539]]
2800+ )
2801+ dtd = np.array(
2802+ [[504, 540, 576, 612, 648, 684],
2803+ [540, 580, 620, 660, 700, 740],
2804+ [576, 620, 664, 708, 752, 796],
2805+ [612, 660, 708, 756, 804, 852],
2806+ [648, 700, 752, 804, 856, 908],
2807+ [684, 740, 796, 852, 908, 964]]
2808+ )
2809+
2810+
2811+ # gemm vs syrk optimizations
2812+ for et in [np.float32, np.float64, np.complex64, np.complex128]:
2813+ eaf = a.astype(et)
2814+ assert_equal(func(eaf, eaf), eaf)
2815+ assert_equal(func(eaf.T, eaf), eaf)
2816+ assert_equal(func(eaf, eaf.T), eaf)
2817+ assert_equal(func(eaf.T, eaf.T), eaf)
2818+ assert_equal(func(eaf.T.copy(), eaf), eaf)
2819+ assert_equal(func(eaf, eaf.T.copy()), eaf)
2820+ assert_equal(func(eaf.T.copy(), eaf.T.copy()), eaf)
2821+
2822+ # syrk validations
2823+ for et in [np.float32, np.float64, np.complex64, np.complex128]:
2824+ eaf = a.astype(et)
2825+ ebf = b.astype(et)
2826+ assert_equal(func(ebf, ebf), eaf)
2827+ assert_equal(func(ebf.T, ebf), eaf)
2828+ assert_equal(func(ebf, ebf.T), eaf)
2829+ assert_equal(func(ebf.T, ebf.T), eaf)
2830+
2831+ # syrk - different shape, stride, and view validations
2832+ for et in [np.float32, np.float64, np.complex64, np.complex128]:
2833+ edf = d.astype(et)
2834+ assert_equal(
2835+ func(edf[::-1, :], edf.T),
2836+ func(edf[::-1, :].copy(), edf.T.copy())
2837+ )
2838+ assert_equal(
2839+ func(edf[:, ::-1], edf.T),
2840+ func(edf[:, ::-1].copy(), edf.T.copy())
2841+ )
2842+ assert_equal(
2843+ func(edf, edf[::-1, :].T),
2844+ func(edf, edf[::-1, :].T.copy())
2845+ )
2846+ assert_equal(
2847+ func(edf, edf[:, ::-1].T),
2848+ func(edf, edf[:, ::-1].T.copy())
2849+ )
2850+ assert_equal(
2851+ func(edf[:edf.shape[0] // 2, :], edf[::2, :].T),
2852+ func(edf[:edf.shape[0] // 2, :].copy(), edf[::2, :].T.copy())
2853+ )
2854+ assert_equal(
2855+ func(edf[::2, :], edf[:edf.shape[0] // 2, :].T),
2856+ func(edf[::2, :].copy(), edf[:edf.shape[0] // 2, :].T.copy())
2857+ )
2858+
2859+ # syrk - different shape
2860+ for et in [np.float32, np.float64, np.complex64, np.complex128]:
2861+ edf = d.astype(et)
2862+ eddtf = ddt.astype(et)
2863+ edtdf = dtd.astype(et)
2864+ assert_equal(func(edf, edf.T), eddtf)
2865+ assert_equal(func(edf.T, edf), edtdf)
2866+
2867+ @pytest.mark.parametrize('func', (np.dot, np.matmul))
2868+ @pytest.mark.parametrize('dtype', 'ifdFD')
2869+ def test_no_dgemv(self, func, dtype):
2870+ # check vector arg for contiguous before gemv
2871+ # gh-12156
2872+ a = np.arange(8.0, dtype=dtype).reshape(2, 4)
2873+ b = np.broadcast_to(1., (4, 1))
2874+ ret1 = func(a, b)
2875+ ret2 = func(a, b.copy())
2876+ assert_equal(ret1, ret2)
2877+
2878+ ret1 = func(b.T, a.T)
2879+ ret2 = func(b.T.copy(), a.T)
2880+ assert_equal(ret1, ret2)
2881+
2882+ # check for unaligned data
2883+ dt = np.dtype(dtype)
2884+ a = np.zeros(8 * dt.itemsize // 2 + 1, dtype='int16')[1:].view(dtype)
2885+ a = a.reshape(2, 4)
2886+ b = a[0]
2887+ # make sure it is not aligned
2888+ assert_(a.__array_interface__['data'][0] % dt.itemsize != 0)
2889+ ret1 = func(a, b)
2890+ ret2 = func(a.copy(), b.copy())
2891+ assert_equal(ret1, ret2)
2892+
2893+ ret1 = func(b.T, a.T)
2894+ ret2 = func(b.T.copy(), a.T.copy())
2895+ assert_equal(ret1, ret2)
2896+
2897+ def test_dot(self):
2898+ a = np.array([[1, 0], [0, 1]])
2899+ b = np.array([[0, 1], [1, 0]])
2900+ c = np.array([[9, 1], [1, -9]])
2901+ # function versus methods
2902+ assert_equal(np.dot(a, b), a.dot(b))
2903+ assert_equal(np.dot(np.dot(a, b), c), a.dot(b).dot(c))
2904+
2905+ # test passing in an output array
2906+ c = np.zeros_like(a)
2907+ a.dot(b, c)
2908+ assert_equal(c, np.dot(a, b))
2909+
2910+ # test keyword args
2911+ c = np.zeros_like(a)
2912+ a.dot(b=b, out=c)
2913+ assert_equal(c, np.dot(a, b))
2914+
2915+ def test_dot_type_mismatch(self):
2916+ c = 1.
2917+ A = np.array((1,1), dtype='i,i')
2918+
2919+ assert_raises(TypeError, np.dot, c, A)
2920+ assert_raises(TypeError, np.dot, A, c)
2921+
2922+ def test_dot_out_mem_overlap(self):
2923+ np.random.seed(1)
2924+
2925+ # Test BLAS and non-BLAS code paths, including all dtypes
2926+ # that dot() supports
2927+ dtypes = [np.dtype(code) for code in np.typecodes['All']
2928+ if code not in 'USVM']
2929+ for dtype in dtypes:
2930+ a = np.random.rand(3, 3).astype(dtype)
2931+
2932+ # Valid dot() output arrays must be aligned
2933+ b = _aligned_zeros((3, 3), dtype=dtype)
2934+ b[...] = np.random.rand(3, 3)
2935+
2936+ y = np.dot(a, b)
2937+ x = np.dot(a, b, out=b)
2938+ assert_equal(x, y, err_msg=repr(dtype))
2939+
2940+ # Check invalid output array
2941+ assert_raises(ValueError, np.dot, a, b, out=b[::2])
2942+ assert_raises(ValueError, np.dot, a, b, out=b.T)
2943+
2944+ def test_dot_matmul_out(self):
2945+ # gh-9641
2946+ class Sub(np.ndarray):
2947+ pass
2948+ a = np.ones((2, 2)).view(Sub)
2949+ b = np.ones((2, 2)).view(Sub)
2950+ out = np.ones((2, 2))
2951+
2952+ # make sure out can be any ndarray (not only subclass of inputs)
2953+ np.dot(a, b, out=out)
2954+ np.matmul(a, b, out=out)
2955+
2956+ def test_dot_matmul_inner_array_casting_fails(self):
2957+
2958+ class A:
2959+ def __array__(self, *args, **kwargs):
2960+ raise NotImplementedError
2961+
2962+ # Don't override the error from calling __array__()
2963+ assert_raises(NotImplementedError, np.dot, A(), A())
2964+ assert_raises(NotImplementedError, np.matmul, A(), A())
2965+ assert_raises(NotImplementedError, np.inner, A(), A())
2966+
2967+ def test_matmul_out(self):
2968+ # overlapping memory
2969+ a = np.arange(18).reshape(2, 3, 3)
2970+ b = np.matmul(a, a)
2971+ c = np.matmul(a, a, out=a)
2972+ assert_(c is a)
2973+ assert_equal(c, b)
2974+ a = np.arange(18).reshape(2, 3, 3)
2975+ c = np.matmul(a, a, out=a[::-1, ...])
2976+ assert_(c.base is a.base)
2977+ assert_equal(c, b)
2978+
2979+ def test_diagonal(self):
2980+ a = np.arange(12).reshape((3, 4))
2981+ assert_equal(a.diagonal(), [0, 5, 10])
2982+ assert_equal(a.diagonal(0), [0, 5, 10])
2983+ assert_equal(a.diagonal(1), [1, 6, 11])
2984+ assert_equal(a.diagonal(-1), [4, 9])
2985+ assert_raises(np.AxisError, a.diagonal, axis1=0, axis2=5)
2986+ assert_raises(np.AxisError, a.diagonal, axis1=5, axis2=0)
2987+ assert_raises(np.AxisError, a.diagonal, axis1=5, axis2=5)
2988+ assert_raises(ValueError, a.diagonal, axis1=1, axis2=1)
2989+
2990+ b = np.arange(8).reshape((2, 2, 2))
2991+ assert_equal(b.diagonal(), [[0, 6], [1, 7]])
2992+ assert_equal(b.diagonal(0), [[0, 6], [1, 7]])
2993+ assert_equal(b.diagonal(1), [[2], [3]])
2994+ assert_equal(b.diagonal(-1), [[4], [5]])
2995+ assert_raises(ValueError, b.diagonal, axis1=0, axis2=0)
2996+ assert_equal(b.diagonal(0, 1, 2), [[0, 3], [4, 7]])
2997+ assert_equal(b.diagonal(0, 0, 1), [[0, 6], [1, 7]])
2998+ assert_equal(b.diagonal(offset=1, axis1=0, axis2=2), [[1], [3]])
2999+ # Order of axis argument doesn't matter:
3000+ assert_equal(b.diagonal(0, 2, 1), [[0, 3], [4, 7]])
3001+
3002+ def test_diagonal_view_notwriteable(self):
3003+ a = np.eye(3).diagonal()
3004+ assert_(not a.flags.writeable)
3005+ assert_(not a.flags.owndata)
3006+
3007+ a = np.diagonal(np.eye(3))
3008+ assert_(not a.flags.writeable)
3009+ assert_(not a.flags.owndata)
3010+
3011+ a = np.diag(np.eye(3))
3012+ assert_(not a.flags.writeable)
3013+ assert_(not a.flags.owndata)
3014+
3015+ def test_diagonal_memleak(self):
3016+ # Regression test for a bug that crept in at one point
3017+ a = np.zeros((100, 100))
3018+ if HAS_REFCOUNT:
3019+ assert_(sys.getrefcount(a) < 50)
3020+ for i in range(100):
3021+ a.diagonal()
3022+ if HAS_REFCOUNT:
3023+ assert_(sys.getrefcount(a) < 50)
3024+
3025+ def test_size_zero_memleak(self):
3026+ # Regression test for issue 9615
3027+ # Exercises a special-case code path for dot products of length
3028+ # zero in cblasfuncs (making it is specific to floating dtypes).
3029+ a = np.array([], dtype=np.float64)
3030+ x = np.array(2.0)
3031+ for _ in range(100):
3032+ np.dot(a, a, out=x)
3033+ if HAS_REFCOUNT:
3034+ assert_(sys.getrefcount(x) < 50)
3035+
3036+ def test_trace(self):
3037+ a = np.arange(12).reshape((3, 4))
3038+ assert_equal(a.trace(), 15)
3039+ assert_equal(a.trace(0), 15)
3040+ assert_equal(a.trace(1), 18)
3041+ assert_equal(a.trace(-1), 13)
3042+
3043+ b = np.arange(8).reshape((2, 2, 2))
3044+ assert_equal(b.trace(), [6, 8])
3045+ assert_equal(b.trace(0), [6, 8])
3046+ assert_equal(b.trace(1), [2, 3])
3047+ assert_equal(b.trace(-1), [4, 5])
3048+ assert_equal(b.trace(0, 0, 1), [6, 8])
3049+ assert_equal(b.trace(0, 0, 2), [5, 9])
3050+ assert_equal(b.trace(0, 1, 2), [3, 11])
3051+ assert_equal(b.trace(offset=1, axis1=0, axis2=2), [1, 3])
3052+
3053+ def test_trace_subclass(self):
3054+ # The class would need to overwrite trace to ensure single-element
3055+ # output also has the right subclass.
3056+ class MyArray(np.ndarray):
3057+ pass
3058+
3059+ b = np.arange(8).reshape((2, 2, 2)).view(MyArray)
3060+ t = b.trace()
3061+ assert_(isinstance(t, MyArray))
3062+
3063+ def test_put(self):
3064+ icodes = np.typecodes['AllInteger']
3065+ fcodes = np.typecodes['AllFloat']
3066+ for dt in icodes + fcodes + 'O':
3067+ tgt = np.array([0, 1, 0, 3, 0, 5], dtype=dt)
3068+
3069+ # test 1-d
3070+ a = np.zeros(6, dtype=dt)
3071+ a.put([1, 3, 5], [1, 3, 5])
3072+ assert_equal(a, tgt)
3073+
3074+ # test 2-d
3075+ a = np.zeros((2, 3), dtype=dt)
3076+ a.put([1, 3, 5], [1, 3, 5])
3077+ assert_equal(a, tgt.reshape(2, 3))
3078+
3079+ for dt in '?':
3080+ tgt = np.array([False, True, False, True, False, True], dtype=dt)
3081+
3082+ # test 1-d
3083+ a = np.zeros(6, dtype=dt)
3084+ a.put([1, 3, 5], [True]*3)
3085+ assert_equal(a, tgt)
3086+
3087+ # test 2-d
3088+ a = np.zeros((2, 3), dtype=dt)
3089+ a.put([1, 3, 5], [True]*3)
3090+ assert_equal(a, tgt.reshape(2, 3))
3091+
3092+ # check must be writeable
3093+ a = np.zeros(6)
3094+ a.flags.writeable = False
3095+ assert_raises(ValueError, a.put, [1, 3, 5], [1, 3, 5])
3096+
3097+ # when calling np.put, make sure a
3098+ # TypeError is raised if the object
3099+ # isn't an ndarray
3100+ bad_array = [1, 2, 3]
3101+ assert_raises(TypeError, np.put, bad_array, [0, 2], 5)
3102+
3103+ def test_ravel(self):
3104+ a = np.array([[0, 1], [2, 3]])
3105+ assert_equal(a.ravel(), [0, 1, 2, 3])
3106+ assert_(not a.ravel().flags.owndata)
3107+ assert_equal(a.ravel('F'), [0, 2, 1, 3])
3108+ assert_equal(a.ravel(order='C'), [0, 1, 2, 3])
3109+ assert_equal(a.ravel(order='F'), [0, 2, 1, 3])
3110+ assert_equal(a.ravel(order='A'), [0, 1, 2, 3])
3111+ assert_(not a.ravel(order='A').flags.owndata)
3112+ assert_equal(a.ravel(order='K'), [0, 1, 2, 3])
3113+ assert_(not a.ravel(order='K').flags.owndata)
3114+ assert_equal(a.ravel(), a.reshape(-1))
3115+
3116+ a = np.array([[0, 1], [2, 3]], order='F')
3117+ assert_equal(a.ravel(), [0, 1, 2, 3])
3118+ assert_equal(a.ravel(order='A'), [0, 2, 1, 3])
3119+ assert_equal(a.ravel(order='K'), [0, 2, 1, 3])
3120+ assert_(not a.ravel(order='A').flags.owndata)
3121+ assert_(not a.ravel(order='K').flags.owndata)
3122+ assert_equal(a.ravel(), a.reshape(-1))
3123+ assert_equal(a.ravel(order='A'), a.reshape(-1, order='A'))
3124+
3125+ a = np.array([[0, 1], [2, 3]])[::-1, :]
3126+ assert_equal(a.ravel(), [2, 3, 0, 1])
3127+ assert_equal(a.ravel(order='C'), [2, 3, 0, 1])
3128+ assert_equal(a.ravel(order='F'), [2, 0, 3, 1])
3129+ assert_equal(a.ravel(order='A'), [2, 3, 0, 1])
3130+ # 'K' doesn't reverse the axes of negative strides
3131+ assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
3132+ assert_(a.ravel(order='K').flags.owndata)
3133+
3134+ # Test simple 1-d copy behaviour:
3135+ a = np.arange(10)[::2]
3136+ assert_(a.ravel('K').flags.owndata)
3137+ assert_(a.ravel('C').flags.owndata)
3138+ assert_(a.ravel('F').flags.owndata)
3139+
3140+ # Not contiguous and 1-sized axis with non matching stride
3141+ a = np.arange(2**3 * 2)[::2]
3142+ a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
3143+ strides = list(a.strides)
3144+ strides[1] = 123
3145+ a.strides = strides
3146+ assert_(a.ravel(order='K').flags.owndata)
3147+ assert_equal(a.ravel('K'), np.arange(0, 15, 2))
3148+
3149+ # contiguous and 1-sized axis with non matching stride works:
3150+ a = np.arange(2**3)
3151+ a = a.reshape(2, 1, 2, 2).swapaxes(-1, -2)
3152+ strides = list(a.strides)
3153+ strides[1] = 123
3154+ a.strides = strides
3155+ assert_(np.may_share_memory(a.ravel(order='K'), a))
3156+ assert_equal(a.ravel(order='K'), np.arange(2**3))
3157+
3158+ # Test negative strides (not very interesting since non-contiguous):
3159+ a = np.arange(4)[::-1].reshape(2, 2)
3160+ assert_(a.ravel(order='C').flags.owndata)
3161+ assert_(a.ravel(order='K').flags.owndata)
3162+ assert_equal(a.ravel('C'), [3, 2, 1, 0])
3163+ assert_equal(a.ravel('K'), [3, 2, 1, 0])
3164+
3165+ # 1-element tidy strides test (NPY_RELAXED_STRIDES_CHECKING):
3166+ a = np.array([[1]])
3167+ a.strides = (123, 432)
3168+ # If the stride is not 8, NPY_RELAXED_STRIDES_CHECKING is messing
3169+ # them up on purpose:
3170+ if np.ones(1).strides == (8,):
3171+ assert_(np.may_share_memory(a.ravel('K'), a))
3172+ assert_equal(a.ravel('K').strides, (a.dtype.itemsize,))
3173+
3174+ for order in ('C', 'F', 'A', 'K'):
3175+ # 0-d corner case:
3176+ a = np.array(0)
3177+ assert_equal(a.ravel(order), [0])
3178+ assert_(np.may_share_memory(a.ravel(order), a))
3179+
3180+ # Test that certain non-inplace ravels work right (mostly) for 'K':
3181+ b = np.arange(2**4 * 2)[::2].reshape(2, 2, 2, 2)
3182+ a = b[..., ::2]
3183+ assert_equal(a.ravel('K'), [0, 4, 8, 12, 16, 20, 24, 28])
3184+ assert_equal(a.ravel('C'), [0, 4, 8, 12, 16, 20, 24, 28])
3185+ assert_equal(a.ravel('A'), [0, 4, 8, 12, 16, 20, 24, 28])
3186+ assert_equal(a.ravel('F'), [0, 16, 8, 24, 4, 20, 12, 28])
3187+
3188+ a = b[::2, ...]
3189+ assert_equal(a.ravel('K'), [0, 2, 4, 6, 8, 10, 12, 14])
3190+ assert_equal(a.ravel('C'), [0, 2, 4, 6, 8, 10, 12, 14])
3191+ assert_equal(a.ravel('A'), [0, 2, 4, 6, 8, 10, 12, 14])
3192+ assert_equal(a.ravel('F'), [0, 8, 4, 12, 2, 10, 6, 14])
3193+
3194+ def test_ravel_subclass(self):
3195+ class ArraySubclass(np.ndarray):
3196+ pass
3197+
3198+ a = np.arange(10).view(ArraySubclass)
3199+ assert_(isinstance(a.ravel('C'), ArraySubclass))
3200+ assert_(isinstance(a.ravel('F'), ArraySubclass))
3201+ assert_(isinstance(a.ravel('A'), ArraySubclass))
3202+ assert_(isinstance(a.ravel('K'), ArraySubclass))
3203+
3204+ a = np.arange(10)[::2].view(ArraySubclass)
3205+ assert_(isinstance(a.ravel('C'), ArraySubclass))
3206+ assert_(isinstance(a.ravel('F'), ArraySubclass))
3207+ assert_(isinstance(a.ravel('A'), ArraySubclass))
3208+ assert_(isinstance(a.ravel('K'), ArraySubclass))
3209+
3210+ def test_swapaxes(self):
3211+ a = np.arange(1*2*3*4).reshape(1, 2, 3, 4).copy()
3212+ idx = np.indices(a.shape)
3213+ assert_(a.flags['OWNDATA'])
3214+ b = a.copy()
3215+ # check exceptions
3216+ assert_raises(np.AxisError, a.swapaxes, -5, 0)
3217+ assert_raises(np.AxisError, a.swapaxes, 4, 0)
3218+ assert_raises(np.AxisError, a.swapaxes, 0, -5)
3219+ assert_raises(np.AxisError, a.swapaxes, 0, 4)
3220+
3221+ for i in range(-4, 4):
3222+ for j in range(-4, 4):
3223+ for k, src in enumerate((a, b)):
3224+ c = src.swapaxes(i, j)
3225+ # check shape
3226+ shape = list(src.shape)
3227+ shape[i] = src.shape[j]
3228+ shape[j] = src.shape[i]
3229+ assert_equal(c.shape, shape, str((i, j, k)))
3230+ # check array contents
3231+ i0, i1, i2, i3 = [dim-1 for dim in c.shape]
3232+ j0, j1, j2, j3 = [dim-1 for dim in src.shape]
3233+ assert_equal(src[idx[j0], idx[j1], idx[j2], idx[j3]],
3234+ c[idx[i0], idx[i1], idx[i2], idx[i3]],
3235+ str((i, j, k)))
3236+ # check a view is always returned, gh-5260
3237+ assert_(not c.flags['OWNDATA'], str((i, j, k)))
3238+ # check on non-contiguous input array
3239+ if k == 1:
3240+ b = c
3241+
3242+ def test_conjugate(self):
3243+ a = np.array([1-1j, 1+1j, 23+23.0j])
3244+ ac = a.conj()
3245+ assert_equal(a.real, ac.real)
3246+ assert_equal(a.imag, -ac.imag)
3247+ assert_equal(ac, a.conjugate())
3248+ assert_equal(ac, np.conjugate(a))
3249+
3250+ a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
3251+ ac = a.conj()
3252+ assert_equal(a.real, ac.real)
3253+ assert_equal(a.imag, -ac.imag)
3254+ assert_equal(ac, a.conjugate())
3255+ assert_equal(ac, np.conjugate(a))
3256+
3257+ a = np.array([1, 2, 3])
3258+ ac = a.conj()
3259+ assert_equal(a, ac)
3260+ assert_equal(ac, a.conjugate())
3261+ assert_equal(ac, np.conjugate(a))
3262+
3263+ a = np.array([1.0, 2.0, 3.0])
3264+ ac = a.conj()
3265+ assert_equal(a, ac)
3266+ assert_equal(ac, a.conjugate())
3267+ assert_equal(ac, np.conjugate(a))
3268+
3269+ a = np.array([1-1j, 1+1j, 1, 2.0], object)
3270+ ac = a.conj()
3271+ assert_equal(ac, [k.conjugate() for k in a])
3272+ assert_equal(ac, a.conjugate())
3273+ assert_equal(ac, np.conjugate(a))
3274+
3275+ a = np.array([1-1j, 1, 2.0, 'f'], object)
3276+ assert_raises(TypeError, lambda: a.conj())
3277+ assert_raises(TypeError, lambda: a.conjugate())
3278+
3279+ def test__complex__(self):
3280+ dtypes = ['i1', 'i2', 'i4', 'i8',
3281+ 'u1', 'u2', 'u4', 'u8',
3282+ 'f', 'd', 'g', 'F', 'D', 'G',
3283+ '?', 'O']
3284+ for dt in dtypes:
3285+ a = np.array(7, dtype=dt)
3286+ b = np.array([7], dtype=dt)
3287+ c = np.array([[[[[7]]]]], dtype=dt)
3288+
3289+ msg = 'dtype: {0}'.format(dt)
3290+ ap = complex(a)
3291+ assert_equal(ap, a, msg)
3292+ bp = complex(b)
3293+ assert_equal(bp, b, msg)
3294+ cp = complex(c)
3295+ assert_equal(cp, c, msg)
3296+
3297+ def test__complex__should_not_work(self):
3298+ dtypes = ['i1', 'i2', 'i4', 'i8',
3299+ 'u1', 'u2', 'u4', 'u8',
3300+ 'f', 'd', 'g', 'F', 'D', 'G',
3301+ '?', 'O']
3302+ for dt in dtypes:
3303+ a = np.array([1, 2, 3], dtype=dt)
3304+ assert_raises(TypeError, complex, a)
3305+
3306+ dt = np.dtype([('a', 'f8'), ('b', 'i1')])
3307+ b = np.array((1.0, 3), dtype=dt)
3308+ assert_raises(TypeError, complex, b)
3309+
3310+ c = np.array([(1.0, 3), (2e-3, 7)], dtype=dt)
3311+ assert_raises(TypeError, complex, c)
3312+
3313+ d = np.array('1+1j')
3314+ assert_raises(TypeError, complex, d)
3315+
3316+ e = np.array(['1+1j'], 'U')
3317+ assert_raises(TypeError, complex, e)
3318+
3319+class TestCequenceMethods:
3320+ def test_array_contains(self):
3321+ assert_(4.0 in np.arange(16.).reshape(4,4))
3322+ assert_(20.0 not in np.arange(16.).reshape(4,4))
3323+
3324+class TestBinop:
3325+ def test_inplace(self):
3326+ # test refcount 1 inplace conversion
3327+ assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
3328+ [0.5, 1.0])
3329+
3330+ d = np.array([0.5, 0.5])[::2]
3331+ assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
3332+ [0.25, 0.5])
3333+
3334+ a = np.array([0.5])
3335+ b = np.array([0.5])
3336+ c = a + b
3337+ c = a - b
3338+ c = a * b
3339+ c = a / b
3340+ assert_equal(a, b)
3341+ assert_almost_equal(c, 1.)
3342+
3343+ c = a + b * 2. / b * a - a / b
3344+ assert_equal(a, b)
3345+ assert_equal(c, 0.5)
3346+
3347+ # true divide
3348+ a = np.array([5])
3349+ b = np.array([3])
3350+ c = (a * a) / b
3351+
3352+ assert_almost_equal(c, 25 / 3)
3353+ assert_equal(a, 5)
3354+ assert_equal(b, 3)
3355+
3356+ # ndarray.__rop__ always calls ufunc
3357+ # ndarray.__iop__ always calls ufunc
3358+ # ndarray.__op__, __rop__:
3359+ # - defer if other has __array_ufunc__ and it is None
3360+ # or other is not a subclass and has higher array priority
3361+ # - else, call ufunc
3362+ def test_ufunc_binop_interaction(self):
3363+ # Python method name (without underscores)
3364+ # -> (numpy ufunc, has_in_place_version, preferred_dtype)
3365+ ops = {
3366+ 'add': (np.add, True, float),
3367+ 'sub': (np.subtract, True, float),
3368+ 'mul': (np.multiply, True, float),
3369+ 'truediv': (np.true_divide, True, float),
3370+ 'floordiv': (np.floor_divide, True, float),
3371+ 'mod': (np.remainder, True, float),
3372+ 'divmod': (np.divmod, False, float),
3373+ 'pow': (np.power, True, int),
3374+ 'lshift': (np.left_shift, True, int),
3375+ 'rshift': (np.right_shift, True, int),
3376+ 'and': (np.bitwise_and, True, int),
3377+ 'xor': (np.bitwise_xor, True, int),
3378+ 'or': (np.bitwise_or, True, int),
3379+ 'matmul': (np.matmul, False, float),
3380+ # 'ge': (np.less_equal, False),
3381+ # 'gt': (np.less, False),
3382+ # 'le': (np.greater_equal, False),
3383+ # 'lt': (np.greater, False),
3384+ # 'eq': (np.equal, False),
3385+ # 'ne': (np.not_equal, False),
3386+ }
3387+
3388+ class Coerced(Exception):
3389+ pass
3390+
3391+ def array_impl(self):
3392+ raise Coerced
3393+
3394+ def op_impl(self, other):
3395+ return "forward"
3396+
3397+ def rop_impl(self, other):
3398+ return "reverse"
3399+
3400+ def iop_impl(self, other):
3401+ return "in-place"
3402+
3403+ def array_ufunc_impl(self, ufunc, method, *args, **kwargs):
3404+ return ("__array_ufunc__", ufunc, method, args, kwargs)
3405+
3406+ # Create an object with the given base, in the given module, with a
3407+ # bunch of placeholder __op__ methods, and optionally a
3408+ # __array_ufunc__ and __array_priority__.
3409+ def make_obj(base, array_priority=False, array_ufunc=False,
3410+ alleged_module="__main__"):
3411+ class_namespace = {"__array__": array_impl}
3412+ if array_priority is not False:
3413+ class_namespace["__array_priority__"] = array_priority
3414+ for op in ops:
3415+ class_namespace["__{0}__".format(op)] = op_impl
3416+ class_namespace["__r{0}__".format(op)] = rop_impl
3417+ class_namespace["__i{0}__".format(op)] = iop_impl
3418+ if array_ufunc is not False:
3419+ class_namespace["__array_ufunc__"] = array_ufunc
3420+ eval_namespace = {"base": base,
3421+ "class_namespace": class_namespace,
3422+ "__name__": alleged_module,
3423+ }
3424+ MyType = eval("type('MyType', (base,), class_namespace)",
3425+ eval_namespace)
3426+ if issubclass(MyType, np.ndarray):
3427+ # Use this range to avoid special case weirdnesses around
3428+ # divide-by-0, pow(x, 2), overflow due to pow(big, big), etc.
3429+ return np.arange(3, 7).reshape(2, 2).view(MyType)
3430+ else:
3431+ return MyType()
3432+
3433+ def check(obj, binop_override_expected, ufunc_override_expected,
3434+ inplace_override_expected, check_scalar=True):
3435+ for op, (ufunc, has_inplace, dtype) in ops.items():
3436+ err_msg = ('op: %s, ufunc: %s, has_inplace: %s, dtype: %s'
3437+ % (op, ufunc, has_inplace, dtype))
3438+ check_objs = [np.arange(3, 7, dtype=dtype).reshape(2, 2)]
3439+ if check_scalar:
3440+ check_objs.append(check_objs[0][0])
3441+ for arr in check_objs:
3442+ arr_method = getattr(arr, "__{0}__".format(op))
3443+
3444+ def first_out_arg(result):
3445+ if op == "divmod":
3446+ assert_(isinstance(result, tuple))
3447+ return result[0]
3448+ else:
3449+ return result
3450+
3451+ # arr __op__ obj
3452+ if binop_override_expected:
3453+ assert_equal(arr_method(obj), NotImplemented, err_msg)
3454+ elif ufunc_override_expected:
3455+ assert_equal(arr_method(obj)[0], "__array_ufunc__",
3456+ err_msg)
3457+ else:
3458+ if (isinstance(obj, np.ndarray) and
3459+ (type(obj).__array_ufunc__ is
3460+ np.ndarray.__array_ufunc__)):
3461+ # __array__ gets ignored
3462+ res = first_out_arg(arr_method(obj))
3463+ assert_(res.__class__ is obj.__class__, err_msg)
3464+ else:
3465+ assert_raises((TypeError, Coerced),
3466+ arr_method, obj, err_msg=err_msg)
3467+ # obj __op__ arr
3468+ arr_rmethod = getattr(arr, "__r{0}__".format(op))
3469+ if ufunc_override_expected:
3470+ res = arr_rmethod(obj)
3471+ assert_equal(res[0], "__array_ufunc__",
3472+ err_msg=err_msg)
3473+ assert_equal(res[1], ufunc, err_msg=err_msg)
3474+ else:
3475+ if (isinstance(obj, np.ndarray) and
3476+ (type(obj).__array_ufunc__ is
3477+ np.ndarray.__array_ufunc__)):
3478+ # __array__ gets ignored
3479+ res = first_out_arg(arr_rmethod(obj))
3480+ assert_(res.__class__ is obj.__class__, err_msg)
3481+ else:
3482+ # __array_ufunc__ = "asdf" creates a TypeError
3483+ assert_raises((TypeError, Coerced),
3484+ arr_rmethod, obj, err_msg=err_msg)
3485+
3486+ # arr __iop__ obj
3487+ # array scalars don't have in-place operators
3488+ if has_inplace and isinstance(arr, np.ndarray):
3489+ arr_imethod = getattr(arr, "__i{0}__".format(op))
3490+ if inplace_override_expected:
3491+ assert_equal(arr_method(obj), NotImplemented,
3492+ err_msg=err_msg)
3493+ elif ufunc_override_expected:
3494+ res = arr_imethod(obj)
3495+ assert_equal(res[0], "__array_ufunc__", err_msg)
3496+ assert_equal(res[1], ufunc, err_msg)
3497+ assert_(type(res[-1]["out"]) is tuple, err_msg)
3498+ assert_(res[-1]["out"][0] is arr, err_msg)
3499+ else:
3500+ if (isinstance(obj, np.ndarray) and
3501+ (type(obj).__array_ufunc__ is
3502+ np.ndarray.__array_ufunc__)):
3503+ # __array__ gets ignored
3504+ assert_(arr_imethod(obj) is arr, err_msg)
3505+ else:
3506+ assert_raises((TypeError, Coerced),
3507+ arr_imethod, obj,
3508+ err_msg=err_msg)
3509+
3510+ op_fn = getattr(operator, op, None)
3511+ if op_fn is None:
3512+ op_fn = getattr(operator, op + "_", None)
3513+ if op_fn is None:
3514+ op_fn = getattr(builtins, op)
3515+ assert_equal(op_fn(obj, arr), "forward", err_msg)
3516+ if not isinstance(obj, np.ndarray):
3517+ if binop_override_expected:
3518+ assert_equal(op_fn(arr, obj), "reverse", err_msg)
3519+ elif ufunc_override_expected:
3520+ assert_equal(op_fn(arr, obj)[0], "__array_ufunc__",
3521+ err_msg)
3522+ if ufunc_override_expected:
3523+ assert_equal(ufunc(obj, arr)[0], "__array_ufunc__",
3524+ err_msg)
3525+
3526+ # No array priority, no array_ufunc -> nothing called
3527+ check(make_obj(object), False, False, False)
3528+ # Negative array priority, no array_ufunc -> nothing called
3529+ # (has to be very negative, because scalar priority is -1000000.0)
3530+ check(make_obj(object, array_priority=-2**30), False, False, False)
3531+ # Positive array priority, no array_ufunc -> binops and iops only
3532+ check(make_obj(object, array_priority=1), True, False, True)
3533+ # ndarray ignores array_priority for ndarray subclasses
3534+ check(make_obj(np.ndarray, array_priority=1), False, False, False,
3535+ check_scalar=False)
3536+ # Positive array_priority and array_ufunc -> array_ufunc only
3537+ check(make_obj(object, array_priority=1,
3538+ array_ufunc=array_ufunc_impl), False, True, False)
3539+ check(make_obj(np.ndarray, array_priority=1,
3540+ array_ufunc=array_ufunc_impl), False, True, False)
3541+ # array_ufunc set to None -> defer binops only
3542+ check(make_obj(object, array_ufunc=None), True, False, False)
3543+ check(make_obj(np.ndarray, array_ufunc=None), True, False, False,
3544+ check_scalar=False)
3545+
3546+ def test_ufunc_override_normalize_signature(self):
3547+ # gh-5674
3548+ class SomeClass:
3549+ def __array_ufunc__(self, ufunc, method, *inputs, **kw):
3550+ return kw
3551+
3552+ a = SomeClass()
3553+ kw = np.add(a, [1])
3554+ assert_('sig' not in kw and 'signature' not in kw)
3555+ kw = np.add(a, [1], sig='ii->i')
3556+ assert_('sig' not in kw and 'signature' in kw)
3557+ assert_equal(kw['signature'], 'ii->i')
3558+ kw = np.add(a, [1], signature='ii->i')
3559+ assert_('sig' not in kw and 'signature' in kw)
3560+ assert_equal(kw['signature'], 'ii->i')
3561+
3562+ def test_array_ufunc_index(self):
3563+ # Check that index is set appropriately, also if only an output
3564+ # is passed on (latter is another regression tests for github bug 4753)
3565+ # This also checks implicitly that 'out' is always a tuple.
3566+ class CheckIndex:
3567+ def __array_ufunc__(self, ufunc, method, *inputs, **kw):
3568+ for i, a in enumerate(inputs):
3569+ if a is self:
3570+ return i
3571+ # calls below mean we must be in an output.
3572+ for j, a in enumerate(kw['out']):
3573+ if a is self:
3574+ return (j,)
3575+
3576+ a = CheckIndex()
3577+ dummy = np.arange(2.)
3578+ # 1 input, 1 output
3579+ assert_equal(np.sin(a), 0)
3580+ assert_equal(np.sin(dummy, a), (0,))
3581+ assert_equal(np.sin(dummy, out=a), (0,))
3582+ assert_equal(np.sin(dummy, out=(a,)), (0,))
3583+ assert_equal(np.sin(a, a), 0)
3584+ assert_equal(np.sin(a, out=a), 0)
3585+ assert_equal(np.sin(a, out=(a,)), 0)
3586+ # 1 input, 2 outputs
3587+ assert_equal(np.modf(dummy, a), (0,))
3588+ assert_equal(np.modf(dummy, None, a), (1,))
3589+ assert_equal(np.modf(dummy, dummy, a), (1,))
3590+ assert_equal(np.modf(dummy, out=(a, None)), (0,))
3591+ assert_equal(np.modf(dummy, out=(a, dummy)), (0,))
3592+ assert_equal(np.modf(dummy, out=(None, a)), (1,))
3593+ assert_equal(np.modf(dummy, out=(dummy, a)), (1,))
3594+ assert_equal(np.modf(a, out=(dummy, a)), 0)
3595+ with assert_raises(TypeError):
3596+ # Out argument must be tuple, since there are multiple outputs
3597+ np.modf(dummy, out=a)
3598+
3599+ assert_raises(ValueError, np.modf, dummy, out=(a,))
3600+
3601+ # 2 inputs, 1 output
3602+ assert_equal(np.add(a, dummy), 0)
3603+ assert_equal(np.add(dummy, a), 1)
3604+ assert_equal(np.add(dummy, dummy, a), (0,))
3605+ assert_equal(np.add(dummy, a, a), 1)
3606+ assert_equal(np.add(dummy, dummy, out=a), (0,))
3607+ assert_equal(np.add(dummy, dummy, out=(a,)), (0,))
3608+ assert_equal(np.add(a, dummy, out=a), 0)
3609+
3610+ def test_out_override(self):
3611+ # regression test for github bug 4753
3612+ class OutClass(np.ndarray):
3613+ def __array_ufunc__(self, ufunc, method, *inputs, **kw):
3614+ if 'out' in kw:
3615+ tmp_kw = kw.copy()
3616+ tmp_kw.pop('out')
3617+ func = getattr(ufunc, method)
3618+ kw['out'][0][...] = func(*inputs, **tmp_kw)
3619+
3620+ A = np.array([0]).view(OutClass)
3621+ B = np.array([5])
3622+ C = np.array([6])
3623+ np.multiply(C, B, A)
3624+ assert_equal(A[0], 30)
3625+ assert_(isinstance(A, OutClass))
3626+ A[0] = 0
3627+ np.multiply(C, B, out=A)
3628+ assert_equal(A[0], 30)
3629+ assert_(isinstance(A, OutClass))
3630+
3631+ def test_pow_override_with_errors(self):
3632+ # regression test for gh-9112
3633+ class PowerOnly(np.ndarray):
3634+ def __array_ufunc__(self, ufunc, method, *inputs, **kw):
3635+ if ufunc is not np.power:
3636+ raise NotImplementedError
3637+ return "POWER!"
3638+ # explicit cast to float, to ensure the fast power path is taken.
3639+ a = np.array(5., dtype=np.float64).view(PowerOnly)
3640+ assert_equal(a ** 2.5, "POWER!")
3641+ with assert_raises(NotImplementedError):
3642+ a ** 0.5
3643+ with assert_raises(NotImplementedError):
3644+ a ** 0
3645+ with assert_raises(NotImplementedError):
3646+ a ** 1
3647+ with assert_raises(NotImplementedError):
3648+ a ** -1
3649+ with assert_raises(NotImplementedError):
3650+ a ** 2
3651+
3652+ def test_pow_array_object_dtype(self):
3653+ # test pow on arrays of object dtype
3654+ class SomeClass:
3655+ def __init__(self, num=None):
3656+ self.num = num
3657+
3658+ # want to ensure a fast pow path is not taken
3659+ def __mul__(self, other):
3660+ raise AssertionError('__mul__ should not be called')
3661+
3662+ def __div__(self, other):
3663+ raise AssertionError('__div__ should not be called')
3664+
3665+ def __pow__(self, exp):
3666+ return SomeClass(num=self.num ** exp)
3667+
3668+ def __eq__(self, other):
3669+ if isinstance(other, SomeClass):
3670+ return self.num == other.num
3671+
3672+ __rpow__ = __pow__
3673+
3674+ def pow_for(exp, arr):
3675+ return np.array([x ** exp for x in arr])
3676+
3677+ obj_arr = np.array([SomeClass(1), SomeClass(2), SomeClass(3)])
3678+
3679+ assert_equal(obj_arr ** 0.5, pow_for(0.5, obj_arr))
3680+ assert_equal(obj_arr ** 0, pow_for(0, obj_arr))
3681+ assert_equal(obj_arr ** 1, pow_for(1, obj_arr))
3682+ assert_equal(obj_arr ** -1, pow_for(-1, obj_arr))
3683+ assert_equal(obj_arr ** 2, pow_for(2, obj_arr))
3684+
3685+ def test_pos_array_ufunc_override(self):
3686+ class A(np.ndarray):
3687+ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
3688+ return getattr(ufunc, method)(*[i.view(np.ndarray) for
3689+ i in inputs], **kwargs)
3690+ tst = np.array('foo').view(A)
3691+ with assert_raises(TypeError):
3692+ +tst
3693+
3694+
3695+class TestTemporaryElide:
3696+ # elision is only triggered on relatively large arrays
3697+
3698+ def test_extension_incref_elide(self):
3699+ # test extension (e.g. cython) calling PyNumber_* slots without
3700+ # increasing the reference counts
3701+ #
3702+ # def incref_elide(a):
3703+ # d = input.copy() # refcount 1
3704+ # return d, d + d # PyNumber_Add without increasing refcount
3705+ from numpy.core._multiarray_tests import incref_elide
3706+ d = np.ones(100000)
3707+ orig, res = incref_elide(d)
3708+ d + d
3709+ # the return original should not be changed to an inplace operation
3710+ assert_array_equal(orig, d)
3711+ assert_array_equal(res, d + d)
3712+
3713+ def test_extension_incref_elide_stack(self):
3714+ # scanning if the refcount == 1 object is on the python stack to check
3715+ # that we are called directly from python is flawed as object may still
3716+ # be above the stack pointer and we have no access to the top of it
3717+ #
3718+ # def incref_elide_l(d):
3719+ # return l[4] + l[4] # PyNumber_Add without increasing refcount
3720+ from numpy.core._multiarray_tests import incref_elide_l
3721+ # padding with 1 makes sure the object on the stack is not overwritten
3722+ l = [1, 1, 1, 1, np.ones(100000)]
3723+ res = incref_elide_l(l)
3724+ # the return original should not be changed to an inplace operation
3725+ assert_array_equal(l[4], np.ones(100000))
3726+ assert_array_equal(res, l[4] + l[4])
3727+
3728+ def test_temporary_with_cast(self):
3729+ # check that we don't elide into a temporary which would need casting
3730+ d = np.ones(200000, dtype=np.int64)
3731+ assert_equal(((d + d) + 2**222).dtype, np.dtype('O'))
3732+
3733+ r = ((d + d) / 2)
3734+ assert_equal(r.dtype, np.dtype('f8'))
3735+
3736+ r = np.true_divide((d + d), 2)
3737+ assert_equal(r.dtype, np.dtype('f8'))
3738+
3739+ r = ((d + d) / 2.)
3740+ assert_equal(r.dtype, np.dtype('f8'))
3741+
3742+ r = ((d + d) // 2)
3743+ assert_equal(r.dtype, np.dtype(np.int64))
3744+
3745+ # commutative elision into the astype result
3746+ f = np.ones(100000, dtype=np.float32)
3747+ assert_equal(((f + f) + f.astype(np.float64)).dtype, np.dtype('f8'))
3748+
3749+ # no elision into lower type
3750+ d = f.astype(np.float64)
3751+ assert_equal(((f + f) + d).dtype, d.dtype)
3752+ l = np.ones(100000, dtype=np.longdouble)
3753+ assert_equal(((d + d) + l).dtype, l.dtype)
3754+
3755+ # test unary abs with different output dtype
3756+ for dt in (np.complex64, np.complex128, np.clongdouble):
3757+ c = np.ones(100000, dtype=dt)
3758+ r = abs(c * 2.0)
3759+ assert_equal(r.dtype, np.dtype('f%d' % (c.itemsize // 2)))
3760+
3761+ def test_elide_broadcast(self):
3762+ # test no elision on broadcast to higher dimension
3763+ # only triggers elision code path in debug mode as triggering it in
3764+ # normal mode needs 256kb large matching dimension, so a lot of memory
3765+ d = np.ones((2000, 1), dtype=int)
3766+ b = np.ones((2000), dtype=bool)
3767+ r = (1 - d) + b
3768+ assert_equal(r, 1)
3769+ assert_equal(r.shape, (2000, 2000))
3770+
3771+ def test_elide_scalar(self):
3772+ # check inplace op does not create ndarray from scalars
3773+ a = np.bool_()
3774+ assert_(type(~(a & a)) is np.bool_)
3775+
3776+ def test_elide_scalar_readonly(self):
3777+ # The imaginary part of a real array is readonly. This needs to go
3778+ # through fast_scalar_power which is only called for powers of
3779+ # +1, -1, 0, 0.5, and 2, so use 2. Also need valid refcount for
3780+ # elision which can be gotten for the imaginary part of a real
3781+ # array. Should not error.
3782+ a = np.empty(100000, dtype=np.float64)
3783+ a.imag ** 2
3784+
3785+ def test_elide_readonly(self):
3786+ # don't try to elide readonly temporaries
3787+ r = np.asarray(np.broadcast_to(np.zeros(1), 100000).flat) * 0.0
3788+ assert_equal(r, 0)
3789+
3790+ def test_elide_updateifcopy(self):
3791+ a = np.ones(2**20)[::2]
3792+ b = a.flat.__array__() + 1
3793+ del b
3794+ assert_equal(a, 1)
3795+
3796+
3797+class TestCAPI:
3798+ def test_IsPythonScalar(self):
3799+ from numpy.core._multiarray_tests import IsPythonScalar
3800+ assert_(IsPythonScalar(b'foobar'))
3801+ assert_(IsPythonScalar(1))
3802+ assert_(IsPythonScalar(2**80))
3803+ assert_(IsPythonScalar(2.))
3804+ assert_(IsPythonScalar("a"))
3805+
3806+
3807+class TestSubscripting:
3808+ def test_test_zero_rank(self):
3809+ x = np.array([1, 2, 3])
3810+ assert_(isinstance(x[0], np.int_))
3811+ assert_(type(x[0, ...]) is np.ndarray)
3812+
3813+
3814+class TestPickling:
3815+ @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL >= 5,
3816+ reason=('this tests the error messages when trying to'
3817+ 'protocol 5 although it is not available'))
3818+ def test_correct_protocol5_error_message(self):
3819+ array = np.arange(10)
3820+
3821+ if sys.version_info[:2] in ((3, 6), (3, 7)):
3822+ # For the specific case of python3.6 and 3.7, raise a clear import
3823+ # error about the pickle5 backport when trying to use protocol=5
3824+ # without the pickle5 package
3825+ with pytest.raises(ImportError):
3826+ array.__reduce_ex__(5)
3827+
3828+ elif sys.version_info[:2] < (3, 6):
3829+ # when calling __reduce_ex__ explicitly with protocol=5 on python
3830+ # raise a ValueError saying that protocol 5 is not available for
3831+ # this python version
3832+ with pytest.raises(ValueError):
3833+ array.__reduce_ex__(5)
3834+
3835+ def test_record_array_with_object_dtype(self):
3836+ my_object = object()
3837+
3838+ arr_with_object = np.array(
3839+ [(my_object, 1, 2.0)],
3840+ dtype=[('a', object), ('b', int), ('c', float)])
3841+ arr_without_object = np.array(
3842+ [('xxx', 1, 2.0)],
3843+ dtype=[('a', str), ('b', int), ('c', float)])
3844+
3845+ for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
3846+ depickled_arr_with_object = pickle.loads(
3847+ pickle.dumps(arr_with_object, protocol=proto))
3848+ depickled_arr_without_object = pickle.loads(
3849+ pickle.dumps(arr_without_object, protocol=proto))
3850+
3851+ assert_equal(arr_with_object.dtype,
3852+ depickled_arr_with_object.dtype)
3853+ assert_equal(arr_without_object.dtype,
3854+ depickled_arr_without_object.dtype)
3855+
3856+ @pytest.mark.skipif(pickle.HIGHEST_PROTOCOL < 5,
3857+ reason="requires pickle protocol 5")
3858+ def test_f_contiguous_array(self):
3859+ f_contiguous_array = np.array([[1, 2, 3], [4, 5, 6]], order='F')
3860+ buffers = []
3861+
3862+ # When using pickle protocol 5, Fortran-contiguous arrays can be
3863+ # serialized using out-of-band buffers
3864+ bytes_string = pickle.dumps(f_contiguous_array, protocol=5,
3865+ buffer_callback=buffers.append)
3866+
3867+ assert len(buffers) > 0
3868+
3869+ depickled_f_contiguous_array = pickle.loads(bytes_string,
3870+ buffers=buffers)
3871+
3872+ assert_equal(f_contiguous_array, depickled_f_contiguous_array)
3873+
3874+ def test_non_contiguous_array(self):
3875+ non_contiguous_array = np.arange(12).reshape(3, 4)[:, :2]
3876+ assert not non_contiguous_array.flags.c_contiguous
3877+ assert not non_contiguous_array.flags.f_contiguous
3878+
3879+ # make sure non-contiguous arrays can be pickled-depickled
3880+ # using any protocol
3881+ for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
3882+ depickled_non_contiguous_array = pickle.loads(
3883+ pickle.dumps(non_contiguous_array, protocol=proto))
3884+
3885+ assert_equal(non_contiguous_array, depickled_non_contiguous_array)
3886+
3887+ def test_roundtrip(self):
3888+ for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
3889+ carray = np.array([[2, 9], [7, 0], [3, 8]])
3890+ DATA = [
3891+ carray,
3892+ np.transpose(carray),
3893+ np.array([('xxx', 1, 2.0)], dtype=[('a', (str, 3)), ('b', int),
3894+ ('c', float)])
3895+ ]
3896+
3897+ refs = [weakref.ref(a) for a in DATA]
3898+ for a in DATA:
3899+ assert_equal(
3900+ a, pickle.loads(pickle.dumps(a, protocol=proto)),
3901+ err_msg="%r" % a)
3902+ del a, DATA, carray
3903+ break_cycles()
3904+ # check for reference leaks (gh-12793)
3905+ for ref in refs:
3906+ assert ref() is None
3907+
3908+ def _loads(self, obj):
3909+ return pickle.loads(obj, encoding='latin1')
3910+
3911+ # version 0 pickles, using protocol=2 to pickle
3912+ # version 0 doesn't have a version field
3913+ def test_version0_int8(self):
3914+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
3915+ a = np.array([1, 2, 3, 4], dtype=np.int8)
3916+ p = self._loads(s)
3917+ assert_equal(a, p)
3918+
3919+ def test_version0_float32(self):
3920+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
3921+ a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
3922+ p = self._loads(s)
3923+ assert_equal(a, p)
3924+
3925+ def test_version0_object(self):
3926+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
3927+ a = np.array([{'a': 1}, {'b': 2}])
3928+ p = self._loads(s)
3929+ assert_equal(a, p)
3930+
3931+ # version 1 pickles, using protocol=2 to pickle
3932+ def test_version1_int8(self):
3933+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02i1K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x04\x01\x02\x03\x04tb.'
3934+ a = np.array([1, 2, 3, 4], dtype=np.int8)
3935+ p = self._loads(s)
3936+ assert_equal(a, p)
3937+
3938+ def test_version1_float32(self):
3939+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x04\x85cnumpy\ndtype\nq\x04U\x02f4K\x00K\x01\x87Rq\x05(K\x01U\x01<NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89U\x10\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@tb.'
3940+ a = np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float32)
3941+ p = self._loads(s)
3942+ assert_equal(a, p)
3943+
3944+ def test_version1_object(self):
3945+ s = b'\x80\x02cnumpy.core._internal\n_reconstruct\nq\x01cnumpy\nndarray\nq\x02K\x00\x85U\x01b\x87Rq\x03(K\x01K\x02\x85cnumpy\ndtype\nq\x04U\x02O8K\x00K\x01\x87Rq\x05(K\x01U\x01|NNJ\xff\xff\xff\xffJ\xff\xff\xff\xfftb\x89]q\x06(}q\x07U\x01aK\x01s}q\x08U\x01bK\x02setb.'
3946+ a = np.array([{'a': 1}, {'b': 2}])
3947+ p = self._loads(s)
3948+ assert_equal(a, p)
3949+
3950+ def test_subarray_int_shape(self):
3951+ s = b"cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'V6'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'a'\np12\ng3\ntp13\n(dp14\ng12\n(g7\n(S'V4'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'|'\np18\n(g7\n(S'i1'\np19\nI0\nI1\ntp20\nRp21\n(I3\nS'|'\np22\nNNNI-1\nI-1\nI0\ntp23\nb(I2\nI2\ntp24\ntp25\nNNI4\nI1\nI0\ntp26\nbI0\ntp27\nsg3\n(g7\n(S'V2'\np28\nI0\nI1\ntp29\nRp30\n(I3\nS'|'\np31\n(g21\nI2\ntp32\nNNI2\nI1\nI0\ntp33\nbI4\ntp34\nsI6\nI1\nI0\ntp35\nbI00\nS'\\x01\\x01\\x01\\x01\\x01\\x02'\np36\ntp37\nb."
3952+ a = np.array([(1, (1, 2))], dtype=[('a', 'i1', (2, 2)), ('b', 'i1', 2)])
3953+ p = self._loads(s)
3954+ assert_equal(a, p)
3955+
3956+ def test_datetime64_byteorder(self):
3957+ original = np.array([['2015-02-24T00:00:00.000000000']], dtype='datetime64[ns]')
3958+
3959+ original_byte_reversed = original.copy(order='K')
3960+ original_byte_reversed.dtype = original_byte_reversed.dtype.newbyteorder('S')
3961+ original_byte_reversed.byteswap(inplace=True)
3962+
3963+ new = pickle.loads(pickle.dumps(original_byte_reversed))
3964+
3965+ assert_equal(original.dtype, new.dtype)
3966+
3967+
3968+class TestFancyIndexing:
3969+ def test_list(self):
3970+ x = np.ones((1, 1))
3971+ x[:, [0]] = 2.0
3972+ assert_array_equal(x, np.array([[2.0]]))
3973+
3974+ x = np.ones((1, 1, 1))
3975+ x[:, :, [0]] = 2.0
3976+ assert_array_equal(x, np.array([[[2.0]]]))
3977+
3978+ def test_tuple(self):
3979+ x = np.ones((1, 1))
3980+ x[:, (0,)] = 2.0
3981+ assert_array_equal(x, np.array([[2.0]]))
3982+ x = np.ones((1, 1, 1))
3983+ x[:, :, (0,)] = 2.0
3984+ assert_array_equal(x, np.array([[[2.0]]]))
3985+
3986+ def test_mask(self):
3987+ x = np.array([1, 2, 3, 4])
3988+ m = np.array([0, 1, 0, 0], bool)
3989+ assert_array_equal(x[m], np.array([2]))
3990+
3991+ def test_mask2(self):
3992+ x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
3993+ m = np.array([0, 1], bool)
3994+ m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
3995+ m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
3996+ assert_array_equal(x[m], np.array([[5, 6, 7, 8]]))
3997+ assert_array_equal(x[m2], np.array([2, 5]))
3998+ assert_array_equal(x[m3], np.array([2]))
3999+
4000+ def test_assign_mask(self):
4001+ x = np.array([1, 2, 3, 4])
4002+ m = np.array([0, 1, 0, 0], bool)
4003+ x[m] = 5
4004+ assert_array_equal(x, np.array([1, 5, 3, 4]))
4005+
4006+ def test_assign_mask2(self):
4007+ xorig = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
4008+ m = np.array([0, 1], bool)
4009+ m2 = np.array([[0, 1, 0, 0], [1, 0, 0, 0]], bool)
4010+ m3 = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], bool)
4011+ x = xorig.copy()
4012+ x[m] = 10
4013+ assert_array_equal(x, np.array([[1, 2, 3, 4], [10, 10, 10, 10]]))
4014+ x = xorig.copy()
4015+ x[m2] = 10
4016+ assert_array_equal(x, np.array([[1, 10, 3, 4], [10, 6, 7, 8]]))
4017+ x = xorig.copy()
4018+ x[m3] = 10
4019+ assert_array_equal(x, np.array([[1, 10, 3, 4], [5, 6, 7, 8]]))
4020+
4021+
4022+class TestStringCompare:
4023+ def test_string(self):
4024+ g1 = np.array(["This", "is", "example"])
4025+ g2 = np.array(["This", "was", "example"])
4026+ assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
4027+ assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
4028+ assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
4029+ assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
4030+ assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
4031+ assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
4032+
4033+ def test_mixed(self):
4034+ g1 = np.array(["spam", "spa", "spammer", "and eggs"])
4035+ g2 = "spam"
4036+ assert_array_equal(g1 == g2, [x == g2 for x in g1])
4037+ assert_array_equal(g1 != g2, [x != g2 for x in g1])
4038+ assert_array_equal(g1 < g2, [x < g2 for x in g1])
4039+ assert_array_equal(g1 > g2, [x > g2 for x in g1])
4040+ assert_array_equal(g1 <= g2, [x <= g2 for x in g1])
4041+ assert_array_equal(g1 >= g2, [x >= g2 for x in g1])
4042+
4043+ def test_unicode(self):
4044+ g1 = np.array([u"This", u"is", u"example"])
4045+ g2 = np.array([u"This", u"was", u"example"])
4046+ assert_array_equal(g1 == g2, [g1[i] == g2[i] for i in [0, 1, 2]])
4047+ assert_array_equal(g1 != g2, [g1[i] != g2[i] for i in [0, 1, 2]])
4048+ assert_array_equal(g1 <= g2, [g1[i] <= g2[i] for i in [0, 1, 2]])
4049+ assert_array_equal(g1 >= g2, [g1[i] >= g2[i] for i in [0, 1, 2]])
4050+ assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
4051+ assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
4052+
4053+
4054+class TestArgmax:
4055+
4056+ nan_arr = [
4057+ ([0, 1, 2, 3, np.nan], 4),
4058+ ([0, 1, 2, np.nan, 3], 3),
4059+ ([np.nan, 0, 1, 2, 3], 0),
4060+ ([np.nan, 0, np.nan, 2, 3], 0),
4061+ ([0, 1, 2, 3, complex(0, np.nan)], 4),
4062+ ([0, 1, 2, 3, complex(np.nan, 0)], 4),
4063+ ([0, 1, 2, complex(np.nan, 0), 3], 3),
4064+ ([0, 1, 2, complex(0, np.nan), 3], 3),
4065+ ([complex(0, np.nan), 0, 1, 2, 3], 0),
4066+ ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
4067+ ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
4068+ ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
4069+ ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
4070+
4071+ ([complex(0, 0), complex(0, 2), complex(0, 1)], 1),
4072+ ([complex(1, 0), complex(0, 2), complex(0, 1)], 0),
4073+ ([complex(1, 0), complex(0, 2), complex(1, 1)], 2),
4074+
4075+ ([np.datetime64('1923-04-14T12:43:12'),
4076+ np.datetime64('1994-06-21T14:43:15'),
4077+ np.datetime64('2001-10-15T04:10:32'),
4078+ np.datetime64('1995-11-25T16:02:16'),
4079+ np.datetime64('2005-01-04T03:14:12'),
4080+ np.datetime64('2041-12-03T14:05:03')], 5),
4081+ ([np.datetime64('1935-09-14T04:40:11'),
4082+ np.datetime64('1949-10-12T12:32:11'),
4083+ np.datetime64('2010-01-03T05:14:12'),
4084+ np.datetime64('2015-11-20T12:20:59'),
4085+ np.datetime64('1932-09-23T10:10:13'),
4086+ np.datetime64('2014-10-10T03:50:30')], 3),
4087+ # Assorted tests with NaTs
4088+ ([np.datetime64('NaT'),
4089+ np.datetime64('NaT'),
4090+ np.datetime64('2010-01-03T05:14:12'),
4091+ np.datetime64('NaT'),
4092+ np.datetime64('2015-09-23T10:10:13'),
4093+ np.datetime64('1932-10-10T03:50:30')], 0),
4094+ ([np.datetime64('2059-03-14T12:43:12'),
4095+ np.datetime64('1996-09-21T14:43:15'),
4096+ np.datetime64('NaT'),
4097+ np.datetime64('2022-12-25T16:02:16'),
4098+ np.datetime64('1963-10-04T03:14:12'),
4099+ np.datetime64('2013-05-08T18:15:23')], 2),
4100+ ([np.timedelta64(2, 's'),
4101+ np.timedelta64(1, 's'),
4102+ np.timedelta64('NaT', 's'),
4103+ np.timedelta64(3, 's')], 2),
4104+ ([np.timedelta64('NaT', 's')] * 3, 0),
4105+
4106+ ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
4107+ timedelta(days=-1, seconds=23)], 0),
4108+ ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
4109+ timedelta(days=5, seconds=14)], 1),
4110+ ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
4111+ timedelta(days=10, seconds=43)], 2),
4112+
4113+ ([False, False, False, False, True], 4),
4114+ ([False, False, False, True, False], 3),
4115+ ([True, False, False, False, False], 0),
4116+ ([True, False, True, False, False], 0),
4117+ ]
4118+
4119+ def test_all(self):
4120+ a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
4121+ for i in range(a.ndim):
4122+ amax = a.max(i)
4123+ aargmax = a.argmax(i)
4124+ axes = list(range(a.ndim))
4125+ axes.remove(i)
4126+ assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
4127+
4128+ def test_combinations(self):
4129+ for arr, pos in self.nan_arr:
4130+ with suppress_warnings() as sup:
4131+ sup.filter(RuntimeWarning,
4132+ "invalid value encountered in reduce")
4133+ max_val = np.max(arr)
4134+
4135+ assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
4136+ assert_equal(arr[np.argmax(arr)], max_val, err_msg="%r" % arr)
4137+
4138+ def test_output_shape(self):
4139+ # see also gh-616
4140+ a = np.ones((10, 5))
4141+ # Check some simple shape mismatches
4142+ out = np.ones(11, dtype=np.int_)
4143+ assert_raises(ValueError, a.argmax, -1, out)
4144+
4145+ out = np.ones((2, 5), dtype=np.int_)
4146+ assert_raises(ValueError, a.argmax, -1, out)
4147+
4148+ # these could be relaxed possibly (used to allow even the previous)
4149+ out = np.ones((1, 10), dtype=np.int_)
4150+ assert_raises(ValueError, a.argmax, -1, out)
4151+
4152+ out = np.ones(10, dtype=np.int_)
4153+ a.argmax(-1, out=out)
4154+ assert_equal(out, a.argmax(-1))
4155+
4156+ def test_argmax_unicode(self):
4157+ d = np.zeros(6031, dtype='<U9')
4158+ d[5942] = "as"
4159+ assert_equal(d.argmax(), 5942)
4160+
4161+ def test_np_vs_ndarray(self):
4162+ # make sure both ndarray.argmax and numpy.argmax support out/axis args
4163+ a = np.random.normal(size=(2,3))
4164+
4165+ # check positional args
4166+ out1 = np.zeros(2, dtype=int)
4167+ out2 = np.zeros(2, dtype=int)
4168+ assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
4169+ assert_equal(out1, out2)
4170+
4171+ # check keyword args
4172+ out1 = np.zeros(3, dtype=int)
4173+ out2 = np.zeros(3, dtype=int)
4174+ assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
4175+ assert_equal(out1, out2)
4176+
4177+ @pytest.mark.leaks_references(reason="replaces None with NULL.")
4178+ def test_object_argmax_with_NULLs(self):
4179+ # See gh-6032
4180+ a = np.empty(4, dtype='O')
4181+ ctypes.memset(a.ctypes.data, 0, a.nbytes)
4182+ assert_equal(a.argmax(), 0)
4183+ a[3] = 10
4184+ assert_equal(a.argmax(), 3)
4185+ a[1] = 30
4186+ assert_equal(a.argmax(), 1)
4187+
4188+
4189+class TestArgmin:
4190+
4191+ nan_arr = [
4192+ ([0, 1, 2, 3, np.nan], 4),
4193+ ([0, 1, 2, np.nan, 3], 3),
4194+ ([np.nan, 0, 1, 2, 3], 0),
4195+ ([np.nan, 0, np.nan, 2, 3], 0),
4196+ ([0, 1, 2, 3, complex(0, np.nan)], 4),
4197+ ([0, 1, 2, 3, complex(np.nan, 0)], 4),
4198+ ([0, 1, 2, complex(np.nan, 0), 3], 3),
4199+ ([0, 1, 2, complex(0, np.nan), 3], 3),
4200+ ([complex(0, np.nan), 0, 1, 2, 3], 0),
4201+ ([complex(np.nan, np.nan), 0, 1, 2, 3], 0),
4202+ ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, 1)], 0),
4203+ ([complex(np.nan, np.nan), complex(np.nan, 2), complex(np.nan, 1)], 0),
4204+ ([complex(np.nan, 0), complex(np.nan, 2), complex(np.nan, np.nan)], 0),
4205+
4206+ ([complex(0, 0), complex(0, 2), complex(0, 1)], 0),
4207+ ([complex(1, 0), complex(0, 2), complex(0, 1)], 2),
4208+ ([complex(1, 0), complex(0, 2), complex(1, 1)], 1),
4209+
4210+ ([np.datetime64('1923-04-14T12:43:12'),
4211+ np.datetime64('1994-06-21T14:43:15'),
4212+ np.datetime64('2001-10-15T04:10:32'),
4213+ np.datetime64('1995-11-25T16:02:16'),
4214+ np.datetime64('2005-01-04T03:14:12'),
4215+ np.datetime64('2041-12-03T14:05:03')], 0),
4216+ ([np.datetime64('1935-09-14T04:40:11'),
4217+ np.datetime64('1949-10-12T12:32:11'),
4218+ np.datetime64('2010-01-03T05:14:12'),
4219+ np.datetime64('2014-11-20T12:20:59'),
4220+ np.datetime64('2015-09-23T10:10:13'),
4221+ np.datetime64('1932-10-10T03:50:30')], 5),
4222+ # Assorted tests with NaTs
4223+ ([np.datetime64('NaT'),
4224+ np.datetime64('NaT'),
4225+ np.datetime64('2010-01-03T05:14:12'),
4226+ np.datetime64('NaT'),
4227+ np.datetime64('2015-09-23T10:10:13'),
4228+ np.datetime64('1932-10-10T03:50:30')], 0),
4229+ ([np.datetime64('2059-03-14T12:43:12'),
4230+ np.datetime64('1996-09-21T14:43:15'),
4231+ np.datetime64('NaT'),
4232+ np.datetime64('2022-12-25T16:02:16'),
4233+ np.datetime64('1963-10-04T03:14:12'),
4234+ np.datetime64('2013-05-08T18:15:23')], 2),
4235+ ([np.timedelta64(2, 's'),
4236+ np.timedelta64(1, 's'),
4237+ np.timedelta64('NaT', 's'),
4238+ np.timedelta64(3, 's')], 2),
4239+ ([np.timedelta64('NaT', 's')] * 3, 0),
4240+
4241+ ([timedelta(days=5, seconds=14), timedelta(days=2, seconds=35),
4242+ timedelta(days=-1, seconds=23)], 2),
4243+ ([timedelta(days=1, seconds=43), timedelta(days=10, seconds=5),
4244+ timedelta(days=5, seconds=14)], 0),
4245+ ([timedelta(days=10, seconds=24), timedelta(days=10, seconds=5),
4246+ timedelta(days=10, seconds=43)], 1),
4247+
4248+ ([True, True, True, True, False], 4),
4249+ ([True, True, True, False, True], 3),
4250+ ([False, True, True, True, True], 0),
4251+ ([False, True, False, True, True], 0),
4252+ ]
4253+
4254+ def test_all(self):
4255+ a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
4256+ for i in range(a.ndim):
4257+ amin = a.min(i)
4258+ aargmin = a.argmin(i)
4259+ axes = list(range(a.ndim))
4260+ axes.remove(i)
4261+ assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
4262+
4263+ def test_combinations(self):
4264+ for arr, pos in self.nan_arr:
4265+ with suppress_warnings() as sup:
4266+ sup.filter(RuntimeWarning,
4267+ "invalid value encountered in reduce")
4268+ min_val = np.min(arr)
4269+
4270+ assert_equal(np.argmin(arr), pos, err_msg="%r" % arr)
4271+ assert_equal(arr[np.argmin(arr)], min_val, err_msg="%r" % arr)
4272+
4273+ def test_minimum_signed_integers(self):
4274+
4275+ a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
4276+ assert_equal(np.argmin(a), 1)
4277+
4278+ a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
4279+ assert_equal(np.argmin(a), 1)
4280+
4281+ a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
4282+ assert_equal(np.argmin(a), 1)
4283+
4284+ a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
4285+ assert_equal(np.argmin(a), 1)
4286+
4287+ def test_output_shape(self):
4288+ # see also gh-616
4289+ a = np.ones((10, 5))
4290+ # Check some simple shape mismatches
4291+ out = np.ones(11, dtype=np.int_)
4292+ assert_raises(ValueError, a.argmin, -1, out)
4293+
4294+ out = np.ones((2, 5), dtype=np.int_)
4295+ assert_raises(ValueError, a.argmin, -1, out)
4296+
4297+ # these could be relaxed possibly (used to allow even the previous)
4298+ out = np.ones((1, 10), dtype=np.int_)
4299+ assert_raises(ValueError, a.argmin, -1, out)
4300+
4301+ out = np.ones(10, dtype=np.int_)
4302+ a.argmin(-1, out=out)
4303+ assert_equal(out, a.argmin(-1))
4304+
4305+ def test_argmin_unicode(self):
4306+ d = np.ones(6031, dtype='<U9')
4307+ d[6001] = "0"
4308+ assert_equal(d.argmin(), 6001)
4309+
4310+ def test_np_vs_ndarray(self):
4311+ # make sure both ndarray.argmin and numpy.argmin support out/axis args
4312+ a = np.random.normal(size=(2, 3))
4313+
4314+ # check positional args
4315+ out1 = np.zeros(2, dtype=int)
4316+ out2 = np.ones(2, dtype=int)
4317+ assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
4318+ assert_equal(out1, out2)
4319+
4320+ # check keyword args
4321+ out1 = np.zeros(3, dtype=int)
4322+ out2 = np.ones(3, dtype=int)
4323+ assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
4324+ assert_equal(out1, out2)
4325+
4326+ @pytest.mark.leaks_references(reason="replaces None with NULL.")
4327+ def test_object_argmin_with_NULLs(self):
4328+ # See gh-6032
4329+ a = np.empty(4, dtype='O')
4330+ ctypes.memset(a.ctypes.data, 0, a.nbytes)
4331+ assert_equal(a.argmin(), 0)
4332+ a[3] = 30
4333+ assert_equal(a.argmin(), 3)
4334+ a[1] = 10
4335+ assert_equal(a.argmin(), 1)
4336+
4337+
4338+class TestMinMax:
4339+
4340+ def test_scalar(self):
4341+ assert_raises(np.AxisError, np.amax, 1, 1)
4342+ assert_raises(np.AxisError, np.amin, 1, 1)
4343+
4344+ assert_equal(np.amax(1, axis=0), 1)
4345+ assert_equal(np.amin(1, axis=0), 1)
4346+ assert_equal(np.amax(1, axis=None), 1)
4347+ assert_equal(np.amin(1, axis=None), 1)
4348+
4349+ def test_axis(self):
4350+ assert_raises(np.AxisError, np.amax, [1, 2, 3], 1000)
4351+ assert_equal(np.amax([[1, 2, 3]], axis=1), 3)
4352+
4353+ def test_datetime(self):
4354+ # Do not ignore NaT
4355+ for dtype in ('m8[s]', 'm8[Y]'):
4356+ a = np.arange(10).astype(dtype)
4357+ assert_equal(np.amin(a), a[0])
4358+ assert_equal(np.amax(a), a[9])
4359+ a[3] = 'NaT'
4360+ assert_equal(np.amin(a), a[3])
4361+ assert_equal(np.amax(a), a[3])
4362+
4363+
4364+class TestNewaxis:
4365+ def test_basic(self):
4366+ sk = np.array([0, -0.1, 0.1])
4367+ res = 250*sk[:, np.newaxis]
4368+ assert_almost_equal(res.ravel(), 250*sk)
4369+
4370+
4371+class TestClip:
4372+ def _check_range(self, x, cmin, cmax):
4373+ assert_(np.all(x >= cmin))
4374+ assert_(np.all(x <= cmax))
4375+
4376+ def _clip_type(self, type_group, array_max,
4377+ clip_min, clip_max, inplace=False,
4378+ expected_min=None, expected_max=None):
4379+ if expected_min is None:
4380+ expected_min = clip_min
4381+ if expected_max is None:
4382+ expected_max = clip_max
4383+
4384+ for T in np.sctypes[type_group]:
4385+ if sys.byteorder == 'little':
4386+ byte_orders = ['=', '>']
4387+ else:
4388+ byte_orders = ['<', '=']
4389+
4390+ for byteorder in byte_orders:
4391+ dtype = np.dtype(T).newbyteorder(byteorder)
4392+
4393+ x = (np.random.random(1000) * array_max).astype(dtype)
4394+ if inplace:
4395+ # The tests that call us pass clip_min and clip_max that
4396+ # might not fit in the destination dtype. They were written
4397+ # assuming the previous unsafe casting, which now must be
4398+ # passed explicitly to avoid a warning.
4399+ x.clip(clip_min, clip_max, x, casting='unsafe')
4400+ else:
4401+ x = x.clip(clip_min, clip_max)
4402+ byteorder = '='
4403+
4404+ if x.dtype.byteorder == '|':
4405+ byteorder = '|'
4406+ assert_equal(x.dtype.byteorder, byteorder)
4407+ self._check_range(x, expected_min, expected_max)
4408+ return x
4409+
4410+ def test_basic(self):
4411+ for inplace in [False, True]:
4412+ self._clip_type(
4413+ 'float', 1024, -12.8, 100.2, inplace=inplace)
4414+ self._clip_type(
4415+ 'float', 1024, 0, 0, inplace=inplace)
4416+
4417+ self._clip_type(
4418+ 'int', 1024, -120, 100, inplace=inplace)
4419+ self._clip_type(
4420+ 'int', 1024, 0, 0, inplace=inplace)
4421+
4422+ self._clip_type(
4423+ 'uint', 1024, 0, 0, inplace=inplace)
4424+ self._clip_type(
4425+ 'uint', 1024, -120, 100, inplace=inplace, expected_min=0)
4426+
4427+ def test_record_array(self):
4428+ rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
4429+ dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')])
4430+ y = rec['x'].clip(-0.3, 0.5)
4431+ self._check_range(y, -0.3, 0.5)
4432+
4433+ def test_max_or_min(self):
4434+ val = np.array([0, 1, 2, 3, 4, 5, 6, 7])
4435+ x = val.clip(3)
4436+ assert_(np.all(x >= 3))
4437+ x = val.clip(min=3)
4438+ assert_(np.all(x >= 3))
4439+ x = val.clip(max=4)
4440+ assert_(np.all(x <= 4))
4441+
4442+ def test_nan(self):
4443+ input_arr = np.array([-2., np.nan, 0.5, 3., 0.25, np.nan])
4444+ result = input_arr.clip(-1, 1)
4445+ expected = np.array([-1., np.nan, 0.5, 1., 0.25, np.nan])
4446+ assert_array_equal(result, expected)
4447+
4448+
4449+class TestCompress:
4450+ def test_axis(self):
4451+ tgt = [[5, 6, 7, 8, 9]]
4452+ arr = np.arange(10).reshape(2, 5)
4453+ out = np.compress([0, 1], arr, axis=0)
4454+ assert_equal(out, tgt)
4455+
4456+ tgt = [[1, 3], [6, 8]]
4457+ out = np.compress([0, 1, 0, 1, 0], arr, axis=1)
4458+ assert_equal(out, tgt)
4459+
4460+ def test_truncate(self):
4461+ tgt = [[1], [6]]
4462+ arr = np.arange(10).reshape(2, 5)
4463+ out = np.compress([0, 1], arr, axis=1)
4464+ assert_equal(out, tgt)
4465+
4466+ def test_flatten(self):
4467+ arr = np.arange(10).reshape(2, 5)
4468+ out = np.compress([0, 1], arr)
4469+ assert_equal(out, 1)
4470+
4471+
4472+class TestPutmask:
4473+ def tst_basic(self, x, T, mask, val):
4474+ np.putmask(x, mask, val)
4475+ assert_equal(x[mask], np.array(val, T))
4476+
4477+ def test_ip_types(self):
4478+ unchecked_types = [bytes, str, np.void]
4479+
4480+ x = np.random.random(1000)*100
4481+ mask = x < 40
4482+
4483+ for val in [-100, 0, 15]:
4484+ for types in np.sctypes.values():
4485+ for T in types:
4486+ if T not in unchecked_types:
4487+ self.tst_basic(x.copy().astype(T), T, mask, val)
4488+
4489+ # Also test string of a length which uses an untypical length
4490+ dt = np.dtype("S3")
4491+ self.tst_basic(x.astype(dt), dt.type, mask, dt.type(val)[:3])
4492+
4493+ def test_mask_size(self):
4494+ assert_raises(ValueError, np.putmask, np.array([1, 2, 3]), [True], 5)
4495+
4496+ @pytest.mark.parametrize('dtype', ('>i4', '<i4'))
4497+ def test_byteorder(self, dtype):
4498+ x = np.array([1, 2, 3], dtype)
4499+ np.putmask(x, [True, False, True], -1)
4500+ assert_array_equal(x, [-1, 2, -1])
4501+
4502+ def test_record_array(self):
4503+ # Note mixed byteorder.
4504+ rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
4505+ dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
4506+ np.putmask(rec['x'], [True, False], 10)
4507+ assert_array_equal(rec['x'], [10, 5])
4508+ assert_array_equal(rec['y'], [2, 4])
4509+ assert_array_equal(rec['z'], [3, 3])
4510+ np.putmask(rec['y'], [True, False], 11)
4511+ assert_array_equal(rec['x'], [10, 5])
4512+ assert_array_equal(rec['y'], [11, 4])
4513+ assert_array_equal(rec['z'], [3, 3])
4514+
4515+ def test_overlaps(self):
4516+ # gh-6272 check overlap
4517+ x = np.array([True, False, True, False])
4518+ np.putmask(x[1:4], [True, True, True], x[:3])
4519+ assert_equal(x, np.array([True, True, False, True]))
4520+
4521+ x = np.array([True, False, True, False])
4522+ np.putmask(x[1:4], x[:3], [True, False, True])
4523+ assert_equal(x, np.array([True, True, True, True]))
4524+
4525+
4526+class TestTake:
4527+ def tst_basic(self, x):
4528+ ind = list(range(x.shape[0]))
4529+ assert_array_equal(x.take(ind, axis=0), x)
4530+
4531+ def test_ip_types(self):
4532+ unchecked_types = [bytes, str, np.void]
4533+
4534+ x = np.random.random(24)*100
4535+ x.shape = 2, 3, 4
4536+ for types in np.sctypes.values():
4537+ for T in types:
4538+ if T not in unchecked_types:
4539+ self.tst_basic(x.copy().astype(T))
4540+
4541+ # Also test string of a length which uses an untypical length
4542+ self.tst_basic(x.astype("S3"))
4543+
4544+ def test_raise(self):
4545+ x = np.random.random(24)*100
4546+ x.shape = 2, 3, 4
4547+ assert_raises(IndexError, x.take, [0, 1, 2], axis=0)
4548+ assert_raises(IndexError, x.take, [-3], axis=0)
4549+ assert_array_equal(x.take([-1], axis=0)[0], x[1])
4550+
4551+ def test_clip(self):
4552+ x = np.random.random(24)*100
4553+ x.shape = 2, 3, 4
4554+ assert_array_equal(x.take([-1], axis=0, mode='clip')[0], x[0])
4555+ assert_array_equal(x.take([2], axis=0, mode='clip')[0], x[1])
4556+
4557+ def test_wrap(self):
4558+ x = np.random.random(24)*100
4559+ x.shape = 2, 3, 4
4560+ assert_array_equal(x.take([-1], axis=0, mode='wrap')[0], x[1])
4561+ assert_array_equal(x.take([2], axis=0, mode='wrap')[0], x[0])
4562+ assert_array_equal(x.take([3], axis=0, mode='wrap')[0], x[1])
4563+
4564+ @pytest.mark.parametrize('dtype', ('>i4', '<i4'))
4565+ def test_byteorder(self, dtype):
4566+ x = np.array([1, 2, 3], dtype)
4567+ assert_array_equal(x.take([0, 2, 1]), [1, 3, 2])
4568+
4569+ def test_record_array(self):
4570+ # Note mixed byteorder.
4571+ rec = np.array([(-5, 2.0, 3.0), (5.0, 4.0, 3.0)],
4572+ dtype=[('x', '<f8'), ('y', '>f8'), ('z', '<f8')])
4573+ rec1 = rec.take([1])
4574+ assert_(rec1['x'] == 5.0 and rec1['y'] == 4.0)
4575+
4576+ def test_out_overlap(self):
4577+ # gh-6272 check overlap on out
4578+ x = np.arange(5)
4579+ y = np.take(x, [1, 2, 3], out=x[2:5], mode='wrap')
4580+ assert_equal(y, np.array([1, 2, 3]))
4581+
4582+class TestLexsort:
4583+ @pytest.mark.parametrize('dtype',[
4584+ np.uint8, np.uint16, np.uint32, np.uint64,
4585+ np.int8, np.int16, np.int32, np.int64,
4586+ np.float16, np.float32, np.float64
4587+ ])
4588+ def test_basic(self, dtype):
4589+ a = np.array([1, 2, 1, 3, 1, 5], dtype=dtype)
4590+ b = np.array([0, 4, 5, 6, 2, 3], dtype=dtype)
4591+ idx = np.lexsort((b, a))
4592+ expected_idx = np.array([0, 4, 2, 1, 3, 5])
4593+ assert_array_equal(idx, expected_idx)
4594+ assert_array_equal(a[idx], np.sort(a))
4595+
4596+ def test_mixed(self):
4597+ a = np.array([1, 2, 1, 3, 1, 5])
4598+ b = np.array([0, 4, 5, 6, 2, 3], dtype='datetime64[D]')
4599+
4600+ idx = np.lexsort((b, a))
4601+ expected_idx = np.array([0, 4, 2, 1, 3, 5])
4602+ assert_array_equal(idx, expected_idx)
4603+
4604+ def test_datetime(self):
4605+ a = np.array([0,0,0], dtype='datetime64[D]')
4606+ b = np.array([2,1,0], dtype='datetime64[D]')
4607+ idx = np.lexsort((b, a))
4608+ expected_idx = np.array([2, 1, 0])
4609+ assert_array_equal(idx, expected_idx)
4610+
4611+ a = np.array([0,0,0], dtype='timedelta64[D]')
4612+ b = np.array([2,1,0], dtype='timedelta64[D]')
4613+ idx = np.lexsort((b, a))
4614+ expected_idx = np.array([2, 1, 0])
4615+ assert_array_equal(idx, expected_idx)
4616+
4617+ def test_object(self): # gh-6312
4618+ a = np.random.choice(10, 1000)
4619+ b = np.random.choice(['abc', 'xy', 'wz', 'efghi', 'qwst', 'x'], 1000)
4620+
4621+ for u in a, b:
4622+ left = np.lexsort((u.astype('O'),))
4623+ right = np.argsort(u, kind='mergesort')
4624+ assert_array_equal(left, right)
4625+
4626+ for u, v in (a, b), (b, a):
4627+ idx = np.lexsort((u, v))
4628+ assert_array_equal(idx, np.lexsort((u.astype('O'), v)))
4629+ assert_array_equal(idx, np.lexsort((u, v.astype('O'))))
4630+ u, v = np.array(u, dtype='object'), np.array(v, dtype='object')
4631+ assert_array_equal(idx, np.lexsort((u, v)))
4632+
4633+ def test_invalid_axis(self): # gh-7528
4634+ x = np.linspace(0., 1., 42*3).reshape(42, 3)
4635+ assert_raises(np.AxisError, np.lexsort, x, axis=2)
4636+
4637+class TestIO:
4638+ """Test tofile, fromfile, tobytes, and fromstring"""
4639+
4640+ def setup(self):
4641+ shape = (2, 4, 3)
4642+ rand = np.random.random
4643+ self.x = rand(shape) + rand(shape).astype(complex)*1j
4644+ self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
4645+ self.dtype = self.x.dtype
4646+ self.tempdir = tempfile.mkdtemp()
4647+ self.filename = tempfile.mktemp(dir=self.tempdir)
4648+
4649+ def teardown(self):
4650+ shutil.rmtree(self.tempdir)
4651+
4652+ def test_nofile(self):
4653+ # this should probably be supported as a file
4654+ # but for now test for proper errors
4655+ b = io.BytesIO()
4656+ assert_raises(IOError, np.fromfile, b, np.uint8, 80)
4657+ d = np.ones(7)
4658+ assert_raises(IOError, lambda x: x.tofile(b), d)
4659+
4660+ def test_bool_fromstring(self):
4661+ v = np.array([True, False, True, False], dtype=np.bool_)
4662+ y = np.fromstring('1 0 -2.3 0.0', sep=' ', dtype=np.bool_)
4663+ assert_array_equal(v, y)
4664+
4665+ def test_uint64_fromstring(self):
4666+ d = np.fromstring("9923372036854775807 104783749223640",
4667+ dtype=np.uint64, sep=' ')
4668+ e = np.array([9923372036854775807, 104783749223640], dtype=np.uint64)
4669+ assert_array_equal(d, e)
4670+
4671+ def test_int64_fromstring(self):
4672+ d = np.fromstring("-25041670086757 104783749223640",
4673+ dtype=np.int64, sep=' ')
4674+ e = np.array([-25041670086757, 104783749223640], dtype=np.int64)
4675+ assert_array_equal(d, e)
4676+
4677+ def test_empty_files_binary(self):
4678+ with open(self.filename, 'w') as f:
4679+ pass
4680+ y = np.fromfile(self.filename)
4681+ assert_(y.size == 0, "Array not empty")
4682+
4683+ def test_empty_files_text(self):
4684+ with open(self.filename, 'wb') as f:
4685+ pass
4686+ y = np.fromfile(self.filename, sep=" ")
4687+ assert_(y.size == 0, "Array not empty")
4688+
4689+ def test_roundtrip_file(self):
4690+ with open(self.filename, 'wb') as f:
4691+ self.x.tofile(f)
4692+ # NB. doesn't work with flush+seek, due to use of C stdio
4693+ with open(self.filename, 'rb') as f:
4694+ y = np.fromfile(f, dtype=self.dtype)
4695+ assert_array_equal(y, self.x.flat)
4696+
4697+ def test_roundtrip_filename(self):
4698+ self.x.tofile(self.filename)
4699+ y = np.fromfile(self.filename, dtype=self.dtype)
4700+ assert_array_equal(y, self.x.flat)
4701+
4702+ def test_roundtrip_pathlib(self):
4703+ p = pathlib.Path(self.filename)
4704+ self.x.tofile(p)
4705+ y = np.fromfile(p, dtype=self.dtype)
4706+ assert_array_equal(y, self.x.flat)
4707+
4708+ def test_roundtrip_dump_pathlib(self):
4709+ p = pathlib.Path(self.filename)
4710+ self.x.dump(p)
4711+ y = np.load(p, allow_pickle=True)
4712+ assert_array_equal(y, self.x)
4713+
4714+ def test_roundtrip_binary_str(self):
4715+ s = self.x.tobytes()
4716+ y = np.frombuffer(s, dtype=self.dtype)
4717+ assert_array_equal(y, self.x.flat)
4718+
4719+ s = self.x.tobytes('F')
4720+ y = np.frombuffer(s, dtype=self.dtype)
4721+ assert_array_equal(y, self.x.flatten('F'))
4722+
4723+ def test_roundtrip_str(self):
4724+ x = self.x.real.ravel()
4725+ s = "@".join(map(str, x))
4726+ y = np.fromstring(s, sep="@")
4727+ # NB. str imbues less precision
4728+ nan_mask = ~np.isfinite(x)
4729+ assert_array_equal(x[nan_mask], y[nan_mask])
4730+ assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
4731+
4732+ def test_roundtrip_repr(self):
4733+ x = self.x.real.ravel()
4734+ s = "@".join(map(repr, x))
4735+ y = np.fromstring(s, sep="@")
4736+ assert_array_equal(x, y)
4737+
4738+ def test_unseekable_fromfile(self):
4739+ # gh-6246
4740+ self.x.tofile(self.filename)
4741+
4742+ def fail(*args, **kwargs):
4743+ raise IOError('Can not tell or seek')
4744+
4745+ with io.open(self.filename, 'rb', buffering=0) as f:
4746+ f.seek = fail
4747+ f.tell = fail
4748+ assert_raises(IOError, np.fromfile, f, dtype=self.dtype)
4749+
4750+ def test_io_open_unbuffered_fromfile(self):
4751+ # gh-6632
4752+ self.x.tofile(self.filename)
4753+ with io.open(self.filename, 'rb', buffering=0) as f:
4754+ y = np.fromfile(f, dtype=self.dtype)
4755+ assert_array_equal(y, self.x.flat)
4756+
4757+ def test_largish_file(self):
4758+ # check the fallocate path on files > 16MB
4759+ d = np.zeros(4 * 1024 ** 2)
4760+ d.tofile(self.filename)
4761+ assert_equal(os.path.getsize(self.filename), d.nbytes)
4762+ assert_array_equal(d, np.fromfile(self.filename))
4763+ # check offset
4764+ with open(self.filename, "r+b") as f:
4765+ f.seek(d.nbytes)
4766+ d.tofile(f)
4767+ assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
4768+ # check append mode (gh-8329)
4769+ open(self.filename, "w").close() # delete file contents
4770+ with open(self.filename, "ab") as f:
4771+ d.tofile(f)
4772+ assert_array_equal(d, np.fromfile(self.filename))
4773+ with open(self.filename, "ab") as f:
4774+ d.tofile(f)
4775+ assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
4776+
4777+ def test_io_open_buffered_fromfile(self):
4778+ # gh-6632
4779+ self.x.tofile(self.filename)
4780+ with io.open(self.filename, 'rb', buffering=-1) as f:
4781+ y = np.fromfile(f, dtype=self.dtype)
4782+ assert_array_equal(y, self.x.flat)
4783+
4784+ def test_file_position_after_fromfile(self):
4785+ # gh-4118
4786+ sizes = [io.DEFAULT_BUFFER_SIZE//8,
4787+ io.DEFAULT_BUFFER_SIZE,
4788+ io.DEFAULT_BUFFER_SIZE*8]
4789+
4790+ for size in sizes:
4791+ with open(self.filename, 'wb') as f:
4792+ f.seek(size-1)
4793+ f.write(b'\0')
4794+
4795+ for mode in ['rb', 'r+b']:
4796+ err_msg = "%d %s" % (size, mode)
4797+
4798+ with open(self.filename, mode) as f:
4799+ f.read(2)
4800+ np.fromfile(f, dtype=np.float64, count=1)
4801+ pos = f.tell()
4802+ assert_equal(pos, 10, err_msg=err_msg)
4803+
4804+ def test_file_position_after_tofile(self):
4805+ # gh-4118
4806+ sizes = [io.DEFAULT_BUFFER_SIZE//8,
4807+ io.DEFAULT_BUFFER_SIZE,
4808+ io.DEFAULT_BUFFER_SIZE*8]
4809+
4810+ for size in sizes:
4811+ err_msg = "%d" % (size,)
4812+
4813+ with open(self.filename, 'wb') as f:
4814+ f.seek(size-1)
4815+ f.write(b'\0')
4816+ f.seek(10)
4817+ f.write(b'12')
4818+ np.array([0], dtype=np.float64).tofile(f)
4819+ pos = f.tell()
4820+ assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
4821+
4822+ with open(self.filename, 'r+b') as f:
4823+ f.read(2)
4824+ f.seek(0, 1) # seek between read&write required by ANSI C
4825+ np.array([0], dtype=np.float64).tofile(f)
4826+ pos = f.tell()
4827+ assert_equal(pos, 10, err_msg=err_msg)
4828+
4829+ def test_load_object_array_fromfile(self):
4830+ # gh-12300
4831+ with open(self.filename, 'w') as f:
4832+ # Ensure we have a file with consistent contents
4833+ pass
4834+
4835+ with open(self.filename, 'rb') as f:
4836+ assert_raises_regex(ValueError, "Cannot read into object array",
4837+ np.fromfile, f, dtype=object)
4838+
4839+ assert_raises_regex(ValueError, "Cannot read into object array",
4840+ np.fromfile, self.filename, dtype=object)
4841+
4842+ def test_fromfile_offset(self):
4843+ with open(self.filename, 'wb') as f:
4844+ self.x.tofile(f)
4845+
4846+ with open(self.filename, 'rb') as f:
4847+ y = np.fromfile(f, dtype=self.dtype, offset=0)
4848+ assert_array_equal(y, self.x.flat)
4849+
4850+ with open(self.filename, 'rb') as f:
4851+ count_items = len(self.x.flat) // 8
4852+ offset_items = len(self.x.flat) // 4
4853+ offset_bytes = self.dtype.itemsize * offset_items
4854+ y = np.fromfile(f, dtype=self.dtype, count=count_items, offset=offset_bytes)
4855+ assert_array_equal(y, self.x.flat[offset_items:offset_items+count_items])
4856+
4857+ # subsequent seeks should stack
4858+ offset_bytes = self.dtype.itemsize
4859+ z = np.fromfile(f, dtype=self.dtype, offset=offset_bytes)
4860+ assert_array_equal(z, self.x.flat[offset_items+count_items+1:])
4861+
4862+ with open(self.filename, 'wb') as f:
4863+ self.x.tofile(f, sep=",")
4864+
4865+ with open(self.filename, 'rb') as f:
4866+ assert_raises_regex(
4867+ TypeError,
4868+ "'offset' argument only permitted for binary files",
4869+ np.fromfile, self.filename, dtype=self.dtype,
4870+ sep=",", offset=1)
4871+
4872+ def _check_from(self, s, value, **kw):
4873+ if 'sep' not in kw:
4874+ y = np.frombuffer(s, **kw)
4875+ else:
4876+ y = np.fromstring(s, **kw)
4877+ assert_array_equal(y, value)
4878+
4879+ with open(self.filename, 'wb') as f:
4880+ f.write(s)
4881+ y = np.fromfile(self.filename, **kw)
4882+ assert_array_equal(y, value)
4883+
4884+ def test_nan(self):
4885+ self._check_from(
4886+ b"nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
4887+ [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
4888+ sep=' ')
4889+
4890+ def test_inf(self):
4891+ self._check_from(
4892+ b"inf +inf -inf infinity -Infinity iNfInItY -inF",
4893+ [np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
4894+ sep=' ')
4895+
4896+ def test_numbers(self):
4897+ self._check_from(b"1.234 -1.234 .3 .3e55 -123133.1231e+133",
4898+ [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
4899+
4900+ def test_binary(self):
4901+ self._check_from(b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
4902+ np.array([1, 2, 3, 4]),
4903+ dtype='<f4')
4904+
4905+ @pytest.mark.slow # takes > 1 minute on mechanical hard drive
4906+ def test_big_binary(self):
4907+ """Test workarounds for 32-bit limited fwrite, fseek, and ftell
4908+ calls in windows. These normally would hang doing something like this.
4909+ See http://projects.scipy.org/numpy/ticket/1660"""
4910+ if sys.platform != 'win32':
4911+ return
4912+ try:
4913+ # before workarounds, only up to 2**32-1 worked
4914+ fourgbplus = 2**32 + 2**16
4915+ testbytes = np.arange(8, dtype=np.int8)
4916+ n = len(testbytes)
4917+ flike = tempfile.NamedTemporaryFile()
4918+ f = flike.file
4919+ np.tile(testbytes, fourgbplus // testbytes.nbytes).tofile(f)
4920+ flike.seek(0)
4921+ a = np.fromfile(f, dtype=np.int8)
4922+ flike.close()
4923+ assert_(len(a) == fourgbplus)
4924+ # check only start and end for speed:
4925+ assert_((a[:n] == testbytes).all())
4926+ assert_((a[-n:] == testbytes).all())
4927+ except (MemoryError, ValueError):
4928+ pass
4929+
4930+ def test_string(self):
4931+ self._check_from(b'1,2,3,4', [1., 2., 3., 4.], sep=',')
4932+
4933+ def test_counted_string(self):
4934+ self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
4935+ self._check_from(b'1,2,3,4', [1., 2., 3.], count=3, sep=',')
4936+ self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
4937+
4938+ def test_string_with_ws(self):
4939+ self._check_from(b'1 2 3 4 ', [1, 2, 3, 4], dtype=int, sep=' ')
4940+
4941+ def test_counted_string_with_ws(self):
4942+ self._check_from(b'1 2 3 4 ', [1, 2, 3], count=3, dtype=int,
4943+ sep=' ')
4944+
4945+ def test_ascii(self):
4946+ self._check_from(b'1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
4947+ self._check_from(b'1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
4948+
4949+ def test_malformed(self):
4950+ with assert_warns(DeprecationWarning):
4951+ self._check_from(b'1.234 1,234', [1.234, 1.], sep=' ')
4952+
4953+ def test_long_sep(self):
4954+ self._check_from(b'1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
4955+
4956+ def test_dtype(self):
4957+ v = np.array([1, 2, 3, 4], dtype=np.int_)
4958+ self._check_from(b'1,2,3,4', v, sep=',', dtype=np.int_)
4959+
4960+ def test_dtype_bool(self):
4961+ # can't use _check_from because fromstring can't handle True/False
4962+ v = np.array([True, False, True, False], dtype=np.bool_)
4963+ s = b'1,0,-2.3,0'
4964+ with open(self.filename, 'wb') as f:
4965+ f.write(s)
4966+ y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
4967+ assert_(y.dtype == '?')
4968+ assert_array_equal(y, v)
4969+
4970+ def test_tofile_sep(self):
4971+ x = np.array([1.51, 2, 3.51, 4], dtype=float)
4972+ with open(self.filename, 'w') as f:
4973+ x.tofile(f, sep=',')
4974+ with open(self.filename, 'r') as f:
4975+ s = f.read()
4976+ #assert_equal(s, '1.51,2.0,3.51,4.0')
4977+ y = np.array([float(p) for p in s.split(',')])
4978+ assert_array_equal(x,y)
4979+
4980+ def test_tofile_format(self):
4981+ x = np.array([1.51, 2, 3.51, 4], dtype=float)
4982+ with open(self.filename, 'w') as f:
4983+ x.tofile(f, sep=',', format='%.2f')
4984+ with open(self.filename, 'r') as f:
4985+ s = f.read()
4986+ assert_equal(s, '1.51,2.00,3.51,4.00')
4987+
4988+ def test_locale(self):
4989+ with CommaDecimalPointLocale():
4990+ self.test_numbers()
4991+ self.test_nan()
4992+ self.test_inf()
4993+ self.test_counted_string()
4994+ self.test_ascii()
4995+ self.test_malformed()
4996+ self.test_tofile_sep()
4997+ self.test_tofile_format()
4998+
4999+ def test_fromfile_subarray_binary(self):
5000+ # Test subarray dtypes which are absorbed into the shape
5001+ x = np.arange(24, dtype="i4").reshape(2, 3, 4)
5002+ x.tofile(self.filename)
5003+ res = np.fromfile(self.filename, dtype="(3,4)i4")
5004+ assert_array_equal(x, res)
5005+
5006+ x_str = x.tobytes()
5007+ with assert_warns(DeprecationWarning):
5008+ # binary fromstring is deprecated
5009+ res = np.fromstring(x_str, dtype="(3,4)i4")
5010+ assert_array_equal(x, res)
5011+
5012+
5013+class TestFromBuffer:
5014+ @pytest.mark.parametrize('byteorder', ['<', '>'])
5015+ @pytest.mark.parametrize('dtype', [float, int, complex])
5016+ def test_basic(self, byteorder, dtype):
5017+ dt = np.dtype(dtype).newbyteorder(byteorder)
5018+ x = (np.random.random((4, 7)) * 5).astype(dt)
5019+ buf = x.tobytes()
5020+ assert_array_equal(np.frombuffer(buf, dtype=dt), x.flat)
5021+
5022+ def test_empty(self):
5023+ assert_array_equal(np.frombuffer(b''), np.array([]))
5024+
5025+
5026+class TestFlat:
5027+ def setup(self):
5028+ a0 = np.arange(20.0)
5029+ a = a0.reshape(4, 5)
5030+ a0.shape = (4, 5)
5031+ a.flags.writeable = False
5032+ self.a = a
5033+ self.b = a[::2, ::2]
5034+ self.a0 = a0
5035+ self.b0 = a0[::2, ::2]
5036+
5037+ def test_contiguous(self):
5038+ testpassed = False
5039+ try:
5040+ self.a.flat[12] = 100.0
5041+ except ValueError:
5042+ testpassed = True
5043+ assert_(testpassed)
5044+ assert_(self.a.flat[12] == 12.0)
5045+
5046+ def test_discontiguous(self):
5047+ testpassed = False
5048+ try:
5049+ self.b.flat[4] = 100.0
5050+ except ValueError:
5051+ testpassed = True
5052+ assert_(testpassed)
5053+ assert_(self.b.flat[4] == 12.0)
5054+
5055+ def test___array__(self):
5056+ c = self.a.flat.__array__()
5057+ d = self.b.flat.__array__()
5058+ e = self.a0.flat.__array__()
5059+ f = self.b0.flat.__array__()
5060+
5061+ assert_(c.flags.writeable is False)
5062+ assert_(d.flags.writeable is False)
5063+ # for 1.14 all are set to non-writeable on the way to replacing the
5064+ # UPDATEIFCOPY array returned for non-contiguous arrays.
5065+ assert_(e.flags.writeable is True)
5066+ assert_(f.flags.writeable is False)
5067+ with assert_warns(DeprecationWarning):
5068+ assert_(c.flags.updateifcopy is False)
5069+ with assert_warns(DeprecationWarning):
5070+ assert_(d.flags.updateifcopy is False)
5071+ with assert_warns(DeprecationWarning):
5072+ assert_(e.flags.updateifcopy is False)
5073+ with assert_warns(DeprecationWarning):
5074+ # UPDATEIFCOPY is removed.
5075+ assert_(f.flags.updateifcopy is False)
5076+ assert_(c.flags.writebackifcopy is False)
5077+ assert_(d.flags.writebackifcopy is False)
5078+ assert_(e.flags.writebackifcopy is False)
5079+ assert_(f.flags.writebackifcopy is False)
5080+
5081+ @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
5082+ def test_refcount(self):
5083+ # includes regression test for reference count error gh-13165
5084+ inds = [np.intp(0), np.array([True]*self.a.size), np.array([0]), None]
5085+ indtype = np.dtype(np.intp)
5086+ rc_indtype = sys.getrefcount(indtype)
5087+ for ind in inds:
5088+ rc_ind = sys.getrefcount(ind)
5089+ for _ in range(100):
5090+ try:
5091+ self.a.flat[ind]
5092+ except IndexError:
5093+ pass
5094+ assert_(abs(sys.getrefcount(ind) - rc_ind) < 50)
5095+ assert_(abs(sys.getrefcount(indtype) - rc_indtype) < 50)
5096+
5097+
5098+class TestResize:
5099+
5100+ @_no_tracing
5101+ def test_basic(self):
5102+ x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
5103+ if IS_PYPY:
5104+ x.resize((5, 5), refcheck=False)
5105+ else:
5106+ x.resize((5, 5))
5107+ assert_array_equal(x.flat[:9],
5108+ np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).flat)
5109+ assert_array_equal(x[9:].flat, 0)
5110+
5111+ def test_check_reference(self):
5112+ x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
5113+ y = x
5114+ assert_raises(ValueError, x.resize, (5, 1))
5115+ del y # avoid pyflakes unused variable warning.
5116+
5117+ @_no_tracing
5118+ def test_int_shape(self):
5119+ x = np.eye(3)
5120+ if IS_PYPY:
5121+ x.resize(3, refcheck=False)
5122+ else:
5123+ x.resize(3)
5124+ assert_array_equal(x, np.eye(3)[0,:])
5125+
5126+ def test_none_shape(self):
5127+ x = np.eye(3)
5128+ x.resize(None)
5129+ assert_array_equal(x, np.eye(3))
5130+ x.resize()
5131+ assert_array_equal(x, np.eye(3))
5132+
5133+ def test_0d_shape(self):
5134+ # to it multiple times to test it does not break alloc cache gh-9216
5135+ for i in range(10):
5136+ x = np.empty((1,))
5137+ x.resize(())
5138+ assert_equal(x.shape, ())
5139+ assert_equal(x.size, 1)
5140+ x = np.empty(())
5141+ x.resize((1,))
5142+ assert_equal(x.shape, (1,))
5143+ assert_equal(x.size, 1)
5144+
5145+ def test_invalid_arguments(self):
5146+ assert_raises(TypeError, np.eye(3).resize, 'hi')
5147+ assert_raises(ValueError, np.eye(3).resize, -1)
5148+ assert_raises(TypeError, np.eye(3).resize, order=1)
5149+ assert_raises(TypeError, np.eye(3).resize, refcheck='hi')
5150+
5151+ @_no_tracing
5152+ def test_freeform_shape(self):
5153+ x = np.eye(3)
5154+ if IS_PYPY:
5155+ x.resize(3, 2, 1, refcheck=False)
5156+ else:
5157+ x.resize(3, 2, 1)
5158+ assert_(x.shape == (3, 2, 1))
5159+
5160+ @_no_tracing
5161+ def test_zeros_appended(self):
5162+ x = np.eye(3)
5163+ if IS_PYPY:
5164+ x.resize(2, 3, 3, refcheck=False)
5165+ else:
5166+ x.resize(2, 3, 3)
5167+ assert_array_equal(x[0], np.eye(3))
5168+ assert_array_equal(x[1], np.zeros((3, 3)))
5169+
5170+ @_no_tracing
5171+ def test_obj_obj(self):
5172+ # check memory is initialized on resize, gh-4857
5173+ a = np.ones(10, dtype=[('k', object, 2)])
5174+ if IS_PYPY:
5175+ a.resize(15, refcheck=False)
5176+ else:
5177+ a.resize(15,)
5178+ assert_equal(a.shape, (15,))
5179+ assert_array_equal(a['k'][-5:], 0)
5180+ assert_array_equal(a['k'][:-5], 1)
5181+
5182+ def test_empty_view(self):
5183+ # check that sizes containing a zero don't trigger a reallocate for
5184+ # already empty arrays
5185+ x = np.zeros((10, 0), int)
5186+ x_view = x[...]
5187+ x_view.resize((0, 10))
5188+ x_view.resize((0, 100))
5189+
5190+ def test_check_weakref(self):
5191+ x = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
5192+ xref = weakref.ref(x)
5193+ assert_raises(ValueError, x.resize, (5, 1))
5194+ del xref # avoid pyflakes unused variable warning.
5195+
5196+
5197+class TestRecord:
5198+ def test_field_rename(self):
5199+ dt = np.dtype([('f', float), ('i', int)])
5200+ dt.names = ['p', 'q']
5201+ assert_equal(dt.names, ['p', 'q'])
5202+
5203+ def test_multiple_field_name_occurrence(self):
5204+ def test_dtype_init():
5205+ np.dtype([("A", "f8"), ("B", "f8"), ("A", "f8")])
5206+
5207+ # Error raised when multiple fields have the same name
5208+ assert_raises(ValueError, test_dtype_init)
5209+
5210+ def test_bytes_fields(self):
5211+ # Bytes are not allowed in field names and not recognized in titles
5212+ # on Py3
5213+ assert_raises(TypeError, np.dtype, [(b'a', int)])
5214+ assert_raises(TypeError, np.dtype, [(('b', b'a'), int)])
5215+
5216+ dt = np.dtype([((b'a', 'b'), int)])
5217+ assert_raises(TypeError, dt.__getitem__, b'a')
5218+
5219+ x = np.array([(1,), (2,), (3,)], dtype=dt)
5220+ assert_raises(IndexError, x.__getitem__, b'a')
5221+
5222+ y = x[0]
5223+ assert_raises(IndexError, y.__getitem__, b'a')
5224+
5225+ def test_multiple_field_name_unicode(self):
5226+ def test_dtype_unicode():
5227+ np.dtype([("\u20B9", "f8"), ("B", "f8"), ("\u20B9", "f8")])
5228+
5229+ # Error raised when multiple fields have the same name(unicode included)
5230+ assert_raises(ValueError, test_dtype_unicode)
5231+
5232+ def test_fromarrays_unicode(self):
5233+ # A single name string provided to fromarrays() is allowed to be unicode
5234+ # on both Python 2 and 3:
5235+ x = np.core.records.fromarrays([[0], [1]], names=u'a,b', formats=u'i4,i4')
5236+ assert_equal(x['a'][0], 0)
5237+ assert_equal(x['b'][0], 1)
5238+
5239+ def test_unicode_order(self):
5240+ # Test that we can sort with order as a unicode field name in both Python 2 and
5241+ # 3:
5242+ name = u'b'
5243+ x = np.array([1, 3, 2], dtype=[(name, int)])
5244+ x.sort(order=name)
5245+ assert_equal(x[u'b'], np.array([1, 2, 3]))
5246+
5247+ def test_field_names(self):
5248+ # Test unicode and 8-bit / byte strings can be used
5249+ a = np.zeros((1,), dtype=[('f1', 'i4'),
5250+ ('f2', 'i4'),
5251+ ('f3', [('sf1', 'i4')])])
5252+ # byte string indexing fails gracefully
5253+ assert_raises(IndexError, a.__setitem__, b'f1', 1)
5254+ assert_raises(IndexError, a.__getitem__, b'f1')
5255+ assert_raises(IndexError, a['f1'].__setitem__, b'sf1', 1)
5256+ assert_raises(IndexError, a['f1'].__getitem__, b'sf1')
5257+ b = a.copy()
5258+ fn1 = str('f1')
5259+ b[fn1] = 1
5260+ assert_equal(b[fn1], 1)
5261+ fnn = str('not at all')
5262+ assert_raises(ValueError, b.__setitem__, fnn, 1)
5263+ assert_raises(ValueError, b.__getitem__, fnn)
5264+ b[0][fn1] = 2
5265+ assert_equal(b[fn1], 2)
5266+ # Subfield
5267+ assert_raises(ValueError, b[0].__setitem__, fnn, 1)
5268+ assert_raises(ValueError, b[0].__getitem__, fnn)
5269+ # Subfield
5270+ fn3 = str('f3')
5271+ sfn1 = str('sf1')
5272+ b[fn3][sfn1] = 1
5273+ assert_equal(b[fn3][sfn1], 1)
5274+ assert_raises(ValueError, b[fn3].__setitem__, fnn, 1)
5275+ assert_raises(ValueError, b[fn3].__getitem__, fnn)
5276+ # multiple subfields
5277+ fn2 = str('f2')
5278+ b[fn2] = 3
5279+
5280+ assert_equal(b[['f1', 'f2']][0].tolist(), (2, 3))
5281+ assert_equal(b[['f2', 'f1']][0].tolist(), (3, 2))
5282+ assert_equal(b[['f1', 'f3']][0].tolist(), (2, (1,)))
5283+
5284+ # non-ascii unicode field indexing is well behaved
5285+ assert_raises(ValueError, a.__setitem__, u'\u03e0', 1)
5286+ assert_raises(ValueError, a.__getitem__, u'\u03e0')
5287+
5288+ def test_record_hash(self):
5289+ a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
5290+ a.flags.writeable = False
5291+ b = np.array([(1, 2), (3, 4)], dtype=[('num1', 'i1'), ('num2', 'i2')])
5292+ b.flags.writeable = False
5293+ c = np.array([(1, 2), (3, 4)], dtype='i1,i2')
5294+ c.flags.writeable = False
5295+ assert_(hash(a[0]) == hash(a[1]))
5296+ assert_(hash(a[0]) == hash(b[0]))
5297+ assert_(hash(a[0]) != hash(b[1]))
5298+ assert_(hash(c[0]) == hash(a[0]) and c[0] == a[0])
5299+
5300+ def test_record_no_hash(self):
5301+ a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
5302+ assert_raises(TypeError, hash, a[0])
5303+
5304+ def test_empty_structure_creation(self):
5305+ # make sure these do not raise errors (gh-5631)
5306+ np.array([()], dtype={'names': [], 'formats': [],
5307+ 'offsets': [], 'itemsize': 12})
5308+ np.array([(), (), (), (), ()], dtype={'names': [], 'formats': [],
5309+ 'offsets': [], 'itemsize': 12})
5310+
5311+ def test_multifield_indexing_view(self):
5312+ a = np.ones(3, dtype=[('a', 'i4'), ('b', 'f4'), ('c', 'u4')])
5313+ v = a[['a', 'c']]
5314+ assert_(v.base is a)
5315+ assert_(v.dtype == np.dtype({'names': ['a', 'c'],
5316+ 'formats': ['i4', 'u4'],
5317+ 'offsets': [0, 8]}))
5318+ v[:] = (4,5)
5319+ assert_equal(a[0].item(), (4, 1, 5))
5320+
5321+class TestView:
5322+ def test_basic(self):
5323+ x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)],
5324+ dtype=[('r', np.int8), ('g', np.int8),
5325+ ('b', np.int8), ('a', np.int8)])
5326+ # We must be specific about the endianness here:
5327+ y = x.view(dtype='<i4')
5328+ # ... and again without the keyword.
5329+ z = x.view('<i4')
5330+ assert_array_equal(y, z)
5331+ assert_array_equal(y, [67305985, 134678021])
5332+
5333+
5334+def _mean(a, **args):
5335+ return a.mean(**args)
5336+
5337+
5338+def _var(a, **args):
5339+ return a.var(**args)
5340+
5341+
5342+def _std(a, **args):
5343+ return a.std(**args)
5344+
5345+
5346+class TestStats:
5347+
5348+ funcs = [_mean, _var, _std]
5349+
5350+ def setup(self):
5351+ np.random.seed(range(3))
5352+ self.rmat = np.random.random((4, 5))
5353+ self.cmat = self.rmat + 1j * self.rmat
5354+ self.omat = np.array([Decimal(repr(r)) for r in self.rmat.flat])
5355+ self.omat = self.omat.reshape(4, 5)
5356+
5357+ def test_python_type(self):
5358+ for x in (np.float16(1.), 1, 1., 1+0j):
5359+ assert_equal(np.mean([x]), 1.)
5360+ assert_equal(np.std([x]), 0.)
5361+ assert_equal(np.var([x]), 0.)
5362+
5363+ def test_keepdims(self):
5364+ mat = np.eye(3)
5365+ for f in self.funcs:
5366+ for axis in [0, 1]:
5367+ res = f(mat, axis=axis, keepdims=True)
5368+ assert_(res.ndim == mat.ndim)
5369+ assert_(res.shape[axis] == 1)
5370+ for axis in [None]:
5371+ res = f(mat, axis=axis, keepdims=True)
5372+ assert_(res.shape == (1, 1))
5373+
5374+ def test_out(self):
5375+ mat = np.eye(3)
5376+ for f in self.funcs:
5377+ out = np.zeros(3)
5378+ tgt = f(mat, axis=1)
5379+ res = f(mat, axis=1, out=out)
5380+ assert_almost_equal(res, out)
5381+ assert_almost_equal(res, tgt)
5382+ out = np.empty(2)
5383+ assert_raises(ValueError, f, mat, axis=1, out=out)
5384+ out = np.empty((2, 2))
5385+ assert_raises(ValueError, f, mat, axis=1, out=out)
5386+
5387+ def test_dtype_from_input(self):
5388+
5389+ icodes = np.typecodes['AllInteger']
5390+ fcodes = np.typecodes['AllFloat']
5391+
5392+ # object type
5393+ for f in self.funcs:
5394+ mat = np.array([[Decimal(1)]*3]*3)
5395+ tgt = mat.dtype.type
5396+ res = f(mat, axis=1).dtype.type
5397+ assert_(res is tgt)
5398+ # scalar case
5399+ res = type(f(mat, axis=None))
5400+ assert_(res is Decimal)
5401+
5402+ # integer types
5403+ for f in self.funcs:
5404+ for c in icodes:
5405+ mat = np.eye(3, dtype=c)
5406+ tgt = np.float64
5407+ res = f(mat, axis=1).dtype.type
5408+ assert_(res is tgt)
5409+ # scalar case
5410+ res = f(mat, axis=None).dtype.type
5411+ assert_(res is tgt)
5412+
5413+ # mean for float types
5414+ for f in [_mean]:
5415+ for c in fcodes:
5416+ mat = np.eye(3, dtype=c)
5417+ tgt = mat.dtype.type
5418+ res = f(mat, axis=1).dtype.type
5419+ assert_(res is tgt)
5420+ # scalar case
5421+ res = f(mat, axis=None).dtype.type
5422+ assert_(res is tgt)
5423+
5424+ # var, std for float types
5425+ for f in [_var, _std]:
5426+ for c in fcodes:
5427+ mat = np.eye(3, dtype=c)
5428+ # deal with complex types
5429+ tgt = mat.real.dtype.type
5430+ res = f(mat, axis=1).dtype.type
5431+ assert_(res is tgt)
5432+ # scalar case
5433+ res = f(mat, axis=None).dtype.type
5434+ assert_(res is tgt)
5435+
5436+ def test_dtype_from_dtype(self):
5437+ mat = np.eye(3)
5438+
5439+ # stats for integer types
5440+ # FIXME:
5441+ # this needs definition as there are lots places along the line
5442+ # where type casting may take place.
5443+
5444+ # for f in self.funcs:
5445+ # for c in np.typecodes['AllInteger']:
5446+ # tgt = np.dtype(c).type
5447+ # res = f(mat, axis=1, dtype=c).dtype.type
5448+ # assert_(res is tgt)
5449+ # # scalar case
5450+ # res = f(mat, axis=None, dtype=c).dtype.type
5451+ # assert_(res is tgt)
5452+
5453+ # stats for float types
5454+ for f in self.funcs:
5455+ for c in np.typecodes['AllFloat']:
5456+ tgt = np.dtype(c).type
5457+ res = f(mat, axis=1, dtype=c).dtype.type
5458+ assert_(res is tgt)
5459+ # scalar case
5460+ res = f(mat, axis=None, dtype=c).dtype.type
5461+ assert_(res is tgt)
5462+
5463+ def test_ddof(self):
5464+ for f in [_var]:
5465+ for ddof in range(3):
5466+ dim = self.rmat.shape[1]
5467+ tgt = f(self.rmat, axis=1) * dim
5468+ res = f(self.rmat, axis=1, ddof=ddof) * (dim - ddof)
5469+ for f in [_std]:
5470+ for ddof in range(3):
5471+ dim = self.rmat.shape[1]
5472+ tgt = f(self.rmat, axis=1) * np.sqrt(dim)
5473+ res = f(self.rmat, axis=1, ddof=ddof) * np.sqrt(dim - ddof)
5474+ assert_almost_equal(res, tgt)
5475+ assert_almost_equal(res, tgt)
5476+
5477+ def test_ddof_too_big(self):
5478+ dim = self.rmat.shape[1]
5479+ for f in [_var, _std]:
5480+ for ddof in range(dim, dim + 2):
5481+ with warnings.catch_warnings(record=True) as w:
5482+ warnings.simplefilter('always')
5483+ res = f(self.rmat, axis=1, ddof=ddof)
5484+ assert_(not (res < 0).any())
5485+ assert_(len(w) > 0)
5486+ assert_(issubclass(w[0].category, RuntimeWarning))
5487+
5488+ def test_empty(self):
5489+ A = np.zeros((0, 3))
5490+ for f in self.funcs:
5491+ for axis in [0, None]:
5492+ with warnings.catch_warnings(record=True) as w:
5493+ warnings.simplefilter('always')
5494+ assert_(np.isnan(f(A, axis=axis)).all())
5495+ assert_(len(w) > 0)
5496+ assert_(issubclass(w[0].category, RuntimeWarning))
5497+ for axis in [1]:
5498+ with warnings.catch_warnings(record=True) as w:
5499+ warnings.simplefilter('always')
5500+ assert_equal(f(A, axis=axis), np.zeros([]))
5501+
5502+ def test_mean_values(self):
5503+ for mat in [self.rmat, self.cmat, self.omat]:
5504+ for axis in [0, 1]:
5505+ tgt = mat.sum(axis=axis)
5506+ res = _mean(mat, axis=axis) * mat.shape[axis]
5507+ assert_almost_equal(res, tgt)
5508+ for axis in [None]:
5509+ tgt = mat.sum(axis=axis)
5510+ res = _mean(mat, axis=axis) * np.prod(mat.shape)
5511+ assert_almost_equal(res, tgt)
5512+
5513+ def test_mean_float16(self):
5514+ # This fail if the sum inside mean is done in float16 instead
5515+ # of float32.
5516+ assert_(_mean(np.ones(100000, dtype='float16')) == 1)
5517+
5518+ def test_mean_axis_error(self):
5519+ # Ensure that AxisError is raised instead of IndexError when axis is
5520+ # out of bounds, see gh-15817.
5521+ with assert_raises(np.core._exceptions.AxisError):
5522+ np.arange(10).mean(axis=2)
5523+
5524+ def test_var_values(self):
5525+ for mat in [self.rmat, self.cmat, self.omat]:
5526+ for axis in [0, 1, None]:
5527+ msqr = _mean(mat * mat.conj(), axis=axis)
5528+ mean = _mean(mat, axis=axis)
5529+ tgt = msqr - mean * mean.conjugate()
5530+ res = _var(mat, axis=axis)
5531+ assert_almost_equal(res, tgt)
5532+
5533+ @pytest.mark.parametrize(('complex_dtype', 'ndec'), (
5534+ ('complex64', 6),
5535+ ('complex128', 7),
5536+ ('clongdouble', 7),
5537+ ))
5538+ def test_var_complex_values(self, complex_dtype, ndec):
5539+ # Test fast-paths for every builtin complex type
5540+ for axis in [0, 1, None]:
5541+ mat = self.cmat.copy().astype(complex_dtype)
5542+ msqr = _mean(mat * mat.conj(), axis=axis)
5543+ mean = _mean(mat, axis=axis)
5544+ tgt = msqr - mean * mean.conjugate()
5545+ res = _var(mat, axis=axis)
5546+ assert_almost_equal(res, tgt, decimal=ndec)
5547+
5548+ def test_var_dimensions(self):
5549+ # _var paths for complex number introduce additions on views that
5550+ # increase dimensions. Ensure this generalizes to higher dims
5551+ mat = np.stack([self.cmat]*3)
5552+ for axis in [0, 1, 2, -1, None]:
5553+ msqr = _mean(mat * mat.conj(), axis=axis)
5554+ mean = _mean(mat, axis=axis)
5555+ tgt = msqr - mean * mean.conjugate()
5556+ res = _var(mat, axis=axis)
5557+ assert_almost_equal(res, tgt)
5558+
5559+ def test_var_complex_byteorder(self):
5560+ # Test that var fast-path does not cause failures for complex arrays
5561+ # with non-native byteorder
5562+ cmat = self.cmat.copy().astype('complex128')
5563+ cmat_swapped = cmat.astype(cmat.dtype.newbyteorder())
5564+ assert_almost_equal(cmat.var(), cmat_swapped.var())
5565+
5566+ def test_var_axis_error(self):
5567+ # Ensure that AxisError is raised instead of IndexError when axis is
5568+ # out of bounds, see gh-15817.
5569+ with assert_raises(np.core._exceptions.AxisError):
5570+ np.arange(10).var(axis=2)
5571+
5572+ def test_std_values(self):
5573+ for mat in [self.rmat, self.cmat, self.omat]:
5574+ for axis in [0, 1, None]:
5575+ tgt = np.sqrt(_var(mat, axis=axis))
5576+ res = _std(mat, axis=axis)
5577+ assert_almost_equal(res, tgt)
5578+
5579+ def test_subclass(self):
5580+ class TestArray(np.ndarray):
5581+ def __new__(cls, data, info):
5582+ result = np.array(data)
5583+ result = result.view(cls)
5584+ result.info = info
5585+ return result
5586+
5587+ def __array_finalize__(self, obj):
5588+ self.info = getattr(obj, "info", '')
5589+
5590+ dat = TestArray([[1, 2, 3, 4], [5, 6, 7, 8]], 'jubba')
5591+ res = dat.mean(1)
5592+ assert_(res.info == dat.info)
5593+ res = dat.std(1)
5594+ assert_(res.info == dat.info)
5595+ res = dat.var(1)
5596+ assert_(res.info == dat.info)
5597+
5598+class TestVdot:
5599+ def test_basic(self):
5600+ dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
5601+ dt_complex = np.typecodes['Complex']
5602+
5603+ # test real
5604+ a = np.eye(3)
5605+ for dt in dt_numeric + 'O':
5606+ b = a.astype(dt)
5607+ res = np.vdot(b, b)
5608+ assert_(np.isscalar(res))
5609+ assert_equal(np.vdot(b, b), 3)
5610+
5611+ # test complex
5612+ a = np.eye(3) * 1j
5613+ for dt in dt_complex + 'O':
5614+ b = a.astype(dt)
5615+ res = np.vdot(b, b)
5616+ assert_(np.isscalar(res))
5617+ assert_equal(np.vdot(b, b), 3)
5618+
5619+ # test boolean
5620+ b = np.eye(3, dtype=bool)
5621+ res = np.vdot(b, b)
5622+ assert_(np.isscalar(res))
5623+ assert_equal(np.vdot(b, b), True)
5624+
5625+ def test_vdot_array_order(self):
5626+ a = np.array([[1, 2], [3, 4]], order='C')
5627+ b = np.array([[1, 2], [3, 4]], order='F')
5628+ res = np.vdot(a, a)
5629+
5630+ # integer arrays are exact
5631+ assert_equal(np.vdot(a, b), res)
5632+ assert_equal(np.vdot(b, a), res)
5633+ assert_equal(np.vdot(b, b), res)
5634+
5635+ def test_vdot_uncontiguous(self):
5636+ for size in [2, 1000]:
5637+ # Different sizes match different branches in vdot.
5638+ a = np.zeros((size, 2, 2))
5639+ b = np.zeros((size, 2, 2))
5640+ a[:, 0, 0] = np.arange(size)
5641+ b[:, 0, 0] = np.arange(size) + 1
5642+ # Make a and b uncontiguous:
5643+ a = a[..., 0]
5644+ b = b[..., 0]
5645+
5646+ assert_equal(np.vdot(a, b),
5647+ np.vdot(a.flatten(), b.flatten()))
5648+ assert_equal(np.vdot(a, b.copy()),
5649+ np.vdot(a.flatten(), b.flatten()))
5650+ assert_equal(np.vdot(a.copy(), b),
5651+ np.vdot(a.flatten(), b.flatten()))
5652+ assert_equal(np.vdot(a.copy('F'), b),
5653+ np.vdot(a.flatten(), b.flatten()))
5654+ assert_equal(np.vdot(a, b.copy('F')),
5655+ np.vdot(a.flatten(), b.flatten()))
5656+
5657+
5658+class TestDot:
5659+ def setup(self):
5660+ np.random.seed(128)
5661+ self.A = np.random.rand(4, 2)
5662+ self.b1 = np.random.rand(2, 1)
5663+ self.b2 = np.random.rand(2)
5664+ self.b3 = np.random.rand(1, 2)
5665+ self.b4 = np.random.rand(4)
5666+ self.N = 7
5667+
5668+ def test_dotmatmat(self):
5669+ A = self.A
5670+ res = np.dot(A.transpose(), A)
5671+ tgt = np.array([[1.45046013, 0.86323640],
5672+ [0.86323640, 0.84934569]])
5673+ assert_almost_equal(res, tgt, decimal=self.N)
5674+
5675+ def test_dotmatvec(self):
5676+ A, b1 = self.A, self.b1
5677+ res = np.dot(A, b1)
5678+ tgt = np.array([[0.32114320], [0.04889721],
5679+ [0.15696029], [0.33612621]])
5680+ assert_almost_equal(res, tgt, decimal=self.N)
5681+
5682+ def test_dotmatvec2(self):
5683+ A, b2 = self.A, self.b2
5684+ res = np.dot(A, b2)
5685+ tgt = np.array([0.29677940, 0.04518649, 0.14468333, 0.31039293])
5686+ assert_almost_equal(res, tgt, decimal=self.N)
5687+
5688+ def test_dotvecmat(self):
5689+ A, b4 = self.A, self.b4
5690+ res = np.dot(b4, A)
5691+ tgt = np.array([1.23495091, 1.12222648])
5692+ assert_almost_equal(res, tgt, decimal=self.N)
5693+
5694+ def test_dotvecmat2(self):
5695+ b3, A = self.b3, self.A
5696+ res = np.dot(b3, A.transpose())
5697+ tgt = np.array([[0.58793804, 0.08957460, 0.30605758, 0.62716383]])
5698+ assert_almost_equal(res, tgt, decimal=self.N)
5699+
5700+ def test_dotvecmat3(self):
5701+ A, b4 = self.A, self.b4
5702+ res = np.dot(A.transpose(), b4)
5703+ tgt = np.array([1.23495091, 1.12222648])
5704+ assert_almost_equal(res, tgt, decimal=self.N)
5705+
5706+ def test_dotvecvecouter(self):
5707+ b1, b3 = self.b1, self.b3
5708+ res = np.dot(b1, b3)
5709+ tgt = np.array([[0.20128610, 0.08400440], [0.07190947, 0.03001058]])
5710+ assert_almost_equal(res, tgt, decimal=self.N)
5711+
5712+ def test_dotvecvecinner(self):
5713+ b1, b3 = self.b1, self.b3
5714+ res = np.dot(b3, b1)
5715+ tgt = np.array([[ 0.23129668]])
5716+ assert_almost_equal(res, tgt, decimal=self.N)
5717+
5718+ def test_dotcolumnvect1(self):
5719+ b1 = np.ones((3, 1))
5720+ b2 = [5.3]
5721+ res = np.dot(b1, b2)
5722+ tgt = np.array([5.3, 5.3, 5.3])
5723+ assert_almost_equal(res, tgt, decimal=self.N)
5724+
5725+ def test_dotcolumnvect2(self):
5726+ b1 = np.ones((3, 1)).transpose()
5727+ b2 = [6.2]
5728+ res = np.dot(b2, b1)
5729+ tgt = np.array([6.2, 6.2, 6.2])
5730+ assert_almost_equal(res, tgt, decimal=self.N)
5731+
5732+ def test_dotvecscalar(self):
5733+ np.random.seed(100)
5734+ b1 = np.random.rand(1, 1)
5735+ b2 = np.random.rand(1, 4)
5736+ res = np.dot(b1, b2)
5737+ tgt = np.array([[0.15126730, 0.23068496, 0.45905553, 0.00256425]])
5738+ assert_almost_equal(res, tgt, decimal=self.N)
5739+
5740+ def test_dotvecscalar2(self):
5741+ np.random.seed(100)
5742+ b1 = np.random.rand(4, 1)
5743+ b2 = np.random.rand(1, 1)
5744+ res = np.dot(b1, b2)
5745+ tgt = np.array([[0.00256425],[0.00131359],[0.00200324],[ 0.00398638]])
5746+ assert_almost_equal(res, tgt, decimal=self.N)
5747+
5748+ def test_all(self):
5749+ dims = [(), (1,), (1, 1)]
5750+ dout = [(), (1,), (1, 1), (1,), (), (1,), (1, 1), (1,), (1, 1)]
5751+ for dim, (dim1, dim2) in zip(dout, itertools.product(dims, dims)):
5752+ b1 = np.zeros(dim1)
5753+ b2 = np.zeros(dim2)
5754+ res = np.dot(b1, b2)
5755+ tgt = np.zeros(dim)
5756+ assert_(res.shape == tgt.shape)
5757+ assert_almost_equal(res, tgt, decimal=self.N)
5758+
5759+ def test_vecobject(self):
5760+ class Vec:
5761+ def __init__(self, sequence=None):
5762+ if sequence is None:
5763+ sequence = []
5764+ self.array = np.array(sequence)
5765+
5766+ def __add__(self, other):
5767+ out = Vec()
5768+ out.array = self.array + other.array
5769+ return out
5770+
5771+ def __sub__(self, other):
5772+ out = Vec()
5773+ out.array = self.array - other.array
5774+ return out
5775+
5776+ def __mul__(self, other): # with scalar
5777+ out = Vec(self.array.copy())
5778+ out.array *= other
5779+ return out
5780+
5781+ def __rmul__(self, other):
5782+ return self*other
5783+
5784+ U_non_cont = np.transpose([[1., 1.], [1., 2.]])
5785+ U_cont = np.ascontiguousarray(U_non_cont)
5786+ x = np.array([Vec([1., 0.]), Vec([0., 1.])])
5787+ zeros = np.array([Vec([0., 0.]), Vec([0., 0.])])
5788+ zeros_test = np.dot(U_cont, x) - np.dot(U_non_cont, x)
5789+ assert_equal(zeros[0].array, zeros_test[0].array)
5790+ assert_equal(zeros[1].array, zeros_test[1].array)
5791+
5792+ def test_dot_2args(self):
5793+ from numpy.core.multiarray import dot
5794+
5795+ a = np.array([[1, 2], [3, 4]], dtype=float)
5796+ b = np.array([[1, 0], [1, 1]], dtype=float)
5797+ c = np.array([[3, 2], [7, 4]], dtype=float)
5798+
5799+ d = dot(a, b)
5800+ assert_allclose(c, d)
5801+
5802+ def test_dot_3args(self):
5803+ from numpy.core.multiarray import dot
5804+
5805+ np.random.seed(22)
5806+ f = np.random.random_sample((1024, 16))
5807+ v = np.random.random_sample((16, 32))
5808+
5809+ r = np.empty((1024, 32))
5810+ for i in range(12):
5811+ dot(f, v, r)
5812+ if HAS_REFCOUNT:
5813+ assert_equal(sys.getrefcount(r), 2)
5814+ r2 = dot(f, v, out=None)
5815+ assert_array_equal(r2, r)
5816+ assert_(r is dot(f, v, out=r))
5817+
5818+ v = v[:, 0].copy() # v.shape == (16,)
5819+ r = r[:, 0].copy() # r.shape == (1024,)
5820+ r2 = dot(f, v)
5821+ assert_(r is dot(f, v, r))
5822+ assert_array_equal(r2, r)
5823+
5824+ def test_dot_3args_errors(self):
5825+ from numpy.core.multiarray import dot
5826+
5827+ np.random.seed(22)
5828+ f = np.random.random_sample((1024, 16))
5829+ v = np.random.random_sample((16, 32))
5830+
5831+ r = np.empty((1024, 31))
5832+ assert_raises(ValueError, dot, f, v, r)
5833+
5834+ r = np.empty((1024,))
5835+ assert_raises(ValueError, dot, f, v, r)
5836+
5837+ r = np.empty((32,))
5838+ assert_raises(ValueError, dot, f, v, r)
5839+
5840+ r = np.empty((32, 1024))
5841+ assert_raises(ValueError, dot, f, v, r)
5842+ assert_raises(ValueError, dot, f, v, r.T)
5843+
5844+ r = np.empty((1024, 64))
5845+ assert_raises(ValueError, dot, f, v, r[:, ::2])
5846+ assert_raises(ValueError, dot, f, v, r[:, :32])
5847+
5848+ r = np.empty((1024, 32), dtype=np.float32)
5849+ assert_raises(ValueError, dot, f, v, r)
5850+
5851+ r = np.empty((1024, 32), dtype=int)
5852+ assert_raises(ValueError, dot, f, v, r)
5853+
5854+ def test_dot_array_order(self):
5855+ a = np.array([[1, 2], [3, 4]], order='C')
5856+ b = np.array([[1, 2], [3, 4]], order='F')
5857+ res = np.dot(a, a)
5858+
5859+ # integer arrays are exact
5860+ assert_equal(np.dot(a, b), res)
5861+ assert_equal(np.dot(b, a), res)
5862+ assert_equal(np.dot(b, b), res)
5863+
5864+ def test_accelerate_framework_sgemv_fix(self):
5865+
5866+ def aligned_array(shape, align, dtype, order='C'):
5867+ d = dtype(0)
5868+ N = np.prod(shape)
5869+ tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
5870+ address = tmp.__array_interface__["data"][0]
5871+ for offset in range(align):
5872+ if (address + offset) % align == 0:
5873+ break
5874+ tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
5875+ return tmp.reshape(shape, order=order)
5876+
5877+ def as_aligned(arr, align, dtype, order='C'):
5878+ aligned = aligned_array(arr.shape, align, dtype, order)
5879+ aligned[:] = arr[:]
5880+ return aligned
5881+
5882+ def assert_dot_close(A, X, desired):
5883+ assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
5884+
5885+ m = aligned_array(100, 15, np.float32)
5886+ s = aligned_array((100, 100), 15, np.float32)
5887+ np.dot(s, m) # this will always segfault if the bug is present
5888+
5889+ testdata = itertools.product((15,32), (10000,), (200,89), ('C','F'))
5890+ for align, m, n, a_order in testdata:
5891+ # Calculation in double precision
5892+ A_d = np.random.rand(m, n)
5893+ X_d = np.random.rand(n)
5894+ desired = np.dot(A_d, X_d)
5895+ # Calculation with aligned single precision
5896+ A_f = as_aligned(A_d, align, np.float32, order=a_order)
5897+ X_f = as_aligned(X_d, align, np.float32)
5898+ assert_dot_close(A_f, X_f, desired)
5899+ # Strided A rows
5900+ A_d_2 = A_d[::2]
5901+ desired = np.dot(A_d_2, X_d)
5902+ A_f_2 = A_f[::2]
5903+ assert_dot_close(A_f_2, X_f, desired)
5904+ # Strided A columns, strided X vector
5905+ A_d_22 = A_d_2[:, ::2]
5906+ X_d_2 = X_d[::2]
5907+ desired = np.dot(A_d_22, X_d_2)
5908+ A_f_22 = A_f_2[:, ::2]
5909+ X_f_2 = X_f[::2]
5910+ assert_dot_close(A_f_22, X_f_2, desired)
5911+ # Check the strides are as expected
5912+ if a_order == 'F':
5913+ assert_equal(A_f_22.strides, (8, 8 * m))
5914+ else:
5915+ assert_equal(A_f_22.strides, (8 * n, 8))
5916+ assert_equal(X_f_2.strides, (8,))
5917+ # Strides in A rows + cols only
5918+ X_f_2c = as_aligned(X_f_2, align, np.float32)
5919+ assert_dot_close(A_f_22, X_f_2c, desired)
5920+ # Strides just in A cols
5921+ A_d_12 = A_d[:, ::2]
5922+ desired = np.dot(A_d_12, X_d_2)
5923+ A_f_12 = A_f[:, ::2]
5924+ assert_dot_close(A_f_12, X_f_2c, desired)
5925+ # Strides in A cols and X
5926+ assert_dot_close(A_f_12, X_f_2, desired)
5927+
5928+
5929+class MatmulCommon:
5930+ """Common tests for '@' operator and numpy.matmul.
5931+
5932+ """
5933+ # Should work with these types. Will want to add
5934+ # "O" at some point
5935+ types = "?bhilqBHILQefdgFDGO"
5936+
5937+ def test_exceptions(self):
5938+ dims = [
5939+ ((1,), (2,)), # mismatched vector vector
5940+ ((2, 1,), (2,)), # mismatched matrix vector
5941+ ((2,), (1, 2)), # mismatched vector matrix
5942+ ((1, 2), (3, 1)), # mismatched matrix matrix
5943+ ((1,), ()), # vector scalar
5944+ ((), (1)), # scalar vector
5945+ ((1, 1), ()), # matrix scalar
5946+ ((), (1, 1)), # scalar matrix
5947+ ((2, 2, 1), (3, 1, 2)), # cannot broadcast
5948+ ]
5949+
5950+ for dt, (dm1, dm2) in itertools.product(self.types, dims):
5951+ a = np.ones(dm1, dtype=dt)
5952+ b = np.ones(dm2, dtype=dt)
5953+ assert_raises(ValueError, self.matmul, a, b)
5954+
5955+ def test_shapes(self):
5956+ dims = [
5957+ ((1, 1), (2, 1, 1)), # broadcast first argument
5958+ ((2, 1, 1), (1, 1)), # broadcast second argument
5959+ ((2, 1, 1), (2, 1, 1)), # matrix stack sizes match
5960+ ]
5961+
5962+ for dt, (dm1, dm2) in itertools.product(self.types, dims):
5963+ a = np.ones(dm1, dtype=dt)
5964+ b = np.ones(dm2, dtype=dt)
5965+ res = self.matmul(a, b)
5966+ assert_(res.shape == (2, 1, 1))
5967+
5968+ # vector vector returns scalars.
5969+ for dt in self.types:
5970+ a = np.ones((2,), dtype=dt)
5971+ b = np.ones((2,), dtype=dt)
5972+ c = self.matmul(a, b)
5973+ assert_(np.array(c).shape == ())
5974+
5975+ def test_result_types(self):
5976+ mat = np.ones((1,1))
5977+ vec = np.ones((1,))
5978+ for dt in self.types:
5979+ m = mat.astype(dt)
5980+ v = vec.astype(dt)
5981+ for arg in [(m, v), (v, m), (m, m)]:
5982+ res = self.matmul(*arg)
5983+ assert_(res.dtype == dt)
5984+
5985+ # vector vector returns scalars
5986+ if dt != "O":
5987+ res = self.matmul(v, v)
5988+ assert_(type(res) is np.dtype(dt).type)
5989+
5990+ def test_scalar_output(self):
5991+ vec1 = np.array([2])
5992+ vec2 = np.array([3, 4]).reshape(1, -1)
5993+ tgt = np.array([6, 8])
5994+ for dt in self.types[1:]:
5995+ v1 = vec1.astype(dt)
5996+ v2 = vec2.astype(dt)
5997+ res = self.matmul(v1, v2)
5998+ assert_equal(res, tgt)
5999+ res = self.matmul(v2.T, v1)
6000+ assert_equal(res, tgt)
6001+
6002+ # boolean type
6003+ vec = np.array([True, True], dtype='?').reshape(1, -1)
6004+ res = self.matmul(vec[:, 0], vec)
6005+ assert_equal(res, True)
6006+
6007+ def test_vector_vector_values(self):
6008+ vec1 = np.array([1, 2])
6009+ vec2 = np.array([3, 4]).reshape(-1, 1)
6010+ tgt1 = np.array([11])
6011+ tgt2 = np.array([[3, 6], [4, 8]])
6012+ for dt in self.types[1:]:
6013+ v1 = vec1.astype(dt)
6014+ v2 = vec2.astype(dt)
6015+ res = self.matmul(v1, v2)
6016+ assert_equal(res, tgt1)
6017+ # no broadcast, we must make v1 into a 2d ndarray
6018+ res = self.matmul(v2, v1.reshape(1, -1))
6019+ assert_equal(res, tgt2)
6020+
6021+ # boolean type
6022+ vec = np.array([True, True], dtype='?')
6023+ res = self.matmul(vec, vec)
6024+ assert_equal(res, True)
6025+
6026+ def test_vector_matrix_values(self):
6027+ vec = np.array([1, 2])
6028+ mat1 = np.array([[1, 2], [3, 4]])
6029+ mat2 = np.stack([mat1]*2, axis=0)
6030+ tgt1 = np.array([7, 10])
6031+ tgt2 = np.stack([tgt1]*2, axis=0)
6032+ for dt in self.types[1:]:
6033+ v = vec.astype(dt)
6034+ m1 = mat1.astype(dt)
6035+ m2 = mat2.astype(dt)
6036+ res = self.matmul(v, m1)
6037+ assert_equal(res, tgt1)
6038+ res = self.matmul(v, m2)
6039+ assert_equal(res, tgt2)
6040+
6041+ # boolean type
6042+ vec = np.array([True, False])
6043+ mat1 = np.array([[True, False], [False, True]])
6044+ mat2 = np.stack([mat1]*2, axis=0)
6045+ tgt1 = np.array([True, False])
6046+ tgt2 = np.stack([tgt1]*2, axis=0)
6047+
6048+ res = self.matmul(vec, mat1)
6049+ assert_equal(res, tgt1)
6050+ res = self.matmul(vec, mat2)
6051+ assert_equal(res, tgt2)
6052+
6053+ def test_matrix_vector_values(self):
6054+ vec = np.array([1, 2])
6055+ mat1 = np.array([[1, 2], [3, 4]])
6056+ mat2 = np.stack([mat1]*2, axis=0)
6057+ tgt1 = np.array([5, 11])
6058+ tgt2 = np.stack([tgt1]*2, axis=0)
6059+ for dt in self.types[1:]:
6060+ v = vec.astype(dt)
6061+ m1 = mat1.astype(dt)
6062+ m2 = mat2.astype(dt)
6063+ res = self.matmul(m1, v)
6064+ assert_equal(res, tgt1)
6065+ res = self.matmul(m2, v)
6066+ assert_equal(res, tgt2)
6067+
6068+ # boolean type
6069+ vec = np.array([True, False])
6070+ mat1 = np.array([[True, False], [False, True]])
6071+ mat2 = np.stack([mat1]*2, axis=0)
6072+ tgt1 = np.array([True, False])
6073+ tgt2 = np.stack([tgt1]*2, axis=0)
6074+
6075+ res = self.matmul(vec, mat1)
6076+ assert_equal(res, tgt1)
6077+ res = self.matmul(vec, mat2)
6078+ assert_equal(res, tgt2)
6079+
6080+ def test_matrix_matrix_values(self):
6081+ mat1 = np.array([[1, 2], [3, 4]])
6082+ mat2 = np.array([[1, 0], [1, 1]])
6083+ mat12 = np.stack([mat1, mat2], axis=0)
6084+ mat21 = np.stack([mat2, mat1], axis=0)
6085+ tgt11 = np.array([[7, 10], [15, 22]])
6086+ tgt12 = np.array([[3, 2], [7, 4]])
6087+ tgt21 = np.array([[1, 2], [4, 6]])
6088+ tgt12_21 = np.stack([tgt12, tgt21], axis=0)
6089+ tgt11_12 = np.stack((tgt11, tgt12), axis=0)
6090+ tgt11_21 = np.stack((tgt11, tgt21), axis=0)
6091+ for dt in self.types[1:]:
6092+ m1 = mat1.astype(dt)
6093+ m2 = mat2.astype(dt)
6094+ m12 = mat12.astype(dt)
6095+ m21 = mat21.astype(dt)
6096+
6097+ # matrix @ matrix
6098+ res = self.matmul(m1, m2)
6099+ assert_equal(res, tgt12)
6100+ res = self.matmul(m2, m1)
6101+ assert_equal(res, tgt21)
6102+
6103+ # stacked @ matrix
6104+ res = self.matmul(m12, m1)
6105+ assert_equal(res, tgt11_21)
6106+
6107+ # matrix @ stacked
6108+ res = self.matmul(m1, m12)
6109+ assert_equal(res, tgt11_12)
6110+
6111+ # stacked @ stacked
6112+ res = self.matmul(m12, m21)
6113+ assert_equal(res, tgt12_21)
6114+
6115+ # boolean type
6116+ m1 = np.array([[1, 1], [0, 0]], dtype=np.bool_)
6117+ m2 = np.array([[1, 0], [1, 1]], dtype=np.bool_)
6118+ m12 = np.stack([m1, m2], axis=0)
6119+ m21 = np.stack([m2, m1], axis=0)
6120+ tgt11 = m1
6121+ tgt12 = m1
6122+ tgt21 = np.array([[1, 1], [1, 1]], dtype=np.bool_)
6123+ tgt12_21 = np.stack([tgt12, tgt21], axis=0)
6124+ tgt11_12 = np.stack((tgt11, tgt12), axis=0)
6125+ tgt11_21 = np.stack((tgt11, tgt21), axis=0)
6126+
6127+ # matrix @ matrix
6128+ res = self.matmul(m1, m2)
6129+ assert_equal(res, tgt12)
6130+ res = self.matmul(m2, m1)
6131+ assert_equal(res, tgt21)
6132+
6133+ # stacked @ matrix
6134+ res = self.matmul(m12, m1)
6135+ assert_equal(res, tgt11_21)
6136+
6137+ # matrix @ stacked
6138+ res = self.matmul(m1, m12)
6139+ assert_equal(res, tgt11_12)
6140+
6141+ # stacked @ stacked
6142+ res = self.matmul(m12, m21)
6143+ assert_equal(res, tgt12_21)
6144+
6145+
6146+class TestMatmul(MatmulCommon):
6147+ matmul = np.matmul
6148+
6149+ def test_out_arg(self):
6150+ a = np.ones((5, 2), dtype=float)
6151+ b = np.array([[1, 3], [5, 7]], dtype=float)
6152+ tgt = np.dot(a, b)
6153+
6154+ # test as positional argument
6155+ msg = "out positional argument"
6156+ out = np.zeros((5, 2), dtype=float)
6157+ self.matmul(a, b, out)
6158+ assert_array_equal(out, tgt, err_msg=msg)
6159+
6160+ # test as keyword argument
6161+ msg = "out keyword argument"
6162+ out = np.zeros((5, 2), dtype=float)
6163+ self.matmul(a, b, out=out)
6164+ assert_array_equal(out, tgt, err_msg=msg)
6165+
6166+ # test out with not allowed type cast (safe casting)
6167+ msg = "Cannot cast ufunc .* output"
6168+ out = np.zeros((5, 2), dtype=np.int32)
6169+ assert_raises_regex(TypeError, msg, self.matmul, a, b, out=out)
6170+
6171+ # test out with type upcast to complex
6172+ out = np.zeros((5, 2), dtype=np.complex128)
6173+ c = self.matmul(a, b, out=out)
6174+ assert_(c is out)
6175+ with suppress_warnings() as sup:
6176+ sup.filter(np.ComplexWarning, '')
6177+ c = c.astype(tgt.dtype)
6178+ assert_array_equal(c, tgt)
6179+
6180+ def test_out_contiguous(self):
6181+ a = np.ones((5, 2), dtype=float)
6182+ b = np.array([[1, 3], [5, 7]], dtype=float)
6183+ v = np.array([1, 3], dtype=float)
6184+ tgt = np.dot(a, b)
6185+ tgt_mv = np.dot(a, v)
6186+
6187+ # test out non-contiguous
6188+ out = np.ones((5, 2, 2), dtype=float)
6189+ c = self.matmul(a, b, out=out[..., 0])
6190+ assert c.base is out
6191+ assert_array_equal(c, tgt)
6192+ c = self.matmul(a, v, out=out[:, 0, 0])
6193+ assert_array_equal(c, tgt_mv)
6194+ c = self.matmul(v, a.T, out=out[:, 0, 0])
6195+ assert_array_equal(c, tgt_mv)
6196+
6197+ # test out contiguous in only last dim
6198+ out = np.ones((10, 2), dtype=float)
6199+ c = self.matmul(a, b, out=out[::2, :])
6200+ assert_array_equal(c, tgt)
6201+
6202+ # test transposes of out, args
6203+ out = np.ones((5, 2), dtype=float)
6204+ c = self.matmul(b.T, a.T, out=out.T)
6205+ assert_array_equal(out, tgt)
6206+
6207+ m1 = np.arange(15.).reshape(5, 3)
6208+ m2 = np.arange(21.).reshape(3, 7)
6209+ m3 = np.arange(30.).reshape(5, 6)[:, ::2] # non-contiguous
6210+ vc = np.arange(10.)
6211+ vr = np.arange(6.)
6212+ m0 = np.zeros((3, 0))
6213+ @pytest.mark.parametrize('args', (
6214+ # matrix-matrix
6215+ (m1, m2), (m2.T, m1.T), (m2.T.copy(), m1.T), (m2.T, m1.T.copy()),
6216+ # matrix-matrix-transpose, contiguous and non
6217+ (m1, m1.T), (m1.T, m1), (m1, m3.T), (m3, m1.T),
6218+ (m3, m3.T), (m3.T, m3),
6219+ # matrix-matrix non-contiguous
6220+ (m3, m2), (m2.T, m3.T), (m2.T.copy(), m3.T),
6221+ # vector-matrix, matrix-vector, contiguous
6222+ (m1, vr[:3]), (vc[:5], m1), (m1.T, vc[:5]), (vr[:3], m1.T),
6223+ # vector-matrix, matrix-vector, vector non-contiguous
6224+ (m1, vr[::2]), (vc[::2], m1), (m1.T, vc[::2]), (vr[::2], m1.T),
6225+ # vector-matrix, matrix-vector, matrix non-contiguous
6226+ (m3, vr[:3]), (vc[:5], m3), (m3.T, vc[:5]), (vr[:3], m3.T),
6227+ # vector-matrix, matrix-vector, both non-contiguous
6228+ (m3, vr[::2]), (vc[::2], m3), (m3.T, vc[::2]), (vr[::2], m3.T),
6229+ # size == 0
6230+ (m0, m0.T), (m0.T, m0), (m1, m0), (m0.T, m1.T),
6231+ ))
6232+ def test_dot_equivalent(self, args):
6233+ r1 = np.matmul(*args)
6234+ r2 = np.dot(*args)
6235+ assert_equal(r1, r2)
6236+
6237+ r3 = np.matmul(args[0].copy(), args[1].copy())
6238+ assert_equal(r1, r3)
6239+
6240+ def test_matmul_object(self):
6241+ import fractions
6242+
6243+ f = np.vectorize(fractions.Fraction)
6244+ def random_ints():
6245+ return np.random.randint(1, 1000, size=(10, 3, 3))
6246+ M1 = f(random_ints(), random_ints())
6247+ M2 = f(random_ints(), random_ints())
6248+
6249+ M3 = self.matmul(M1, M2)
6250+
6251+ [N1, N2, N3] = [a.astype(float) for a in [M1, M2, M3]]
6252+
6253+ assert_allclose(N3, self.matmul(N1, N2))
6254+
6255+ def test_matmul_object_type_scalar(self):
6256+ from fractions import Fraction as F
6257+ v = np.array([F(2,3), F(5,7)])
6258+ res = self.matmul(v, v)
6259+ assert_(type(res) is F)
6260+
6261+ def test_matmul_empty(self):
6262+ a = np.empty((3, 0), dtype=object)
6263+ b = np.empty((0, 3), dtype=object)
6264+ c = np.zeros((3, 3))
6265+ assert_array_equal(np.matmul(a, b), c)
6266+
6267+ def test_matmul_exception_multiply(self):
6268+ # test that matmul fails if `__mul__` is missing
6269+ class add_not_multiply():
6270+ def __add__(self, other):
6271+ return self
6272+ a = np.full((3,3), add_not_multiply())
6273+ with assert_raises(TypeError):
6274+ b = np.matmul(a, a)
6275+
6276+ def test_matmul_exception_add(self):
6277+ # test that matmul fails if `__add__` is missing
6278+ class multiply_not_add():
6279+ def __mul__(self, other):
6280+ return self
6281+ a = np.full((3,3), multiply_not_add())
6282+ with assert_raises(TypeError):
6283+ b = np.matmul(a, a)
6284+
6285+ def test_matmul_bool(self):
6286+ # gh-14439
6287+ a = np.array([[1, 0],[1, 1]], dtype=bool)
6288+ assert np.max(a.view(np.uint8)) == 1
6289+ b = np.matmul(a, a)
6290+ # matmul with boolean output should always be 0, 1
6291+ assert np.max(b.view(np.uint8)) == 1
6292+
6293+ rg = np.random.default_rng(np.random.PCG64(43))
6294+ d = rg.integers(2, size=4*5, dtype=np.int8)
6295+ d = d.reshape(4, 5) > 0
6296+ out1 = np.matmul(d, d.reshape(5, 4))
6297+ out2 = np.dot(d, d.reshape(5, 4))
6298+ assert_equal(out1, out2)
6299+
6300+ c = np.matmul(np.zeros((2, 0), dtype=bool), np.zeros(0, dtype=bool))
6301+ assert not np.any(c)
6302+
6303+
6304+class TestMatmulOperator(MatmulCommon):
6305+ import operator
6306+ matmul = operator.matmul
6307+
6308+ def test_array_priority_override(self):
6309+
6310+ class A:
6311+ __array_priority__ = 1000
6312+
6313+ def __matmul__(self, other):
6314+ return "A"
6315+
6316+ def __rmatmul__(self, other):
6317+ return "A"
6318+
6319+ a = A()
6320+ b = np.ones(2)
6321+ assert_equal(self.matmul(a, b), "A")
6322+ assert_equal(self.matmul(b, a), "A")
6323+
6324+ def test_matmul_raises(self):
6325+ assert_raises(TypeError, self.matmul, np.int8(5), np.int8(5))
6326+ assert_raises(TypeError, self.matmul, np.void(b'abc'), np.void(b'abc'))
6327+ assert_raises(ValueError, self.matmul, np.arange(10), np.void(b'abc'))
6328+
6329+def test_matmul_inplace():
6330+ # It would be nice to support in-place matmul eventually, but for now
6331+ # we don't have a working implementation, so better just to error out
6332+ # and nudge people to writing "a = a @ b".
6333+ a = np.eye(3)
6334+ b = np.eye(3)
6335+ assert_raises(TypeError, a.__imatmul__, b)
6336+ import operator
6337+ assert_raises(TypeError, operator.imatmul, a, b)
6338+ assert_raises(TypeError, exec, "a @= b", globals(), locals())
6339+
6340+def test_matmul_axes():
6341+ a = np.arange(3*4*5).reshape(3, 4, 5)
6342+ c = np.matmul(a, a, axes=[(-2, -1), (-1, -2), (1, 2)])
6343+ assert c.shape == (3, 4, 4)
6344+ d = np.matmul(a, a, axes=[(-2, -1), (-1, -2), (0, 1)])
6345+ assert d.shape == (4, 4, 3)
6346+ e = np.swapaxes(d, 0, 2)
6347+ assert_array_equal(e, c)
6348+ f = np.matmul(a, np.arange(3), axes=[(1, 0), (0), (0)])
6349+ assert f.shape == (4, 5)
6350+
6351+
6352+class TestInner:
6353+
6354+ def test_inner_type_mismatch(self):
6355+ c = 1.
6356+ A = np.array((1,1), dtype='i,i')
6357+
6358+ assert_raises(TypeError, np.inner, c, A)
6359+ assert_raises(TypeError, np.inner, A, c)
6360+
6361+ def test_inner_scalar_and_vector(self):
6362+ for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
6363+ sca = np.array(3, dtype=dt)[()]
6364+ vec = np.array([1, 2], dtype=dt)
6365+ desired = np.array([3, 6], dtype=dt)
6366+ assert_equal(np.inner(vec, sca), desired)
6367+ assert_equal(np.inner(sca, vec), desired)
6368+
6369+ def test_vecself(self):
6370+ # Ticket 844.
6371+ # Inner product of a vector with itself segfaults or give
6372+ # meaningless result
6373+ a = np.zeros(shape=(1, 80), dtype=np.float64)
6374+ p = np.inner(a, a)
6375+ assert_almost_equal(p, 0, decimal=14)
6376+
6377+ def test_inner_product_with_various_contiguities(self):
6378+ # github issue 6532
6379+ for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
6380+ # check an inner product involving a matrix transpose
6381+ A = np.array([[1, 2], [3, 4]], dtype=dt)
6382+ B = np.array([[1, 3], [2, 4]], dtype=dt)
6383+ C = np.array([1, 1], dtype=dt)
6384+ desired = np.array([4, 6], dtype=dt)
6385+ assert_equal(np.inner(A.T, C), desired)
6386+ assert_equal(np.inner(C, A.T), desired)
6387+ assert_equal(np.inner(B, C), desired)
6388+ assert_equal(np.inner(C, B), desired)
6389+ # check a matrix product
6390+ desired = np.array([[7, 10], [15, 22]], dtype=dt)
6391+ assert_equal(np.inner(A, B), desired)
6392+ # check the syrk vs. gemm paths
6393+ desired = np.array([[5, 11], [11, 25]], dtype=dt)
6394+ assert_equal(np.inner(A, A), desired)
6395+ assert_equal(np.inner(A, A.copy()), desired)
6396+ # check an inner product involving an aliased and reversed view
6397+ a = np.arange(5).astype(dt)
6398+ b = a[::-1]
6399+ desired = np.array(10, dtype=dt).item()
6400+ assert_equal(np.inner(b, a), desired)
6401+
6402+ def test_3d_tensor(self):
6403+ for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?':
6404+ a = np.arange(24).reshape(2,3,4).astype(dt)
6405+ b = np.arange(24, 48).reshape(2,3,4).astype(dt)
6406+ desired = np.array(
6407+ [[[[ 158, 182, 206],
6408+ [ 230, 254, 278]],
6409+
6410+ [[ 566, 654, 742],
6411+ [ 830, 918, 1006]],
6412+
6413+ [[ 974, 1126, 1278],
6414+ [1430, 1582, 1734]]],
6415+
6416+ [[[1382, 1598, 1814],
6417+ [2030, 2246, 2462]],
6418+
6419+ [[1790, 2070, 2350],
6420+ [2630, 2910, 3190]],
6421+
6422+ [[2198, 2542, 2886],
6423+ [3230, 3574, 3918]]]],
6424+ dtype=dt
6425+ )
6426+ assert_equal(np.inner(a, b), desired)
6427+ assert_equal(np.inner(b, a).transpose(2,3,0,1), desired)
6428+
6429+
6430+class TestAlen:
6431+ def test_basic(self):
6432+ with pytest.warns(DeprecationWarning):
6433+ m = np.array([1, 2, 3])
6434+ assert_equal(np.alen(m), 3)
6435+
6436+ m = np.array([[1, 2, 3], [4, 5, 7]])
6437+ assert_equal(np.alen(m), 2)
6438+
6439+ m = [1, 2, 3]
6440+ assert_equal(np.alen(m), 3)
6441+
6442+ m = [[1, 2, 3], [4, 5, 7]]
6443+ assert_equal(np.alen(m), 2)
6444+
6445+ def test_singleton(self):
6446+ with pytest.warns(DeprecationWarning):
6447+ assert_equal(np.alen(5), 1)
6448+
6449+
6450+class TestChoose:
6451+ def setup(self):
6452+ self.x = 2*np.ones((3,), dtype=int)
6453+ self.y = 3*np.ones((3,), dtype=int)
6454+ self.x2 = 2*np.ones((2, 3), dtype=int)
6455+ self.y2 = 3*np.ones((2, 3), dtype=int)
6456+ self.ind = [0, 0, 1]
6457+
6458+ def test_basic(self):
6459+ A = np.choose(self.ind, (self.x, self.y))
6460+ assert_equal(A, [2, 2, 3])
6461+
6462+ def test_broadcast1(self):
6463+ A = np.choose(self.ind, (self.x2, self.y2))
6464+ assert_equal(A, [[2, 2, 3], [2, 2, 3]])
6465+
6466+ def test_broadcast2(self):
6467+ A = np.choose(self.ind, (self.x, self.y2))
6468+ assert_equal(A, [[2, 2, 3], [2, 2, 3]])
6469+
6470+ @pytest.mark.parametrize("ops",
6471+ [(1000, np.array([1], dtype=np.uint8)),
6472+ (-1, np.array([1], dtype=np.uint8)),
6473+ (1., np.float32(3)),
6474+ (1., np.array([3], dtype=np.float32))],)
6475+ def test_output_dtype(self, ops):
6476+ expected_dt = np.result_type(*ops)
6477+ assert(np.choose([0], ops).dtype == expected_dt)
6478+
6479+
6480+class TestRepeat:
6481+ def setup(self):
6482+ self.m = np.array([1, 2, 3, 4, 5, 6])
6483+ self.m_rect = self.m.reshape((2, 3))
6484+
6485+ def test_basic(self):
6486+ A = np.repeat(self.m, [1, 3, 2, 1, 1, 2])
6487+ assert_equal(A, [1, 2, 2, 2, 3,
6488+ 3, 4, 5, 6, 6])
6489+
6490+ def test_broadcast1(self):
6491+ A = np.repeat(self.m, 2)
6492+ assert_equal(A, [1, 1, 2, 2, 3, 3,
6493+ 4, 4, 5, 5, 6, 6])
6494+
6495+ def test_axis_spec(self):
6496+ A = np.repeat(self.m_rect, [2, 1], axis=0)
6497+ assert_equal(A, [[1, 2, 3],
6498+ [1, 2, 3],
6499+ [4, 5, 6]])
6500+
6501+ A = np.repeat(self.m_rect, [1, 3, 2], axis=1)
6502+ assert_equal(A, [[1, 2, 2, 2, 3, 3],
6503+ [4, 5, 5, 5, 6, 6]])
6504+
6505+ def test_broadcast2(self):
6506+ A = np.repeat(self.m_rect, 2, axis=0)
6507+ assert_equal(A, [[1, 2, 3],
6508+ [1, 2, 3],
6509+ [4, 5, 6],
6510+ [4, 5, 6]])
6511+
6512+ A = np.repeat(self.m_rect, 2, axis=1)
6513+ assert_equal(A, [[1, 1, 2, 2, 3, 3],
6514+ [4, 4, 5, 5, 6, 6]])
6515+
6516+
6517+# TODO: test for multidimensional
6518+NEIGH_MODE = {'zero': 0, 'one': 1, 'constant': 2, 'circular': 3, 'mirror': 4}
6519+
6520+
6521+@pytest.mark.parametrize('dt', [float, Decimal], ids=['float', 'object'])
6522+class TestNeighborhoodIter:
6523+ # Simple, 2d tests
6524+ def test_simple2d(self, dt):
6525+ # Test zero and one padding for simple data type
6526+ x = np.array([[0, 1], [2, 3]], dtype=dt)
6527+ r = [np.array([[0, 0, 0], [0, 0, 1]], dtype=dt),
6528+ np.array([[0, 0, 0], [0, 1, 0]], dtype=dt),
6529+ np.array([[0, 0, 1], [0, 2, 3]], dtype=dt),
6530+ np.array([[0, 1, 0], [2, 3, 0]], dtype=dt)]
6531+ l = _multiarray_tests.test_neighborhood_iterator(
6532+ x, [-1, 0, -1, 1], x[0], NEIGH_MODE['zero'])
6533+ assert_array_equal(l, r)
6534+
6535+ r = [np.array([[1, 1, 1], [1, 0, 1]], dtype=dt),
6536+ np.array([[1, 1, 1], [0, 1, 1]], dtype=dt),
6537+ np.array([[1, 0, 1], [1, 2, 3]], dtype=dt),
6538+ np.array([[0, 1, 1], [2, 3, 1]], dtype=dt)]
6539+ l = _multiarray_tests.test_neighborhood_iterator(
6540+ x, [-1, 0, -1, 1], x[0], NEIGH_MODE['one'])
6541+ assert_array_equal(l, r)
6542+
6543+ r = [np.array([[4, 4, 4], [4, 0, 1]], dtype=dt),
6544+ np.array([[4, 4, 4], [0, 1, 4]], dtype=dt),
6545+ np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
6546+ np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
6547+ l = _multiarray_tests.test_neighborhood_iterator(
6548+ x, [-1, 0, -1, 1], 4, NEIGH_MODE['constant'])
6549+ assert_array_equal(l, r)
6550+
6551+ def test_mirror2d(self, dt):
6552+ x = np.array([[0, 1], [2, 3]], dtype=dt)
6553+ r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
6554+ np.array([[0, 1, 1], [0, 1, 1]], dtype=dt),
6555+ np.array([[0, 0, 1], [2, 2, 3]], dtype=dt),
6556+ np.array([[0, 1, 1], [2, 3, 3]], dtype=dt)]
6557+ l = _multiarray_tests.test_neighborhood_iterator(
6558+ x, [-1, 0, -1, 1], x[0], NEIGH_MODE['mirror'])
6559+ assert_array_equal(l, r)
6560+
6561+ # Simple, 1d tests
6562+ def test_simple(self, dt):
6563+ # Test padding with constant values
6564+ x = np.linspace(1, 5, 5).astype(dt)
6565+ r = [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 0]]
6566+ l = _multiarray_tests.test_neighborhood_iterator(
6567+ x, [-1, 1], x[0], NEIGH_MODE['zero'])
6568+ assert_array_equal(l, r)
6569+
6570+ r = [[1, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 1]]
6571+ l = _multiarray_tests.test_neighborhood_iterator(
6572+ x, [-1, 1], x[0], NEIGH_MODE['one'])
6573+ assert_array_equal(l, r)
6574+
6575+ r = [[x[4], 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, x[4]]]
6576+ l = _multiarray_tests.test_neighborhood_iterator(
6577+ x, [-1, 1], x[4], NEIGH_MODE['constant'])
6578+ assert_array_equal(l, r)
6579+
6580+ # Test mirror modes
6581+ def test_mirror(self, dt):
6582+ x = np.linspace(1, 5, 5).astype(dt)
6583+ r = np.array([[2, 1, 1, 2, 3], [1, 1, 2, 3, 4], [1, 2, 3, 4, 5],
6584+ [2, 3, 4, 5, 5], [3, 4, 5, 5, 4]], dtype=dt)
6585+ l = _multiarray_tests.test_neighborhood_iterator(
6586+ x, [-2, 2], x[1], NEIGH_MODE['mirror'])
6587+ assert_([i.dtype == dt for i in l])
6588+ assert_array_equal(l, r)
6589+
6590+ # Circular mode
6591+ def test_circular(self, dt):
6592+ x = np.linspace(1, 5, 5).astype(dt)
6593+ r = np.array([[4, 5, 1, 2, 3], [5, 1, 2, 3, 4], [1, 2, 3, 4, 5],
6594+ [2, 3, 4, 5, 1], [3, 4, 5, 1, 2]], dtype=dt)
6595+ l = _multiarray_tests.test_neighborhood_iterator(
6596+ x, [-2, 2], x[0], NEIGH_MODE['circular'])
6597+ assert_array_equal(l, r)
6598+
6599+
6600+# Test stacking neighborhood iterators
6601+class TestStackedNeighborhoodIter:
6602+ # Simple, 1d test: stacking 2 constant-padded neigh iterators
6603+ def test_simple_const(self):
6604+ dt = np.float64
6605+ # Test zero and one padding for simple data type
6606+ x = np.array([1, 2, 3], dtype=dt)
6607+ r = [np.array([0], dtype=dt),
6608+ np.array([0], dtype=dt),
6609+ np.array([1], dtype=dt),
6610+ np.array([2], dtype=dt),
6611+ np.array([3], dtype=dt),
6612+ np.array([0], dtype=dt),
6613+ np.array([0], dtype=dt)]
6614+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6615+ x, [-2, 4], NEIGH_MODE['zero'], [0, 0], NEIGH_MODE['zero'])
6616+ assert_array_equal(l, r)
6617+
6618+ r = [np.array([1, 0, 1], dtype=dt),
6619+ np.array([0, 1, 2], dtype=dt),
6620+ np.array([1, 2, 3], dtype=dt),
6621+ np.array([2, 3, 0], dtype=dt),
6622+ np.array([3, 0, 1], dtype=dt)]
6623+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6624+ x, [-1, 3], NEIGH_MODE['zero'], [-1, 1], NEIGH_MODE['one'])
6625+ assert_array_equal(l, r)
6626+
6627+ # 2nd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
6628+ # mirror padding
6629+ def test_simple_mirror(self):
6630+ dt = np.float64
6631+ # Stacking zero on top of mirror
6632+ x = np.array([1, 2, 3], dtype=dt)
6633+ r = [np.array([0, 1, 1], dtype=dt),
6634+ np.array([1, 1, 2], dtype=dt),
6635+ np.array([1, 2, 3], dtype=dt),
6636+ np.array([2, 3, 3], dtype=dt),
6637+ np.array([3, 3, 0], dtype=dt)]
6638+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6639+ x, [-1, 3], NEIGH_MODE['mirror'], [-1, 1], NEIGH_MODE['zero'])
6640+ assert_array_equal(l, r)
6641+
6642+ # Stacking mirror on top of zero
6643+ x = np.array([1, 2, 3], dtype=dt)
6644+ r = [np.array([1, 0, 0], dtype=dt),
6645+ np.array([0, 0, 1], dtype=dt),
6646+ np.array([0, 1, 2], dtype=dt),
6647+ np.array([1, 2, 3], dtype=dt),
6648+ np.array([2, 3, 0], dtype=dt)]
6649+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6650+ x, [-1, 3], NEIGH_MODE['zero'], [-2, 0], NEIGH_MODE['mirror'])
6651+ assert_array_equal(l, r)
6652+
6653+ # Stacking mirror on top of zero: 2nd
6654+ x = np.array([1, 2, 3], dtype=dt)
6655+ r = [np.array([0, 1, 2], dtype=dt),
6656+ np.array([1, 2, 3], dtype=dt),
6657+ np.array([2, 3, 0], dtype=dt),
6658+ np.array([3, 0, 0], dtype=dt),
6659+ np.array([0, 0, 3], dtype=dt)]
6660+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6661+ x, [-1, 3], NEIGH_MODE['zero'], [0, 2], NEIGH_MODE['mirror'])
6662+ assert_array_equal(l, r)
6663+
6664+ # Stacking mirror on top of zero: 3rd
6665+ x = np.array([1, 2, 3], dtype=dt)
6666+ r = [np.array([1, 0, 0, 1, 2], dtype=dt),
6667+ np.array([0, 0, 1, 2, 3], dtype=dt),
6668+ np.array([0, 1, 2, 3, 0], dtype=dt),
6669+ np.array([1, 2, 3, 0, 0], dtype=dt),
6670+ np.array([2, 3, 0, 0, 3], dtype=dt)]
6671+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6672+ x, [-1, 3], NEIGH_MODE['zero'], [-2, 2], NEIGH_MODE['mirror'])
6673+ assert_array_equal(l, r)
6674+
6675+ # 3rd simple, 1d test: stacking 2 neigh iterators, mixing const padding and
6676+ # circular padding
6677+ def test_simple_circular(self):
6678+ dt = np.float64
6679+ # Stacking zero on top of mirror
6680+ x = np.array([1, 2, 3], dtype=dt)
6681+ r = [np.array([0, 3, 1], dtype=dt),
6682+ np.array([3, 1, 2], dtype=dt),
6683+ np.array([1, 2, 3], dtype=dt),
6684+ np.array([2, 3, 1], dtype=dt),
6685+ np.array([3, 1, 0], dtype=dt)]
6686+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6687+ x, [-1, 3], NEIGH_MODE['circular'], [-1, 1], NEIGH_MODE['zero'])
6688+ assert_array_equal(l, r)
6689+
6690+ # Stacking mirror on top of zero
6691+ x = np.array([1, 2, 3], dtype=dt)
6692+ r = [np.array([3, 0, 0], dtype=dt),
6693+ np.array([0, 0, 1], dtype=dt),
6694+ np.array([0, 1, 2], dtype=dt),
6695+ np.array([1, 2, 3], dtype=dt),
6696+ np.array([2, 3, 0], dtype=dt)]
6697+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6698+ x, [-1, 3], NEIGH_MODE['zero'], [-2, 0], NEIGH_MODE['circular'])
6699+ assert_array_equal(l, r)
6700+
6701+ # Stacking mirror on top of zero: 2nd
6702+ x = np.array([1, 2, 3], dtype=dt)
6703+ r = [np.array([0, 1, 2], dtype=dt),
6704+ np.array([1, 2, 3], dtype=dt),
6705+ np.array([2, 3, 0], dtype=dt),
6706+ np.array([3, 0, 0], dtype=dt),
6707+ np.array([0, 0, 1], dtype=dt)]
6708+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6709+ x, [-1, 3], NEIGH_MODE['zero'], [0, 2], NEIGH_MODE['circular'])
6710+ assert_array_equal(l, r)
6711+
6712+ # Stacking mirror on top of zero: 3rd
6713+ x = np.array([1, 2, 3], dtype=dt)
6714+ r = [np.array([3, 0, 0, 1, 2], dtype=dt),
6715+ np.array([0, 0, 1, 2, 3], dtype=dt),
6716+ np.array([0, 1, 2, 3, 0], dtype=dt),
6717+ np.array([1, 2, 3, 0, 0], dtype=dt),
6718+ np.array([2, 3, 0, 0, 1], dtype=dt)]
6719+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6720+ x, [-1, 3], NEIGH_MODE['zero'], [-2, 2], NEIGH_MODE['circular'])
6721+ assert_array_equal(l, r)
6722+
6723+ # 4th simple, 1d test: stacking 2 neigh iterators, but with lower iterator
6724+ # being strictly within the array
6725+ def test_simple_strict_within(self):
6726+ dt = np.float64
6727+ # Stacking zero on top of zero, first neighborhood strictly inside the
6728+ # array
6729+ x = np.array([1, 2, 3], dtype=dt)
6730+ r = [np.array([1, 2, 3, 0], dtype=dt)]
6731+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6732+ x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['zero'])
6733+ assert_array_equal(l, r)
6734+
6735+ # Stacking mirror on top of zero, first neighborhood strictly inside the
6736+ # array
6737+ x = np.array([1, 2, 3], dtype=dt)
6738+ r = [np.array([1, 2, 3, 3], dtype=dt)]
6739+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6740+ x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['mirror'])
6741+ assert_array_equal(l, r)
6742+
6743+ # Stacking mirror on top of zero, first neighborhood strictly inside the
6744+ # array
6745+ x = np.array([1, 2, 3], dtype=dt)
6746+ r = [np.array([1, 2, 3, 1], dtype=dt)]
6747+ l = _multiarray_tests.test_neighborhood_iterator_oob(
6748+ x, [1, 1], NEIGH_MODE['zero'], [-1, 2], NEIGH_MODE['circular'])
6749+ assert_array_equal(l, r)
6750+
6751+class TestWarnings:
6752+
6753+ def test_complex_warning(self):
6754+ x = np.array([1, 2])
6755+ y = np.array([1-2j, 1+2j])
6756+
6757+ with warnings.catch_warnings():
6758+ warnings.simplefilter("error", np.ComplexWarning)
6759+ assert_raises(np.ComplexWarning, x.__setitem__, slice(None), y)
6760+ assert_equal(x, [1, 2])
6761+
6762+
6763+class TestMinScalarType:
6764+
6765+ def test_usigned_shortshort(self):
6766+ dt = np.min_scalar_type(2**8-1)
6767+ wanted = np.dtype('uint8')
6768+ assert_equal(wanted, dt)
6769+
6770+ def test_usigned_short(self):
6771+ dt = np.min_scalar_type(2**16-1)
6772+ wanted = np.dtype('uint16')
6773+ assert_equal(wanted, dt)
6774+
6775+ def test_usigned_int(self):
6776+ dt = np.min_scalar_type(2**32-1)
6777+ wanted = np.dtype('uint32')
6778+ assert_equal(wanted, dt)
6779+
6780+ def test_usigned_longlong(self):
6781+ dt = np.min_scalar_type(2**63-1)
6782+ wanted = np.dtype('uint64')
6783+ assert_equal(wanted, dt)
6784+
6785+ def test_object(self):
6786+ dt = np.min_scalar_type(2**64)
6787+ wanted = np.dtype('O')
6788+ assert_equal(wanted, dt)
6789+
6790+
6791+from numpy.core._internal import _dtype_from_pep3118
6792+
6793+
6794+class TestPEP3118Dtype:
6795+ def _check(self, spec, wanted):
6796+ dt = np.dtype(wanted)
6797+ actual = _dtype_from_pep3118(spec)
6798+ assert_equal(actual, dt,
6799+ err_msg="spec %r != dtype %r" % (spec, wanted))
6800+
6801+ def test_native_padding(self):
6802+ align = np.dtype('i').alignment
6803+ for j in range(8):
6804+ if j == 0:
6805+ s = 'bi'
6806+ else:
6807+ s = 'b%dxi' % j
6808+ self._check('@'+s, {'f0': ('i1', 0),
6809+ 'f1': ('i', align*(1 + j//align))})
6810+ self._check('='+s, {'f0': ('i1', 0),
6811+ 'f1': ('i', 1+j)})
6812+
6813+ def test_native_padding_2(self):
6814+ # Native padding should work also for structs and sub-arrays
6815+ self._check('x3T{xi}', {'f0': (({'f0': ('i', 4)}, (3,)), 4)})
6816+ self._check('^x3T{xi}', {'f0': (({'f0': ('i', 1)}, (3,)), 1)})
6817+
6818+ def test_trailing_padding(self):
6819+ # Trailing padding should be included, *and*, the item size
6820+ # should match the alignment if in aligned mode
6821+ align = np.dtype('i').alignment
6822+ size = np.dtype('i').itemsize
6823+
6824+ def aligned(n):
6825+ return align*(1 + (n-1)//align)
6826+
6827+ base = dict(formats=['i'], names=['f0'])
6828+
6829+ self._check('ix', dict(itemsize=aligned(size + 1), **base))
6830+ self._check('ixx', dict(itemsize=aligned(size + 2), **base))
6831+ self._check('ixxx', dict(itemsize=aligned(size + 3), **base))
6832+ self._check('ixxxx', dict(itemsize=aligned(size + 4), **base))
6833+ self._check('i7x', dict(itemsize=aligned(size + 7), **base))
6834+
6835+ self._check('^ix', dict(itemsize=size + 1, **base))
6836+ self._check('^ixx', dict(itemsize=size + 2, **base))
6837+ self._check('^ixxx', dict(itemsize=size + 3, **base))
6838+ self._check('^ixxxx', dict(itemsize=size + 4, **base))
6839+ self._check('^i7x', dict(itemsize=size + 7, **base))
6840+
6841+ def test_native_padding_3(self):
6842+ dt = np.dtype(
6843+ [('a', 'b'), ('b', 'i'),
6844+ ('sub', np.dtype('b,i')), ('c', 'i')],
6845+ align=True)
6846+ self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
6847+
6848+ dt = np.dtype(
6849+ [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
6850+ ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
6851+ self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
6852+
6853+ def test_padding_with_array_inside_struct(self):
6854+ dt = np.dtype(
6855+ [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)),
6856+ ('d', 'i')],
6857+ align=True)
6858+ self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
6859+
6860+ def test_byteorder_inside_struct(self):
6861+ # The byte order after @T{=i} should be '=', not '@'.
6862+ # Check this by noting the absence of native alignment.
6863+ self._check('@T{^i}xi', {'f0': ({'f0': ('i', 0)}, 0),
6864+ 'f1': ('i', 5)})
6865+
6866+ def test_intra_padding(self):
6867+ # Natively aligned sub-arrays may require some internal padding
6868+ align = np.dtype('i').alignment
6869+ size = np.dtype('i').itemsize
6870+
6871+ def aligned(n):
6872+ return (align*(1 + (n-1)//align))
6873+
6874+ self._check('(3)T{ix}', (dict(
6875+ names=['f0'],
6876+ formats=['i'],
6877+ offsets=[0],
6878+ itemsize=aligned(size + 1)
6879+ ), (3,)))
6880+
6881+ def test_char_vs_string(self):
6882+ dt = np.dtype('c')
6883+ self._check('c', dt)
6884+
6885+ dt = np.dtype([('f0', 'S1', (4,)), ('f1', 'S4')])
6886+ self._check('4c4s', dt)
6887+
6888+ def test_field_order(self):
6889+ # gh-9053 - previously, we relied on dictionary key order
6890+ self._check("(0)I:a:f:b:", [('a', 'I', (0,)), ('b', 'f')])
6891+ self._check("(0)I:b:f:a:", [('b', 'I', (0,)), ('a', 'f')])
6892+
6893+ def test_unnamed_fields(self):
6894+ self._check('ii', [('f0', 'i'), ('f1', 'i')])
6895+ self._check('ii:f0:', [('f1', 'i'), ('f0', 'i')])
6896+
6897+ self._check('i', 'i')
6898+ self._check('i:f0:', [('f0', 'i')])
6899+
6900+
6901+class TestNewBufferProtocol:
6902+ """ Test PEP3118 buffers """
6903+
6904+ def _check_roundtrip(self, obj):
6905+ obj = np.asarray(obj)
6906+ x = memoryview(obj)
6907+ y = np.asarray(x)
6908+ y2 = np.array(x)
6909+ assert_(not y.flags.owndata)
6910+ assert_(y2.flags.owndata)
6911+
6912+ assert_equal(y.dtype, obj.dtype)
6913+ assert_equal(y.shape, obj.shape)
6914+ assert_array_equal(obj, y)
6915+
6916+ assert_equal(y2.dtype, obj.dtype)
6917+ assert_equal(y2.shape, obj.shape)
6918+ assert_array_equal(obj, y2)
6919+
6920+ def test_roundtrip(self):
6921+ x = np.array([1, 2, 3, 4, 5], dtype='i4')
6922+ self._check_roundtrip(x)
6923+
6924+ x = np.array([[1, 2], [3, 4]], dtype=np.float64)
6925+ self._check_roundtrip(x)
6926+
6927+ x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
6928+ self._check_roundtrip(x)
6929+
6930+ dt = [('a', 'b'),
6931+ ('b', 'h'),
6932+ ('c', 'i'),
6933+ ('d', 'l'),
6934+ ('dx', 'q'),
6935+ ('e', 'B'),
6936+ ('f', 'H'),
6937+ ('g', 'I'),
6938+ ('h', 'L'),
6939+ ('hx', 'Q'),
6940+ ('i', np.single),
6941+ ('j', np.double),
6942+ ('k', np.longdouble),
6943+ ('ix', np.csingle),
6944+ ('jx', np.cdouble),
6945+ ('kx', np.clongdouble),
6946+ ('l', 'S4'),
6947+ ('m', 'U4'),
6948+ ('n', 'V3'),
6949+ ('o', '?'),
6950+ ('p', np.half),
6951+ ]
6952+ x = np.array(
6953+ [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
6954+ b'aaaa', 'bbbb', b'xxx', True, 1.0)],
6955+ dtype=dt)
6956+ self._check_roundtrip(x)
6957+
6958+ x = np.array(([[1, 2], [3, 4]],), dtype=[('a', (int, (2, 2)))])
6959+ self._check_roundtrip(x)
6960+
6961+ x = np.array([1, 2, 3], dtype='>i2')
6962+ self._check_roundtrip(x)
6963+
6964+ x = np.array([1, 2, 3], dtype='<i2')
6965+ self._check_roundtrip(x)
6966+
6967+ x = np.array([1, 2, 3], dtype='>i4')
6968+ self._check_roundtrip(x)
6969+
6970+ x = np.array([1, 2, 3], dtype='<i4')
6971+ self._check_roundtrip(x)
6972+
6973+ # check long long can be represented as non-native
6974+ x = np.array([1, 2, 3], dtype='>q')
6975+ self._check_roundtrip(x)
6976+
6977+ # Native-only data types can be passed through the buffer interface
6978+ # only in native byte order
6979+ if sys.byteorder == 'little':
6980+ x = np.array([1, 2, 3], dtype='>g')
6981+ assert_raises(ValueError, self._check_roundtrip, x)
6982+ x = np.array([1, 2, 3], dtype='<g')
6983+ self._check_roundtrip(x)
6984+ else:
6985+ x = np.array([1, 2, 3], dtype='>g')
6986+ self._check_roundtrip(x)
6987+ x = np.array([1, 2, 3], dtype='<g')
6988+ assert_raises(ValueError, self._check_roundtrip, x)
6989+
6990+ def test_roundtrip_half(self):
6991+ half_list = [
6992+ 1.0,
6993+ -2.0,
6994+ 6.5504 * 10**4, # (max half precision)
6995+ 2**-14, # ~= 6.10352 * 10**-5 (minimum positive normal)
6996+ 2**-24, # ~= 5.96046 * 10**-8 (minimum strictly positive subnormal)
6997+ 0.0,
6998+ -0.0,
6999+ float('+inf'),
7000+ float('-inf'),
7001+ 0.333251953125, # ~= 1/3
7002+ ]
7003+
7004+ x = np.array(half_list, dtype='>e')
7005+ self._check_roundtrip(x)
7006+ x = np.array(half_list, dtype='<e')
7007+ self._check_roundtrip(x)
7008+
7009+ def test_roundtrip_single_types(self):
7010+ for typ in np.typeDict.values():
7011+ dtype = np.dtype(typ)
7012+
7013+ if dtype.char in 'Mm':
7014+ # datetimes cannot be used in buffers
7015+ continue
7016+ if dtype.char == 'V':
7017+ # skip void
7018+ continue
7019+
7020+ x = np.zeros(4, dtype=dtype)
7021+ self._check_roundtrip(x)
7022+
7023+ if dtype.char not in 'qQgG':
7024+ dt = dtype.newbyteorder('<')
7025+ x = np.zeros(4, dtype=dt)
7026+ self._check_roundtrip(x)
7027+
7028+ dt = dtype.newbyteorder('>')
7029+ x = np.zeros(4, dtype=dt)
7030+ self._check_roundtrip(x)
7031+
7032+ def test_roundtrip_scalar(self):
7033+ # Issue #4015.
7034+ self._check_roundtrip(0)
7035+
7036+ def test_invalid_buffer_format(self):
7037+ # datetime64 cannot be used fully in a buffer yet
7038+ # Should be fixed in the next Numpy major release
7039+ dt = np.dtype([('a', 'uint16'), ('b', 'M8[s]')])
7040+ a = np.empty(3, dt)
7041+ assert_raises((ValueError, BufferError), memoryview, a)
7042+ assert_raises((ValueError, BufferError), memoryview, np.array((3), 'M8[D]'))
7043+
7044+ def test_export_simple_1d(self):
7045+ x = np.array([1, 2, 3, 4, 5], dtype='i')
7046+ y = memoryview(x)
7047+ assert_equal(y.format, 'i')
7048+ assert_equal(y.shape, (5,))
7049+ assert_equal(y.ndim, 1)
7050+ assert_equal(y.strides, (4,))
7051+ assert_equal(y.suboffsets, ())
7052+ assert_equal(y.itemsize, 4)
7053+
7054+ def test_export_simple_nd(self):
7055+ x = np.array([[1, 2], [3, 4]], dtype=np.float64)
7056+ y = memoryview(x)
7057+ assert_equal(y.format, 'd')
7058+ assert_equal(y.shape, (2, 2))
7059+ assert_equal(y.ndim, 2)
7060+ assert_equal(y.strides, (16, 8))
7061+ assert_equal(y.suboffsets, ())
7062+ assert_equal(y.itemsize, 8)
7063+
7064+ def test_export_discontiguous(self):
7065+ x = np.zeros((3, 3, 3), dtype=np.float32)[:, 0,:]
7066+ y = memoryview(x)
7067+ assert_equal(y.format, 'f')
7068+ assert_equal(y.shape, (3, 3))
7069+ assert_equal(y.ndim, 2)
7070+ assert_equal(y.strides, (36, 4))
7071+ assert_equal(y.suboffsets, ())
7072+ assert_equal(y.itemsize, 4)
7073+
7074+ def test_export_record(self):
7075+ dt = [('a', 'b'),
7076+ ('b', 'h'),
7077+ ('c', 'i'),
7078+ ('d', 'l'),
7079+ ('dx', 'q'),
7080+ ('e', 'B'),
7081+ ('f', 'H'),
7082+ ('g', 'I'),
7083+ ('h', 'L'),
7084+ ('hx', 'Q'),
7085+ ('i', np.single),
7086+ ('j', np.double),
7087+ ('k', np.longdouble),
7088+ ('ix', np.csingle),
7089+ ('jx', np.cdouble),
7090+ ('kx', np.clongdouble),
7091+ ('l', 'S4'),
7092+ ('m', 'U4'),
7093+ ('n', 'V3'),
7094+ ('o', '?'),
7095+ ('p', np.half),
7096+ ]
7097+ x = np.array(
7098+ [(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
7099+ b'aaaa', 'bbbb', b' ', True, 1.0)],
7100+ dtype=dt)
7101+ y = memoryview(x)
7102+ assert_equal(y.shape, (1,))
7103+ assert_equal(y.ndim, 1)
7104+ assert_equal(y.suboffsets, ())
7105+
7106+ sz = sum([np.dtype(b).itemsize for a, b in dt])
7107+ if np.dtype('l').itemsize == 4:
7108+ assert_equal(y.format, 'T{b:a:=h:b:i:c:l:d:q:dx:B:e:@H:f:=I:g:L:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
7109+ else:
7110+ assert_equal(y.format, 'T{b:a:=h:b:i:c:q:d:q:dx:B:e:@H:f:=I:g:Q:h:Q:hx:f:i:d:j:^g:k:=Zf:ix:Zd:jx:^Zg:kx:4s:l:=4w:m:3x:n:?:o:@e:p:}')
7111+ # Cannot test if NPY_RELAXED_STRIDES_CHECKING changes the strides
7112+ if not (np.ones(1).strides[0] == np.iinfo(np.intp).max):
7113+ assert_equal(y.strides, (sz,))
7114+ assert_equal(y.itemsize, sz)
7115+
7116+ def test_export_subarray(self):
7117+ x = np.array(([[1, 2], [3, 4]],), dtype=[('a', ('i', (2, 2)))])
7118+ y = memoryview(x)
7119+ assert_equal(y.format, 'T{(2,2)i:a:}')
7120+ assert_equal(y.shape, ())
7121+ assert_equal(y.ndim, 0)
7122+ assert_equal(y.strides, ())
7123+ assert_equal(y.suboffsets, ())
7124+ assert_equal(y.itemsize, 16)
7125+
7126+ def test_export_endian(self):
7127+ x = np.array([1, 2, 3], dtype='>i')
7128+ y = memoryview(x)
7129+ if sys.byteorder == 'little':
7130+ assert_equal(y.format, '>i')
7131+ else:
7132+ assert_equal(y.format, 'i')
7133+
7134+ x = np.array([1, 2, 3], dtype='<i')
7135+ y = memoryview(x)
7136+ if sys.byteorder == 'little':
7137+ assert_equal(y.format, 'i')
7138+ else:
7139+ assert_equal(y.format, '<i')
7140+
7141+ def test_export_flags(self):
7142+ # Check SIMPLE flag, see also gh-3613 (exception should be BufferError)
7143+ assert_raises(ValueError,
7144+ _multiarray_tests.get_buffer_info,
7145+ np.arange(5)[::2], ('SIMPLE',))
7146+
7147+ def test_padding(self):
7148+ for j in range(8):
7149+ x = np.array([(1,), (2,)], dtype={'f0': (int, j)})
7150+ self._check_roundtrip(x)
7151+
7152+ def test_reference_leak(self):
7153+ if HAS_REFCOUNT:
7154+ count_1 = sys.getrefcount(np.core._internal)
7155+ a = np.zeros(4)
7156+ b = memoryview(a)
7157+ c = np.asarray(b)
7158+ if HAS_REFCOUNT:
7159+ count_2 = sys.getrefcount(np.core._internal)
7160+ assert_equal(count_1, count_2)
7161+ del c # avoid pyflakes unused variable warning.
7162+
7163+ def test_padded_struct_array(self):
7164+ dt1 = np.dtype(
7165+ [('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')],
7166+ align=True)
7167+ x1 = np.arange(dt1.itemsize, dtype=np.int8).view(dt1)
7168+ self._check_roundtrip(x1)
7169+
7170+ dt2 = np.dtype(
7171+ [('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')],
7172+ align=True)
7173+ x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
7174+ self._check_roundtrip(x2)
7175+
7176+ dt3 = np.dtype(
7177+ [('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'),
7178+ ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
7179+ x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
7180+ self._check_roundtrip(x3)
7181+
7182+ @pytest.mark.valgrind_error(reason="leaks buffer info cache temporarily.")
7183+ def test_relaxed_strides(self, c=np.ones((1, 10, 10), dtype='i8')):
7184+ # Note: c defined as parameter so that it is persistent and leak
7185+ # checks will notice gh-16934 (buffer info cache leak).
7186+
7187+ # Check for NPY_RELAXED_STRIDES_CHECKING:
7188+ if np.ones((10, 1), order="C").flags.f_contiguous:
7189+ c.strides = (-1, 80, 8)
7190+
7191+ assert_(memoryview(c).strides == (800, 80, 8))
7192+
7193+ # Writing C-contiguous data to a BytesIO buffer should work
7194+ fd = io.BytesIO()
7195+ fd.write(c.data)
7196+
7197+ fortran = c.T
7198+ assert_(memoryview(fortran).strides == (8, 80, 800))
7199+
7200+ arr = np.ones((1, 10))
7201+ if arr.flags.f_contiguous:
7202+ shape, strides = _multiarray_tests.get_buffer_info(
7203+ arr, ['F_CONTIGUOUS'])
7204+ assert_(strides[0] == 8)
7205+ arr = np.ones((10, 1), order='F')
7206+ shape, strides = _multiarray_tests.get_buffer_info(
7207+ arr, ['C_CONTIGUOUS'])
7208+ assert_(strides[-1] == 8)
7209+
7210+ @pytest.mark.valgrind_error(reason="leaks buffer info cache temporarily.")
7211+ @pytest.mark.skipif(not np.ones((10, 1), order="C").flags.f_contiguous,
7212+ reason="Test is unnecessary (but fails) without relaxed strides.")
7213+ def test_relaxed_strides_buffer_info_leak(self, arr=np.ones((1, 10))):
7214+ """Test that alternating export of C- and F-order buffers from
7215+ an array which is both C- and F-order when relaxed strides is
7216+ active works.
7217+ This test defines array in the signature to ensure leaking more
7218+ references every time the test is run (catching the leak with
7219+ pytest-leaks).
7220+ """
7221+ for i in range(10):
7222+ _, s = _multiarray_tests.get_buffer_info(arr, ['F_CONTIGUOUS'])
7223+ assert s == (8, 8)
7224+ _, s = _multiarray_tests.get_buffer_info(arr, ['C_CONTIGUOUS'])
7225+ assert s == (80, 8)
7226+
7227+ def test_out_of_order_fields(self):
7228+ dt = np.dtype(dict(
7229+ formats=['<i4', '<i4'],
7230+ names=['one', 'two'],
7231+ offsets=[4, 0],
7232+ itemsize=8
7233+ ))
7234+
7235+ # overlapping fields cannot be represented by PEP3118
7236+ arr = np.empty(1, dt)
7237+ with assert_raises(ValueError):
7238+ memoryview(arr)
7239+
7240+ def test_max_dims(self):
7241+ a = np.empty((1,) * 32)
7242+ self._check_roundtrip(a)
7243+
7244+ @pytest.mark.slow
7245+ def test_error_too_many_dims(self):
7246+ def make_ctype(shape, scalar_type):
7247+ t = scalar_type
7248+ for dim in shape[::-1]:
7249+ t = dim * t
7250+ return t
7251+
7252+ # construct a memoryview with 33 dimensions
7253+ c_u8_33d = make_ctype((1,)*33, ctypes.c_uint8)
7254+ m = memoryview(c_u8_33d())
7255+ assert_equal(m.ndim, 33)
7256+
7257+ assert_raises_regex(
7258+ RuntimeError, "ndim",
7259+ np.array, m)
7260+
7261+ # The above seems to create some deep cycles, clean them up for
7262+ # easier reference count debugging:
7263+ del c_u8_33d, m
7264+ for i in range(33):
7265+ if gc.collect() == 0:
7266+ break
7267+
7268+ def test_error_pointer_type(self):
7269+ # gh-6741
7270+ m = memoryview(ctypes.pointer(ctypes.c_uint8()))
7271+ assert_('&' in m.format)
7272+
7273+ assert_raises_regex(
7274+ ValueError, "format string",
7275+ np.array, m)
7276+
7277+ def test_error_message_unsupported(self):
7278+ # wchar has no corresponding numpy type - if this changes in future, we
7279+ # need a better way to construct an invalid memoryview format.
7280+ t = ctypes.c_wchar * 4
7281+ with assert_raises(ValueError) as cm:
7282+ np.array(t())
7283+
7284+ exc = cm.exception
7285+ with assert_raises_regex(
7286+ NotImplementedError,
7287+ r"Unrepresentable .* 'u' \(UCS-2 strings\)"
7288+ ):
7289+ raise exc.__cause__
7290+
7291+ def test_ctypes_integer_via_memoryview(self):
7292+ # gh-11150, due to bpo-10746
7293+ for c_integer in {ctypes.c_int, ctypes.c_long, ctypes.c_longlong}:
7294+ value = c_integer(42)
7295+ with warnings.catch_warnings(record=True):
7296+ warnings.filterwarnings('always', r'.*\bctypes\b', RuntimeWarning)
7297+ np.asarray(value)
7298+
7299+ def test_ctypes_struct_via_memoryview(self):
7300+ # gh-10528
7301+ class foo(ctypes.Structure):
7302+ _fields_ = [('a', ctypes.c_uint8), ('b', ctypes.c_uint32)]
7303+ f = foo(a=1, b=2)
7304+
7305+ with warnings.catch_warnings(record=True):
7306+ warnings.filterwarnings('always', r'.*\bctypes\b', RuntimeWarning)
7307+ arr = np.asarray(f)
7308+
7309+ assert_equal(arr['a'], 1)
7310+ assert_equal(arr['b'], 2)
7311+ f.a = 3
7312+ assert_equal(arr['a'], 3)
7313+
7314+
7315+class TestArrayAttributeDeletion:
7316+
7317+ def test_multiarray_writable_attributes_deletion(self):
7318+ # ticket #2046, should not seqfault, raise AttributeError
7319+ a = np.ones(2)
7320+ attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
7321+ with suppress_warnings() as sup:
7322+ sup.filter(DeprecationWarning, "Assigning the 'data' attribute")
7323+ for s in attr:
7324+ assert_raises(AttributeError, delattr, a, s)
7325+
7326+ def test_multiarray_not_writable_attributes_deletion(self):
7327+ a = np.ones(2)
7328+ attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
7329+ "ctypes", "T", "__array_interface__", "__array_struct__",
7330+ "__array_priority__", "__array_finalize__"]
7331+ for s in attr:
7332+ assert_raises(AttributeError, delattr, a, s)
7333+
7334+ def test_multiarray_flags_writable_attribute_deletion(self):
7335+ a = np.ones(2).flags
7336+ attr = ['writebackifcopy', 'updateifcopy', 'aligned', 'writeable']
7337+ for s in attr:
7338+ assert_raises(AttributeError, delattr, a, s)
7339+
7340+ def test_multiarray_flags_not_writable_attribute_deletion(self):
7341+ a = np.ones(2).flags
7342+ attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
7343+ "owndata", "fnc", "forc", "behaved", "carray", "farray",
7344+ "num"]
7345+ for s in attr:
7346+ assert_raises(AttributeError, delattr, a, s)
7347+
7348+
7349+class TestArrayInterface():
7350+ class Foo:
7351+ def __init__(self, value):
7352+ self.value = value
7353+ self.iface = {'typestr': 'f8'}
7354+
7355+ def __float__(self):
7356+ return float(self.value)
7357+
7358+ @property
7359+ def __array_interface__(self):
7360+ return self.iface
7361+
7362+
7363+ f = Foo(0.5)
7364+
7365+ @pytest.mark.parametrize('val, iface, expected', [
7366+ (f, {}, 0.5),
7367+ ([f], {}, [0.5]),
7368+ ([f, f], {}, [0.5, 0.5]),
7369+ (f, {'shape': ()}, 0.5),
7370+ (f, {'shape': None}, TypeError),
7371+ (f, {'shape': (1, 1)}, [[0.5]]),
7372+ (f, {'shape': (2,)}, ValueError),
7373+ (f, {'strides': ()}, 0.5),
7374+ (f, {'strides': (2,)}, ValueError),
7375+ (f, {'strides': 16}, TypeError),
7376+ ])
7377+ def test_scalar_interface(self, val, iface, expected):
7378+ # Test scalar coercion within the array interface
7379+ self.f.iface = {'typestr': 'f8'}
7380+ self.f.iface.update(iface)
7381+ if HAS_REFCOUNT:
7382+ pre_cnt = sys.getrefcount(np.dtype('f8'))
7383+ if isinstance(expected, type):
7384+ assert_raises(expected, np.array, val)
7385+ else:
7386+ result = np.array(val)
7387+ assert_equal(np.array(val), expected)
7388+ assert result.dtype == 'f8'
7389+ del result
7390+ if HAS_REFCOUNT:
7391+ post_cnt = sys.getrefcount(np.dtype('f8'))
7392+ assert_equal(pre_cnt, post_cnt)
7393+
7394+def test_interface_no_shape():
7395+ class ArrayLike:
7396+ array = np.array(1)
7397+ __array_interface__ = array.__array_interface__
7398+ assert_equal(np.array(ArrayLike()), 1)
7399+
7400+
7401+def test_array_interface_itemsize():
7402+ # See gh-6361
7403+ my_dtype = np.dtype({'names': ['A', 'B'], 'formats': ['f4', 'f4'],
7404+ 'offsets': [0, 8], 'itemsize': 16})
7405+ a = np.ones(10, dtype=my_dtype)
7406+ descr_t = np.dtype(a.__array_interface__['descr'])
7407+ typestr_t = np.dtype(a.__array_interface__['typestr'])
7408+ assert_equal(descr_t.itemsize, typestr_t.itemsize)
7409+
7410+
7411+def test_array_interface_empty_shape():
7412+ # See gh-7994
7413+ arr = np.array([1, 2, 3])
7414+ interface1 = dict(arr.__array_interface__)
7415+ interface1['shape'] = ()
7416+
7417+ class DummyArray1:
7418+ __array_interface__ = interface1
7419+
7420+ # NOTE: Because Py2 str/Py3 bytes supports the buffer interface, setting
7421+ # the interface data to bytes would invoke the bug this tests for, that
7422+ # __array_interface__ with shape=() is not allowed if the data is an object
7423+ # exposing the buffer interface
7424+ interface2 = dict(interface1)
7425+ interface2['data'] = arr[0].tobytes()
7426+
7427+ class DummyArray2:
7428+ __array_interface__ = interface2
7429+
7430+ arr1 = np.asarray(DummyArray1())
7431+ arr2 = np.asarray(DummyArray2())
7432+ arr3 = arr[:1].reshape(())
7433+ assert_equal(arr1, arr2)
7434+ assert_equal(arr1, arr3)
7435+
7436+def test_array_interface_offset():
7437+ arr = np.array([1, 2, 3], dtype='int32')
7438+ interface = dict(arr.__array_interface__)
7439+ interface['data'] = memoryview(arr)
7440+ interface['shape'] = (2,)
7441+ interface['offset'] = 4
7442+
7443+
7444+ class DummyArray:
7445+ __array_interface__ = interface
7446+
7447+ arr1 = np.asarray(DummyArray())
7448+ assert_equal(arr1, arr[1:])
7449+
7450+def test_flat_element_deletion():
7451+ it = np.ones(3).flat
7452+ try:
7453+ del it[1]
7454+ del it[1:2]
7455+ except TypeError:
7456+ pass
7457+ except Exception:
7458+ raise AssertionError
7459+
7460+
7461+def test_scalar_element_deletion():
7462+ a = np.zeros(2, dtype=[('x', 'int'), ('y', 'int')])
7463+ assert_raises(ValueError, a[0].__delitem__, 'x')
7464+
7465+
7466+class TestMemEventHook:
7467+ def test_mem_seteventhook(self):
7468+ # The actual tests are within the C code in
7469+ # multiarray/_multiarray_tests.c.src
7470+ _multiarray_tests.test_pydatamem_seteventhook_start()
7471+ # force an allocation and free of a numpy array
7472+ # needs to be larger then limit of small memory cacher in ctors.c
7473+ a = np.zeros(1000)
7474+ del a
7475+ break_cycles()
7476+ _multiarray_tests.test_pydatamem_seteventhook_end()
7477+
7478+class TestMapIter:
7479+ def test_mapiter(self):
7480+ # The actual tests are within the C code in
7481+ # multiarray/_multiarray_tests.c.src
7482+
7483+ a = np.arange(12).reshape((3, 4)).astype(float)
7484+ index = ([1, 1, 2, 0],
7485+ [0, 0, 2, 3])
7486+ vals = [50, 50, 30, 16]
7487+
7488+ _multiarray_tests.test_inplace_increment(a, index, vals)
7489+ assert_equal(a, [[0.00, 1., 2.0, 19.],
7490+ [104., 5., 6.0, 7.0],
7491+ [8.00, 9., 40., 11.]])
7492+
7493+ b = np.arange(6).astype(float)
7494+ index = (np.array([1, 2, 0]),)
7495+ vals = [50, 4, 100.1]
7496+ _multiarray_tests.test_inplace_increment(b, index, vals)
7497+ assert_equal(b, [100.1, 51., 6., 3., 4., 5.])
7498+
7499+
7500+class TestAsCArray:
7501+ def test_1darray(self):
7502+ array = np.arange(24, dtype=np.double)
7503+ from_c = _multiarray_tests.test_as_c_array(array, 3)
7504+ assert_equal(array[3], from_c)
7505+
7506+ def test_2darray(self):
7507+ array = np.arange(24, dtype=np.double).reshape(3, 8)
7508+ from_c = _multiarray_tests.test_as_c_array(array, 2, 4)
7509+ assert_equal(array[2, 4], from_c)
7510+
7511+ def test_3darray(self):
7512+ array = np.arange(24, dtype=np.double).reshape(2, 3, 4)
7513+ from_c = _multiarray_tests.test_as_c_array(array, 1, 2, 3)
7514+ assert_equal(array[1, 2, 3], from_c)
7515+
7516+
7517+class TestConversion:
7518+ def test_array_scalar_relational_operation(self):
7519+ # All integer
7520+ for dt1 in np.typecodes['AllInteger']:
7521+ assert_(1 > np.array(0, dtype=dt1), "type %s failed" % (dt1,))
7522+ assert_(not 1 < np.array(0, dtype=dt1), "type %s failed" % (dt1,))
7523+
7524+ for dt2 in np.typecodes['AllInteger']:
7525+ assert_(np.array(1, dtype=dt1) > np.array(0, dtype=dt2),
7526+ "type %s and %s failed" % (dt1, dt2))
7527+ assert_(not np.array(1, dtype=dt1) < np.array(0, dtype=dt2),
7528+ "type %s and %s failed" % (dt1, dt2))
7529+
7530+ # Unsigned integers
7531+ for dt1 in 'BHILQP':
7532+ assert_(-1 < np.array(1, dtype=dt1), "type %s failed" % (dt1,))
7533+ assert_(not -1 > np.array(1, dtype=dt1), "type %s failed" % (dt1,))
7534+ assert_(-1 != np.array(1, dtype=dt1), "type %s failed" % (dt1,))
7535+
7536+ # Unsigned vs signed
7537+ for dt2 in 'bhilqp':
7538+ assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
7539+ "type %s and %s failed" % (dt1, dt2))
7540+ assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
7541+ "type %s and %s failed" % (dt1, dt2))
7542+ assert_(np.array(1, dtype=dt1) != np.array(-1, dtype=dt2),
7543+ "type %s and %s failed" % (dt1, dt2))
7544+
7545+ # Signed integers and floats
7546+ for dt1 in 'bhlqp' + np.typecodes['Float']:
7547+ assert_(1 > np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
7548+ assert_(not 1 < np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
7549+ assert_(-1 == np.array(-1, dtype=dt1), "type %s failed" % (dt1,))
7550+
7551+ for dt2 in 'bhlqp' + np.typecodes['Float']:
7552+ assert_(np.array(1, dtype=dt1) > np.array(-1, dtype=dt2),
7553+ "type %s and %s failed" % (dt1, dt2))
7554+ assert_(not np.array(1, dtype=dt1) < np.array(-1, dtype=dt2),
7555+ "type %s and %s failed" % (dt1, dt2))
7556+ assert_(np.array(-1, dtype=dt1) == np.array(-1, dtype=dt2),
7557+ "type %s and %s failed" % (dt1, dt2))
7558+
7559+ def test_to_bool_scalar(self):
7560+ assert_equal(bool(np.array([False])), False)
7561+ assert_equal(bool(np.array([True])), True)
7562+ assert_equal(bool(np.array([[42]])), True)
7563+ assert_raises(ValueError, bool, np.array([1, 2]))
7564+
7565+ class NotConvertible:
7566+ def __bool__(self):
7567+ raise NotImplementedError
7568+
7569+ assert_raises(NotImplementedError, bool, np.array(NotConvertible()))
7570+ assert_raises(NotImplementedError, bool, np.array([NotConvertible()]))
7571+
7572+ self_containing = np.array([None])
7573+ self_containing[0] = self_containing
7574+ try:
7575+ Error = RecursionError
7576+ except NameError:
7577+ Error = RuntimeError # python < 3.5
7578+ assert_raises(Error, bool, self_containing) # previously stack overflow
7579+ self_containing[0] = None # resolve circular reference
7580+
7581+ def test_to_int_scalar(self):
7582+ # gh-9972 means that these aren't always the same
7583+ int_funcs = (int, lambda x: x.__int__())
7584+ for int_func in int_funcs:
7585+ assert_equal(int_func(np.array(0)), 0)
7586+ assert_equal(int_func(np.array([1])), 1)
7587+ assert_equal(int_func(np.array([[42]])), 42)
7588+ assert_raises(TypeError, int_func, np.array([1, 2]))
7589+
7590+ # gh-9972
7591+ assert_equal(4, int_func(np.array('4')))
7592+ assert_equal(5, int_func(np.bytes_(b'5')))
7593+ assert_equal(6, int_func(np.unicode_(u'6')))
7594+
7595+ class HasTrunc:
7596+ def __trunc__(self):
7597+ return 3
7598+ assert_equal(3, int_func(np.array(HasTrunc())))
7599+ assert_equal(3, int_func(np.array([HasTrunc()])))
7600+
7601+ class NotConvertible:
7602+ def __int__(self):
7603+ raise NotImplementedError
7604+ assert_raises(NotImplementedError,
7605+ int_func, np.array(NotConvertible()))
7606+ assert_raises(NotImplementedError,
7607+ int_func, np.array([NotConvertible()]))
7608+
7609+
7610+class TestWhere:
7611+ def test_basic(self):
7612+ dts = [bool, np.int16, np.int32, np.int64, np.double, np.complex128,
7613+ np.longdouble, np.clongdouble]
7614+ for dt in dts:
7615+ c = np.ones(53, dtype=bool)
7616+ assert_equal(np.where( c, dt(0), dt(1)), dt(0))
7617+ assert_equal(np.where(~c, dt(0), dt(1)), dt(1))
7618+ assert_equal(np.where(True, dt(0), dt(1)), dt(0))
7619+ assert_equal(np.where(False, dt(0), dt(1)), dt(1))
7620+ d = np.ones_like(c).astype(dt)
7621+ e = np.zeros_like(d)
7622+ r = d.astype(dt)
7623+ c[7] = False
7624+ r[7] = e[7]
7625+ assert_equal(np.where(c, e, e), e)
7626+ assert_equal(np.where(c, d, e), r)
7627+ assert_equal(np.where(c, d, e[0]), r)
7628+ assert_equal(np.where(c, d[0], e), r)
7629+ assert_equal(np.where(c[::2], d[::2], e[::2]), r[::2])
7630+ assert_equal(np.where(c[1::2], d[1::2], e[1::2]), r[1::2])
7631+ assert_equal(np.where(c[::3], d[::3], e[::3]), r[::3])
7632+ assert_equal(np.where(c[1::3], d[1::3], e[1::3]), r[1::3])
7633+ assert_equal(np.where(c[::-2], d[::-2], e[::-2]), r[::-2])
7634+ assert_equal(np.where(c[::-3], d[::-3], e[::-3]), r[::-3])
7635+ assert_equal(np.where(c[1::-3], d[1::-3], e[1::-3]), r[1::-3])
7636+
7637+ def test_exotic(self):
7638+ # object
7639+ assert_array_equal(np.where(True, None, None), np.array(None))
7640+ # zero sized
7641+ m = np.array([], dtype=bool).reshape(0, 3)
7642+ b = np.array([], dtype=np.float64).reshape(0, 3)
7643+ assert_array_equal(np.where(m, 0, b), np.array([]).reshape(0, 3))
7644+
7645+ # object cast
7646+ d = np.array([-1.34, -0.16, -0.54, -0.31, -0.08, -0.95, 0.000, 0.313,
7647+ 0.547, -0.18, 0.876, 0.236, 1.969, 0.310, 0.699, 1.013,
7648+ 1.267, 0.229, -1.39, 0.487])
7649+ nan = float('NaN')
7650+ e = np.array(['5z', '0l', nan, 'Wz', nan, nan, 'Xq', 'cs', nan, nan,
7651+ 'QN', nan, nan, 'Fd', nan, nan, 'kp', nan, '36', 'i1'],
7652+ dtype=object)
7653+ m = np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1,
7654+ 0, 1, 1, 0, 1, 1, 0, 1, 0, 0], dtype=bool)
7655+
7656+ r = e[:]
7657+ r[np.where(m)] = d[np.where(m)]
7658+ assert_array_equal(np.where(m, d, e), r)
7659+
7660+ r = e[:]
7661+ r[np.where(~m)] = d[np.where(~m)]
7662+ assert_array_equal(np.where(m, e, d), r)
7663+
7664+ assert_array_equal(np.where(m, e, e), e)
7665+
7666+ # minimal dtype result with NaN scalar (e.g required by pandas)
7667+ d = np.array([1., 2.], dtype=np.float32)
7668+ e = float('NaN')
7669+ assert_equal(np.where(True, d, e).dtype, np.float32)
7670+ e = float('Infinity')
7671+ assert_equal(np.where(True, d, e).dtype, np.float32)
7672+ e = float('-Infinity')
7673+ assert_equal(np.where(True, d, e).dtype, np.float32)
7674+ # also check upcast
7675+ e = float(1e150)
7676+ assert_equal(np.where(True, d, e).dtype, np.float64)
7677+
7678+ def test_ndim(self):
7679+ c = [True, False]
7680+ a = np.zeros((2, 25))
7681+ b = np.ones((2, 25))
7682+ r = np.where(np.array(c)[:,np.newaxis], a, b)
7683+ assert_array_equal(r[0], a[0])
7684+ assert_array_equal(r[1], b[0])
7685+
7686+ a = a.T
7687+ b = b.T
7688+ r = np.where(c, a, b)
7689+ assert_array_equal(r[:,0], a[:,0])
7690+ assert_array_equal(r[:,1], b[:,0])
7691+
7692+ def test_dtype_mix(self):
7693+ c = np.array([False, True, False, False, False, False, True, False,
7694+ False, False, True, False])
7695+ a = np.uint32(1)
7696+ b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
7697+ dtype=np.float64)
7698+ r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
7699+ dtype=np.float64)
7700+ assert_equal(np.where(c, a, b), r)
7701+
7702+ a = a.astype(np.float32)
7703+ b = b.astype(np.int64)
7704+ assert_equal(np.where(c, a, b), r)
7705+
7706+ # non bool mask
7707+ c = c.astype(int)
7708+ c[c != 0] = 34242324
7709+ assert_equal(np.where(c, a, b), r)
7710+ # invert
7711+ tmpmask = c != 0
7712+ c[c == 0] = 41247212
7713+ c[tmpmask] = 0
7714+ assert_equal(np.where(c, b, a), r)
7715+
7716+ def test_foreign(self):
7717+ c = np.array([False, True, False, False, False, False, True, False,
7718+ False, False, True, False])
7719+ r = np.array([5., 1., 3., 2., -1., -4., 1., -10., 10., 1., 1., 3.],
7720+ dtype=np.float64)
7721+ a = np.ones(1, dtype='>i4')
7722+ b = np.array([5., 0., 3., 2., -1., -4., 0., -10., 10., 1., 0., 3.],
7723+ dtype=np.float64)
7724+ assert_equal(np.where(c, a, b), r)
7725+
7726+ b = b.astype('>f8')
7727+ assert_equal(np.where(c, a, b), r)
7728+
7729+ a = a.astype('<i4')
7730+ assert_equal(np.where(c, a, b), r)
7731+
7732+ c = c.astype('>i4')
7733+ assert_equal(np.where(c, a, b), r)
7734+
7735+ def test_error(self):
7736+ c = [True, True]
7737+ a = np.ones((4, 5))
7738+ b = np.ones((5, 5))
7739+ assert_raises(ValueError, np.where, c, a, a)
7740+ assert_raises(ValueError, np.where, c[0], a, b)
7741+
7742+ def test_string(self):
7743+ # gh-4778 check strings are properly filled with nulls
7744+ a = np.array("abc")
7745+ b = np.array("x" * 753)
7746+ assert_equal(np.where(True, a, b), "abc")
7747+ assert_equal(np.where(False, b, a), "abc")
7748+
7749+ # check native datatype sized strings
7750+ a = np.array("abcd")
7751+ b = np.array("x" * 8)
7752+ assert_equal(np.where(True, a, b), "abcd")
7753+ assert_equal(np.where(False, b, a), "abcd")
7754+
7755+ def test_empty_result(self):
7756+ # pass empty where result through an assignment which reads the data of
7757+ # empty arrays, error detectable with valgrind, see gh-8922
7758+ x = np.zeros((1, 1))
7759+ ibad = np.vstack(np.where(x == 99.))
7760+ assert_array_equal(ibad,
7761+ np.atleast_2d(np.array([[],[]], dtype=np.intp)))
7762+
7763+ def test_largedim(self):
7764+ # invalid read regression gh-9304
7765+ shape = [10, 2, 3, 4, 5, 6]
7766+ np.random.seed(2)
7767+ array = np.random.rand(*shape)
7768+
7769+ for i in range(10):
7770+ benchmark = array.nonzero()
7771+ result = array.nonzero()
7772+ assert_array_equal(benchmark, result)
7773+
7774+
7775+if not IS_PYPY:
7776+ # sys.getsizeof() is not valid on PyPy
7777+ class TestSizeOf:
7778+
7779+ def test_empty_array(self):
7780+ x = np.array([])
7781+ assert_(sys.getsizeof(x) > 0)
7782+
7783+ def check_array(self, dtype):
7784+ elem_size = dtype(0).itemsize
7785+
7786+ for length in [10, 50, 100, 500]:
7787+ x = np.arange(length, dtype=dtype)
7788+ assert_(sys.getsizeof(x) > length * elem_size)
7789+
7790+ def test_array_int32(self):
7791+ self.check_array(np.int32)
7792+
7793+ def test_array_int64(self):
7794+ self.check_array(np.int64)
7795+
7796+ def test_array_float32(self):
7797+ self.check_array(np.float32)
7798+
7799+ def test_array_float64(self):
7800+ self.check_array(np.float64)
7801+
7802+ def test_view(self):
7803+ d = np.ones(100)
7804+ assert_(sys.getsizeof(d[...]) < sys.getsizeof(d))
7805+
7806+ def test_reshape(self):
7807+ d = np.ones(100)
7808+ assert_(sys.getsizeof(d) < sys.getsizeof(d.reshape(100, 1, 1).copy()))
7809+
7810+ @_no_tracing
7811+ def test_resize(self):
7812+ d = np.ones(100)
7813+ old = sys.getsizeof(d)
7814+ d.resize(50)
7815+ assert_(old > sys.getsizeof(d))
7816+ d.resize(150)
7817+ assert_(old < sys.getsizeof(d))
7818+
7819+ def test_error(self):
7820+ d = np.ones(100)
7821+ assert_raises(TypeError, d.__sizeof__, "a")
7822+
7823+
7824+class TestHashing:
7825+
7826+ def test_arrays_not_hashable(self):
7827+ x = np.ones(3)
7828+ assert_raises(TypeError, hash, x)
7829+
7830+ def test_collections_hashable(self):
7831+ x = np.array([])
7832+ assert_(not isinstance(x, collections.abc.Hashable))
7833+
7834+
7835+class TestArrayPriority:
7836+ # This will go away when __array_priority__ is settled, meanwhile
7837+ # it serves to check unintended changes.
7838+ op = operator
7839+ binary_ops = [
7840+ op.pow, op.add, op.sub, op.mul, op.floordiv, op.truediv, op.mod,
7841+ op.and_, op.or_, op.xor, op.lshift, op.rshift, op.mod, op.gt,
7842+ op.ge, op.lt, op.le, op.ne, op.eq
7843+ ]
7844+
7845+ class Foo(np.ndarray):
7846+ __array_priority__ = 100.
7847+
7848+ def __new__(cls, *args, **kwargs):
7849+ return np.array(*args, **kwargs).view(cls)
7850+
7851+ class Bar(np.ndarray):
7852+ __array_priority__ = 101.
7853+
7854+ def __new__(cls, *args, **kwargs):
7855+ return np.array(*args, **kwargs).view(cls)
7856+
7857+ class Other:
7858+ __array_priority__ = 1000.
7859+
7860+ def _all(self, other):
7861+ return self.__class__()
7862+
7863+ __add__ = __radd__ = _all
7864+ __sub__ = __rsub__ = _all
7865+ __mul__ = __rmul__ = _all
7866+ __pow__ = __rpow__ = _all
7867+ __div__ = __rdiv__ = _all
7868+ __mod__ = __rmod__ = _all
7869+ __truediv__ = __rtruediv__ = _all
7870+ __floordiv__ = __rfloordiv__ = _all
7871+ __and__ = __rand__ = _all
7872+ __xor__ = __rxor__ = _all
7873+ __or__ = __ror__ = _all
7874+ __lshift__ = __rlshift__ = _all
7875+ __rshift__ = __rrshift__ = _all
7876+ __eq__ = _all
7877+ __ne__ = _all
7878+ __gt__ = _all
7879+ __ge__ = _all
7880+ __lt__ = _all
7881+ __le__ = _all
7882+
7883+ def test_ndarray_subclass(self):
7884+ a = np.array([1, 2])
7885+ b = self.Bar([1, 2])
7886+ for f in self.binary_ops:
7887+ msg = repr(f)
7888+ assert_(isinstance(f(a, b), self.Bar), msg)
7889+ assert_(isinstance(f(b, a), self.Bar), msg)
7890+
7891+ def test_ndarray_other(self):
7892+ a = np.array([1, 2])
7893+ b = self.Other()
7894+ for f in self.binary_ops:
7895+ msg = repr(f)
7896+ assert_(isinstance(f(a, b), self.Other), msg)
7897+ assert_(isinstance(f(b, a), self.Other), msg)
7898+
7899+ def test_subclass_subclass(self):
7900+ a = self.Foo([1, 2])
7901+ b = self.Bar([1, 2])
7902+ for f in self.binary_ops:
7903+ msg = repr(f)
7904+ assert_(isinstance(f(a, b), self.Bar), msg)
7905+ assert_(isinstance(f(b, a), self.Bar), msg)
7906+
7907+ def test_subclass_other(self):
7908+ a = self.Foo([1, 2])
7909+ b = self.Other()
7910+ for f in self.binary_ops:
7911+ msg = repr(f)
7912+ assert_(isinstance(f(a, b), self.Other), msg)
7913+ assert_(isinstance(f(b, a), self.Other), msg)
7914+
7915+
7916+class TestBytestringArrayNonzero:
7917+
7918+ def test_empty_bstring_array_is_falsey(self):
7919+ assert_(not np.array([''], dtype=str))
7920+
7921+ def test_whitespace_bstring_array_is_falsey(self):
7922+ a = np.array(['spam'], dtype=str)
7923+ a[0] = ' \0\0'
7924+ assert_(not a)
7925+
7926+ def test_all_null_bstring_array_is_falsey(self):
7927+ a = np.array(['spam'], dtype=str)
7928+ a[0] = '\0\0\0\0'
7929+ assert_(not a)
7930+
7931+ def test_null_inside_bstring_array_is_truthy(self):
7932+ a = np.array(['spam'], dtype=str)
7933+ a[0] = ' \0 \0'
7934+ assert_(a)
7935+
7936+
7937+class TestUnicodeEncoding:
7938+ """
7939+ Tests for encoding related bugs, such as UCS2 vs UCS4, round-tripping
7940+ issues, etc
7941+ """
7942+ def test_round_trip(self):
7943+ """ Tests that GETITEM, SETITEM, and PyArray_Scalar roundtrip """
7944+ # gh-15363
7945+ arr = np.zeros(shape=(), dtype="U1")
7946+ for i in range(1, sys.maxunicode + 1):
7947+ expected = chr(i)
7948+ arr[()] = expected
7949+ assert arr[()] == expected
7950+ assert arr.item() == expected
7951+
7952+ def test_assign_scalar(self):
7953+ # gh-3258
7954+ l = np.array(['aa', 'bb'])
7955+ l[:] = np.unicode_('cc')
7956+ assert_equal(l, ['cc', 'cc'])
7957+
7958+ def test_fill_scalar(self):
7959+ # gh-7227
7960+ l = np.array(['aa', 'bb'])
7961+ l.fill(np.unicode_('cc'))
7962+ assert_equal(l, ['cc', 'cc'])
7963+
7964+
7965+class TestUnicodeArrayNonzero:
7966+
7967+ def test_empty_ustring_array_is_falsey(self):
7968+ assert_(not np.array([''], dtype=np.unicode_))
7969+
7970+ def test_whitespace_ustring_array_is_falsey(self):
7971+ a = np.array(['eggs'], dtype=np.unicode_)
7972+ a[0] = ' \0\0'
7973+ assert_(not a)
7974+
7975+ def test_all_null_ustring_array_is_falsey(self):
7976+ a = np.array(['eggs'], dtype=np.unicode_)
7977+ a[0] = '\0\0\0\0'
7978+ assert_(not a)
7979+
7980+ def test_null_inside_ustring_array_is_truthy(self):
7981+ a = np.array(['eggs'], dtype=np.unicode_)
7982+ a[0] = ' \0 \0'
7983+ assert_(a)
7984+
7985+
7986+class TestFormat:
7987+
7988+ def test_0d(self):
7989+ a = np.array(np.pi)
7990+ assert_equal('{:0.3g}'.format(a), '3.14')
7991+ assert_equal('{:0.3g}'.format(a[()]), '3.14')
7992+
7993+ def test_1d_no_format(self):
7994+ a = np.array([np.pi])
7995+ assert_equal('{}'.format(a), str(a))
7996+
7997+ def test_1d_format(self):
7998+ # until gh-5543, ensure that the behaviour matches what it used to be
7999+ a = np.array([np.pi])
8000+ assert_raises(TypeError, '{:30}'.format, a)
8001+
8002+from numpy.testing import IS_PYPY
8003+
8004+class TestCTypes:
8005+
8006+ def test_ctypes_is_available(self):
8007+ test_arr = np.array([[1, 2, 3], [4, 5, 6]])
8008+
8009+ assert_equal(ctypes, test_arr.ctypes._ctypes)
8010+ assert_equal(tuple(test_arr.ctypes.shape), (2, 3))
8011+
8012+ def test_ctypes_is_not_available(self):
8013+ from numpy.core import _internal
8014+ _internal.ctypes = None
8015+ try:
8016+ test_arr = np.array([[1, 2, 3], [4, 5, 6]])
8017+
8018+ assert_(isinstance(test_arr.ctypes._ctypes,
8019+ _internal._missing_ctypes))
8020+ assert_equal(tuple(test_arr.ctypes.shape), (2, 3))
8021+ finally:
8022+ _internal.ctypes = ctypes
8023+
8024+ def _make_readonly(x):
8025+ x.flags.writeable = False
8026+ return x
8027+
8028+ @pytest.mark.parametrize('arr', [
8029+ np.array([1, 2, 3]),
8030+ np.array([['one', 'two'], ['three', 'four']]),
8031+ np.array((1, 2), dtype='i4,i4'),
8032+ np.zeros((2,), dtype=
8033+ np.dtype(dict(
8034+ formats=['<i4', '<i4'],
8035+ names=['a', 'b'],
8036+ offsets=[0, 2],
8037+ itemsize=6
8038+ ))
8039+ ),
8040+ np.array([None], dtype=object),
8041+ np.array([]),
8042+ np.empty((0, 0)),
8043+ _make_readonly(np.array([1, 2, 3])),
8044+ ], ids=[
8045+ '1d',
8046+ '2d',
8047+ 'structured',
8048+ 'overlapping',
8049+ 'object',
8050+ 'empty',
8051+ 'empty-2d',
8052+ 'readonly'
8053+ ])
8054+ def test_ctypes_data_as_holds_reference(self, arr):
8055+ # gh-9647
8056+ # create a copy to ensure that pytest does not mess with the refcounts
8057+ arr = arr.copy()
8058+
8059+ arr_ref = weakref.ref(arr)
8060+
8061+ ctypes_ptr = arr.ctypes.data_as(ctypes.c_void_p)
8062+
8063+ # `ctypes_ptr` should hold onto `arr`
8064+ del arr
8065+ break_cycles()
8066+ assert_(arr_ref() is not None, "ctypes pointer did not hold onto a reference")
8067+
8068+ # but when the `ctypes_ptr` object dies, so should `arr`
8069+ del ctypes_ptr
8070+ if IS_PYPY:
8071+ # Pypy does not recycle arr objects immediately. Trigger gc to
8072+ # release arr. Cpython uses refcounts. An explicit call to gc
8073+ # should not be needed here.
8074+ break_cycles()
8075+ assert_(arr_ref() is None, "unknowable whether ctypes pointer holds a reference")
8076+
8077+ def test_ctypes_as_parameter_holds_reference(self):
8078+ arr = np.array([None]).copy()
8079+
8080+ arr_ref = weakref.ref(arr)
8081+
8082+ ctypes_ptr = arr.ctypes._as_parameter_
8083+
8084+ # `ctypes_ptr` should hold onto `arr`
8085+ del arr
8086+ break_cycles()
8087+ assert_(arr_ref() is not None, "ctypes pointer did not hold onto a reference")
8088+
8089+ # but when the `ctypes_ptr` object dies, so should `arr`
8090+ del ctypes_ptr
8091+ if IS_PYPY:
8092+ break_cycles()
8093+ assert_(arr_ref() is None, "unknowable whether ctypes pointer holds a reference")
8094+
8095+
8096+class TestWritebackIfCopy:
8097+ # all these tests use the WRITEBACKIFCOPY mechanism
8098+ def test_argmax_with_out(self):
8099+ mat = np.eye(5)
8100+ out = np.empty(5, dtype='i2')
8101+ res = np.argmax(mat, 0, out=out)
8102+ assert_equal(res, range(5))
8103+
8104+ def test_argmin_with_out(self):
8105+ mat = -np.eye(5)
8106+ out = np.empty(5, dtype='i2')
8107+ res = np.argmin(mat, 0, out=out)
8108+ assert_equal(res, range(5))
8109+
8110+ def test_insert_noncontiguous(self):
8111+ a = np.arange(6).reshape(2,3).T # force non-c-contiguous
8112+ # uses arr_insert
8113+ np.place(a, a>2, [44, 55])
8114+ assert_equal(a, np.array([[0, 44], [1, 55], [2, 44]]))
8115+ # hit one of the failing paths
8116+ assert_raises(ValueError, np.place, a, a>20, [])
8117+
8118+ def test_put_noncontiguous(self):
8119+ a = np.arange(6).reshape(2,3).T # force non-c-contiguous
8120+ np.put(a, [0, 2], [44, 55])
8121+ assert_equal(a, np.array([[44, 3], [55, 4], [2, 5]]))
8122+
8123+ def test_putmask_noncontiguous(self):
8124+ a = np.arange(6).reshape(2,3).T # force non-c-contiguous
8125+ # uses arr_putmask
8126+ np.putmask(a, a>2, a**2)
8127+ assert_equal(a, np.array([[0, 9], [1, 16], [2, 25]]))
8128+
8129+ def test_take_mode_raise(self):
8130+ a = np.arange(6, dtype='int')
8131+ out = np.empty(2, dtype='int')
8132+ np.take(a, [0, 2], out=out, mode='raise')
8133+ assert_equal(out, np.array([0, 2]))
8134+
8135+ def test_choose_mod_raise(self):
8136+ a = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]])
8137+ out = np.empty((3,3), dtype='int')
8138+ choices = [-10, 10]
8139+ np.choose(a, choices, out=out, mode='raise')
8140+ assert_equal(out, np.array([[ 10, -10, 10],
8141+ [-10, 10, -10],
8142+ [ 10, -10, 10]]))
8143+
8144+ def test_flatiter__array__(self):
8145+ a = np.arange(9).reshape(3,3)
8146+ b = a.T.flat
8147+ c = b.__array__()
8148+ # triggers the WRITEBACKIFCOPY resolution, assuming refcount semantics
8149+ del c
8150+
8151+ def test_dot_out(self):
8152+ # if HAVE_CBLAS, will use WRITEBACKIFCOPY
8153+ a = np.arange(9, dtype=float).reshape(3,3)
8154+ b = np.dot(a, a, out=a)
8155+ assert_equal(b, np.array([[15, 18, 21], [42, 54, 66], [69, 90, 111]]))
8156+
8157+ def test_view_assign(self):
8158+ from numpy.core._multiarray_tests import npy_create_writebackifcopy, npy_resolve
8159+
8160+ arr = np.arange(9).reshape(3, 3).T
8161+ arr_wb = npy_create_writebackifcopy(arr)
8162+ assert_(arr_wb.flags.writebackifcopy)
8163+ assert_(arr_wb.base is arr)
8164+ arr_wb[...] = -100
8165+ npy_resolve(arr_wb)
8166+ # arr changes after resolve, even though we assigned to arr_wb
8167+ assert_equal(arr, -100)
8168+ # after resolve, the two arrays no longer reference each other
8169+ assert_(arr_wb.ctypes.data != 0)
8170+ assert_equal(arr_wb.base, None)
8171+ # assigning to arr_wb does not get transferred to arr
8172+ arr_wb[...] = 100
8173+ assert_equal(arr, -100)
8174+
8175+ @pytest.mark.leaks_references(
8176+ reason="increments self in dealloc; ignore since deprecated path.")
8177+ def test_dealloc_warning(self):
8178+ with suppress_warnings() as sup:
8179+ sup.record(RuntimeWarning)
8180+ arr = np.arange(9).reshape(3, 3)
8181+ v = arr.T
8182+ _multiarray_tests.npy_abuse_writebackifcopy(v)
8183+ assert len(sup.log) == 1
8184+
8185+ def test_view_discard_refcount(self):
8186+ from numpy.core._multiarray_tests import npy_create_writebackifcopy, npy_discard
8187+
8188+ arr = np.arange(9).reshape(3, 3).T
8189+ orig = arr.copy()
8190+ if HAS_REFCOUNT:
8191+ arr_cnt = sys.getrefcount(arr)
8192+ arr_wb = npy_create_writebackifcopy(arr)
8193+ assert_(arr_wb.flags.writebackifcopy)
8194+ assert_(arr_wb.base is arr)
8195+ arr_wb[...] = -100
8196+ npy_discard(arr_wb)
8197+ # arr remains unchanged after discard
8198+ assert_equal(arr, orig)
8199+ # after discard, the two arrays no longer reference each other
8200+ assert_(arr_wb.ctypes.data != 0)
8201+ assert_equal(arr_wb.base, None)
8202+ if HAS_REFCOUNT:
8203+ assert_equal(arr_cnt, sys.getrefcount(arr))
8204+ # assigning to arr_wb does not get transferred to arr
8205+ arr_wb[...] = 100
8206+ assert_equal(arr, orig)
8207+
8208+
8209+class TestArange:
8210+ def test_infinite(self):
8211+ assert_raises_regex(
8212+ ValueError, "size exceeded",
8213+ np.arange, 0, np.inf
8214+ )
8215+
8216+ def test_nan_step(self):
8217+ assert_raises_regex(
8218+ ValueError, "cannot compute length",
8219+ np.arange, 0, 1, np.nan
8220+ )
8221+
8222+ def test_zero_step(self):
8223+ assert_raises(ZeroDivisionError, np.arange, 0, 10, 0)
8224+ assert_raises(ZeroDivisionError, np.arange, 0.0, 10.0, 0.0)
8225+
8226+ # empty range
8227+ assert_raises(ZeroDivisionError, np.arange, 0, 0, 0)
8228+ assert_raises(ZeroDivisionError, np.arange, 0.0, 0.0, 0.0)
8229+
8230+
8231+class TestArrayFinalize:
8232+ """ Tests __array_finalize__ """
8233+
8234+ def test_receives_base(self):
8235+ # gh-11237
8236+ class SavesBase(np.ndarray):
8237+ def __array_finalize__(self, obj):
8238+ self.saved_base = self.base
8239+
8240+ a = np.array(1).view(SavesBase)
8241+ assert_(a.saved_base is a.base)
8242+
8243+ def test_lifetime_on_error(self):
8244+ # gh-11237
8245+ class RaisesInFinalize(np.ndarray):
8246+ def __array_finalize__(self, obj):
8247+ # crash, but keep this object alive
8248+ raise Exception(self)
8249+
8250+ # a plain object can't be weakref'd
8251+ class Dummy: pass
8252+
8253+ # get a weak reference to an object within an array
8254+ obj_arr = np.array(Dummy())
8255+ obj_ref = weakref.ref(obj_arr[()])
8256+
8257+ # get an array that crashed in __array_finalize__
8258+ with assert_raises(Exception) as e:
8259+ obj_arr.view(RaisesInFinalize)
8260+
8261+ obj_subarray = e.exception.args[0]
8262+ del e
8263+ assert_(isinstance(obj_subarray, RaisesInFinalize))
8264+
8265+ # reference should still be held by obj_arr
8266+ break_cycles()
8267+ assert_(obj_ref() is not None, "object should not already be dead")
8268+
8269+ del obj_arr
8270+ break_cycles()
8271+ assert_(obj_ref() is not None, "obj_arr should not hold the last reference")
8272+
8273+ del obj_subarray
8274+ break_cycles()
8275+ assert_(obj_ref() is None, "no references should remain")
8276+
8277+
8278+def test_orderconverter_with_nonASCII_unicode_ordering():
8279+ # gh-7475
8280+ a = np.arange(5)
8281+ assert_raises(ValueError, a.flatten, order=u'\xe2')
8282+
8283+
8284+def test_equal_override():
8285+ # gh-9153: ndarray.__eq__ uses special logic for structured arrays, which
8286+ # did not respect overrides with __array_priority__ or __array_ufunc__.
8287+ # The PR fixed this for __array_priority__ and __array_ufunc__ = None.
8288+ class MyAlwaysEqual:
8289+ def __eq__(self, other):
8290+ return "eq"
8291+
8292+ def __ne__(self, other):
8293+ return "ne"
8294+
8295+ class MyAlwaysEqualOld(MyAlwaysEqual):
8296+ __array_priority__ = 10000
8297+
8298+ class MyAlwaysEqualNew(MyAlwaysEqual):
8299+ __array_ufunc__ = None
8300+
8301+ array = np.array([(0, 1), (2, 3)], dtype='i4,i4')
8302+ for my_always_equal_cls in MyAlwaysEqualOld, MyAlwaysEqualNew:
8303+ my_always_equal = my_always_equal_cls()
8304+ assert_equal(my_always_equal == array, 'eq')
8305+ assert_equal(array == my_always_equal, 'eq')
8306+ assert_equal(my_always_equal != array, 'ne')
8307+ assert_equal(array != my_always_equal, 'ne')
8308+
8309+
8310+def test_npymath_complex():
8311+ # Smoketest npymath functions
8312+ from numpy.core._multiarray_tests import (
8313+ npy_cabs, npy_carg)
8314+
8315+ funcs = {npy_cabs: np.absolute,
8316+ npy_carg: np.angle}
8317+ vals = (1, np.inf, -np.inf, np.nan)
8318+ types = (np.complex64, np.complex128, np.clongdouble)
8319+
8320+ for fun, npfun in funcs.items():
8321+ for x, y in itertools.product(vals, vals):
8322+ for t in types:
8323+ z = t(complex(x, y))
8324+ got = fun(z)
8325+ expected = npfun(z)
8326+ assert_allclose(got, expected)
8327+
8328+
8329+def test_npymath_real():
8330+ # Smoketest npymath functions
8331+ from numpy.core._multiarray_tests import (
8332+ npy_log10, npy_cosh, npy_sinh, npy_tan, npy_tanh)
8333+
8334+ funcs = {npy_log10: np.log10,
8335+ npy_cosh: np.cosh,
8336+ npy_sinh: np.sinh,
8337+ npy_tan: np.tan,
8338+ npy_tanh: np.tanh}
8339+ vals = (1, np.inf, -np.inf, np.nan)
8340+ types = (np.float32, np.float64, np.longdouble)
8341+
8342+ with np.errstate(all='ignore'):
8343+ for fun, npfun in funcs.items():
8344+ for x, t in itertools.product(vals, types):
8345+ z = t(x)
8346+ got = fun(z)
8347+ expected = npfun(z)
8348+ assert_allclose(got, expected)
8349+
8350+def test_uintalignment_and_alignment():
8351+ # alignment code needs to satisfy these requirements:
8352+ # 1. numpy structs match C struct layout
8353+ # 2. ufuncs/casting is safe wrt to aligned access
8354+ # 3. copy code is safe wrt to "uint alidned" access
8355+ #
8356+ # Complex types are the main problem, whose alignment may not be the same
8357+ # as their "uint alignment".
8358+ #
8359+ # This test might only fail on certain platforms, where uint64 alignment is
8360+ # not equal to complex64 alignment. The second 2 tests will only fail
8361+ # for DEBUG=1.
8362+
8363+ d1 = np.dtype('u1,c8', align=True)
8364+ d2 = np.dtype('u4,c8', align=True)
8365+ d3 = np.dtype({'names': ['a', 'b'], 'formats': ['u1', d1]}, align=True)
8366+
8367+ assert_equal(np.zeros(1, dtype=d1)['f1'].flags['ALIGNED'], True)
8368+ assert_equal(np.zeros(1, dtype=d2)['f1'].flags['ALIGNED'], True)
8369+ assert_equal(np.zeros(1, dtype='u1,c8')['f1'].flags['ALIGNED'], False)
8370+
8371+ # check that C struct matches numpy struct size
8372+ s = _multiarray_tests.get_struct_alignments()
8373+ for d, (alignment, size) in zip([d1,d2,d3], s):
8374+ assert_equal(d.alignment, alignment)
8375+ assert_equal(d.itemsize, size)
8376+
8377+ # check that ufuncs don't complain in debug mode
8378+ # (this is probably OK if the aligned flag is true above)
8379+ src = np.zeros((2,2), dtype=d1)['f1'] # 4-byte aligned, often
8380+ np.exp(src) # assert fails?
8381+
8382+ # check that copy code doesn't complain in debug mode
8383+ dst = np.zeros((2,2), dtype='c8')
8384+ dst[:,1] = src[:,1] # assert in lowlevel_strided_loops fails?
8385+
8386+class TestAlignment:
8387+ # adapted from scipy._lib.tests.test__util.test__aligned_zeros
8388+ # Checks that unusual memory alignments don't trip up numpy.
8389+ # In particular, check RELAXED_STRIDES don't trip alignment assertions in
8390+ # NDEBUG mode for size-0 arrays (gh-12503)
8391+
8392+ def check(self, shape, dtype, order, align):
8393+ err_msg = repr((shape, dtype, order, align))
8394+ x = _aligned_zeros(shape, dtype, order, align=align)
8395+ if align is None:
8396+ align = np.dtype(dtype).alignment
8397+ assert_equal(x.__array_interface__['data'][0] % align, 0)
8398+ if hasattr(shape, '__len__'):
8399+ assert_equal(x.shape, shape, err_msg)
8400+ else:
8401+ assert_equal(x.shape, (shape,), err_msg)
8402+ assert_equal(x.dtype, dtype)
8403+ if order == "C":
8404+ assert_(x.flags.c_contiguous, err_msg)
8405+ elif order == "F":
8406+ if x.size > 0:
8407+ assert_(x.flags.f_contiguous, err_msg)
8408+ elif order is None:
8409+ assert_(x.flags.c_contiguous, err_msg)
8410+ else:
8411+ raise ValueError()
8412+
8413+ def test_various_alignments(self):
8414+ for align in [1, 2, 3, 4, 8, 12, 16, 32, 64, None]:
8415+ for n in [0, 1, 3, 11]:
8416+ for order in ["C", "F", None]:
8417+ for dtype in list(np.typecodes["All"]) + ['i4,i4,i4']:
8418+ if dtype == 'O':
8419+ # object dtype can't be misaligned
8420+ continue
8421+ for shape in [n, (1, 2, 3, n)]:
8422+ self.check(shape, np.dtype(dtype), order, align)
8423+
8424+ def test_strided_loop_alignments(self):
8425+ # particularly test that complex64 and float128 use right alignment
8426+ # code-paths, since these are particularly problematic. It is useful to
8427+ # turn on USE_DEBUG for this test, so lowlevel-loop asserts are run.
8428+ for align in [1, 2, 4, 8, 12, 16, None]:
8429+ xf64 = _aligned_zeros(3, np.float64)
8430+
8431+ xc64 = _aligned_zeros(3, np.complex64, align=align)
8432+ xf128 = _aligned_zeros(3, np.longdouble, align=align)
8433+
8434+ # test casting, both to and from misaligned
8435+ with suppress_warnings() as sup:
8436+ sup.filter(np.ComplexWarning, "Casting complex values")
8437+ xc64.astype('f8')
8438+ xf64.astype(np.complex64)
8439+ test = xc64 + xf64
8440+
8441+ xf128.astype('f8')
8442+ xf64.astype(np.longdouble)
8443+ test = xf128 + xf64
8444+
8445+ test = xf128 + xc64
8446+
8447+ # test copy, both to and from misaligned
8448+ # contig copy
8449+ xf64[:] = xf64.copy()
8450+ xc64[:] = xc64.copy()
8451+ xf128[:] = xf128.copy()
8452+ # strided copy
8453+ xf64[::2] = xf64[::2].copy()
8454+ xc64[::2] = xc64[::2].copy()
8455+ xf128[::2] = xf128[::2].copy()
8456+
8457+def test_getfield():
8458+ a = np.arange(32, dtype='uint16')
8459+ if sys.byteorder == 'little':
8460+ i = 0
8461+ j = 1
8462+ else:
8463+ i = 1
8464+ j = 0
8465+ b = a.getfield('int8', i)
8466+ assert_equal(b, a)
8467+ b = a.getfield('int8', j)
8468+ assert_equal(b, 0)
8469+ pytest.raises(ValueError, a.getfield, 'uint8', -1)
8470+ pytest.raises(ValueError, a.getfield, 'uint8', 16)
8471+ pytest.raises(ValueError, a.getfield, 'uint64', 0)