Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

alkaline-ml / numpy   python

Repository URL to install this package:

Version: 1.19.1 

/ core / tests / test_umath.py

import platform
import warnings
import fnmatch
import itertools
import pytest
from fractions import Fraction

import numpy.core.umath as ncu
from numpy.core import _umath_tests as ncu_tests
import numpy as np
from numpy.testing import (
    assert_, assert_equal, assert_raises, assert_raises_regex,
    assert_array_equal, assert_almost_equal, assert_array_almost_equal,
    assert_array_max_ulp, assert_allclose, assert_no_warnings, suppress_warnings,
    _gen_alignment_data, assert_array_almost_equal_nulp
    )

def on_powerpc():
    """ True if we are running on a Power PC platform."""
    return platform.processor() == 'powerpc' or \
           platform.machine().startswith('ppc')


def bad_arcsinh():
    """The blacklisted trig functions are not accurate on aarch64 for
    complex256. Rather than dig through the actual problem skip the
    test. This should be fixed when we can move past glibc2.17
    which is the version in manylinux2014
    """
    x = 1.78e-10
    v1 = np.arcsinh(np.float128(x))
    v2 = np.arcsinh(np.complex256(x)).real
    # The eps for float128 is 1-e33, so this is way bigger
    return abs((v1 / v2) - 1.0) > 1e-23

if platform.machine() == 'aarch64' and bad_arcsinh():
    skip_longcomplex_msg = ('Trig functions of np.longcomplex values known to be '
                            'inaccurate on aarch64 for some compilation '
                            'configurations, should be fixed by building on a '
                            'platform using glibc>2.17')
else:
    skip_longcomplex_msg = ''


class _FilterInvalids:
    def setup(self):
        self.olderr = np.seterr(invalid='ignore')

    def teardown(self):
        np.seterr(**self.olderr)


class TestConstants:
    def test_pi(self):
        assert_allclose(ncu.pi, 3.141592653589793, 1e-15)

    def test_e(self):
        assert_allclose(ncu.e, 2.718281828459045, 1e-15)

    def test_euler_gamma(self):
        assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15)


class TestOut:
    def test_out_subok(self):
        for subok in (True, False):
            a = np.array(0.5)
            o = np.empty(())

            r = np.add(a, 2, o, subok=subok)
            assert_(r is o)
            r = np.add(a, 2, out=o, subok=subok)
            assert_(r is o)
            r = np.add(a, 2, out=(o,), subok=subok)
            assert_(r is o)

            d = np.array(5.7)
            o1 = np.empty(())
            o2 = np.empty((), dtype=np.int32)

            r1, r2 = np.frexp(d, o1, None, subok=subok)
            assert_(r1 is o1)
            r1, r2 = np.frexp(d, None, o2, subok=subok)
            assert_(r2 is o2)
            r1, r2 = np.frexp(d, o1, o2, subok=subok)
            assert_(r1 is o1)
            assert_(r2 is o2)

            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
            assert_(r1 is o1)
            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
            assert_(r2 is o2)
            r1, r2 = np.frexp(d, out=(o1, o2), subok=subok)
            assert_(r1 is o1)
            assert_(r2 is o2)

            with assert_raises(TypeError):
                # Out argument must be tuple, since there are multiple outputs.
                r1, r2 = np.frexp(d, out=o1, subok=subok)

            assert_raises(ValueError, np.add, a, 2, o, o, subok=subok)
            assert_raises(ValueError, np.add, a, 2, o, out=o, subok=subok)
            assert_raises(ValueError, np.add, a, 2, None, out=o, subok=subok)
            assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok)
            assert_raises(ValueError, np.add, a, 2, out=(), subok=subok)
            assert_raises(TypeError, np.add, a, 2, [], subok=subok)
            assert_raises(TypeError, np.add, a, 2, out=[], subok=subok)
            assert_raises(TypeError, np.add, a, 2, out=([],), subok=subok)
            o.flags.writeable = False
            assert_raises(ValueError, np.add, a, 2, o, subok=subok)
            assert_raises(ValueError, np.add, a, 2, out=o, subok=subok)
            assert_raises(ValueError, np.add, a, 2, out=(o,), subok=subok)

    def test_out_wrap_subok(self):
        class ArrayWrap(np.ndarray):
            __array_priority__ = 10

            def __new__(cls, arr):
                return np.asarray(arr).view(cls).copy()

            def __array_wrap__(self, arr, context):
                return arr.view(type(self))

        for subok in (True, False):
            a = ArrayWrap([0.5])

            r = np.add(a, 2, subok=subok)
            if subok:
                assert_(isinstance(r, ArrayWrap))
            else:
                assert_(type(r) == np.ndarray)

            r = np.add(a, 2, None, subok=subok)
            if subok:
                assert_(isinstance(r, ArrayWrap))
            else:
                assert_(type(r) == np.ndarray)

            r = np.add(a, 2, out=None, subok=subok)
            if subok:
                assert_(isinstance(r, ArrayWrap))
            else:
                assert_(type(r) == np.ndarray)

            r = np.add(a, 2, out=(None,), subok=subok)
            if subok:
                assert_(isinstance(r, ArrayWrap))
            else:
                assert_(type(r) == np.ndarray)

            d = ArrayWrap([5.7])
            o1 = np.empty((1,))
            o2 = np.empty((1,), dtype=np.int32)

            r1, r2 = np.frexp(d, o1, subok=subok)
            if subok:
                assert_(isinstance(r2, ArrayWrap))
            else:
                assert_(type(r2) == np.ndarray)

            r1, r2 = np.frexp(d, o1, None, subok=subok)
            if subok:
                assert_(isinstance(r2, ArrayWrap))
            else:
                assert_(type(r2) == np.ndarray)

            r1, r2 = np.frexp(d, None, o2, subok=subok)
            if subok:
                assert_(isinstance(r1, ArrayWrap))
            else:
                assert_(type(r1) == np.ndarray)

            r1, r2 = np.frexp(d, out=(o1, None), subok=subok)
            if subok:
                assert_(isinstance(r2, ArrayWrap))
            else:
                assert_(type(r2) == np.ndarray)

            r1, r2 = np.frexp(d, out=(None, o2), subok=subok)
            if subok:
                assert_(isinstance(r1, ArrayWrap))
            else:
                assert_(type(r1) == np.ndarray)

            with assert_raises(TypeError):
                # Out argument must be tuple, since there are multiple outputs.
                r1, r2 = np.frexp(d, out=o1, subok=subok)


class TestComparisons:
    def test_ignore_object_identity_in_equal(self):
        # Check comparing identical objects whose comparison
        # is not a simple boolean, e.g., arrays that are compared elementwise.
        a = np.array([np.array([1, 2, 3]), None], dtype=object)
        assert_raises(ValueError, np.equal, a, a)

        # Check error raised when comparing identical non-comparable objects.
        class FunkyType:
            def __eq__(self, other):
                raise TypeError("I won't compare")

        a = np.array([FunkyType()])
        assert_raises(TypeError, np.equal, a, a)

        # Check identity doesn't override comparison mismatch.
        a = np.array([np.nan], dtype=object)
        assert_equal(np.equal(a, a), [False])

    def test_ignore_object_identity_in_not_equal(self):
        # Check comparing identical objects whose comparison
        # is not a simple boolean, e.g., arrays that are compared elementwise.
        a = np.array([np.array([1, 2, 3]), None], dtype=object)
        assert_raises(ValueError, np.not_equal, a, a)

        # Check error raised when comparing identical non-comparable objects.
        class FunkyType:
            def __ne__(self, other):
                raise TypeError("I won't compare")

        a = np.array([FunkyType()])
        assert_raises(TypeError, np.not_equal, a, a)

        # Check identity doesn't override comparison mismatch.
        a = np.array([np.nan], dtype=object)
        assert_equal(np.not_equal(a, a), [True])


class TestAdd:
    def test_reduce_alignment(self):
        # gh-9876
        # make sure arrays with weird strides work with the optimizations in
        # pairwise_sum_@TYPE@. On x86, the 'b' field will count as aligned at a
        # 4 byte offset, even though its itemsize is 8.
        a = np.zeros(2, dtype=[('a', np.int32), ('b', np.float64)])
        a['a'] = -1
        assert_equal(a['b'].sum(), 0)


class TestDivision:
    def test_division_int(self):
        # int division should follow Python
        x = np.array([5, 10, 90, 100, -5, -10, -90, -100, -120])
        if 5 / 10 == 0.5:
            assert_equal(x / 100, [0.05, 0.1, 0.9, 1,
                                   -0.05, -0.1, -0.9, -1, -1.2])
        else:
            assert_equal(x / 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
        assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
        assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80])

    def test_division_complex(self):
        # check that implementation is correct
        msg = "Complex division implementation check"
        x = np.array([1. + 1.*1j, 1. + .5*1j, 1. + 2.*1j], dtype=np.complex128)
        assert_almost_equal(x**2/x, x, err_msg=msg)
        # check overflow, underflow
        msg = "Complex division overflow/underflow check"
        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
        y = x**2/x
        assert_almost_equal(y/x, [1, 1], err_msg=msg)

    def test_zero_division_complex(self):
        with np.errstate(invalid="ignore", divide="ignore"):
            x = np.array([0.0], dtype=np.complex128)
            y = 1.0/x
            assert_(np.isinf(y)[0])
            y = complex(np.inf, np.nan)/x
            assert_(np.isinf(y)[0])
            y = complex(np.nan, np.inf)/x
            assert_(np.isinf(y)[0])
            y = complex(np.inf, np.inf)/x
            assert_(np.isinf(y)[0])
            y = 0.0/x
            assert_(np.isnan(y)[0])

    def test_floor_division_complex(self):
        # check that implementation is correct
        msg = "Complex floor division implementation check"
        x = np.array([.9 + 1j, -.1 + 1j, .9 + .5*1j, .9 + 2.*1j], dtype=np.complex128)
        y = np.array([0., -1., 0., 0.], dtype=np.complex128)
        assert_equal(np.floor_divide(x**2, x), y, err_msg=msg)
        # check overflow, underflow
        msg = "Complex floor division overflow/underflow check"
        x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
        y = np.floor_divide(x**2, x)
        assert_equal(y, [1.e+110, 0], err_msg=msg)

    def test_floor_division_signed_zero(self):
        # Check that the sign bit is correctly set when dividing positive and
        # negative zero by one.
        x = np.zeros(10)
        assert_equal(np.signbit(x//1), 0)
        assert_equal(np.signbit((-x)//1), 1)

def floor_divide_and_remainder(x, y):
    return (np.floor_divide(x, y), np.remainder(x, y))


def _signs(dt):
    if dt in np.typecodes['UnsignedInteger']:
        return (+1,)
    else:
        return (+1, -1)


class TestRemainder:

    def test_remainder_basic(self):
        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
        for op in [floor_divide_and_remainder, np.divmod]:
            for dt1, dt2 in itertools.product(dt, dt):
                for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)):
                    fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
                    msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
                    a = np.array(sg1*71, dtype=dt1)
                    b = np.array(sg2*19, dtype=dt2)
                    div, rem = op(a, b)
                    assert_equal(div*b + rem, a, err_msg=msg)
                    if sg2 == -1:
                        assert_(b < rem <= 0, msg)
                    else:
                        assert_(b > rem >= 0, msg)

    def test_float_remainder_exact(self):
        # test that float results are exact for small integers. This also
        # holds for the same integers scaled by powers of two.
        nlst = list(range(-127, 0))
        plst = list(range(1, 128))
        dividend = nlst + [0] + plst
        divisor = nlst + plst
        arg = list(itertools.product(dividend, divisor))
        tgt = list(divmod(*t) for t in arg)

        a, b = np.array(arg, dtype=int).T
        # convert exact integer results from Python to float so that
        # signed zero can be used, it is checked.
        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)

        for op in [floor_divide_and_remainder, np.divmod]:
            for dt in np.typecodes['Float']:
                msg = 'op: %s, dtype: %s' % (op.__name__, dt)
                fa = a.astype(dt)
                fb = b.astype(dt)
Loading ...