| from __future__ import division, absolute_import, print_function |
| |
| import sys |
| import platform |
| import warnings |
| import fnmatch |
| import itertools |
| |
| import numpy.core.umath as ncu |
| from numpy.core import umath_tests as ncu_tests |
| import numpy as np |
| from numpy.testing import ( |
| TestCase, run_module_suite, assert_, assert_equal, assert_raises, |
| assert_raises_regex, assert_array_equal, assert_almost_equal, |
| assert_array_almost_equal, dec, assert_allclose, assert_no_warnings, |
| suppress_warnings, _gen_alignment_data, |
| ) |
| |
| |
| def on_powerpc(): |
| """ True if we are running on a Power PC platform.""" |
| return platform.processor() == 'powerpc' or \ |
| platform.machine().startswith('ppc') |
| |
| |
| class _FilterInvalids(object): |
| def setUp(self): |
| self.olderr = np.seterr(invalid='ignore') |
| |
| def tearDown(self): |
| np.seterr(**self.olderr) |
| |
| |
| class TestConstants(TestCase): |
| 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(TestCase): |
| 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 warnings.catch_warnings(record=True) as w: |
| warnings.filterwarnings('always', '', DeprecationWarning) |
| r1, r2 = np.frexp(d, out=o1, subok=subok) |
| assert_(r1 is o1) |
| assert_(w[0].category is DeprecationWarning) |
| |
| 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 warnings.catch_warnings(record=True) as w: |
| warnings.filterwarnings('always', '', DeprecationWarning) |
| r1, r2 = np.frexp(d, out=o1, subok=subok) |
| if subok: |
| assert_(isinstance(r2, ArrayWrap)) |
| else: |
| assert_(type(r2) == np.ndarray) |
| assert_(w[0].category is DeprecationWarning) |
| |
| |
| class TestComparisons(TestCase): |
| def test_ignore_object_identity_in_equal(self): |
| # Check error raised when 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(object): |
| 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 error raised when 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(object): |
| 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 TestDivision(TestCase): |
| 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 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(TestCase): |
| |
| 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) |
| div, rem = op(fa, fb) |
| assert_equal(div, tgtdiv, err_msg=msg) |
| assert_equal(rem, tgtrem, err_msg=msg) |
| |
| def test_float_remainder_roundoff(self): |
| # gh-6127 |
| dt = 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((+1, -1), (+1, -1)): |
| fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s' |
| msg = fmt % (op.__name__, dt1, dt2, sg1, sg2) |
| a = np.array(sg1*78*6e-8, dtype=dt1) |
| b = np.array(sg2*6e-8, dtype=dt2) |
| div, rem = op(a, b) |
| # Equal assertion should hold when fmod is used |
| 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_corner_cases(self): |
| # Check remainder magnitude. |
| for dt in np.typecodes['Float']: |
| b = np.array(1.0, dtype=dt) |
| a = np.nextafter(np.array(0.0, dtype=dt), -b) |
| rem = np.remainder(a, b) |
| assert_(rem <= b, 'dt: %s' % dt) |
| rem = np.remainder(-a, -b) |
| assert_(rem >= -b, 'dt: %s' % dt) |
| |
| # Check nans, inf |
| with suppress_warnings() as sup: |
| sup.filter(RuntimeWarning, "invalid value encountered in remainder") |
| for dt in np.typecodes['Float']: |
| fone = np.array(1.0, dtype=dt) |
| fzer = np.array(0.0, dtype=dt) |
| finf = np.array(np.inf, dtype=dt) |
| fnan = np.array(np.nan, dtype=dt) |
| rem = np.remainder(fone, fzer) |
| assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) |
| # MSVC 2008 returns NaN here, so disable the check. |
| #rem = np.remainder(fone, finf) |
| #assert_(rem == fone, 'dt: %s, rem: %s' % (dt, rem)) |
| rem = np.remainder(fone, fnan) |
| assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) |
| rem = np.remainder(finf, fone) |
| assert_(np.isnan(rem), 'dt: %s, rem: %s' % (dt, rem)) |
| |
| |
| class TestCbrt(TestCase): |
| def test_cbrt_scalar(self): |
| assert_almost_equal((np.cbrt(np.float32(-2.5)**3)), -2.5) |
| |
| def test_cbrt(self): |
| x = np.array([1., 2., -3., np.inf, -np.inf]) |
| assert_almost_equal(np.cbrt(x**3), x) |
| |
| assert_(np.isnan(np.cbrt(np.nan))) |
| assert_equal(np.cbrt(np.inf), np.inf) |
| assert_equal(np.cbrt(-np.inf), -np.inf) |
| |
| |
| class TestPower(TestCase): |
| def test_power_float(self): |
| x = np.array([1., 2., 3.]) |
| assert_equal(x**0, [1., 1., 1.]) |
| assert_equal(x**1, x) |
| assert_equal(x**2, [1., 4., 9.]) |
| y = x.copy() |
| y **= 2 |
| assert_equal(y, [1., 4., 9.]) |
| assert_almost_equal(x**(-1), [1., 0.5, 1./3]) |
| assert_almost_equal(x**(0.5), [1., ncu.sqrt(2), ncu.sqrt(3)]) |
| |
| for out, inp, msg in _gen_alignment_data(dtype=np.float32, |
| type='unary', |
| max_size=11): |
| exp = [ncu.sqrt(i) for i in inp] |
| assert_almost_equal(inp**(0.5), exp, err_msg=msg) |
| np.sqrt(inp, out=out) |
| assert_equal(out, exp, err_msg=msg) |
| |
| for out, inp, msg in _gen_alignment_data(dtype=np.float64, |
| type='unary', |
| max_size=7): |
| exp = [ncu.sqrt(i) for i in inp] |
| assert_almost_equal(inp**(0.5), exp, err_msg=msg) |
| np.sqrt(inp, out=out) |
| assert_equal(out, exp, err_msg=msg) |
| |
| def test_power_complex(self): |
| x = np.array([1+2j, 2+3j, 3+4j]) |
| assert_equal(x**0, [1., 1., 1.]) |
| assert_equal(x**1, x) |
| assert_almost_equal(x**2, [-3+4j, -5+12j, -7+24j]) |
| assert_almost_equal(x**3, [(1+2j)**3, (2+3j)**3, (3+4j)**3]) |
| assert_almost_equal(x**4, [(1+2j)**4, (2+3j)**4, (3+4j)**4]) |
| assert_almost_equal(x**(-1), [1/(1+2j), 1/(2+3j), 1/(3+4j)]) |
| assert_almost_equal(x**(-2), [1/(1+2j)**2, 1/(2+3j)**2, 1/(3+4j)**2]) |
| assert_almost_equal(x**(-3), [(-11+2j)/125, (-46-9j)/2197, |
| (-117-44j)/15625]) |
| assert_almost_equal(x**(0.5), [ncu.sqrt(1+2j), ncu.sqrt(2+3j), |
| ncu.sqrt(3+4j)]) |
| norm = 1./((x**14)[0]) |
| assert_almost_equal(x**14 * norm, |
| [i * norm for i in [-76443+16124j, 23161315+58317492j, |
| 5583548873 + 2465133864j]]) |
| |
| # Ticket #836 |
| def assert_complex_equal(x, y): |
| assert_array_equal(x.real, y.real) |
| assert_array_equal(x.imag, y.imag) |
| |
| for z in [complex(0, np.inf), complex(1, np.inf)]: |
| z = np.array([z], dtype=np.complex_) |
| with np.errstate(invalid="ignore"): |
| assert_complex_equal(z**1, z) |
| assert_complex_equal(z**2, z*z) |
| assert_complex_equal(z**3, z*z*z) |
| |
| def test_power_zero(self): |
| # ticket #1271 |
| zero = np.array([0j]) |
| one = np.array([1+0j]) |
| cnan = np.array([complex(np.nan, np.nan)]) |
| # FIXME cinf not tested. |
| #cinf = np.array([complex(np.inf, 0)]) |
| |
| def assert_complex_equal(x, y): |
| x, y = np.asarray(x), np.asarray(y) |
| assert_array_equal(x.real, y.real) |
| assert_array_equal(x.imag, y.imag) |
| |
| # positive powers |
| for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]: |
| assert_complex_equal(np.power(zero, p), zero) |
| |
| # zero power |
| assert_complex_equal(np.power(zero, 0), one) |
| with np.errstate(invalid="ignore"): |
| assert_complex_equal(np.power(zero, 0+1j), cnan) |
| |
| # negative power |
| for p in [0.33, 0.5, 1, 1.5, 2, 3, 4, 5, 6.6]: |
| assert_complex_equal(np.power(zero, -p), cnan) |
| assert_complex_equal(np.power(zero, -1+0.2j), cnan) |
| |
| def test_fast_power(self): |
| x = np.array([1, 2, 3], np.int16) |
| res = x**2.0 |
| assert_((x**2.00001).dtype is res.dtype) |
| assert_array_equal(res, [1, 4, 9]) |
| # check the inplace operation on the casted copy doesn't mess with x |
| assert_(not np.may_share_memory(res, x)) |
| assert_array_equal(x, [1, 2, 3]) |
| |
| # Check that the fast path ignores 1-element not 0-d arrays |
| res = x ** np.array([[[2]]]) |
| assert_equal(res.shape, (1, 1, 3)) |
| |
| def test_integer_power(self): |
| a = np.array([15, 15], 'i8') |
| b = np.power(a, a) |
| assert_equal(b, [437893890380859375, 437893890380859375]) |
| |
| def test_integer_power_with_integer_zero_exponent(self): |
| dtypes = np.typecodes['Integer'] |
| for dt in dtypes: |
| arr = np.arange(-10, 10, dtype=dt) |
| assert_equal(np.power(arr, 0), np.ones_like(arr)) |
| |
| dtypes = np.typecodes['UnsignedInteger'] |
| for dt in dtypes: |
| arr = np.arange(10, dtype=dt) |
| assert_equal(np.power(arr, 0), np.ones_like(arr)) |
| |
| def test_integer_power_of_1(self): |
| dtypes = np.typecodes['AllInteger'] |
| for dt in dtypes: |
| arr = np.arange(10, dtype=dt) |
| assert_equal(np.power(1, arr), np.ones_like(arr)) |
| |
| def test_integer_power_of_zero(self): |
| dtypes = np.typecodes['AllInteger'] |
| for dt in dtypes: |
| arr = np.arange(1, 10, dtype=dt) |
| assert_equal(np.power(0, arr), np.zeros_like(arr)) |
| |
| def test_integer_to_negative_power(self): |
| dtypes = np.typecodes['Integer'] |
| for dt in dtypes: |
| a = np.array([0, 1, 2, 3], dtype=dt) |
| b = np.array([0, 1, 2, -3], dtype=dt) |
| one = np.array(1, dtype=dt) |
| minusone = np.array(-1, dtype=dt) |
| assert_raises(ValueError, np.power, a, b) |
| assert_raises(ValueError, np.power, a, minusone) |
| assert_raises(ValueError, np.power, one, b) |
| assert_raises(ValueError, np.power, one, minusone) |
| |
| |
| class TestFloat_power(TestCase): |
| def test_type_conversion(self): |
| arg_type = '?bhilBHILefdgFDG' |
| res_type = 'ddddddddddddgDDG' |
| for dtin, dtout in zip(arg_type, res_type): |
| msg = "dtin: %s, dtout: %s" % (dtin, dtout) |
| arg = np.ones(1, dtype=dtin) |
| res = np.float_power(arg, arg) |
| assert_(res.dtype.name == np.dtype(dtout).name, msg) |
| |
| |
| class TestLog2(TestCase): |
| def test_log2_values(self): |
| x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] |
| y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
| for dt in ['f', 'd', 'g']: |
| xf = np.array(x, dtype=dt) |
| yf = np.array(y, dtype=dt) |
| assert_almost_equal(np.log2(xf), yf) |
| |
| def test_log2_ints(self): |
| # a good log2 implementation should provide this, |
| # might fail on OS with bad libm |
| for i in range(1, 65): |
| v = np.log2(2.**i) |
| assert_equal(v, float(i), err_msg='at exponent %d' % i) |
| |
| def test_log2_special(self): |
| assert_equal(np.log2(1.), 0.) |
| assert_equal(np.log2(np.inf), np.inf) |
| assert_(np.isnan(np.log2(np.nan))) |
| |
| with warnings.catch_warnings(record=True) as w: |
| warnings.filterwarnings('always', '', RuntimeWarning) |
| assert_(np.isnan(np.log2(-1.))) |
| assert_(np.isnan(np.log2(-np.inf))) |
| assert_equal(np.log2(0.), -np.inf) |
| assert_(w[0].category is RuntimeWarning) |
| assert_(w[1].category is RuntimeWarning) |
| assert_(w[2].category is RuntimeWarning) |
| |
| |
| class TestExp2(TestCase): |
| def test_exp2_values(self): |
| x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] |
| y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
| for dt in ['f', 'd', 'g']: |
| xf = np.array(x, dtype=dt) |
| yf = np.array(y, dtype=dt) |
| assert_almost_equal(np.exp2(yf), xf) |
| |
| |
| class TestLogAddExp2(_FilterInvalids): |
| # Need test for intermediate precisions |
| def test_logaddexp2_values(self): |
| x = [1, 2, 3, 4, 5] |
| y = [5, 4, 3, 2, 1] |
| z = [6, 6, 6, 6, 6] |
| for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]): |
| xf = np.log2(np.array(x, dtype=dt)) |
| yf = np.log2(np.array(y, dtype=dt)) |
| zf = np.log2(np.array(z, dtype=dt)) |
| assert_almost_equal(np.logaddexp2(xf, yf), zf, decimal=dec_) |
| |
| def test_logaddexp2_range(self): |
| x = [1000000, -1000000, 1000200, -1000200] |
| y = [1000200, -1000200, 1000000, -1000000] |
| z = [1000200, -1000000, 1000200, -1000000] |
| for dt in ['f', 'd', 'g']: |
| logxf = np.array(x, dtype=dt) |
| logyf = np.array(y, dtype=dt) |
| logzf = np.array(z, dtype=dt) |
| assert_almost_equal(np.logaddexp2(logxf, logyf), logzf) |
| |
| def test_inf(self): |
| inf = np.inf |
| x = [inf, -inf, inf, -inf, inf, 1, -inf, 1] |
| y = [inf, inf, -inf, -inf, 1, inf, 1, -inf] |
| z = [inf, inf, inf, -inf, inf, inf, 1, 1] |
| with np.errstate(invalid='raise'): |
| for dt in ['f', 'd', 'g']: |
| logxf = np.array(x, dtype=dt) |
| logyf = np.array(y, dtype=dt) |
| logzf = np.array(z, dtype=dt) |
| assert_equal(np.logaddexp2(logxf, logyf), logzf) |
| |
| def test_nan(self): |
| assert_(np.isnan(np.logaddexp2(np.nan, np.inf))) |
| assert_(np.isnan(np.logaddexp2(np.inf, np.nan))) |
| assert_(np.isnan(np.logaddexp2(np.nan, 0))) |
| assert_(np.isnan(np.logaddexp2(0, np.nan))) |
| assert_(np.isnan(np.logaddexp2(np.nan, np.nan))) |
| |
| |
| class TestLog(TestCase): |
| def test_log_values(self): |
| x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] |
| y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
| for dt in ['f', 'd', 'g']: |
| log2_ = 0.69314718055994530943 |
| xf = np.array(x, dtype=dt) |
| yf = np.array(y, dtype=dt)*log2_ |
| assert_almost_equal(np.log(xf), yf) |
| |
| |
| class TestExp(TestCase): |
| def test_exp_values(self): |
| x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] |
| y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
| for dt in ['f', 'd', 'g']: |
| log2_ = 0.69314718055994530943 |
| xf = np.array(x, dtype=dt) |
| yf = np.array(y, dtype=dt)*log2_ |
| assert_almost_equal(np.exp(yf), xf) |
| |
| |
| class TestLogAddExp(_FilterInvalids): |
| def test_logaddexp_values(self): |
| x = [1, 2, 3, 4, 5] |
| y = [5, 4, 3, 2, 1] |
| z = [6, 6, 6, 6, 6] |
| for dt, dec_ in zip(['f', 'd', 'g'], [6, 15, 15]): |
| xf = np.log(np.array(x, dtype=dt)) |
| yf = np.log(np.array(y, dtype=dt)) |
| zf = np.log(np.array(z, dtype=dt)) |
| assert_almost_equal(np.logaddexp(xf, yf), zf, decimal=dec_) |
| |
| def test_logaddexp_range(self): |
| x = [1000000, -1000000, 1000200, -1000200] |
| y = [1000200, -1000200, 1000000, -1000000] |
| z = [1000200, -1000000, 1000200, -1000000] |
| for dt in ['f', 'd', 'g']: |
| logxf = np.array(x, dtype=dt) |
| logyf = np.array(y, dtype=dt) |
| logzf = np.array(z, dtype=dt) |
| assert_almost_equal(np.logaddexp(logxf, logyf), logzf) |
| |
| def test_inf(self): |
| inf = np.inf |
| x = [inf, -inf, inf, -inf, inf, 1, -inf, 1] |
| y = [inf, inf, -inf, -inf, 1, inf, 1, -inf] |
| z = [inf, inf, inf, -inf, inf, inf, 1, 1] |
| with np.errstate(invalid='raise'): |
| for dt in ['f', 'd', 'g']: |
| logxf = np.array(x, dtype=dt) |
| logyf = np.array(y, dtype=dt) |
| logzf = np.array(z, dtype=dt) |
| assert_equal(np.logaddexp(logxf, logyf), logzf) |
| |
| def test_nan(self): |
| assert_(np.isnan(np.logaddexp(np.nan, np.inf))) |
| assert_(np.isnan(np.logaddexp(np.inf, np.nan))) |
| assert_(np.isnan(np.logaddexp(np.nan, 0))) |
| assert_(np.isnan(np.logaddexp(0, np.nan))) |
| assert_(np.isnan(np.logaddexp(np.nan, np.nan))) |
| |
| |
| class TestLog1p(TestCase): |
| def test_log1p(self): |
| assert_almost_equal(ncu.log1p(0.2), ncu.log(1.2)) |
| assert_almost_equal(ncu.log1p(1e-6), ncu.log(1+1e-6)) |
| |
| def test_special(self): |
| with np.errstate(invalid="ignore", divide="ignore"): |
| assert_equal(ncu.log1p(np.nan), np.nan) |
| assert_equal(ncu.log1p(np.inf), np.inf) |
| assert_equal(ncu.log1p(-1.), -np.inf) |
| assert_equal(ncu.log1p(-2.), np.nan) |
| assert_equal(ncu.log1p(-np.inf), np.nan) |
| |
| |
| class TestExpm1(TestCase): |
| def test_expm1(self): |
| assert_almost_equal(ncu.expm1(0.2), ncu.exp(0.2)-1) |
| assert_almost_equal(ncu.expm1(1e-6), ncu.exp(1e-6)-1) |
| |
| def test_special(self): |
| assert_equal(ncu.expm1(np.inf), np.inf) |
| assert_equal(ncu.expm1(0.), 0.) |
| assert_equal(ncu.expm1(-0.), -0.) |
| assert_equal(ncu.expm1(np.inf), np.inf) |
| assert_equal(ncu.expm1(-np.inf), -1.) |
| |
| |
| class TestHypot(TestCase, object): |
| def test_simple(self): |
| assert_almost_equal(ncu.hypot(1, 1), ncu.sqrt(2)) |
| assert_almost_equal(ncu.hypot(0, 0), 0) |
| |
| def test_reduce(self): |
| assert_almost_equal(ncu.hypot.reduce([3.0, 4.0]), 5.0) |
| assert_almost_equal(ncu.hypot.reduce([3.0, 4.0, 0]), 5.0) |
| assert_almost_equal(ncu.hypot.reduce([9.0, 12.0, 20.0]), 25.0) |
| assert_equal(ncu.hypot.reduce([]), 0.0) |
| |
| |
| def assert_hypot_isnan(x, y): |
| with np.errstate(invalid='ignore'): |
| assert_(np.isnan(ncu.hypot(x, y)), |
| "hypot(%s, %s) is %s, not nan" % (x, y, ncu.hypot(x, y))) |
| |
| |
| def assert_hypot_isinf(x, y): |
| with np.errstate(invalid='ignore'): |
| assert_(np.isinf(ncu.hypot(x, y)), |
| "hypot(%s, %s) is %s, not inf" % (x, y, ncu.hypot(x, y))) |
| |
| |
| class TestHypotSpecialValues(TestCase): |
| def test_nan_outputs(self): |
| assert_hypot_isnan(np.nan, np.nan) |
| assert_hypot_isnan(np.nan, 1) |
| |
| def test_nan_outputs2(self): |
| assert_hypot_isinf(np.nan, np.inf) |
| assert_hypot_isinf(np.inf, np.nan) |
| assert_hypot_isinf(np.inf, 0) |
| assert_hypot_isinf(0, np.inf) |
| assert_hypot_isinf(np.inf, np.inf) |
| assert_hypot_isinf(np.inf, 23.0) |
| |
| def test_no_fpe(self): |
| assert_no_warnings(ncu.hypot, np.inf, 0) |
| |
| |
| def assert_arctan2_isnan(x, y): |
| assert_(np.isnan(ncu.arctan2(x, y)), "arctan(%s, %s) is %s, not nan" % (x, y, ncu.arctan2(x, y))) |
| |
| |
| def assert_arctan2_ispinf(x, y): |
| assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) > 0), "arctan(%s, %s) is %s, not +inf" % (x, y, ncu.arctan2(x, y))) |
| |
| |
| def assert_arctan2_isninf(x, y): |
| assert_((np.isinf(ncu.arctan2(x, y)) and ncu.arctan2(x, y) < 0), "arctan(%s, %s) is %s, not -inf" % (x, y, ncu.arctan2(x, y))) |
| |
| |
| def assert_arctan2_ispzero(x, y): |
| assert_((ncu.arctan2(x, y) == 0 and not np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not +0" % (x, y, ncu.arctan2(x, y))) |
| |
| |
| def assert_arctan2_isnzero(x, y): |
| assert_((ncu.arctan2(x, y) == 0 and np.signbit(ncu.arctan2(x, y))), "arctan(%s, %s) is %s, not -0" % (x, y, ncu.arctan2(x, y))) |
| |
| |
| class TestArctan2SpecialValues(TestCase): |
| def test_one_one(self): |
| # atan2(1, 1) returns pi/4. |
| assert_almost_equal(ncu.arctan2(1, 1), 0.25 * np.pi) |
| assert_almost_equal(ncu.arctan2(-1, 1), -0.25 * np.pi) |
| assert_almost_equal(ncu.arctan2(1, -1), 0.75 * np.pi) |
| |
| def test_zero_nzero(self): |
| # atan2(+-0, -0) returns +-pi. |
| assert_almost_equal(ncu.arctan2(np.PZERO, np.NZERO), np.pi) |
| assert_almost_equal(ncu.arctan2(np.NZERO, np.NZERO), -np.pi) |
| |
| def test_zero_pzero(self): |
| # atan2(+-0, +0) returns +-0. |
| assert_arctan2_ispzero(np.PZERO, np.PZERO) |
| assert_arctan2_isnzero(np.NZERO, np.PZERO) |
| |
| def test_zero_negative(self): |
| # atan2(+-0, x) returns +-pi for x < 0. |
| assert_almost_equal(ncu.arctan2(np.PZERO, -1), np.pi) |
| assert_almost_equal(ncu.arctan2(np.NZERO, -1), -np.pi) |
| |
| def test_zero_positive(self): |
| # atan2(+-0, x) returns +-0 for x > 0. |
| assert_arctan2_ispzero(np.PZERO, 1) |
| assert_arctan2_isnzero(np.NZERO, 1) |
| |
| def test_positive_zero(self): |
| # atan2(y, +-0) returns +pi/2 for y > 0. |
| assert_almost_equal(ncu.arctan2(1, np.PZERO), 0.5 * np.pi) |
| assert_almost_equal(ncu.arctan2(1, np.NZERO), 0.5 * np.pi) |
| |
| def test_negative_zero(self): |
| # atan2(y, +-0) returns -pi/2 for y < 0. |
| assert_almost_equal(ncu.arctan2(-1, np.PZERO), -0.5 * np.pi) |
| assert_almost_equal(ncu.arctan2(-1, np.NZERO), -0.5 * np.pi) |
| |
| def test_any_ninf(self): |
| # atan2(+-y, -infinity) returns +-pi for finite y > 0. |
| assert_almost_equal(ncu.arctan2(1, np.NINF), np.pi) |
| assert_almost_equal(ncu.arctan2(-1, np.NINF), -np.pi) |
| |
| def test_any_pinf(self): |
| # atan2(+-y, +infinity) returns +-0 for finite y > 0. |
| assert_arctan2_ispzero(1, np.inf) |
| assert_arctan2_isnzero(-1, np.inf) |
| |
| def test_inf_any(self): |
| # atan2(+-infinity, x) returns +-pi/2 for finite x. |
| assert_almost_equal(ncu.arctan2( np.inf, 1), 0.5 * np.pi) |
| assert_almost_equal(ncu.arctan2(-np.inf, 1), -0.5 * np.pi) |
| |
| def test_inf_ninf(self): |
| # atan2(+-infinity, -infinity) returns +-3*pi/4. |
| assert_almost_equal(ncu.arctan2( np.inf, -np.inf), 0.75 * np.pi) |
| assert_almost_equal(ncu.arctan2(-np.inf, -np.inf), -0.75 * np.pi) |
| |
| def test_inf_pinf(self): |
| # atan2(+-infinity, +infinity) returns +-pi/4. |
| assert_almost_equal(ncu.arctan2( np.inf, np.inf), 0.25 * np.pi) |
| assert_almost_equal(ncu.arctan2(-np.inf, np.inf), -0.25 * np.pi) |
| |
| def test_nan_any(self): |
| # atan2(nan, x) returns nan for any x, including inf |
| assert_arctan2_isnan(np.nan, np.inf) |
| assert_arctan2_isnan(np.inf, np.nan) |
| assert_arctan2_isnan(np.nan, np.nan) |
| |
| |
| class TestLdexp(TestCase): |
| def _check_ldexp(self, tp): |
| assert_almost_equal(ncu.ldexp(np.array(2., np.float32), |
| np.array(3, tp)), 16.) |
| assert_almost_equal(ncu.ldexp(np.array(2., np.float64), |
| np.array(3, tp)), 16.) |
| assert_almost_equal(ncu.ldexp(np.array(2., np.longdouble), |
| np.array(3, tp)), 16.) |
| |
| def test_ldexp(self): |
| # The default Python int type should work |
| assert_almost_equal(ncu.ldexp(2., 3), 16.) |
| # The following int types should all be accepted |
| self._check_ldexp(np.int8) |
| self._check_ldexp(np.int16) |
| self._check_ldexp(np.int32) |
| self._check_ldexp('i') |
| self._check_ldexp('l') |
| |
| def test_ldexp_overflow(self): |
| # silence warning emitted on overflow |
| with np.errstate(over="ignore"): |
| imax = np.iinfo(np.dtype('l')).max |
| imin = np.iinfo(np.dtype('l')).min |
| assert_equal(ncu.ldexp(2., imax), np.inf) |
| assert_equal(ncu.ldexp(2., imin), 0) |
| |
| |
| class TestMaximum(_FilterInvalids): |
| def test_reduce(self): |
| dflt = np.typecodes['AllFloat'] |
| dint = np.typecodes['AllInteger'] |
| seq1 = np.arange(11) |
| seq2 = seq1[::-1] |
| func = np.maximum.reduce |
| for dt in dint: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 10) |
| assert_equal(func(tmp2), 10) |
| for dt in dflt: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 10) |
| assert_equal(func(tmp2), 10) |
| tmp1[::2] = np.nan |
| tmp2[::2] = np.nan |
| assert_equal(func(tmp1), np.nan) |
| assert_equal(func(tmp2), np.nan) |
| |
| def test_reduce_complex(self): |
| assert_equal(np.maximum.reduce([1, 2j]), 1) |
| assert_equal(np.maximum.reduce([1+3j, 2j]), 1+3j) |
| |
| def test_float_nans(self): |
| nan = np.nan |
| arg1 = np.array([0, nan, nan]) |
| arg2 = np.array([nan, 0, nan]) |
| out = np.array([nan, nan, nan]) |
| assert_equal(np.maximum(arg1, arg2), out) |
| |
| def test_object_nans(self): |
| # Multiple checks to give this a chance to |
| # fail if cmp is used instead of rich compare. |
| # Failure cannot be guaranteed. |
| for i in range(1): |
| x = np.array(float('nan'), np.object) |
| y = 1.0 |
| z = np.array(float('nan'), np.object) |
| assert_(np.maximum(x, y) == 1.0) |
| assert_(np.maximum(z, y) == 1.0) |
| |
| def test_complex_nans(self): |
| nan = np.nan |
| for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: |
| arg1 = np.array([0, cnan, cnan], dtype=np.complex) |
| arg2 = np.array([cnan, 0, cnan], dtype=np.complex) |
| out = np.array([nan, nan, nan], dtype=np.complex) |
| assert_equal(np.maximum(arg1, arg2), out) |
| |
| def test_object_array(self): |
| arg1 = np.arange(5, dtype=np.object) |
| arg2 = arg1 + 1 |
| assert_equal(np.maximum(arg1, arg2), arg2) |
| |
| |
| class TestMinimum(_FilterInvalids): |
| def test_reduce(self): |
| dflt = np.typecodes['AllFloat'] |
| dint = np.typecodes['AllInteger'] |
| seq1 = np.arange(11) |
| seq2 = seq1[::-1] |
| func = np.minimum.reduce |
| for dt in dint: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 0) |
| assert_equal(func(tmp2), 0) |
| for dt in dflt: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 0) |
| assert_equal(func(tmp2), 0) |
| tmp1[::2] = np.nan |
| tmp2[::2] = np.nan |
| assert_equal(func(tmp1), np.nan) |
| assert_equal(func(tmp2), np.nan) |
| |
| def test_reduce_complex(self): |
| assert_equal(np.minimum.reduce([1, 2j]), 2j) |
| assert_equal(np.minimum.reduce([1+3j, 2j]), 2j) |
| |
| def test_float_nans(self): |
| nan = np.nan |
| arg1 = np.array([0, nan, nan]) |
| arg2 = np.array([nan, 0, nan]) |
| out = np.array([nan, nan, nan]) |
| assert_equal(np.minimum(arg1, arg2), out) |
| |
| def test_object_nans(self): |
| # Multiple checks to give this a chance to |
| # fail if cmp is used instead of rich compare. |
| # Failure cannot be guaranteed. |
| for i in range(1): |
| x = np.array(float('nan'), np.object) |
| y = 1.0 |
| z = np.array(float('nan'), np.object) |
| assert_(np.minimum(x, y) == 1.0) |
| assert_(np.minimum(z, y) == 1.0) |
| |
| def test_complex_nans(self): |
| nan = np.nan |
| for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: |
| arg1 = np.array([0, cnan, cnan], dtype=np.complex) |
| arg2 = np.array([cnan, 0, cnan], dtype=np.complex) |
| out = np.array([nan, nan, nan], dtype=np.complex) |
| assert_equal(np.minimum(arg1, arg2), out) |
| |
| def test_object_array(self): |
| arg1 = np.arange(5, dtype=np.object) |
| arg2 = arg1 + 1 |
| assert_equal(np.minimum(arg1, arg2), arg1) |
| |
| |
| class TestFmax(_FilterInvalids): |
| def test_reduce(self): |
| dflt = np.typecodes['AllFloat'] |
| dint = np.typecodes['AllInteger'] |
| seq1 = np.arange(11) |
| seq2 = seq1[::-1] |
| func = np.fmax.reduce |
| for dt in dint: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 10) |
| assert_equal(func(tmp2), 10) |
| for dt in dflt: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 10) |
| assert_equal(func(tmp2), 10) |
| tmp1[::2] = np.nan |
| tmp2[::2] = np.nan |
| assert_equal(func(tmp1), 9) |
| assert_equal(func(tmp2), 9) |
| |
| def test_reduce_complex(self): |
| assert_equal(np.fmax.reduce([1, 2j]), 1) |
| assert_equal(np.fmax.reduce([1+3j, 2j]), 1+3j) |
| |
| def test_float_nans(self): |
| nan = np.nan |
| arg1 = np.array([0, nan, nan]) |
| arg2 = np.array([nan, 0, nan]) |
| out = np.array([0, 0, nan]) |
| assert_equal(np.fmax(arg1, arg2), out) |
| |
| def test_complex_nans(self): |
| nan = np.nan |
| for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: |
| arg1 = np.array([0, cnan, cnan], dtype=np.complex) |
| arg2 = np.array([cnan, 0, cnan], dtype=np.complex) |
| out = np.array([0, 0, nan], dtype=np.complex) |
| assert_equal(np.fmax(arg1, arg2), out) |
| |
| |
| class TestFmin(_FilterInvalids): |
| def test_reduce(self): |
| dflt = np.typecodes['AllFloat'] |
| dint = np.typecodes['AllInteger'] |
| seq1 = np.arange(11) |
| seq2 = seq1[::-1] |
| func = np.fmin.reduce |
| for dt in dint: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 0) |
| assert_equal(func(tmp2), 0) |
| for dt in dflt: |
| tmp1 = seq1.astype(dt) |
| tmp2 = seq2.astype(dt) |
| assert_equal(func(tmp1), 0) |
| assert_equal(func(tmp2), 0) |
| tmp1[::2] = np.nan |
| tmp2[::2] = np.nan |
| assert_equal(func(tmp1), 1) |
| assert_equal(func(tmp2), 1) |
| |
| def test_reduce_complex(self): |
| assert_equal(np.fmin.reduce([1, 2j]), 2j) |
| assert_equal(np.fmin.reduce([1+3j, 2j]), 2j) |
| |
| def test_float_nans(self): |
| nan = np.nan |
| arg1 = np.array([0, nan, nan]) |
| arg2 = np.array([nan, 0, nan]) |
| out = np.array([0, 0, nan]) |
| assert_equal(np.fmin(arg1, arg2), out) |
| |
| def test_complex_nans(self): |
| nan = np.nan |
| for cnan in [complex(nan, 0), complex(0, nan), complex(nan, nan)]: |
| arg1 = np.array([0, cnan, cnan], dtype=np.complex) |
| arg2 = np.array([cnan, 0, cnan], dtype=np.complex) |
| out = np.array([0, 0, nan], dtype=np.complex) |
| assert_equal(np.fmin(arg1, arg2), out) |
| |
| |
| class TestBool(TestCase): |
| def test_exceptions(self): |
| a = np.ones(1, dtype=np.bool_) |
| assert_raises(TypeError, np.negative, a) |
| assert_raises(TypeError, np.positive, a) |
| assert_raises(TypeError, np.subtract, a, a) |
| |
| def test_truth_table_logical(self): |
| # 2, 3 and 4 serves as true values |
| input1 = [0, 0, 3, 2] |
| input2 = [0, 4, 0, 2] |
| |
| typecodes = (np.typecodes['AllFloat'] |
| + np.typecodes['AllInteger'] |
| + '?') # boolean |
| for dtype in map(np.dtype, typecodes): |
| arg1 = np.asarray(input1, dtype=dtype) |
| arg2 = np.asarray(input2, dtype=dtype) |
| |
| # OR |
| out = [False, True, True, True] |
| for func in (np.logical_or, np.maximum): |
| assert_equal(func(arg1, arg2).astype(bool), out) |
| # AND |
| out = [False, False, False, True] |
| for func in (np.logical_and, np.minimum): |
| assert_equal(func(arg1, arg2).astype(bool), out) |
| # XOR |
| out = [False, True, True, False] |
| for func in (np.logical_xor, np.not_equal): |
| assert_equal(func(arg1, arg2).astype(bool), out) |
| |
| def test_truth_table_bitwise(self): |
| arg1 = [False, False, True, True] |
| arg2 = [False, True, False, True] |
| |
| out = [False, True, True, True] |
| assert_equal(np.bitwise_or(arg1, arg2), out) |
| |
| out = [False, False, False, True] |
| assert_equal(np.bitwise_and(arg1, arg2), out) |
| |
| out = [False, True, True, False] |
| assert_equal(np.bitwise_xor(arg1, arg2), out) |
| |
| def test_reduce(self): |
| none = np.array([0, 0, 0, 0], bool) |
| some = np.array([1, 0, 1, 1], bool) |
| every = np.array([1, 1, 1, 1], bool) |
| empty = np.array([], bool) |
| |
| arrs = [none, some, every, empty] |
| |
| for arr in arrs: |
| assert_equal(np.logical_and.reduce(arr), all(arr)) |
| |
| for arr in arrs: |
| assert_equal(np.logical_or.reduce(arr), any(arr)) |
| |
| for arr in arrs: |
| assert_equal(np.logical_xor.reduce(arr), arr.sum() % 2 == 1) |
| |
| |
| class TestBitwiseUFuncs(TestCase): |
| |
| bitwise_types = [np.dtype(c) for c in '?' + 'bBhHiIlLqQ' + 'O'] |
| |
| def test_values(self): |
| for dt in self.bitwise_types: |
| zeros = np.array([0], dtype=dt) |
| ones = np.array([-1], dtype=dt) |
| msg = "dt = '%s'" % dt.char |
| |
| assert_equal(np.bitwise_not(zeros), ones, err_msg=msg) |
| assert_equal(np.bitwise_not(ones), zeros, err_msg=msg) |
| |
| assert_equal(np.bitwise_or(zeros, zeros), zeros, err_msg=msg) |
| assert_equal(np.bitwise_or(zeros, ones), ones, err_msg=msg) |
| assert_equal(np.bitwise_or(ones, zeros), ones, err_msg=msg) |
| assert_equal(np.bitwise_or(ones, ones), ones, err_msg=msg) |
| |
| assert_equal(np.bitwise_xor(zeros, zeros), zeros, err_msg=msg) |
| assert_equal(np.bitwise_xor(zeros, ones), ones, err_msg=msg) |
| assert_equal(np.bitwise_xor(ones, zeros), ones, err_msg=msg) |
| assert_equal(np.bitwise_xor(ones, ones), zeros, err_msg=msg) |
| |
| assert_equal(np.bitwise_and(zeros, zeros), zeros, err_msg=msg) |
| assert_equal(np.bitwise_and(zeros, ones), zeros, err_msg=msg) |
| assert_equal(np.bitwise_and(ones, zeros), zeros, err_msg=msg) |
| assert_equal(np.bitwise_and(ones, ones), ones, err_msg=msg) |
| |
| def test_types(self): |
| for dt in self.bitwise_types: |
| zeros = np.array([0], dtype=dt) |
| ones = np.array([-1], dtype=dt) |
| msg = "dt = '%s'" % dt.char |
| |
| assert_(np.bitwise_not(zeros).dtype == dt, msg) |
| assert_(np.bitwise_or(zeros, zeros).dtype == dt, msg) |
| assert_(np.bitwise_xor(zeros, zeros).dtype == dt, msg) |
| assert_(np.bitwise_and(zeros, zeros).dtype == dt, msg) |
| |
| |
| def test_identity(self): |
| assert_(np.bitwise_or.identity == 0, 'bitwise_or') |
| assert_(np.bitwise_xor.identity == 0, 'bitwise_xor') |
| assert_(np.bitwise_and.identity == -1, 'bitwise_and') |
| |
| def test_reduction(self): |
| binary_funcs = (np.bitwise_or, np.bitwise_xor, np.bitwise_and) |
| |
| for dt in self.bitwise_types: |
| zeros = np.array([0], dtype=dt) |
| ones = np.array([-1], dtype=dt) |
| for f in binary_funcs: |
| msg = "dt: '%s', f: '%s'" % (dt, f) |
| assert_equal(f.reduce(zeros), zeros, err_msg=msg) |
| assert_equal(f.reduce(ones), ones, err_msg=msg) |
| |
| # Test empty reduction, no object dtype |
| for dt in self.bitwise_types[:-1]: |
| # No object array types |
| empty = np.array([], dtype=dt) |
| for f in binary_funcs: |
| msg = "dt: '%s', f: '%s'" % (dt, f) |
| tgt = np.array(f.identity, dtype=dt) |
| res = f.reduce(empty) |
| assert_equal(res, tgt, err_msg=msg) |
| assert_(res.dtype == tgt.dtype, msg) |
| |
| # Empty object arrays use the identity. Note that the types may |
| # differ, the actual type used is determined by the assign_identity |
| # function and is not the same as the type returned by the identity |
| # method. |
| for f in binary_funcs: |
| msg = "dt: '%s'" % (f,) |
| empty = np.array([], dtype=object) |
| tgt = f.identity |
| res = f.reduce(empty) |
| assert_equal(res, tgt, err_msg=msg) |
| |
| # Non-empty object arrays do not use the identity |
| for f in binary_funcs: |
| msg = "dt: '%s'" % (f,) |
| btype = np.array([True], dtype=object) |
| assert_(type(f.reduce(btype)) is bool, msg) |
| |
| |
| class TestInt(TestCase): |
| def test_logical_not(self): |
| x = np.ones(10, dtype=np.int16) |
| o = np.ones(10 * 2, dtype=np.bool) |
| tgt = o.copy() |
| tgt[::2] = False |
| os = o[::2] |
| assert_array_equal(np.logical_not(x, out=os), False) |
| assert_array_equal(o, tgt) |
| |
| |
| class TestFloatingPoint(TestCase): |
| def test_floating_point(self): |
| assert_equal(ncu.FLOATING_POINT_SUPPORT, 1) |
| |
| |
| class TestDegrees(TestCase): |
| def test_degrees(self): |
| assert_almost_equal(ncu.degrees(np.pi), 180.0) |
| assert_almost_equal(ncu.degrees(-0.5*np.pi), -90.0) |
| |
| |
| class TestRadians(TestCase): |
| def test_radians(self): |
| assert_almost_equal(ncu.radians(180.0), np.pi) |
| assert_almost_equal(ncu.radians(-90.0), -0.5*np.pi) |
| |
| |
| class TestHeavside(TestCase): |
| def test_heaviside(self): |
| x = np.array([[-30.0, -0.1, 0.0, 0.2], [7.5, np.nan, np.inf, -np.inf]]) |
| expectedhalf = np.array([[0.0, 0.0, 0.5, 1.0], [1.0, np.nan, 1.0, 0.0]]) |
| expected1 = expectedhalf.copy() |
| expected1[0, 2] = 1 |
| |
| h = ncu.heaviside(x, 0.5) |
| assert_equal(h, expectedhalf) |
| |
| h = ncu.heaviside(x, 1.0) |
| assert_equal(h, expected1) |
| |
| x = x.astype(np.float32) |
| |
| h = ncu.heaviside(x, np.float32(0.5)) |
| assert_equal(h, expectedhalf.astype(np.float32)) |
| |
| h = ncu.heaviside(x, np.float32(1.0)) |
| assert_equal(h, expected1.astype(np.float32)) |
| |
| |
| class TestSign(TestCase): |
| def test_sign(self): |
| a = np.array([np.inf, -np.inf, np.nan, 0.0, 3.0, -3.0]) |
| out = np.zeros(a.shape) |
| tgt = np.array([1., -1., np.nan, 0.0, 1.0, -1.0]) |
| |
| with np.errstate(invalid='ignore'): |
| res = ncu.sign(a) |
| assert_equal(res, tgt) |
| res = ncu.sign(a, out) |
| assert_equal(res, tgt) |
| assert_equal(out, tgt) |
| |
| def test_sign_dtype_object(self): |
| # In reference to github issue #6229 |
| |
| foo = np.array([-.1, 0, .1]) |
| a = np.sign(foo.astype(np.object)) |
| b = np.sign(foo) |
| |
| assert_array_equal(a, b) |
| |
| def test_sign_dtype_nan_object(self): |
| # In reference to github issue #6229 |
| def test_nan(): |
| foo = np.array([np.nan]) |
| a = np.sign(foo.astype(np.object)) |
| |
| assert_raises(TypeError, test_nan) |
| |
| class TestMinMax(TestCase): |
| def test_minmax_blocked(self): |
| # simd tests on max/min, test all alignments, slow but important |
| # for 2 * vz + 2 * (vs - 1) + 1 (unrolled once) |
| for dt, sz in [(np.float32, 15), (np.float64, 7)]: |
| for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary', |
| max_size=sz): |
| for i in range(inp.size): |
| inp[:] = np.arange(inp.size, dtype=dt) |
| inp[i] = np.nan |
| emsg = lambda: '%r\n%s' % (inp, msg) |
| with suppress_warnings() as sup: |
| sup.filter(RuntimeWarning, |
| "invalid value encountered in reduce") |
| assert_(np.isnan(inp.max()), msg=emsg) |
| assert_(np.isnan(inp.min()), msg=emsg) |
| |
| inp[i] = 1e10 |
| assert_equal(inp.max(), 1e10, err_msg=msg) |
| inp[i] = -1e10 |
| assert_equal(inp.min(), -1e10, err_msg=msg) |
| |
| def test_lower_align(self): |
| # check data that is not aligned to element size |
| # i.e doubles are aligned to 4 bytes on i386 |
| d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) |
| assert_equal(d.max(), d[0]) |
| assert_equal(d.min(), d[0]) |
| |
| |
| class TestAbsoluteNegative(TestCase): |
| def test_abs_neg_blocked(self): |
| # simd tests on abs, test all alignments for vz + 2 * (vs - 1) + 1 |
| for dt, sz in [(np.float32, 11), (np.float64, 5)]: |
| for out, inp, msg in _gen_alignment_data(dtype=dt, type='unary', |
| max_size=sz): |
| tgt = [ncu.absolute(i) for i in inp] |
| np.absolute(inp, out=out) |
| assert_equal(out, tgt, err_msg=msg) |
| self.assertTrue((out >= 0).all()) |
| |
| tgt = [-1*(i) for i in inp] |
| np.negative(inp, out=out) |
| assert_equal(out, tgt, err_msg=msg) |
| |
| for v in [np.nan, -np.inf, np.inf]: |
| for i in range(inp.size): |
| d = np.arange(inp.size, dtype=dt) |
| inp[:] = -d |
| inp[i] = v |
| d[i] = -v if v == -np.inf else v |
| assert_array_equal(np.abs(inp), d, err_msg=msg) |
| np.abs(inp, out=out) |
| assert_array_equal(out, d, err_msg=msg) |
| |
| assert_array_equal(-inp, -1*inp, err_msg=msg) |
| d = -1 * inp |
| np.negative(inp, out=out) |
| assert_array_equal(out, d, err_msg=msg) |
| |
| def test_lower_align(self): |
| # check data that is not aligned to element size |
| # i.e doubles are aligned to 4 bytes on i386 |
| d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64) |
| assert_equal(np.abs(d), d) |
| assert_equal(np.negative(d), -d) |
| np.negative(d, out=d) |
| np.negative(np.ones_like(d), out=d) |
| np.abs(d, out=d) |
| np.abs(np.ones_like(d), out=d) |
| |
| |
| class TestPositive(TestCase): |
| def test_valid(self): |
| valid_dtypes = [int, float, complex, object] |
| for dtype in valid_dtypes: |
| x = np.arange(5, dtype=dtype) |
| result = np.positive(x) |
| assert_equal(x, result, err_msg=str(dtype)) |
| |
| def test_invalid(self): |
| with assert_raises(TypeError): |
| np.positive(True) |
| with assert_raises(TypeError): |
| np.positive(np.datetime64('2000-01-01')) |
| with assert_raises(TypeError): |
| np.positive(np.array(['foo'], dtype=str)) |
| with assert_raises(TypeError): |
| np.positive(np.array(['bar'], dtype=object)) |
| |
| |
| class TestSpecialMethods(TestCase): |
| def test_wrap(self): |
| |
| class with_wrap(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr, context): |
| r = with_wrap() |
| r.arr = arr |
| r.context = context |
| return r |
| |
| a = with_wrap() |
| x = ncu.minimum(a, a) |
| assert_equal(x.arr, np.zeros(1)) |
| func, args, i = x.context |
| self.assertTrue(func is ncu.minimum) |
| self.assertEqual(len(args), 2) |
| assert_equal(args[0], a) |
| assert_equal(args[1], a) |
| self.assertEqual(i, 0) |
| |
| def test_wrap_with_iterable(self): |
| # test fix for bug #1026: |
| |
| class with_wrap(np.ndarray): |
| __array_priority__ = 10 |
| |
| def __new__(cls): |
| return np.asarray(1).view(cls).copy() |
| |
| def __array_wrap__(self, arr, context): |
| return arr.view(type(self)) |
| |
| a = with_wrap() |
| x = ncu.multiply(a, (1, 2, 3)) |
| self.assertTrue(isinstance(x, with_wrap)) |
| assert_array_equal(x, np.array((1, 2, 3))) |
| |
| def test_priority_with_scalar(self): |
| # test fix for bug #826: |
| |
| class A(np.ndarray): |
| __array_priority__ = 10 |
| |
| def __new__(cls): |
| return np.asarray(1.0, 'float64').view(cls).copy() |
| |
| a = A() |
| x = np.float64(1)*a |
| self.assertTrue(isinstance(x, A)) |
| assert_array_equal(x, np.array(1)) |
| |
| def test_old_wrap(self): |
| |
| class with_wrap(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr): |
| r = with_wrap() |
| r.arr = arr |
| return r |
| |
| a = with_wrap() |
| x = ncu.minimum(a, a) |
| assert_equal(x.arr, np.zeros(1)) |
| |
| def test_priority(self): |
| |
| class A(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr, context): |
| r = type(self)() |
| r.arr = arr |
| r.context = context |
| return r |
| |
| class B(A): |
| __array_priority__ = 20. |
| |
| class C(A): |
| __array_priority__ = 40. |
| |
| x = np.zeros(1) |
| a = A() |
| b = B() |
| c = C() |
| f = ncu.minimum |
| self.assertTrue(type(f(x, x)) is np.ndarray) |
| self.assertTrue(type(f(x, a)) is A) |
| self.assertTrue(type(f(x, b)) is B) |
| self.assertTrue(type(f(x, c)) is C) |
| self.assertTrue(type(f(a, x)) is A) |
| self.assertTrue(type(f(b, x)) is B) |
| self.assertTrue(type(f(c, x)) is C) |
| |
| self.assertTrue(type(f(a, a)) is A) |
| self.assertTrue(type(f(a, b)) is B) |
| self.assertTrue(type(f(b, a)) is B) |
| self.assertTrue(type(f(b, b)) is B) |
| self.assertTrue(type(f(b, c)) is C) |
| self.assertTrue(type(f(c, b)) is C) |
| self.assertTrue(type(f(c, c)) is C) |
| |
| self.assertTrue(type(ncu.exp(a) is A)) |
| self.assertTrue(type(ncu.exp(b) is B)) |
| self.assertTrue(type(ncu.exp(c) is C)) |
| |
| def test_failing_wrap(self): |
| |
| class A(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr, context): |
| raise RuntimeError |
| |
| a = A() |
| self.assertRaises(RuntimeError, ncu.maximum, a, a) |
| |
| def test_none_wrap(self): |
| # Tests that issue #8507 is resolved. Previously, this would segfault |
| |
| class A(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr, context=None): |
| return None |
| |
| a = A() |
| assert_equal(ncu.maximum(a, a), None) |
| |
| def test_default_prepare(self): |
| |
| class with_wrap(object): |
| __array_priority__ = 10 |
| |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_wrap__(self, arr, context): |
| return arr |
| |
| a = with_wrap() |
| x = ncu.minimum(a, a) |
| assert_equal(x, np.zeros(1)) |
| assert_equal(type(x), np.ndarray) |
| |
| def test_prepare(self): |
| |
| class with_prepare(np.ndarray): |
| __array_priority__ = 10 |
| |
| def __array_prepare__(self, arr, context): |
| # make sure we can return a new |
| return np.array(arr).view(type=with_prepare) |
| |
| a = np.array(1).view(type=with_prepare) |
| x = np.add(a, a) |
| assert_equal(x, np.array(2)) |
| assert_equal(type(x), with_prepare) |
| |
| def test_prepare_out(self): |
| |
| class with_prepare(np.ndarray): |
| __array_priority__ = 10 |
| |
| def __array_prepare__(self, arr, context): |
| return np.array(arr).view(type=with_prepare) |
| |
| a = np.array([1]).view(type=with_prepare) |
| x = np.add(a, a, a) |
| # Returned array is new, because of the strange |
| # __array_prepare__ above |
| assert_(not np.shares_memory(x, a)) |
| assert_equal(x, np.array([2])) |
| assert_equal(type(x), with_prepare) |
| |
| def test_failing_prepare(self): |
| |
| class A(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| def __array_prepare__(self, arr, context=None): |
| raise RuntimeError |
| |
| a = A() |
| self.assertRaises(RuntimeError, ncu.maximum, a, a) |
| |
| def test_array_with_context(self): |
| |
| class A(object): |
| def __array__(self, dtype=None, context=None): |
| func, args, i = context |
| self.func = func |
| self.args = args |
| self.i = i |
| return np.zeros(1) |
| |
| class B(object): |
| def __array__(self, dtype=None): |
| return np.zeros(1, dtype) |
| |
| class C(object): |
| def __array__(self): |
| return np.zeros(1) |
| |
| a = A() |
| ncu.maximum(np.zeros(1), a) |
| self.assertTrue(a.func is ncu.maximum) |
| assert_equal(a.args[0], 0) |
| self.assertTrue(a.args[1] is a) |
| self.assertTrue(a.i == 1) |
| assert_equal(ncu.maximum(a, B()), 0) |
| assert_equal(ncu.maximum(a, C()), 0) |
| |
| def test_ufunc_override(self): |
| |
| class A(object): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return self, func, method, inputs, kwargs |
| |
| a = A() |
| b = np.matrix([1]) |
| res0 = np.multiply(a, b) |
| res1 = np.multiply(b, b, out=a) |
| |
| # self |
| assert_equal(res0[0], a) |
| assert_equal(res1[0], a) |
| assert_equal(res0[1], np.multiply) |
| assert_equal(res1[1], np.multiply) |
| assert_equal(res0[2], '__call__') |
| assert_equal(res1[2], '__call__') |
| assert_equal(res0[3], (a, b)) |
| assert_equal(res1[3], (b, b)) |
| assert_equal(res0[4], {}) |
| assert_equal(res1[4], {'out': (a,)}) |
| |
| def test_ufunc_override_mro(self): |
| |
| # Some multi arg functions for testing. |
| def tres_mul(a, b, c): |
| return a * b * c |
| |
| def quatro_mul(a, b, c, d): |
| return a * b * c * d |
| |
| # Make these into ufuncs. |
| three_mul_ufunc = np.frompyfunc(tres_mul, 3, 1) |
| four_mul_ufunc = np.frompyfunc(quatro_mul, 4, 1) |
| |
| class A(object): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return "A" |
| |
| class ASub(A): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return "ASub" |
| |
| class B(object): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return "B" |
| |
| class C(object): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return NotImplemented |
| |
| class CSub(C): |
| def __array_ufunc__(self, func, method, *inputs, **kwargs): |
| return NotImplemented |
| |
| a = A() |
| a_sub = ASub() |
| b = B() |
| c = C() |
| c_sub = CSub() |
| |
| # Standard |
| res = np.multiply(a, a_sub) |
| assert_equal(res, "ASub") |
| res = np.multiply(a_sub, b) |
| assert_equal(res, "ASub") |
| |
| # With 1 NotImplemented |
| res = np.multiply(c, a) |
| assert_equal(res, "A") |
| |
| # Both NotImplemented. |
| assert_raises(TypeError, np.multiply, c, c_sub) |
| assert_raises(TypeError, np.multiply, c_sub, c) |
| assert_raises(TypeError, np.multiply, 2, c) |
| |
| # Ternary testing. |
| assert_equal(three_mul_ufunc(a, 1, 2), "A") |
| assert_equal(three_mul_ufunc(1, a, 2), "A") |
| assert_equal(three_mul_ufunc(1, 2, a), "A") |
| |
| assert_equal(three_mul_ufunc(a, a, 6), "A") |
| assert_equal(three_mul_ufunc(a, 2, a), "A") |
| assert_equal(three_mul_ufunc(a, 2, b), "A") |
| assert_equal(three_mul_ufunc(a, 2, a_sub), "ASub") |
| assert_equal(three_mul_ufunc(a, a_sub, 3), "ASub") |
| assert_equal(three_mul_ufunc(c, a_sub, 3), "ASub") |
| assert_equal(three_mul_ufunc(1, a_sub, c), "ASub") |
| |
| assert_equal(three_mul_ufunc(a, b, c), "A") |
| assert_equal(three_mul_ufunc(a, b, c_sub), "A") |
| assert_equal(three_mul_ufunc(1, 2, b), "B") |
| |
| assert_raises(TypeError, three_mul_ufunc, 1, 2, c) |
| assert_raises(TypeError, three_mul_ufunc, c_sub, 2, c) |
| assert_raises(TypeError, three_mul_ufunc, c_sub, 2, 3) |
| |
| # Quaternary testing. |
| assert_equal(four_mul_ufunc(a, 1, 2, 3), "A") |
| assert_equal(four_mul_ufunc(1, a, 2, 3), "A") |
| assert_equal(four_mul_ufunc(1, 1, a, 3), "A") |
| assert_equal(four_mul_ufunc(1, 1, 2, a), "A") |
| |
| assert_equal(four_mul_ufunc(a, b, 2, 3), "A") |
| assert_equal(four_mul_ufunc(1, a, 2, b), "A") |
| assert_equal(four_mul_ufunc(b, 1, a, 3), "B") |
| assert_equal(four_mul_ufunc(a_sub, 1, 2, a), "ASub") |
| assert_equal(four_mul_ufunc(a, 1, 2, a_sub), "ASub") |
| |
| assert_raises(TypeError, four_mul_ufunc, 1, 2, 3, c) |
| assert_raises(TypeError, four_mul_ufunc, 1, 2, c_sub, c) |
| assert_raises(TypeError, four_mul_ufunc, 1, c, c_sub, c) |
| |
| def test_ufunc_override_methods(self): |
| |
| class A(object): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| return self, ufunc, method, inputs, kwargs |
| |
| # __call__ |
| a = A() |
| res = np.multiply.__call__(1, a, foo='bar', answer=42) |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], '__call__') |
| assert_equal(res[3], (1, a)) |
| assert_equal(res[4], {'foo': 'bar', 'answer': 42}) |
| |
| # __call__, wrong args |
| assert_raises(TypeError, np.multiply, a) |
| assert_raises(TypeError, np.multiply, a, a, a, a) |
| assert_raises(TypeError, np.multiply, a, a, sig='a', signature='a') |
| |
| # reduce, positional args |
| res = np.multiply.reduce(a, 'axis0', 'dtype0', 'out0', 'keep0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'reduce') |
| assert_equal(res[3], (a,)) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'keepdims': 'keep0', |
| 'axis': 'axis0'}) |
| |
| # reduce, kwargs |
| res = np.multiply.reduce(a, axis='axis0', dtype='dtype0', out='out0', |
| keepdims='keep0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'reduce') |
| assert_equal(res[3], (a,)) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'keepdims': 'keep0', |
| 'axis': 'axis0'}) |
| |
| # reduce, output equal to None removed, but not other explicit ones, |
| # even if they are at their default value. |
| res = np.multiply.reduce(a, 0, None, None, False) |
| assert_equal(res[4], {'axis': 0, 'dtype': None, 'keepdims': False}) |
| res = np.multiply.reduce(a, out=None, axis=0, keepdims=True) |
| assert_equal(res[4], {'axis': 0, 'keepdims': True}) |
| res = np.multiply.reduce(a, None, out=(None,), dtype=None) |
| assert_equal(res[4], {'axis': None, 'dtype': None}) |
| |
| # reduce, wrong args |
| assert_raises(ValueError, np.multiply.reduce, a, out=()) |
| assert_raises(ValueError, np.multiply.reduce, a, out=('out0', 'out1')) |
| assert_raises(TypeError, np.multiply.reduce, a, 'axis0', axis='axis0') |
| |
| # accumulate, pos args |
| res = np.multiply.accumulate(a, 'axis0', 'dtype0', 'out0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'accumulate') |
| assert_equal(res[3], (a,)) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'axis': 'axis0'}) |
| |
| # accumulate, kwargs |
| res = np.multiply.accumulate(a, axis='axis0', dtype='dtype0', |
| out='out0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'accumulate') |
| assert_equal(res[3], (a,)) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'axis': 'axis0'}) |
| |
| # accumulate, output equal to None removed. |
| res = np.multiply.accumulate(a, 0, None, None) |
| assert_equal(res[4], {'axis': 0, 'dtype': None}) |
| res = np.multiply.accumulate(a, out=None, axis=0, dtype='dtype1') |
| assert_equal(res[4], {'axis': 0, 'dtype': 'dtype1'}) |
| res = np.multiply.accumulate(a, None, out=(None,), dtype=None) |
| assert_equal(res[4], {'axis': None, 'dtype': None}) |
| |
| # accumulate, wrong args |
| assert_raises(ValueError, np.multiply.accumulate, a, out=()) |
| assert_raises(ValueError, np.multiply.accumulate, a, |
| out=('out0', 'out1')) |
| assert_raises(TypeError, np.multiply.accumulate, a, |
| 'axis0', axis='axis0') |
| |
| # reduceat, pos args |
| res = np.multiply.reduceat(a, [4, 2], 'axis0', 'dtype0', 'out0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'reduceat') |
| assert_equal(res[3], (a, [4, 2])) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'axis': 'axis0'}) |
| |
| # reduceat, kwargs |
| res = np.multiply.reduceat(a, [4, 2], axis='axis0', dtype='dtype0', |
| out='out0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'reduceat') |
| assert_equal(res[3], (a, [4, 2])) |
| assert_equal(res[4], {'dtype':'dtype0', |
| 'out': ('out0',), |
| 'axis': 'axis0'}) |
| |
| # reduceat, output equal to None removed. |
| res = np.multiply.reduceat(a, [4, 2], 0, None, None) |
| assert_equal(res[4], {'axis': 0, 'dtype': None}) |
| res = np.multiply.reduceat(a, [4, 2], axis=None, out=None, dtype='dt') |
| assert_equal(res[4], {'axis': None, 'dtype': 'dt'}) |
| res = np.multiply.reduceat(a, [4, 2], None, None, out=(None,)) |
| assert_equal(res[4], {'axis': None, 'dtype': None}) |
| |
| # reduceat, wrong args |
| assert_raises(ValueError, np.multiply.reduce, a, [4, 2], out=()) |
| assert_raises(ValueError, np.multiply.reduce, a, [4, 2], |
| out=('out0', 'out1')) |
| assert_raises(TypeError, np.multiply.reduce, a, [4, 2], |
| 'axis0', axis='axis0') |
| |
| # outer |
| res = np.multiply.outer(a, 42) |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'outer') |
| assert_equal(res[3], (a, 42)) |
| assert_equal(res[4], {}) |
| |
| # outer, wrong args |
| assert_raises(TypeError, np.multiply.outer, a) |
| assert_raises(TypeError, np.multiply.outer, a, a, a, a) |
| |
| # at |
| res = np.multiply.at(a, [4, 2], 'b0') |
| assert_equal(res[0], a) |
| assert_equal(res[1], np.multiply) |
| assert_equal(res[2], 'at') |
| assert_equal(res[3], (a, [4, 2], 'b0')) |
| |
| # at, wrong args |
| assert_raises(TypeError, np.multiply.at, a) |
| assert_raises(TypeError, np.multiply.at, a, a, a, a) |
| |
| def test_ufunc_override_out(self): |
| |
| class A(object): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| return kwargs |
| |
| class B(object): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| return kwargs |
| |
| a = A() |
| b = B() |
| res0 = np.multiply(a, b, 'out_arg') |
| res1 = np.multiply(a, b, out='out_arg') |
| res2 = np.multiply(2, b, 'out_arg') |
| res3 = np.multiply(3, b, out='out_arg') |
| res4 = np.multiply(a, 4, 'out_arg') |
| res5 = np.multiply(a, 5, out='out_arg') |
| |
| assert_equal(res0['out'][0], 'out_arg') |
| assert_equal(res1['out'][0], 'out_arg') |
| assert_equal(res2['out'][0], 'out_arg') |
| assert_equal(res3['out'][0], 'out_arg') |
| assert_equal(res4['out'][0], 'out_arg') |
| assert_equal(res5['out'][0], 'out_arg') |
| |
| # ufuncs with multiple output modf and frexp. |
| res6 = np.modf(a, 'out0', 'out1') |
| res7 = np.frexp(a, 'out0', 'out1') |
| assert_equal(res6['out'][0], 'out0') |
| assert_equal(res6['out'][1], 'out1') |
| assert_equal(res7['out'][0], 'out0') |
| assert_equal(res7['out'][1], 'out1') |
| |
| # While we're at it, check that default output is never passed on. |
| assert_(np.sin(a, None) == {}) |
| assert_(np.sin(a, out=None) == {}) |
| assert_(np.sin(a, out=(None,)) == {}) |
| assert_(np.modf(a, None) == {}) |
| assert_(np.modf(a, None, None) == {}) |
| assert_(np.modf(a, out=(None, None)) == {}) |
| with warnings.catch_warnings(record=True) as w: |
| warnings.filterwarnings('always', '', DeprecationWarning) |
| assert_(np.modf(a, out=None) == {}) |
| assert_(w[0].category is DeprecationWarning) |
| |
| # don't give positional and output argument, or too many arguments. |
| # wrong number of arguments in the tuple is an error too. |
| assert_raises(TypeError, np.multiply, a, b, 'one', out='two') |
| assert_raises(TypeError, np.multiply, a, b, 'one', 'two') |
| assert_raises(ValueError, np.multiply, a, b, out=('one', 'two')) |
| assert_raises(ValueError, np.multiply, a, out=()) |
| assert_raises(TypeError, np.modf, a, 'one', out=('two', 'three')) |
| assert_raises(TypeError, np.modf, a, 'one', 'two', 'three') |
| assert_raises(ValueError, np.modf, a, out=('one', 'two', 'three')) |
| assert_raises(ValueError, np.modf, a, out=('one',)) |
| |
| def test_ufunc_override_exception(self): |
| |
| class A(object): |
| def __array_ufunc__(self, *a, **kwargs): |
| raise ValueError("oops") |
| |
| a = A() |
| assert_raises(ValueError, np.negative, 1, out=a) |
| assert_raises(ValueError, np.negative, a) |
| assert_raises(ValueError, np.divide, 1., a) |
| |
| def test_ufunc_override_not_implemented(self): |
| |
| class A(object): |
| def __array_ufunc__(self, *args, **kwargs): |
| return NotImplemented |
| |
| msg = ("operand type(s) all returned NotImplemented from " |
| "__array_ufunc__(<ufunc 'negative'>, '__call__', <*>): 'A'") |
| with assert_raises_regex(TypeError, fnmatch.translate(msg)): |
| np.negative(A()) |
| |
| msg = ("operand type(s) all returned NotImplemented from " |
| "__array_ufunc__(<ufunc 'add'>, '__call__', <*>, <object *>, " |
| "out=(1,)): 'A', 'object', 'int'") |
| with assert_raises_regex(TypeError, fnmatch.translate(msg)): |
| np.add(A(), object(), out=1) |
| |
| def test_ufunc_override_disabled(self): |
| |
| class OptOut(object): |
| __array_ufunc__ = None |
| |
| opt_out = OptOut() |
| |
| # ufuncs always raise |
| msg = "operand 'OptOut' does not support ufuncs" |
| with assert_raises_regex(TypeError, msg): |
| np.add(opt_out, 1) |
| with assert_raises_regex(TypeError, msg): |
| np.add(1, opt_out) |
| with assert_raises_regex(TypeError, msg): |
| np.negative(opt_out) |
| |
| # opt-outs still hold even when other arguments have pathological |
| # __array_ufunc__ implementations |
| |
| class GreedyArray(object): |
| def __array_ufunc__(self, *args, **kwargs): |
| return self |
| |
| greedy = GreedyArray() |
| assert_(np.negative(greedy) is greedy) |
| with assert_raises_regex(TypeError, msg): |
| np.add(greedy, opt_out) |
| with assert_raises_regex(TypeError, msg): |
| np.add(greedy, 1, out=opt_out) |
| |
| def test_gufunc_override(self): |
| # gufunc are just ufunc instances, but follow a different path, |
| # so check __array_ufunc__ overrides them properly. |
| class A(object): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| return self, ufunc, method, inputs, kwargs |
| |
| inner1d = ncu_tests.inner1d |
| a = A() |
| res = inner1d(a, a) |
| assert_equal(res[0], a) |
| assert_equal(res[1], inner1d) |
| assert_equal(res[2], '__call__') |
| assert_equal(res[3], (a, a)) |
| assert_equal(res[4], {}) |
| |
| res = inner1d(1, 1, out=a) |
| assert_equal(res[0], a) |
| assert_equal(res[1], inner1d) |
| assert_equal(res[2], '__call__') |
| assert_equal(res[3], (1, 1)) |
| assert_equal(res[4], {'out': (a,)}) |
| |
| # wrong number of arguments in the tuple is an error too. |
| assert_raises(TypeError, inner1d, a, out='two') |
| assert_raises(TypeError, inner1d, a, a, 'one', out='two') |
| assert_raises(TypeError, inner1d, a, a, 'one', 'two') |
| assert_raises(ValueError, inner1d, a, a, out=('one', 'two')) |
| assert_raises(ValueError, inner1d, a, a, out=()) |
| |
| def test_ufunc_override_with_super(self): |
| # NOTE: this class is given as an example in doc/subclassing.py; |
| # if you make any changes here, do update it there too. |
| class A(np.ndarray): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| args = [] |
| in_no = [] |
| for i, input_ in enumerate(inputs): |
| if isinstance(input_, A): |
| in_no.append(i) |
| args.append(input_.view(np.ndarray)) |
| else: |
| args.append(input_) |
| |
| outputs = kwargs.pop('out', None) |
| out_no = [] |
| if outputs: |
| out_args = [] |
| for j, output in enumerate(outputs): |
| if isinstance(output, A): |
| out_no.append(j) |
| out_args.append(output.view(np.ndarray)) |
| else: |
| out_args.append(output) |
| kwargs['out'] = tuple(out_args) |
| else: |
| outputs = (None,) * ufunc.nout |
| |
| info = {} |
| if in_no: |
| info['inputs'] = in_no |
| if out_no: |
| info['outputs'] = out_no |
| |
| results = super(A, self).__array_ufunc__(ufunc, method, |
| *args, **kwargs) |
| if results is NotImplemented: |
| return NotImplemented |
| |
| if method == 'at': |
| if isinstance(inputs[0], A): |
| inputs[0].info = info |
| return |
| |
| if ufunc.nout == 1: |
| results = (results,) |
| |
| results = tuple((np.asarray(result).view(A) |
| if output is None else output) |
| for result, output in zip(results, outputs)) |
| if results and isinstance(results[0], A): |
| results[0].info = info |
| |
| return results[0] if len(results) == 1 else results |
| |
| class B(object): |
| def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): |
| if any(isinstance(input_, A) for input_ in inputs): |
| return "A!" |
| else: |
| return NotImplemented |
| |
| d = np.arange(5.) |
| # 1 input, 1 output |
| a = np.arange(5.).view(A) |
| b = np.sin(a) |
| check = np.sin(d) |
| assert_(np.all(check == b)) |
| assert_equal(b.info, {'inputs': [0]}) |
| b = np.sin(d, out=(a,)) |
| assert_(np.all(check == b)) |
| assert_equal(b.info, {'outputs': [0]}) |
| assert_(b is a) |
| a = np.arange(5.).view(A) |
| b = np.sin(a, out=a) |
| assert_(np.all(check == b)) |
| assert_equal(b.info, {'inputs': [0], 'outputs': [0]}) |
| |
| # 1 input, 2 outputs |
| a = np.arange(5.).view(A) |
| b1, b2 = np.modf(a) |
| assert_equal(b1.info, {'inputs': [0]}) |
| b1, b2 = np.modf(d, out=(None, a)) |
| assert_(b2 is a) |
| assert_equal(b1.info, {'outputs': [1]}) |
| a = np.arange(5.).view(A) |
| b = np.arange(5.).view(A) |
| c1, c2 = np.modf(a, out=(a, b)) |
| assert_(c1 is a) |
| assert_(c2 is b) |
| assert_equal(c1.info, {'inputs': [0], 'outputs': [0, 1]}) |
| |
| # 2 input, 1 output |
| a = np.arange(5.).view(A) |
| b = np.arange(5.).view(A) |
| c = np.add(a, b, out=a) |
| assert_(c is a) |
| assert_equal(c.info, {'inputs': [0, 1], 'outputs': [0]}) |
| # some tests with a non-ndarray subclass |
| a = np.arange(5.) |
| b = B() |
| assert_(a.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) |
| assert_(b.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) |
| assert_raises(TypeError, np.add, a, b) |
| a = a.view(A) |
| assert_(a.__array_ufunc__(np.add, '__call__', a, b) is NotImplemented) |
| assert_(b.__array_ufunc__(np.add, '__call__', a, b) == "A!") |
| assert_(np.add(a, b) == "A!") |
| # regression check for gh-9102 -- tests ufunc.reduce implicitly. |
| d = np.array([[1, 2, 3], [1, 2, 3]]) |
| a = d.view(A) |
| c = a.any() |
| check = d.any() |
| assert_equal(c, check) |
| assert_(c.info, {'inputs': [0]}) |
| c = a.max() |
| check = d.max() |
| assert_equal(c, check) |
| assert_(c.info, {'inputs': [0]}) |
| b = np.array(0).view(A) |
| c = a.max(out=b) |
| assert_equal(c, check) |
| assert_(c is b) |
| assert_(c.info, {'inputs': [0], 'outputs': [0]}) |
| check = a.max(axis=0) |
| b = np.zeros_like(check).view(A) |
| c = a.max(axis=0, out=b) |
| assert_equal(c, check) |
| assert_(c is b) |
| assert_(c.info, {'inputs': [0], 'outputs': [0]}) |
| # simple explicit tests of reduce, accumulate, reduceat |
| check = np.add.reduce(d, axis=1) |
| c = np.add.reduce(a, axis=1) |
| assert_equal(c, check) |
| assert_(c.info, {'inputs': [0]}) |
| b = np.zeros_like(c) |
| c = np.add.reduce(a, 1, None, b) |
| assert_equal(c, check) |
| assert_(c is b) |
| assert_(c.info, {'inputs': [0], 'outputs': [0]}) |
| check = np.add.accumulate(d, axis=0) |
| c = np.add.accumulate(a, axis=0) |
| assert_equal(c, check) |
| assert_(c.info, {'inputs': [0]}) |
| b = np.zeros_like(c) |
| c = np.add.accumulate(a, 0, None, b) |
| assert_equal(c, check) |
| assert_(c is b) |
| assert_(c.info, {'inputs': [0], 'outputs': [0]}) |
| indices = [0, 2, 1] |
| check = np.add.reduceat(d, indices, axis=1) |
| c = np.add.reduceat(a, indices, axis=1) |
| assert_equal(c, check) |
| assert_(c.info, {'inputs': [0]}) |
| b = np.zeros_like(c) |
| c = np.add.reduceat(a, indices, 1, None, b) |
| assert_equal(c, check) |
| assert_(c is b) |
| assert_(c.info, {'inputs': [0], 'outputs': [0]}) |
| # and a few tests for at |
| d = np.array([[1, 2, 3], [1, 2, 3]]) |
| check = d.copy() |
| a = d.copy().view(A) |
| np.add.at(check, ([0, 1], [0, 2]), 1.) |
| np.add.at(a, ([0, 1], [0, 2]), 1.) |
| assert_equal(a, check) |
| assert_(a.info, {'inputs': [0]}) |
| b = np.array(1.).view(A) |
| a = d.copy().view(A) |
| np.add.at(a, ([0, 1], [0, 2]), b) |
| assert_equal(a, check) |
| assert_(a.info, {'inputs': [0, 2]}) |
| |
| |
| class TestChoose(TestCase): |
| def test_mixed(self): |
| c = np.array([True, True]) |
| a = np.array([True, True]) |
| assert_equal(np.choose(c, (a, 1)), np.array([1, 1])) |
| |
| |
| def is_longdouble_finfo_bogus(): |
| info = np.finfo(np.longcomplex) |
| return not np.isfinite(np.log10(info.tiny/info.eps)) |
| |
| |
| class TestComplexFunctions(object): |
| funcs = [np.arcsin, np.arccos, np.arctan, np.arcsinh, np.arccosh, |
| np.arctanh, np.sin, np.cos, np.tan, np.exp, |
| np.exp2, np.log, np.sqrt, np.log10, np.log2, |
| np.log1p] |
| |
| def test_it(self): |
| for f in self.funcs: |
| if f is np.arccosh: |
| x = 1.5 |
| else: |
| x = .5 |
| fr = f(x) |
| fz = f(np.complex(x)) |
| assert_almost_equal(fz.real, fr, err_msg='real part %s' % f) |
| assert_almost_equal(fz.imag, 0., err_msg='imag part %s' % f) |
| |
| def test_precisions_consistent(self): |
| z = 1 + 1j |
| for f in self.funcs: |
| fcf = f(np.csingle(z)) |
| fcd = f(np.cdouble(z)) |
| fcl = f(np.clongdouble(z)) |
| assert_almost_equal(fcf, fcd, decimal=6, err_msg='fch-fcd %s' % f) |
| assert_almost_equal(fcl, fcd, decimal=15, err_msg='fch-fcl %s' % f) |
| |
| def test_branch_cuts(self): |
| # check branch cuts and continuity on them |
| yield _check_branch_cut, np.log, -0.5, 1j, 1, -1, True |
| yield _check_branch_cut, np.log2, -0.5, 1j, 1, -1, True |
| yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True |
| yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True |
| yield _check_branch_cut, np.sqrt, -0.5, 1j, 1, -1, True |
| |
| yield _check_branch_cut, np.arcsin, [ -2, 2], [1j, 1j], 1, -1, True |
| yield _check_branch_cut, np.arccos, [ -2, 2], [1j, 1j], 1, -1, True |
| yield _check_branch_cut, np.arctan, [0-2j, 2j], [1, 1], -1, 1, True |
| |
| yield _check_branch_cut, np.arcsinh, [0-2j, 2j], [1, 1], -1, 1, True |
| yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j, 1j], 1, -1, True |
| yield _check_branch_cut, np.arctanh, [ -2, 2], [1j, 1j], 1, -1, True |
| |
| # check against bogus branch cuts: assert continuity between quadrants |
| yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1, 1], 1, 1 |
| yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1, 1], 1, 1 |
| yield _check_branch_cut, np.arctan, [ -2, 2], [1j, 1j], 1, 1 |
| |
| yield _check_branch_cut, np.arcsinh, [ -2, 2, 0], [1j, 1j, 1], 1, 1 |
| yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1, 1, 1j], 1, 1 |
| yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1, 1, 1j], 1, 1 |
| |
| def test_branch_cuts_complex64(self): |
| # check branch cuts and continuity on them |
| yield _check_branch_cut, np.log, -0.5, 1j, 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.log2, -0.5, 1j, 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.log10, -0.5, 1j, 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.log1p, -1.5, 1j, 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.sqrt, -0.5, 1j, 1, -1, True, np.complex64 |
| |
| yield _check_branch_cut, np.arcsin, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.arccos, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.arctan, [0-2j, 2j], [1, 1], -1, 1, True, np.complex64 |
| |
| yield _check_branch_cut, np.arcsinh, [0-2j, 2j], [1, 1], -1, 1, True, np.complex64 |
| yield _check_branch_cut, np.arccosh, [ -1, 0.5], [1j, 1j], 1, -1, True, np.complex64 |
| yield _check_branch_cut, np.arctanh, [ -2, 2], [1j, 1j], 1, -1, True, np.complex64 |
| |
| # check against bogus branch cuts: assert continuity between quadrants |
| yield _check_branch_cut, np.arcsin, [0-2j, 2j], [ 1, 1], 1, 1, False, np.complex64 |
| yield _check_branch_cut, np.arccos, [0-2j, 2j], [ 1, 1], 1, 1, False, np.complex64 |
| yield _check_branch_cut, np.arctan, [ -2, 2], [1j, 1j], 1, 1, False, np.complex64 |
| |
| yield _check_branch_cut, np.arcsinh, [ -2, 2, 0], [1j, 1j, 1], 1, 1, False, np.complex64 |
| yield _check_branch_cut, np.arccosh, [0-2j, 2j, 2], [1, 1, 1j], 1, 1, False, np.complex64 |
| yield _check_branch_cut, np.arctanh, [0-2j, 2j, 0], [1, 1, 1j], 1, 1, False, np.complex64 |
| |
| def test_against_cmath(self): |
| import cmath |
| |
| points = [-1-1j, -1+1j, +1-1j, +1+1j] |
| name_map = {'arcsin': 'asin', 'arccos': 'acos', 'arctan': 'atan', |
| 'arcsinh': 'asinh', 'arccosh': 'acosh', 'arctanh': 'atanh'} |
| atol = 4*np.finfo(np.complex).eps |
| for func in self.funcs: |
| fname = func.__name__.split('.')[-1] |
| cname = name_map.get(fname, fname) |
| try: |
| cfunc = getattr(cmath, cname) |
| except AttributeError: |
| continue |
| for p in points: |
| a = complex(func(np.complex_(p))) |
| b = cfunc(p) |
| assert_(abs(a - b) < atol, "%s %s: %s; cmath: %s" % (fname, p, a, b)) |
| |
| def check_loss_of_precision(self, dtype): |
| """Check loss of precision in complex arc* functions""" |
| |
| # Check against known-good functions |
| |
| info = np.finfo(dtype) |
| real_dtype = dtype(0.).real.dtype |
| eps = info.eps |
| |
| def check(x, rtol): |
| x = x.astype(real_dtype) |
| |
| z = x.astype(dtype) |
| d = np.absolute(np.arcsinh(x)/np.arcsinh(z).real - 1) |
| assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 'arcsinh')) |
| |
| z = (1j*x).astype(dtype) |
| d = np.absolute(np.arcsinh(x)/np.arcsin(z).imag - 1) |
| assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 'arcsin')) |
| |
| z = x.astype(dtype) |
| d = np.absolute(np.arctanh(x)/np.arctanh(z).real - 1) |
| assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 'arctanh')) |
| |
| z = (1j*x).astype(dtype) |
| d = np.absolute(np.arctanh(x)/np.arctan(z).imag - 1) |
| assert_(np.all(d < rtol), (np.argmax(d), x[np.argmax(d)], d.max(), |
| 'arctan')) |
| |
| # The switchover was chosen as 1e-3; hence there can be up to |
| # ~eps/1e-3 of relative cancellation error before it |
| |
| x_series = np.logspace(-20, -3.001, 200) |
| x_basic = np.logspace(-2.999, 0, 10, endpoint=False) |
| |
| if dtype is np.longcomplex: |
| # It's not guaranteed that the system-provided arc functions |
| # are accurate down to a few epsilons. (Eg. on Linux 64-bit) |
| # So, give more leeway for long complex tests here: |
| check(x_series, 50*eps) |
| else: |
| check(x_series, 2.1*eps) |
| check(x_basic, 2*eps/1e-3) |
| |
| # Check a few points |
| |
| z = np.array([1e-5*(1+1j)], dtype=dtype) |
| p = 9.999999999333333333e-6 + 1.000000000066666666e-5j |
| d = np.absolute(1-np.arctanh(z)/p) |
| assert_(np.all(d < 1e-15)) |
| |
| p = 1.0000000000333333333e-5 + 9.999999999666666667e-6j |
| d = np.absolute(1-np.arcsinh(z)/p) |
| assert_(np.all(d < 1e-15)) |
| |
| p = 9.999999999333333333e-6j + 1.000000000066666666e-5 |
| d = np.absolute(1-np.arctan(z)/p) |
| assert_(np.all(d < 1e-15)) |
| |
| p = 1.0000000000333333333e-5j + 9.999999999666666667e-6 |
| d = np.absolute(1-np.arcsin(z)/p) |
| assert_(np.all(d < 1e-15)) |
| |
| # Check continuity across switchover points |
| |
| def check(func, z0, d=1): |
| z0 = np.asarray(z0, dtype=dtype) |
| zp = z0 + abs(z0) * d * eps * 2 |
| zm = z0 - abs(z0) * d * eps * 2 |
| assert_(np.all(zp != zm), (zp, zm)) |
| |
| # NB: the cancellation error at the switchover is at least eps |
| good = (abs(func(zp) - func(zm)) < 2*eps) |
| assert_(np.all(good), (func, z0[~good])) |
| |
| for func in (np.arcsinh, np.arcsinh, np.arcsin, np.arctanh, np.arctan): |
| pts = [rp+1j*ip for rp in (-1e-3, 0, 1e-3) for ip in(-1e-3, 0, 1e-3) |
| if rp != 0 or ip != 0] |
| check(func, pts, 1) |
| check(func, pts, 1j) |
| check(func, pts, 1+1j) |
| |
| def test_loss_of_precision(self): |
| for dtype in [np.complex64, np.complex_]: |
| yield self.check_loss_of_precision, dtype |
| |
| @dec.knownfailureif(is_longdouble_finfo_bogus(), "Bogus long double finfo") |
| def test_loss_of_precision_longcomplex(self): |
| self.check_loss_of_precision(np.longcomplex) |
| |
| |
| class TestAttributes(TestCase): |
| def test_attributes(self): |
| add = ncu.add |
| assert_equal(add.__name__, 'add') |
| self.assertTrue(add.ntypes >= 18) # don't fail if types added |
| self.assertTrue('ii->i' in add.types) |
| assert_equal(add.nin, 2) |
| assert_equal(add.nout, 1) |
| assert_equal(add.identity, 0) |
| |
| def test_doc(self): |
| # don't bother checking the long list of kwargs, which are likely to |
| # change |
| assert_(ncu.add.__doc__.startswith( |
| "add(x1, x2, /, out=None, *, where=True")) |
| assert_(ncu.frexp.__doc__.startswith( |
| "frexp(x[, out1, out2], / [, out=(None, None)], *, where=True")) |
| |
| |
| class TestSubclass(TestCase): |
| |
| def test_subclass_op(self): |
| |
| class simple(np.ndarray): |
| def __new__(subtype, shape): |
| self = np.ndarray.__new__(subtype, shape, dtype=object) |
| self.fill(0) |
| return self |
| |
| a = simple((3, 4)) |
| assert_equal(a+a, a) |
| |
| def _check_branch_cut(f, x0, dx, re_sign=1, im_sign=-1, sig_zero_ok=False, |
| dtype=np.complex): |
| """ |
| Check for a branch cut in a function. |
| |
| Assert that `x0` lies on a branch cut of function `f` and `f` is |
| continuous from the direction `dx`. |
| |
| Parameters |
| ---------- |
| f : func |
| Function to check |
| x0 : array-like |
| Point on branch cut |
| dx : array-like |
| Direction to check continuity in |
| re_sign, im_sign : {1, -1} |
| Change of sign of the real or imaginary part expected |
| sig_zero_ok : bool |
| Whether to check if the branch cut respects signed zero (if applicable) |
| dtype : dtype |
| Dtype to check (should be complex) |
| |
| """ |
| x0 = np.atleast_1d(x0).astype(dtype) |
| dx = np.atleast_1d(dx).astype(dtype) |
| |
| if np.dtype(dtype).char == 'F': |
| scale = np.finfo(dtype).eps * 1e2 |
| atol = np.float32(1e-2) |
| else: |
| scale = np.finfo(dtype).eps * 1e3 |
| atol = 1e-4 |
| |
| y0 = f(x0) |
| yp = f(x0 + dx*scale*np.absolute(x0)/np.absolute(dx)) |
| ym = f(x0 - dx*scale*np.absolute(x0)/np.absolute(dx)) |
| |
| assert_(np.all(np.absolute(y0.real - yp.real) < atol), (y0, yp)) |
| assert_(np.all(np.absolute(y0.imag - yp.imag) < atol), (y0, yp)) |
| assert_(np.all(np.absolute(y0.real - ym.real*re_sign) < atol), (y0, ym)) |
| assert_(np.all(np.absolute(y0.imag - ym.imag*im_sign) < atol), (y0, ym)) |
| |
| if sig_zero_ok: |
| # check that signed zeros also work as a displacement |
| jr = (x0.real == 0) & (dx.real != 0) |
| ji = (x0.imag == 0) & (dx.imag != 0) |
| if np.any(jr): |
| x = x0[jr] |
| x.real = np.NZERO |
| ym = f(x) |
| assert_(np.all(np.absolute(y0[jr].real - ym.real*re_sign) < atol), (y0[jr], ym)) |
| assert_(np.all(np.absolute(y0[jr].imag - ym.imag*im_sign) < atol), (y0[jr], ym)) |
| |
| if np.any(ji): |
| x = x0[ji] |
| x.imag = np.NZERO |
| ym = f(x) |
| assert_(np.all(np.absolute(y0[ji].real - ym.real*re_sign) < atol), (y0[ji], ym)) |
| assert_(np.all(np.absolute(y0[ji].imag - ym.imag*im_sign) < atol), (y0[ji], ym)) |
| |
| def test_copysign(): |
| assert_(np.copysign(1, -1) == -1) |
| with np.errstate(divide="ignore"): |
| assert_(1 / np.copysign(0, -1) < 0) |
| assert_(1 / np.copysign(0, 1) > 0) |
| assert_(np.signbit(np.copysign(np.nan, -1))) |
| assert_(not np.signbit(np.copysign(np.nan, 1))) |
| |
| def _test_nextafter(t): |
| one = t(1) |
| two = t(2) |
| zero = t(0) |
| eps = np.finfo(t).eps |
| assert_(np.nextafter(one, two) - one == eps) |
| assert_(np.nextafter(one, zero) - one < 0) |
| assert_(np.isnan(np.nextafter(np.nan, one))) |
| assert_(np.isnan(np.nextafter(one, np.nan))) |
| assert_(np.nextafter(one, one) == one) |
| |
| def test_nextafter(): |
| return _test_nextafter(np.float64) |
| |
| def test_nextafterf(): |
| return _test_nextafter(np.float32) |
| |
| @dec.knownfailureif(sys.platform == 'win32', |
| "Long double support buggy on win32, ticket 1664.") |
| def test_nextafterl(): |
| return _test_nextafter(np.longdouble) |
| |
| def test_nextafter_0(): |
| for t, direction in itertools.product(np.sctypes['float'], (1, -1)): |
| tiny = np.finfo(t).tiny |
| assert_(0. < direction * np.nextafter(t(0), t(direction)) < tiny) |
| assert_equal(np.nextafter(t(0), t(direction)) / t(2.1), direction * 0.0) |
| |
| def _test_spacing(t): |
| one = t(1) |
| eps = np.finfo(t).eps |
| nan = t(np.nan) |
| inf = t(np.inf) |
| with np.errstate(invalid='ignore'): |
| assert_(np.spacing(one) == eps) |
| assert_(np.isnan(np.spacing(nan))) |
| assert_(np.isnan(np.spacing(inf))) |
| assert_(np.isnan(np.spacing(-inf))) |
| assert_(np.spacing(t(1e30)) != 0) |
| |
| def test_spacing(): |
| return _test_spacing(np.float64) |
| |
| def test_spacingf(): |
| return _test_spacing(np.float32) |
| |
| @dec.knownfailureif(sys.platform == 'win32', |
| "Long double support buggy on win32, ticket 1664.") |
| def test_spacingl(): |
| return _test_spacing(np.longdouble) |
| |
| def test_spacing_gfortran(): |
| # Reference from this fortran file, built with gfortran 4.3.3 on linux |
| # 32bits: |
| # PROGRAM test_spacing |
| # INTEGER, PARAMETER :: SGL = SELECTED_REAL_KIND(p=6, r=37) |
| # INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(p=13, r=200) |
| # |
| # WRITE(*,*) spacing(0.00001_DBL) |
| # WRITE(*,*) spacing(1.0_DBL) |
| # WRITE(*,*) spacing(1000._DBL) |
| # WRITE(*,*) spacing(10500._DBL) |
| # |
| # WRITE(*,*) spacing(0.00001_SGL) |
| # WRITE(*,*) spacing(1.0_SGL) |
| # WRITE(*,*) spacing(1000._SGL) |
| # WRITE(*,*) spacing(10500._SGL) |
| # END PROGRAM |
| ref = {np.float64: [1.69406589450860068E-021, |
| 2.22044604925031308E-016, |
| 1.13686837721616030E-013, |
| 1.81898940354585648E-012], |
| np.float32: [9.09494702E-13, |
| 1.19209290E-07, |
| 6.10351563E-05, |
| 9.76562500E-04]} |
| |
| for dt, dec_ in zip([np.float32, np.float64], (10, 20)): |
| x = np.array([1e-5, 1, 1000, 10500], dtype=dt) |
| assert_array_almost_equal(np.spacing(x), ref[dt], decimal=dec_) |
| |
| def test_nextafter_vs_spacing(): |
| # XXX: spacing does not handle long double yet |
| for t in [np.float32, np.float64]: |
| for _f in [1, 1e-5, 1000]: |
| f = t(_f) |
| f1 = t(_f + 1) |
| assert_(np.nextafter(f, f1) - f == np.spacing(f)) |
| |
| def test_pos_nan(): |
| """Check np.nan is a positive nan.""" |
| assert_(np.signbit(np.nan) == 0) |
| |
| def test_reduceat(): |
| """Test bug in reduceat when structured arrays are not copied.""" |
| db = np.dtype([('name', 'S11'), ('time', np.int64), ('value', np.float32)]) |
| a = np.empty([100], dtype=db) |
| a['name'] = 'Simple' |
| a['time'] = 10 |
| a['value'] = 100 |
| indx = [0, 7, 15, 25] |
| |
| h2 = [] |
| val1 = indx[0] |
| for val2 in indx[1:]: |
| h2.append(np.add.reduce(a['value'][val1:val2])) |
| val1 = val2 |
| h2.append(np.add.reduce(a['value'][val1:])) |
| h2 = np.array(h2) |
| |
| # test buffered -- this should work |
| h1 = np.add.reduceat(a['value'], indx) |
| assert_array_almost_equal(h1, h2) |
| |
| # This is when the error occurs. |
| # test no buffer |
| np.setbufsize(32) |
| h1 = np.add.reduceat(a['value'], indx) |
| np.setbufsize(np.UFUNC_BUFSIZE_DEFAULT) |
| assert_array_almost_equal(h1, h2) |
| |
| def test_reduceat_empty(): |
| """Reduceat should work with empty arrays""" |
| indices = np.array([], 'i4') |
| x = np.array([], 'f8') |
| result = np.add.reduceat(x, indices) |
| assert_equal(result.dtype, x.dtype) |
| assert_equal(result.shape, (0,)) |
| # Another case with a slightly different zero-sized shape |
| x = np.ones((5, 2)) |
| result = np.add.reduceat(x, [], axis=0) |
| assert_equal(result.dtype, x.dtype) |
| assert_equal(result.shape, (0, 2)) |
| result = np.add.reduceat(x, [], axis=1) |
| assert_equal(result.dtype, x.dtype) |
| assert_equal(result.shape, (5, 0)) |
| |
| def test_complex_nan_comparisons(): |
| nans = [complex(np.nan, 0), complex(0, np.nan), complex(np.nan, np.nan)] |
| fins = [complex(1, 0), complex(-1, 0), complex(0, 1), complex(0, -1), |
| complex(1, 1), complex(-1, -1), complex(0, 0)] |
| |
| with np.errstate(invalid='ignore'): |
| for x in nans + fins: |
| x = np.array([x]) |
| for y in nans + fins: |
| y = np.array([y]) |
| |
| if np.isfinite(x) and np.isfinite(y): |
| continue |
| |
| assert_equal(x < y, False, err_msg="%r < %r" % (x, y)) |
| assert_equal(x > y, False, err_msg="%r > %r" % (x, y)) |
| assert_equal(x <= y, False, err_msg="%r <= %r" % (x, y)) |
| assert_equal(x >= y, False, err_msg="%r >= %r" % (x, y)) |
| assert_equal(x == y, False, err_msg="%r == %r" % (x, y)) |
| |
| |
| def test_rint_big_int(): |
| # np.rint bug for large integer values on Windows 32-bit and MKL |
| # https://github.com/numpy/numpy/issues/6685 |
| val = 4607998452777363968 |
| # This is exactly representable in floating point |
| assert_equal(val, int(float(val))) |
| # Rint should not change the value |
| assert_equal(val, np.rint(val)) |
| |
| |
| def test_signaling_nan_exceptions(): |
| with assert_no_warnings(): |
| a = np.ndarray(shape=(), dtype='float32', buffer=b'\x00\xe0\xbf\xff') |
| np.isnan(a) |
| |
| |
| if __name__ == "__main__": |
| run_module_suite() |