Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
test_umath.py4976 linesDownload Raw Back to tests
1import fnmatch
2import inspect
3import itertools
4import operator
5import platform
6import sys
7import warnings
8from collections import namedtuple
9from fractions import Fraction
10from functools import reduce
11
12import pytest
13
14import numpy as np
15import numpy._core.umath as ncu
16from numpy._core import _umath_tests as ncu_tests, sctypes
17from numpy.testing import (
18    HAS_REFCOUNT,
19    IS_MUSL,
20    IS_PYPY,
21    IS_WASM,
22    _gen_alignment_data,
23    assert_,
24    assert_allclose,
25    assert_almost_equal,
26    assert_array_almost_equal,
27    assert_array_almost_equal_nulp,
28    assert_array_equal,
29    assert_array_max_ulp,
30    assert_equal,
31    assert_no_warnings,
32    assert_raises,
33    assert_raises_regex,
34)
35from numpy.testing._private.utils import _glibc_older_than
36
37UFUNCS = [obj for obj in np._core.umath.__dict__.values()
38         if isinstance(obj, np.ufunc)]
39
40UFUNCS_UNARY = [
41    uf for uf in UFUNCS if uf.nin == 1
42]
43UFUNCS_UNARY_FP = [
44    uf for uf in UFUNCS_UNARY if 'f->f' in uf.types
45]
46
47UFUNCS_BINARY = [
48    uf for uf in UFUNCS if uf.nin == 2
49]
50UFUNCS_BINARY_ACC = [
51    uf for uf in UFUNCS_BINARY if hasattr(uf, "accumulate") and uf.nout == 1
52]
53
54def interesting_binop_operands(val1, val2, dtype):
55    """
56    Helper to create "interesting" operands to cover common code paths:
57    * scalar inputs
58    * only first "values" is an array (e.g. scalar division fast-paths)
59    * Longer array (SIMD) placing the value of interest at different positions
60    * Oddly strided arrays which may not be SIMD compatible
61
62    It does not attempt to cover unaligned access or mixed dtypes.
63    These are normally handled by the casting/buffering machinery.
64
65    This is not a fixture (currently), since I believe a fixture normally
66    only yields once?
67    """
68    fill_value = 1  # could be a parameter, but maybe not an optional one?
69
70    arr1 = np.full(10003, dtype=dtype, fill_value=fill_value)
71    arr2 = np.full(10003, dtype=dtype, fill_value=fill_value)
72
73    arr1[0] = val1
74    arr2[0] = val2
75
76    extractor = lambda res: res
77    yield arr1[0], arr2[0], extractor, "scalars"
78
79    extractor = lambda res: res
80    yield arr1[0, ...], arr2[0, ...], extractor, "scalar-arrays"
81
82    # reset array values to fill_value:
83    arr1[0] = fill_value
84    arr2[0] = fill_value
85
86    for pos in [0, 1, 2, 3, 4, 5, -1, -2, -3, -4]:
87        arr1[pos] = val1
88        arr2[pos] = val2
89
90        extractor = lambda res: res[pos]
91        yield arr1, arr2, extractor, f"off-{pos}"
92        yield arr1, arr2[pos], extractor, f"off-{pos}-with-scalar"
93
94        arr1[pos] = fill_value
95        arr2[pos] = fill_value
96
97    for stride in [-1, 113]:
98        op1 = arr1[::stride]
99        op2 = arr2[::stride]
100        op1[10] = val1
101        op2[10] = val2
102
103        extractor = lambda res: res[10]
104        yield op1, op2, extractor, f"stride-{stride}"
105
106        op1[10] = fill_value
107        op2[10] = fill_value
108
109
110def on_powerpc():
111    """ True if we are running on a Power PC platform."""
112    return platform.processor() == 'powerpc' or \
113           platform.machine().startswith('ppc')
114
115
116def bad_arcsinh():
117    """The blocklisted trig functions are not accurate on aarch64/PPC for
118    complex256. Rather than dig through the actual problem skip the
119    test. This should be fixed when we can move past glibc2.17
120    which is the version in manylinux2014
121    """
122    if platform.machine() == 'aarch64':
123        x = 1.78e-10
124    elif on_powerpc():
125        x = 2.16e-10
126    else:
127        return False
128    v1 = np.arcsinh(np.float128(x))
129    v2 = np.arcsinh(np.complex256(x)).real
130    # The eps for float128 is 1-e33, so this is way bigger
131    return abs((v1 / v2) - 1.0) > 1e-23
132
133
134class _FilterInvalids:
135    def setup_method(self):
136        self.olderr = np.seterr(invalid='ignore')
137
138    def teardown_method(self):
139        np.seterr(**self.olderr)
140
141
142class TestConstants:
143    def test_pi(self):
144        assert_allclose(ncu.pi, 3.141592653589793, 1e-15)
145
146    def test_e(self):
147        assert_allclose(ncu.e, 2.718281828459045, 1e-15)
148
149    def test_euler_gamma(self):
150        assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15)
151
152
153class TestOut:
154    def test_out_subok(self):
155        for subok in (True, False):
156            a = np.array(0.5)
157            o = np.empty(())
158
159            r = np.add(a, 2, o, subok=subok)
160            assert_(r is o)
161            r = np.add(a, 2, out=o, subok=subok)
162            assert_(r is o)
163            r = np.add(a, 2, out=(o,), subok=subok)
164            assert_(r is o)
165
166            d = np.array(5.7)
167            o1 = np.empty(())
168            o2 = np.empty((), dtype=np.int32)
169
170            r1, r2 = np.frexp(d, o1, None, subok=subok)
171            assert_(r1 is o1)
172            r1, r2 = np.frexp(d, None, o2, subok=subok)
173            assert_(r2 is o2)
174            r1, r2 = np.frexp(d, o1, o2, subok=subok)
175            assert_(r1 is o1)
176            assert_(r2 is o2)
177
178            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
179            assert_(r1 is o1)
180            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
181            assert_(r2 is o2)
182            r1, r2 = np.frexp(d, out=(o1, o2), subok=subok)
183            assert_(r1 is o1)
184            assert_(r2 is o2)
185
186            with assert_raises(TypeError):
187                # Out argument must be tuple, since there are multiple outputs.
188                r1, r2 = np.frexp(d, out=o1, subok=subok)
189
190            assert_raises(TypeError, np.add, a, 2, o, o, subok=subok)
191            assert_raises(TypeError, np.add, a, 2, o, out=o, subok=subok)
192            assert_raises(TypeError, np.add, a, 2, None, out=o, subok=subok)
193            assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok)
194            assert_raises(ValueError, np.add, a, 2, out=(), subok=subok)
195            assert_raises(TypeError, np.add, a, 2, [], subok=subok)
196            assert_raises(TypeError, np.add, a, 2, out=[], subok=subok)
197            assert_raises(TypeError, np.add, a, 2, out=([],), subok=subok)
198            o.flags.writeable = False
199            assert_raises(ValueError, np.add, a, 2, o, subok=subok)
200            assert_raises(ValueError, np.add, a, 2, out=o, subok=subok)
201            assert_raises(ValueError, np.add, a, 2, out=(o,), subok=subok)
202
203    def test_out_wrap_subok(self):
204        class ArrayWrap(np.ndarray):
205            __array_priority__ = 10
206
207            def __new__(cls, arr):
208                return np.asarray(arr).view(cls).copy()
209
210            def __array_wrap__(self, arr, context=None, return_scalar=False):
211                return arr.view(type(self))
212
213        for subok in (True, False):
214            a = ArrayWrap([0.5])
215
216            r = np.add(a, 2, subok=subok)
217            if subok:
218                assert_(isinstance(r, ArrayWrap))
219            else:
220                assert_(type(r) == np.ndarray)
221
222            r = np.add(a, 2, None, subok=subok)
223            if subok:
224                assert_(isinstance(r, ArrayWrap))
225            else:
226                assert_(type(r) == np.ndarray)
227
228            r = np.add(a, 2, out=None, subok=subok)
229            if subok:
230                assert_(isinstance(r, ArrayWrap))
231            else:
232                assert_(type(r) == np.ndarray)
233
234            r = np.add(a, 2, out=(None,), subok=subok)
235            if subok:
236                assert_(isinstance(r, ArrayWrap))
237            else:
238                assert_(type(r) == np.ndarray)
239
240            d = ArrayWrap([5.7])
241            o1 = np.empty((1,))
242            o2 = np.empty((1,), dtype=np.int32)
243
244            r1, r2 = np.frexp(d, o1, subok=subok)
245            if subok:
246                assert_(isinstance(r2, ArrayWrap))
247            else:
248                assert_(type(r2) == np.ndarray)
249
250            r1, r2 = np.frexp(d, o1, None, subok=subok)
251            if subok:
252                assert_(isinstance(r2, ArrayWrap))
253            else:
254                assert_(type(r2) == np.ndarray)
255
256            r1, r2 = np.frexp(d, None, o2, subok=subok)
257            if subok:
258                assert_(isinstance(r1, ArrayWrap))
259            else:
260                assert_(type(r1) == np.ndarray)
261
262            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
263            if subok:
264                assert_(isinstance(r2, ArrayWrap))
265            else:
266                assert_(type(r2) == np.ndarray)
267
268            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
269            if subok:
270                assert_(isinstance(r1, ArrayWrap))
271            else:
272                assert_(type(r1) == np.ndarray)
273
274            with assert_raises(TypeError):
275                # Out argument must be tuple, since there are multiple outputs.
276                r1, r2 = np.frexp(d, out=o1, subok=subok)
277
278    @pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
279    def test_out_wrap_no_leak(self):
280        # Regression test for gh-26545
281        class ArrSubclass(np.ndarray):
282            pass
283
284        arr = np.arange(10).view(ArrSubclass)
285        orig_refcount = sys.getrefcount(arr)
286        arr *= 1
287        assert sys.getrefcount(arr) == orig_refcount
288
289
290class TestComparisons:
291    import operator
292
293    @pytest.mark.parametrize('dtype', sctypes['uint'] + sctypes['int'] +
294                             sctypes['float'] + [np.bool])
295    @pytest.mark.parametrize('py_comp,np_comp', [
296        (operator.lt, np.less),
297        (operator.le, np.less_equal),
298        (operator.gt, np.greater),
299        (operator.ge, np.greater_equal),
300        (operator.eq, np.equal),
301        (operator.ne, np.not_equal)
302    ])
303    def test_comparison_functions(self, dtype, py_comp, np_comp):
304        # Initialize input arrays
305        if dtype == np.bool:
306            a = np.random.choice(a=[False, True], size=1000)
307            b = np.random.choice(a=[False, True], size=1000)
308            scalar = True
309        else:
310            a = np.random.randint(low=1, high=10, size=1000).astype(dtype)
311            b = np.random.randint(low=1, high=10, size=1000).astype(dtype)
312            scalar = 5
313        np_scalar = np.dtype(dtype).type(scalar)
314        a_lst = a.tolist()
315        b_lst = b.tolist()
316
317        # (Binary) Comparison (x1=array, x2=array)
318        comp_b = np_comp(a, b).view(np.uint8)
319        comp_b_list = [int(py_comp(x, y)) for x, y in zip(a_lst, b_lst)]
320
321        # (Scalar1) Comparison (x1=scalar, x2=array)
322        comp_s1 = np_comp(np_scalar, b).view(np.uint8)
323        comp_s1_list = [int(py_comp(scalar, x)) for x in b_lst]
324
325        # (Scalar2) Comparison (x1=array, x2=scalar)
326        comp_s2 = np_comp(a, np_scalar).view(np.uint8)
327        comp_s2_list = [int(py_comp(x, scalar)) for x in a_lst]
328
329        # Sequence: Binary, Scalar1 and Scalar2
330        assert_(comp_b.tolist() == comp_b_list,
331            f"Failed comparison ({py_comp.__name__})")
332        assert_(comp_s1.tolist() == comp_s1_list,
333            f"Failed comparison ({py_comp.__name__})")
334        assert_(comp_s2.tolist() == comp_s2_list,
335            f"Failed comparison ({py_comp.__name__})")
336
337    def test_ignore_object_identity_in_equal(self):
338        # Check comparing identical objects whose comparison
339        # is not a simple boolean, e.g., arrays that are compared elementwise.
340        a = np.array([np.array([1, 2, 3]), None], dtype=object)
341        assert_raises(ValueError, np.equal, a, a)
342
343        # Check error raised when comparing identical non-comparable objects.
344        class FunkyType:
345            def __eq__(self, other):
346                raise TypeError("I won't compare")
347
348        a = np.array([FunkyType()])
349        assert_raises(TypeError, np.equal, a, a)
350
351        # Check identity doesn't override comparison mismatch.
352        a = np.array([np.nan], dtype=object)
353        assert_equal(np.equal(a, a), [False])
354
355    def test_ignore_object_identity_in_not_equal(self):
356        # Check comparing identical objects whose comparison
357        # is not a simple boolean, e.g., arrays that are compared elementwise.
358        a = np.array([np.array([1, 2, 3]), None], dtype=object)
359        assert_raises(ValueError, np.not_equal, a, a)
360
361        # Check error raised when comparing identical non-comparable objects.
362        class FunkyType:
363            def __ne__(self, other):
364                raise TypeError("I won't compare")
365
366        a = np.array([FunkyType()])
367        assert_raises(TypeError, np.not_equal, a, a)
368
369        # Check identity doesn't override comparison mismatch.
370        a = np.array([np.nan], dtype=object)
371        assert_equal(np.not_equal(a, a), [True])
372
373    def test_error_in_equal_reduce(self):
374        # gh-20929
375        # make sure np.equal.reduce raises a TypeError if an array is passed
376        # without specifying the dtype
377        a = np.array([0, 0])
378        assert_equal(np.equal.reduce(a, dtype=bool), True)
379        assert_raises(TypeError, np.equal.reduce, a)
380
381    def test_object_dtype(self):
382        assert np.equal(1, [1], dtype=object).dtype == object
383        assert np.equal(1, [1], signature=(None, None, "O")).dtype == object
384
385    def test_object_nonbool_dtype_error(self):
386        # bool output dtype is fine of course:
387        assert np.equal(1, [1], dtype=bool).dtype == bool
388
389        # but the following are examples do not have a loop:
390        with pytest.raises(TypeError, match="No loop matching"):
391            np.equal(1, 1, dtype=np.int64)
392
393        with pytest.raises(TypeError, match="No loop matching"):
394            np.equal(1, 1, sig=(None, None, "l"))
395
396    @pytest.mark.parametrize("dtypes", ["qQ", "Qq"])
397    @pytest.mark.parametrize('py_comp, np_comp', [
398        (operator.lt, np.less),
399        (operator.le, np.less_equal),
400        (operator.gt, np.greater),
401        (operator.ge, np.greater_equal),
402        (operator.eq, np.equal),
403        (operator.ne, np.not_equal)
404    ])
405    @pytest.mark.parametrize("vals", [(2**60, 2**60 + 1), (2**60 + 1, 2**60)])
406    def test_large_integer_direct_comparison(
407            self, dtypes, py_comp, np_comp, vals):
408        # Note that float(2**60) + 1 == float(2**60).
409        a1 = np.array([2**60], dtype=dtypes[0])
410        a2 = np.array([2**60 + 1], dtype=dtypes[1])
411        expected = py_comp(2**60, 2**60 + 1)
412
413        assert py_comp(a1, a2) == expected
414        assert np_comp(a1, a2) == expected
415        # Also check the scalars:
416        s1 = a1[0]
417        s2 = a2[0]
418        assert isinstance(s1, np.integer)
419        assert isinstance(s2, np.integer)
420        # The Python operator here is mainly interesting:
421        assert py_comp(s1, s2) == expected
422        assert np_comp(s1, s2) == expected
423
424    @pytest.mark.parametrize("dtype", np.typecodes['UnsignedInteger'])
425    @pytest.mark.parametrize('py_comp_func, np_comp_func', [
426        (operator.lt, np.less),
427        (operator.le, np.less_equal),
428        (operator.gt, np.greater),
429        (operator.ge, np.greater_equal),
430        (operator.eq, np.equal),
431        (operator.ne, np.not_equal)
432    ])
433    @pytest.mark.parametrize("flip", [True, False])
434    def test_unsigned_signed_direct_comparison(
435            self, dtype, py_comp_func, np_comp_func, flip):
436        if flip:
437            py_comp = lambda x, y: py_comp_func(y, x)
438            np_comp = lambda x, y: np_comp_func(y, x)
439        else:
440            py_comp = py_comp_func
441            np_comp = np_comp_func
442
443        arr = np.array([np.iinfo(dtype).max], dtype=dtype)
444        expected = py_comp(int(arr[0]), -1)
445
446        assert py_comp(arr, -1) == expected
447        assert np_comp(arr, -1) == expected
448
449        scalar = arr[0]
450        assert isinstance(scalar, np.integer)
451        # The Python operator here is mainly interesting:
452        assert py_comp(scalar, -1) == expected
453        assert np_comp(scalar, -1) == expected
454
455
456class TestAdd:
457    def test_reduce_alignment(self):
458        # gh-9876
459        # make sure arrays with weird strides work with the optimizations in
460        # pairwise_sum_@TYPE@. On x86, the 'b' field will count as aligned at a
461        # 4 byte offset, even though its itemsize is 8.
462        a = np.zeros(2, dtype=[('a', np.int32), ('b', np.float64)])
463        a['a'] = -1
464        assert_equal(a['b'].sum(), 0)
465
466
467class TestDivision:
468    def test_division_int(self):
469        # int division should follow Python
470        x = np.array([5, 10, 90, 100, -5, -10, -90, -100, -120])
471        if 5 / 10 == 0.5:
472            assert_equal(x / 100, [0.05, 0.1, 0.9, 1,
473                                   -0.05, -0.1, -0.9, -1, -1.2])
474        else:
475            assert_equal(x / 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
476        assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
477        assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80])
478
479    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
480    @pytest.mark.parametrize("dtype,ex_val", itertools.product(
481        sctypes['int'] + sctypes['uint'], (
482            (
483                # dividend
484                "np.array(range(fo.max-lsize, fo.max)).astype(dtype),"
485                # divisors
486                "np.arange(lsize).astype(dtype),"
487                # scalar divisors
488                "range(15)"
489            ),
490            (
491                # dividend
492                "np.arange(fo.min, fo.min+lsize).astype(dtype),"
493                # divisors
494                "np.arange(lsize//-2, lsize//2).astype(dtype),"
495                # scalar divisors
496                "range(fo.min, fo.min + 15)"
497            ), (
498                # dividend
499                "np.array(range(fo.max-lsize, fo.max)).astype(dtype),"
500                # divisors
501                "np.arange(lsize).astype(dtype),"
502                # scalar divisors
503                "[1,3,9,13,neg, fo.min+1, fo.min//2, fo.max//3, fo.max//4]"
504            )
505        )
506    ))
507    def test_division_int_boundary(self, dtype, ex_val):
508        fo = np.iinfo(dtype)
509        neg = -1 if fo.min < 0 else 1
510        # Large enough to test SIMD loops and remainder elements
511        lsize = 512 + 7
512        a, b, divisors = eval(ex_val)
513        a_lst, b_lst = a.tolist(), b.tolist()
514
515        c_div = lambda n, d: (
516            0 if d == 0 else (
517                fo.min if (n and n == fo.min and d == -1) else n // d
518            )
519        )
520        with np.errstate(divide='ignore'):
521            ac = a.copy()
522            ac //= b
523            div_ab = a // b
524        div_lst = [c_div(x, y) for x, y in zip(a_lst, b_lst)]
525
526        msg = "Integer arrays floor division check (//)"
527        assert all(div_ab == div_lst), msg
528        msg_eq = "Integer arrays floor division check (//=)"
529        assert all(ac == div_lst), msg_eq
530
531        for divisor in divisors:
532            ac = a.copy()
533            with np.errstate(divide='ignore', over='ignore'):
534                div_a = a // divisor
535                ac //= divisor
536            div_lst = [c_div(i, divisor) for i in a_lst]
537
538            assert all(div_a == div_lst), msg
539            assert all(ac == div_lst), msg_eq
540
541        with np.errstate(divide='raise', over='raise'):
542            if 0 in b:
543                # Verify overflow case
544                with pytest.raises(FloatingPointError,
545                        match="divide by zero encountered in floor_divide"):
546                    a // b
547            else:
548                a // b
549            if fo.min and fo.min in a:
550                with pytest.raises(FloatingPointError,
551                        match='overflow encountered in floor_divide'):
552                    a // -1
553            elif fo.min:
554                a // -1
555            with pytest.raises(FloatingPointError,
556                    match="divide by zero encountered in floor_divide"):
557                a // 0
558            with pytest.raises(FloatingPointError,
559                    match="divide by zero encountered in floor_divide"):
560                ac = a.copy()
561                ac //= 0
562
563            np.array([], dtype=dtype) // 0
564
565    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
566    @pytest.mark.parametrize("dtype,ex_val", itertools.product(
567        sctypes['int'] + sctypes['uint'], (
568            "np.array([fo.max, 1, 2, 1, 1, 2, 3], dtype=dtype)",
569            "np.array([fo.min, 1, -2, 1, 1, 2, -3]).astype(dtype)",
570            "np.arange(fo.min, fo.min+(100*10), 10, dtype=dtype)",
571            "np.array(range(fo.max-(100*7), fo.max, 7)).astype(dtype)",
572        )
573    ))
574    def test_division_int_reduce(self, dtype, ex_val):
575        fo = np.iinfo(dtype)
576        a = eval(ex_val)
577        lst = a.tolist()
578        c_div = lambda n, d: (
579            0 if d == 0 or (n and n == fo.min and d == -1) else n // d
580        )
581
582        with np.errstate(divide='ignore'):
583            div_a = np.floor_divide.reduce(a)
584        div_lst = reduce(c_div, lst)
585        msg = "Reduce floor integer division check"
586        assert div_a == div_lst, msg
587
588        with np.errstate(divide='raise', over='raise'):
589            with pytest.raises(FloatingPointError,
590                    match="divide by zero encountered in reduce"):
591                np.floor_divide.reduce(np.arange(-100, 100).astype(dtype))
592            if fo.min:
593                with pytest.raises(FloatingPointError,
594                        match='overflow encountered in reduce'):
595                    np.floor_divide.reduce(
596                        np.array([fo.min, 1, -1], dtype=dtype)
597                    )
598
599    @pytest.mark.parametrize(
600            "dividend,divisor,quotient",
601            [(np.timedelta64(2, 'Y'), np.timedelta64(2, 'M'), 12),
602             (np.timedelta64(2, 'Y'), np.timedelta64(-2, 'M'), -12),
603             (np.timedelta64(-2, 'Y'), np.timedelta64(2, 'M'), -12),
604             (np.timedelta64(-2, 'Y'), np.timedelta64(-2, 'M'), 12),
605             (np.timedelta64(2, 'M'), np.timedelta64(-2, 'Y'), -1),
606             (np.timedelta64(2, 'Y'), np.timedelta64(0, 'M'), 0),
607             (np.timedelta64(2, 'Y'), 2, np.timedelta64(1, 'Y')),
608             (np.timedelta64(2, 'Y'), -2, np.timedelta64(-1, 'Y')),
609             (np.timedelta64(-2, 'Y'), 2, np.timedelta64(-1, 'Y')),
610             (np.timedelta64(-2, 'Y'), -2, np.timedelta64(1, 'Y')),
611             (np.timedelta64(-2, 'Y'), -2, np.timedelta64(1, 'Y')),
612             (np.timedelta64(-2, 'Y'), -3, np.timedelta64(0, 'Y')),
613             (np.timedelta64(-2, 'Y'), 0, np.timedelta64('Nat', 'Y')),
614            ])
615    def test_division_int_timedelta(self, dividend, divisor, quotient):
616        # If either divisor is 0 or quotient is Nat, check for division by 0
617        if divisor and (isinstance(quotient, int) or not np.isnat(quotient)):
618            msg = "Timedelta floor division check"
619            assert dividend // divisor == quotient, msg
620
621            # Test for arrays as well
622            msg = "Timedelta arrays floor division check"
623            dividend_array = np.array([dividend] * 5)
624            quotient_array = np.array([quotient] * 5)
625            assert all(dividend_array // divisor == quotient_array), msg
626        else:
627            if IS_WASM:
628                pytest.skip("fp errors don't work in wasm")
629            with np.errstate(divide='raise', invalid='raise'):
630                with pytest.raises(FloatingPointError):
631                    dividend // divisor
632
633    def test_division_complex(self):
634        # check that implementation is correct
635        msg = "Complex division implementation check"
636        x = np.array([1. + 1. * 1j, 1. + .5 * 1j, 1. + 2. * 1j], dtype=np.complex128)
637        assert_almost_equal(x**2 / x, x, err_msg=msg)
638        # check overflow, underflow
639        msg = "Complex division overflow/underflow check"
640        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
641        y = x**2 / x
642        assert_almost_equal(y / x, [1, 1], err_msg=msg)
643
644    def test_zero_division_complex(self):
645        with np.errstate(invalid="ignore", divide="ignore"):
646            x = np.array([0.0], dtype=np.complex128)
647            y = 1.0 / x
648            assert_(np.isinf(y)[0])
649            y = complex(np.inf, np.nan) / x
650            assert_(np.isinf(y)[0])
651            y = complex(np.nan, np.inf) / x
652            assert_(np.isinf(y)[0])
653            y = complex(np.inf, np.inf) / x
654            assert_(np.isinf(y)[0])
655            y = 0.0 / x
656            assert_(np.isnan(y)[0])
657
658    def test_floor_division_complex(self):
659        # check that floor division, divmod and remainder raises type errors
660        x = np.array([.9 + 1j, -.1 + 1j, .9 + .5 * 1j, .9 + 2. * 1j], dtype=np.complex128)
661        with pytest.raises(TypeError):
662            x // 7
663        with pytest.raises(TypeError):
664            np.divmod(x, 7)
665        with pytest.raises(TypeError):
666            np.remainder(x, 7)
667
668    def test_floor_division_signed_zero(self):
669        # Check that the sign bit is correctly set when dividing positive and
670        # negative zero by one.
671        x = np.zeros(10)
672        assert_equal(np.signbit(x // 1), 0)
673        assert_equal(np.signbit((-x) // 1), 1)
674
675    @pytest.mark.skipif(hasattr(np.__config__, "blas_ssl2_info"),
676            reason="gh-22982")
677    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
678    @pytest.mark.parametrize('dtype', np.typecodes['Float'])
679    def test_floor_division_errors(self, dtype):
680        fnan = np.array(np.nan, dtype=dtype)
681        fone = np.array(1.0, dtype=dtype)
682        fzer = np.array(0.0, dtype=dtype)
683        finf = np.array(np.inf, dtype=dtype)
684        # divide by zero error check
685        with np.errstate(divide='raise', invalid='ignore'):
686            assert_raises(FloatingPointError, np.floor_divide, fone, fzer)
687        with np.errstate(divide='ignore', invalid='raise'):
688            np.floor_divide(fone, fzer)
689
690        # The following already contain a NaN and should not warn
691        with np.errstate(all='raise'):
692            np.floor_divide(fnan, fone)
693            np.floor_divide(fone, fnan)
694            np.floor_divide(fnan, fzer)
695            np.floor_divide(fzer, fnan)
696
697    @pytest.mark.parametrize('dtype', np.typecodes['Float'])
698    def test_floor_division_corner_cases(self, dtype):
699        # test corner cases like 1.0//0.0 for errors and return vals
700        x = np.zeros(10, dtype=dtype)
701        y = np.ones(10, dtype=dtype)
702        fnan = np.array(np.nan, dtype=dtype)
703        fone = np.array(1.0, dtype=dtype)
704        fzer = np.array(0.0, dtype=dtype)
705        finf = np.array(np.inf, dtype=dtype)
706        with warnings.catch_warnings():
707            warnings.filterwarnings('ignore', "invalid value encountered in floor_divide", RuntimeWarning)
708            div = np.floor_divide(fnan, fone)
709            assert np.isnan(div), f"div: {div}"
710            div = np.floor_divide(fone, fnan)
711            assert np.isnan(div), f"div: {div}"
712            div = np.floor_divide(fnan, fzer)
713            assert np.isnan(div), f"div: {div}"
714        # verify 1.0//0.0 computations return inf
715        with np.errstate(divide='ignore'):
716            z = np.floor_divide(y, x)
717            assert_(np.isinf(z).all())
718
719def floor_divide_and_remainder(x, y):
720    return (np.floor_divide(x, y), np.remainder(x, y))
721
722
723def _signs(dt):
724    if dt in np.typecodes['UnsignedInteger']:
725        return (+1,)
726    else:
727        return (+1, -1)
728
729
730class TestRemainder:
731
732    def test_remainder_basic(self):
733        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
734        for op in [floor_divide_and_remainder, np.divmod]:
735            for dt1, dt2 in itertools.product(dt, dt):
736                for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)):
737                    fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
738                    msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
739                    a = np.array(sg1 * 71, dtype=dt1)
740                    b = np.array(sg2 * 19, dtype=dt2)
741                    div, rem = op(a, b)
742                    assert_equal(div * b + rem, a, err_msg=msg)
743                    if sg2 == -1:
744                        assert_(b < rem <= 0, msg)
745                    else:
746                        assert_(b > rem >= 0, msg)
747
748    def test_float_remainder_exact(self):
749        # test that float results are exact for small integers. This also
750        # holds for the same integers scaled by powers of two.
751        nlst = list(range(-127, 0))
752        plst = list(range(1, 128))
753        dividend = nlst + [0] + plst
754        divisor = nlst + plst
755        arg = list(itertools.product(dividend, divisor))
756        tgt = [divmod(*t) for t in arg]
757
758        a, b = np.array(arg, dtype=int).T
759        # convert exact integer results from Python to float so that
760        # signed zero can be used, it is checked.
761        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
762        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
763        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)
764
765        for op in [floor_divide_and_remainder, np.divmod]:
766            for dt in np.typecodes['Float']:
767                msg = f'op: {op.__name__}, dtype: {dt}'
768                fa = a.astype(dt)
769                fb = b.astype(dt)
770                div, rem = op(fa, fb)
771                assert_equal(div, tgtdiv, err_msg=msg)
772                assert_equal(rem, tgtrem, err_msg=msg)
773
774    def test_float_remainder_roundoff(self):
775        # gh-6127
776        dt = np.typecodes['Float']
777        for op in [floor_divide_and_remainder, np.divmod]:
778            for dt1, dt2 in itertools.product(dt, dt):
779                for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
780                    fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
781                    msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
782                    a = np.array(sg1 * 78 * 6e-8, dtype=dt1)
783                    b = np.array(sg2 * 6e-8, dtype=dt2)
784                    div, rem = op(a, b)
785                    # Equal assertion should hold when fmod is used
786                    assert_equal(div * b + rem, a, err_msg=msg)
787                    if sg2 == -1:
788                        assert_(b < rem <= 0, msg)
789                    else:
790                        assert_(b > rem >= 0, msg)
791
792    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
793    @pytest.mark.xfail(sys.platform.startswith("darwin"),
794            reason="MacOS seems to not give the correct 'invalid' warning for "
795                   "`fmod`.  Hopefully, others always do.")
796    @pytest.mark.parametrize('dtype', np.typecodes['Float'])
797    def test_float_divmod_errors(self, dtype):
798        # Check valid errors raised for divmod and remainder
799        fzero = np.array(0.0, dtype=dtype)
800        fone = np.array(1.0, dtype=dtype)
801        finf = np.array(np.inf, dtype=dtype)
802        fnan = np.array(np.nan, dtype=dtype)
803        # since divmod is combination of both remainder and divide
804        # ops it will set both dividebyzero and invalid flags
805        with np.errstate(divide='raise', invalid='ignore'):
806            assert_raises(FloatingPointError, np.divmod, fone, fzero)
807        with np.errstate(divide='ignore', invalid='raise'):
808            assert_raises(FloatingPointError, np.divmod, fone, fzero)
809        with np.errstate(invalid='raise'):
810            assert_raises(FloatingPointError, np.divmod, fzero, fzero)
811        with np.errstate(invalid='raise'):
812            assert_raises(FloatingPointError, np.divmod, finf, finf)
813        with np.errstate(divide='ignore', invalid='raise'):
814            assert_raises(FloatingPointError, np.divmod, finf, fzero)
815        with np.errstate(divide='raise', invalid='ignore'):
816            # inf / 0 does not set any flags, only the modulo creates a NaN
817            np.divmod(finf, fzero)
818
819    @pytest.mark.skipif(hasattr(np.__config__, "blas_ssl2_info"),
820            reason="gh-22982")
821    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
822    @pytest.mark.xfail(sys.platform.startswith("darwin"),
823           reason="MacOS seems to not give the correct 'invalid' warning for "
824                  "`fmod`.  Hopefully, others always do.")
825    @pytest.mark.parametrize('dtype', np.typecodes['Float'])
826    @pytest.mark.parametrize('fn', [np.fmod, np.remainder])
827    def test_float_remainder_errors(self, dtype, fn):
828        fzero = np.array(0.0, dtype=dtype)
829        fone = np.array(1.0, dtype=dtype)
830        finf = np.array(np.inf, dtype=dtype)
831        fnan = np.array(np.nan, dtype=dtype)
832
833        # The following already contain a NaN and should not warn.
834        with np.errstate(all='raise'):
835            with pytest.raises(FloatingPointError,
836                    match="invalid value"):
837                fn(fone, fzero)
838            fn(fnan, fzero)
839            fn(fzero, fnan)
840            fn(fone, fnan)
841            fn(fnan, fone)
842
843    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
844    def test_float_remainder_overflow(self):
845        a = np.finfo(np.float64).tiny
846        with np.errstate(over='ignore', invalid='ignore'):
847            div, mod = np.divmod(4, a)
848            np.isinf(div)
849            assert_(mod == 0)
850        with np.errstate(over='raise', invalid='ignore'):
851            assert_raises(FloatingPointError, np.divmod, 4, a)
852        with np.errstate(invalid='raise', over='ignore'):
853            assert_raises(FloatingPointError, np.divmod, 4, a)
854
855    def test_float_divmod_corner_cases(self):
856        # check nan cases
857        for dt in np.typecodes['Float']:
858            fnan = np.array(np.nan, dtype=dt)
859            fone = np.array(1.0, dtype=dt)
860            fzer = np.array(0.0, dtype=dt)
861            finf = np.array(np.inf, dtype=dt)
862            with warnings.catch_warnings():
863                warnings.filterwarnings('ignore', "invalid value encountered in divmod", RuntimeWarning)
864                warnings.filterwarnings('ignore', "divide by zero encountered in divmod", RuntimeWarning)
865                div, rem = np.divmod(fone, fzer)
866                assert np.isinf(div), f'dt: {dt}, div: {rem}'
867                assert np.isnan(rem), f'dt: {dt}, rem: {rem}'
868                div, rem = np.divmod(fzer, fzer)
869                assert np.isnan(rem), f'dt: {dt}, rem: {rem}'
870                assert_(np.isnan(div)), f'dt: {dt}, rem: {rem}'
871                div, rem = np.divmod(finf, finf)
872                assert np.isnan(div), f'dt: {dt}, rem: {rem}'
873                assert np.isnan(rem), f'dt: {dt}, rem: {rem}'
874                div, rem = np.divmod(finf, fzer)
875                assert np.isinf(div), f'dt: {dt}, rem: {rem}'
876                assert np.isnan(rem), f'dt: {dt}, rem: {rem}'
877                div, rem = np.divmod(fnan, fone)
878                assert np.isnan(rem), f"dt: {dt}, rem: {rem}"
879                assert np.isnan(div), f"dt: {dt}, rem: {rem}"
880                div, rem = np.divmod(fone, fnan)
881                assert np.isnan(rem), f"dt: {dt}, rem: {rem}"
882                assert np.isnan(div), f"dt: {dt}, rem: {rem}"
883                div, rem = np.divmod(fnan, fzer)
884                assert np.isnan(rem), f"dt: {dt}, rem: {rem}"
885                assert np.isnan(div), f"dt: {dt}, rem: {rem}"
886
887    def test_float_remainder_corner_cases(self):
888        # Check remainder magnitude.
889        for dt in np.typecodes['Float']:
890            fone = np.array(1.0, dtype=dt)
891            fzer = np.array(0.0, dtype=dt)
892            fnan = np.array(np.nan, dtype=dt)
893            b = np.array(1.0, dtype=dt)
894            a = np.nextafter(np.array(0.0, dtype=dt), -b)
895            rem = np.remainder(a, b)
896            assert_(rem <= b, f'dt: {dt}')
897            rem = np.remainder(-a, -b)
898            assert_(rem >= -b, f'dt: {dt}')
899
900        # Check nans, inf
901        with warnings.catch_warnings():
902            warnings.filterwarnings('ignore', "invalid value encountered in remainder", RuntimeWarning)
903            warnings.filterwarnings('ignore', "invalid value encountered in fmod", RuntimeWarning)
904            for dt in np.typecodes['Float']:
905                fone = np.array(1.0, dtype=dt)
906                fzer = np.array(0.0, dtype=dt)
907                finf = np.array(np.inf, dtype=dt)
908                fnan = np.array(np.nan, dtype=dt)
909                rem = np.remainder(fone, fzer)
910                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
911                # MSVC 2008 returns NaN here, so disable the check.
912                #rem = np.remainder(fone, finf)
913                #assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem))
914                rem = np.remainder(finf, fone)
915                fmod = np.fmod(finf, fone)
916                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {fmod}')
917                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
918                rem = np.remainder(finf, finf)
919                fmod = np.fmod(finf, fone)
920                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
921                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {fmod}')
922                rem = np.remainder(finf, fzer)
923                fmod = np.fmod(finf, fzer)
924                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
925                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {fmod}')
926                rem = np.remainder(fone, fnan)
927                fmod = np.fmod(fone, fnan)
928                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
929                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {fmod}')
930                rem = np.remainder(fnan, fzer)
931                fmod = np.fmod(fnan, fzer)
932                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
933                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {rem}')
934                rem = np.remainder(fnan, fone)
935                fmod = np.fmod(fnan, fone)
936                assert_(np.isnan(rem), f'dt: {dt}, rem: {rem}')
937                assert_(np.isnan(fmod), f'dt: {dt}, fmod: {rem}')
938
939
940class TestDivisionIntegerOverflowsAndDivideByZero:
941    result_type = namedtuple('result_type',
942            ['nocast', 'casted'])
943    helper_lambdas = {
944        'zero': lambda dtype: 0,
945        'min': lambda dtype: np.iinfo(dtype).min,
946        'neg_min': lambda dtype: -np.iinfo(dtype).min,
947        'min-zero': lambda dtype: (np.iinfo(dtype).min, 0),
948        'neg_min-zero': lambda dtype: (-np.iinfo(dtype).min, 0),
949    }
950    overflow_results = {
951        np.remainder: result_type(
952            helper_lambdas['zero'], helper_lambdas['zero']),
953        np.fmod: result_type(
954            helper_lambdas['zero'], helper_lambdas['zero']),
955        operator.mod: result_type(
956            helper_lambdas['zero'], helper_lambdas['zero']),
957        operator.floordiv: result_type(
958            helper_lambdas['min'], helper_lambdas['neg_min']),
959        np.floor_divide: result_type(
960            helper_lambdas['min'], helper_lambdas['neg_min']),
961        np.divmod: result_type(
962            helper_lambdas['min-zero'], helper_lambdas['neg_min-zero'])
963    }
964
965    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
966    @pytest.mark.parametrize("dtype", np.typecodes["Integer"])
967    def test_signed_division_overflow(self, dtype):
968        to_check = interesting_binop_operands(np.iinfo(dtype).min, -1, dtype)
969        for op1, op2, extractor, operand_identifier in to_check:
970            with pytest.warns(RuntimeWarning, match="overflow encountered"):
971                res = op1 // op2
972
973            assert res.dtype == op1.dtype
974            assert extractor(res) == np.iinfo(op1.dtype).min
975
976            # Remainder is well defined though, and does not warn:
977            res = op1 % op2
978            assert res.dtype == op1.dtype
979            assert extractor(res) == 0
980            # Check fmod as well:
981            res = np.fmod(op1, op2)
982            assert extractor(res) == 0
983
984            # Divmod warns for the division part:
985            with pytest.warns(RuntimeWarning, match="overflow encountered"):
986                res1, res2 = np.divmod(op1, op2)
987
988            assert res1.dtype == res2.dtype == op1.dtype
989            assert extractor(res1) == np.iinfo(op1.dtype).min
990            assert extractor(res2) == 0
991
992    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
993    @pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
994    def test_divide_by_zero(self, dtype):
995        # Note that the return value cannot be well defined here, but NumPy
996        # currently uses 0 consistently.  This could be changed.
997        to_check = interesting_binop_operands(1, 0, dtype)
998        for op1, op2, extractor, operand_identifier in to_check:
999            with pytest.warns(RuntimeWarning, match="divide by zero"):
1000                res = op1 // op2
1001
1002            assert res.dtype == op1.dtype
1003            assert extractor(res) == 0
1004
1005            with pytest.warns(RuntimeWarning, match="divide by zero"):
1006                res1, res2 = np.divmod(op1, op2)
1007
1008            assert res1.dtype == res2.dtype == op1.dtype
1009            assert extractor(res1) == 0
1010            assert extractor(res2) == 0
1011
1012    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
1013    @pytest.mark.parametrize("dividend_dtype", sctypes['int'])
1014    @pytest.mark.parametrize("divisor_dtype", sctypes['int'])
1015    @pytest.mark.parametrize("operation",
1016            [np.remainder, np.fmod, np.divmod, np.floor_divide,
1017             operator.mod, operator.floordiv])
1018    @np.errstate(divide='warn', over='warn')
1019    def test_overflows(self, dividend_dtype, divisor_dtype, operation):
1020        # SIMD tries to perform the operation on as many elements as possible
1021        # that is a multiple of the register's size. We resort to the
1022        # default implementation for the leftover elements.
1023        # We try to cover all paths here.
1024        arrays = [np.array([np.iinfo(dividend_dtype).min] * i,
1025                           dtype=dividend_dtype) for i in range(1, 129)]
1026        divisor = np.array([-1], dtype=divisor_dtype)
1027        # If dividend is a larger type than the divisor (`else` case),
1028        # then, result will be a larger type than dividend and will not
1029        # result in an overflow for `divmod` and `floor_divide`.
1030        if np.dtype(dividend_dtype).itemsize >= np.dtype(
1031                divisor_dtype).itemsize and operation in (
1032                        np.divmod, np.floor_divide, operator.floordiv):
1033            with pytest.warns(
1034                    RuntimeWarning,
1035                    match="overflow encountered in"):
1036                result = operation(
1037                            dividend_dtype(np.iinfo(dividend_dtype).min),
1038                            divisor_dtype(-1)
1039                        )
1040                assert result == self.overflow_results[operation].nocast(
1041                        dividend_dtype)
1042
1043            # Arrays
1044            for a in arrays:
1045                # In case of divmod, we need to flatten the result
1046                # column first as we get a column vector of quotient and
1047                # remainder and a normal flatten of the expected result.
1048                with pytest.warns(
1049                        RuntimeWarning,
1050                        match="overflow encountered in"):
1051                    result = np.array(operation(a, divisor)).flatten('f')
1052                    expected_array = np.array(
1053                            [self.overflow_results[operation].nocast(
1054                                dividend_dtype)] * len(a)).flatten()
1055                    assert_array_equal(result, expected_array)
1056        else:
1057            # Scalars
1058            result = operation(
1059                        dividend_dtype(np.iinfo(dividend_dtype).min),
1060                        divisor_dtype(-1)
1061                    )
1062            assert result == self.overflow_results[operation].casted(
1063                    dividend_dtype)
1064
1065            # Arrays
1066            for a in arrays:
1067                # See above comment on flatten
1068                result = np.array(operation(a, divisor)).flatten('f')
1069                expected_array = np.array(
1070                        [self.overflow_results[operation].casted(
1071                            dividend_dtype)] * len(a)).flatten()
1072                assert_array_equal(result, expected_array)
1073
1074
1075class TestCbrt:
1076    def test_cbrt_scalar(self):
1077        assert_almost_equal((np.cbrt(np.float32(-2.5)**3)), -2.5)
1078
1079    def test_cbrt(self):
1080        x = np.array([1., 2., -3., np.inf, -np.inf])
1081        assert_almost_equal(np.cbrt(x**3), x)
1082
1083        assert_(np.isnan(np.cbrt(np.nan)))
1084        assert_equal(np.cbrt(np.inf), np.inf)
1085        assert_equal(np.cbrt(-np.inf), -np.inf)
1086
1087
1088class TestPower:
1089    def test_power_float(self):
1090        x = np.array([1., 2., 3.])
1091        assert_equal(x**0, [1., 1., 1.])
1092        assert_equal(x**1, x)
1093        assert_equal(x**2, [1., 4., 9.])
1094        y = x.copy()
1095        y **= 2
1096        assert_equal(y, [1., 4., 9.])
1097        assert_almost_equal(x**(-1), [1., 0.5, 1. / 3])
1098        assert_almost_equal(x**(0.5), [1., ncu.sqrt(2), ncu.sqrt(3)])
1099
1100        for out, inp, msg in _gen_alignment_data(dtype=np.float32,
1101                                                 type='unary',
1102                                                 max_size=11):
1103            exp = [ncu.sqrt(i) for i in inp]
1104            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
1105            np.sqrt(inp, out=out)
1106            assert_equal(out, exp, err_msg=msg)
1107
1108        for out, inp, msg in _gen_alignment_data(dtype=np.float64,
1109                                                 type='unary',
1110                                                 max_size=7):
1111            exp = [ncu.sqrt(i) for i in inp]
1112            assert_almost_equal(inp**(0.5), exp, err_msg=msg)
1113            np.sqrt(inp, out=out)
1114            assert_equal(out, exp, err_msg=msg)
1115
1116    def test_power_complex(self):
1117        x = np.array([1 + 2j, 2 + 3j, 3 + 4j])
1118        assert_equal(x**0, [1., 1., 1.])
1119        assert_equal(x**1, x)
1120        assert_almost_equal(x**2, [-3 + 4j, -5 + 12j, -7 + 24j])
1121        assert_almost_equal(x**3, [(1 + 2j)**3, (2 + 3j)**3, (3 + 4j)**3])
1122        assert_almost_equal(x**4, [(1 + 2j)**4, (2 + 3j)**4, (3 + 4j)**4])
1123        assert_almost_equal(x**(-1), [1 / (1 + 2j), 1 / (2 + 3j), 1 / (3 + 4j)])
1124        assert_almost_equal(x**(-2), [1 / (1 + 2j)**2, 1 / (2 + 3j)**2, 1 / (3 + 4j)**2])
1125        assert_almost_equal(x**(-3), [(-11 + 2j) / 125, (-46 - 9j) / 2197,
1126                                      (-117 - 44j) / 15625])
1127        assert_almost_equal(x**(0.5), [ncu.sqrt(1 + 2j), ncu.sqrt(2 + 3j),
1128                                       ncu.sqrt(3 + 4j)])
1129        norm = 1. / ((x**14)[0])
1130        assert_almost_equal(x**14 * norm,
1131                [i * norm for i in [-76443 + 16124j, 23161315 + 58317492j,
1132                                    5583548873 + 2465133864j]])
1133
1134        # Ticket #836
1135        def assert_complex_equal(x, y):
1136            assert_array_equal(x.real, y.real)
1137            assert_array_equal(x.imag, y.imag)
1138
1139        for z in [complex(0, np.inf), complex(1, np.inf)]:
1140            z = np.array([z], dtype=np.complex128)
1141            with np.errstate(invalid="ignore"):
1142                assert_complex_equal(z**1, z)
1143                assert_complex_equal(z**2, z * z)
1144                assert_complex_equal(z**3, z * z * z)
1145
1146    def test_power_zero(self):
1147        # ticket #1271
1148        zero = np.array([0j])
1149        one = np.array([1 + 0j])
1150        cnan = np.array([complex(np.nan, np.nan)])
1151        # FIXME cinf not tested.
1152        #cinf = np.array([complex(np.inf, 0)])
1153
1154        def assert_complex_equal(x, y):
1155            x, y = np.asarray(x), np.asarray(y)
1156            assert_array_equal(x.real, y.real)
1157            assert_array_equal(x.imag, y.imag)
1158
1159        # positive powers
1160        for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
1161            assert_complex_equal(np.power(zero, p), zero)
1162
1163        # zero power
1164        assert_complex_equal(np.power(zero, 0), one)
1165        with np.errstate(invalid="ignore"):
1166            assert_complex_equal(np.power(zero, 0 + 1j), cnan)
1167
1168            # negative power
1169            for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]:
1170                assert_complex_equal(np.power(zero, -p), cnan)
1171            assert_complex_equal(np.power(zero, -1 + 0.2j), cnan)
1172
1173    @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
1174    def test_zero_power_nonzero(self):
1175        # Testing 0^{Non-zero} issue 18378
1176        zero = np.array([0.0 + 0.0j])
1177        cnan = np.array([complex(np.nan, np.nan)])
1178
1179        def assert_complex_equal(x, y):
1180            assert_array_equal(x.real, y.real)
1181            assert_array_equal(x.imag, y.imag)
1182
1183        # Complex powers with positive real part will not generate a warning
1184        assert_complex_equal(np.power(zero, 1 + 4j), zero)
1185        assert_complex_equal(np.power(zero, 2 - 3j), zero)
1186        # Testing zero values when real part is greater than zero
1187        assert_complex_equal(np.power(zero, 1 + 1j), zero)
1188        assert_complex_equal(np.power(zero, 1 + 0j), zero)
1189        assert_complex_equal(np.power(zero, 1 - 1j), zero)
1190        # Complex powers will negative real part or 0 (provided imaginary
1191        # part is not zero) will generate a NAN and hence a RUNTIME warning
1192        with pytest.warns(expected_warning=RuntimeWarning) as r:
1193            assert_complex_equal(np.power(zero, -1 + 1j), cnan)
1194            assert_complex_equal(np.power(zero, -2 - 3j), cnan)
1195            assert_complex_equal(np.power(zero, -7 + 0j), cnan)
1196            assert_complex_equal(np.power(zero, 0 + 1j), cnan)
1197            assert_complex_equal(np.power(zero, 0 - 1j), cnan)
1198        assert len(r) == 5
1199
1200    def test_fast_power(self):

Showing the first 1,200 of 4976 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai