summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/add_newdocs.py24
-rw-r--r--numpy/compat/py3k.py2
-rw-r--r--numpy/compat/tests/test_compat.py19
-rw-r--r--numpy/core/__init__.py6
-rw-r--r--numpy/core/bscript2
-rw-r--r--numpy/core/code_generators/cversions.txt2
-rw-r--r--numpy/core/code_generators/genapi.py4
-rw-r--r--numpy/core/code_generators/generate_numpy_api.py3
-rw-r--r--numpy/core/code_generators/generate_umath.py36
-rw-r--r--numpy/core/code_generators/ufunc_docstrings.py6
-rw-r--r--numpy/core/function_base.py2
-rw-r--r--numpy/core/include/numpy/ndarraytypes.h6
-rw-r--r--numpy/core/include/numpy/npy_endian.h20
-rw-r--r--numpy/core/include/numpy/npy_math.h10
-rw-r--r--numpy/core/include/numpy/ufuncobject.h4
-rw-r--r--numpy/core/numeric.py13
-rw-r--r--numpy/core/setup.py7
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src6
-rw-r--r--numpy/core/src/multiarray/calculation.c2
-rw-r--r--numpy/core/src/multiarray/common.c4
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c54
-rw-r--r--numpy/core/src/multiarray/ctors.c15
-rw-r--r--numpy/core/src/multiarray/descriptor.c181
-rw-r--r--numpy/core/src/multiarray/lowlevel_strided_loops.c.src4
-rw-r--r--numpy/core/src/multiarray/mapping.c110
-rw-r--r--numpy/core/src/multiarray/methods.c7
-rw-r--r--numpy/core/src/multiarray/multiarray_tests.c.src42
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c124
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.h11
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src18
-rw-r--r--numpy/core/src/multiarray/shape.c3
-rw-r--r--numpy/core/src/npymath/npy_math.c.src35
-rw-r--r--numpy/core/src/npysort/selection.c.src10
-rw-r--r--numpy/core/src/private/npy_config.h11
-rw-r--r--numpy/core/src/private/ufunc_override.h1
-rw-r--r--numpy/core/src/umath/loops.c.src31
-rw-r--r--numpy/core/src/umath/loops.h.src4
-rw-r--r--numpy/core/src/umath/simd.inc.src22
-rw-r--r--numpy/core/src/umath/ufunc_object.c82
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c20
-rw-r--r--numpy/core/src/umath/umathmodule.c194
-rw-r--r--numpy/core/tests/test_deprecations.py30
-rw-r--r--numpy/core/tests/test_indexing.py49
-rw-r--r--numpy/core/tests/test_multiarray.py152
-rw-r--r--numpy/core/tests/test_numeric.py15
-rw-r--r--numpy/core/tests/test_regression.py124
-rw-r--r--numpy/core/tests/test_scalarmath.py12
-rw-r--r--numpy/core/tests/test_ufunc.py103
-rw-r--r--numpy/core/tests/test_umath.py18
-rw-r--r--numpy/distutils/command/autodist.py34
-rw-r--r--numpy/distutils/command/config.py32
-rw-r--r--numpy/f2py/tests/test_array_from_pyobj.py79
-rw-r--r--numpy/lib/function_base.py9
-rw-r--r--numpy/lib/nanfunctions.py6
-rw-r--r--numpy/lib/npyio.py3
-rw-r--r--numpy/lib/tests/test_function_base.py7
-rw-r--r--numpy/lib/tests/test_io.py16
-rw-r--r--numpy/lib/tests/test_twodim_base.py34
-rw-r--r--numpy/lib/twodim_base.py9
-rw-r--r--numpy/ma/core.py34
-rw-r--r--numpy/ma/tests/test_core.py14
-rw-r--r--numpy/ma/tests/test_old_ma.py3
-rw-r--r--numpy/polynomial/polynomial.py18
-rw-r--r--numpy/polynomial/polytemplate.py927
-rw-r--r--numpy/random/mtrand/mtrand.pyx9
-rw-r--r--numpy/testing/utils.py35
66 files changed, 1391 insertions, 1538 deletions
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py
index 86ea4b8b6..09311a536 100644
--- a/numpy/add_newdocs.py
+++ b/numpy/add_newdocs.py
@@ -4459,12 +4459,12 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('tolist',
tobytesdoc = """
- a.tostring(order='C')
+ a.{name}(order='C')
- Construct a Python string containing the raw data bytes in the array.
+ Construct Python bytes containing the raw data bytes in the array.
- Constructs a Python string showing a copy of the raw contents of
- data memory. The string can be produced in either 'C' or 'Fortran',
+ Constructs Python bytes showing a copy of the raw contents of
+ data memory. The bytes object can be produced in either 'C' or 'Fortran',
or 'Any' order (the default is 'C'-order). 'Any' order means C-order
unless the F_CONTIGUOUS flag in the array is set, in which case it
means 'Fortran' order.
@@ -4479,29 +4479,31 @@ tobytesdoc = """
Returns
-------
- s : str
- A Python string exhibiting a copy of `a`'s raw data.
+ s : bytes
+ Python bytes exhibiting a copy of `a`'s raw data.
Examples
--------
>>> x = np.array([[0, 1], [2, 3]])
>>> x.tobytes()
- '\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+ b'\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
>>> x.tobytes('C') == x.tobytes()
True
>>> x.tobytes('F')
- '\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
+ b'\\x00\\x00\\x00\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x03\\x00\\x00\\x00'
"""
add_newdoc('numpy.core.multiarray', 'ndarray',
- ('tostring', tobytesdoc.format(deprecated=
+ ('tostring', tobytesdoc.format(name='tostring',
+ deprecated=
'This function is a compatibility '
'alias for tobytes. Despite its '
'name it returns bytes not '
'strings.')))
add_newdoc('numpy.core.multiarray', 'ndarray',
- ('tobytes', tobytesdoc.format(deprecated='.. versionadded:: 1.9.0')))
+ ('tobytes', tobytesdoc.format(name='tobytes',
+ deprecated='.. versionadded:: 1.9.0')))
add_newdoc('numpy.core.multiarray', 'ndarray', ('trace',
"""
@@ -5519,6 +5521,8 @@ add_newdoc('numpy.core', 'ufunc', ('reduce',
in the result as dimensions with size one. With this option,
the result will broadcast correctly against the original `arr`.
+ .. versionadded:: 1.7.0
+
Returns
-------
r : ndarray
diff --git a/numpy/compat/py3k.py b/numpy/compat/py3k.py
index f5ac3f9f8..4607d9502 100644
--- a/numpy/compat/py3k.py
+++ b/numpy/compat/py3k.py
@@ -36,7 +36,7 @@ if sys.version_info[0] >= 3:
return str(s)
def isfileobj(f):
- return isinstance(f, (io.FileIO, io.BufferedReader))
+ return isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter))
def open_latin1(filename, mode='r'):
return open(filename, mode=mode, encoding='iso-8859-1')
diff --git a/numpy/compat/tests/test_compat.py b/numpy/compat/tests/test_compat.py
new file mode 100644
index 000000000..3df142e04
--- /dev/null
+++ b/numpy/compat/tests/test_compat.py
@@ -0,0 +1,19 @@
+from os.path import join
+
+from numpy.compat import isfileobj
+from numpy.testing import TestCase, assert_
+from numpy.testing.utils import tempdir
+
+
+def test_isfileobj():
+ with tempdir(prefix="numpy_test_compat_") as folder:
+ filename = join(folder, 'a.bin')
+
+ with open(filename, 'wb') as f:
+ assert_(isfileobj(f))
+
+ with open(filename, 'ab') as f:
+ assert_(isfileobj(f))
+
+ with open(filename, 'rb') as f:
+ assert_(isfileobj(f))
diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py
index 79bc72a8c..0b8d5bb17 100644
--- a/numpy/core/__init__.py
+++ b/numpy/core/__init__.py
@@ -52,7 +52,11 @@ bench = Tester().bench
# The name numpy.core._ufunc_reconstruct must be
# available for unpickling to work.
def _ufunc_reconstruct(module, name):
- mod = __import__(module)
+ # The `fromlist` kwarg is required to ensure that `mod` points to the
+ # inner-most module rather than the parent package when module name is
+ # nested. This makes it possible to pickle non-toplevel ufuncs such as
+ # scipy.special.expit for instance.
+ mod = __import__(module, fromlist=[name])
return getattr(mod, name)
def _ufunc_reduce(func):
diff --git a/numpy/core/bscript b/numpy/core/bscript
index 5230aa428..416e16524 100644
--- a/numpy/core/bscript
+++ b/numpy/core/bscript
@@ -28,7 +28,7 @@ from setup_common \
MANDATORY_FUNCS, C_ABI_VERSION, C_API_VERSION
ENABLE_SEPARATE_COMPILATION = (os.environ.get('NPY_SEPARATE_COMPILATION', "1") != "0")
-NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "0") != "0")
+NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "1") != "0")
NUMPYCONFIG_SYM = []
diff --git a/numpy/core/code_generators/cversions.txt b/numpy/core/code_generators/cversions.txt
index d62115224..acfced812 100644
--- a/numpy/core/code_generators/cversions.txt
+++ b/numpy/core/code_generators/cversions.txt
@@ -28,4 +28,4 @@
# Version 9 (NumPy 1.9) Added function annotations.
# The interface has not changed, but the hash is different due to
# the annotations, so keep the previous version number.
-0x00000009 = 49b27dc2dc7206a775a7376fdbc3b80c
+0x00000009 = 982c4ebb6e7e4c194bf46b1535b4ef1b
diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py
index 5ab60a37c..84bd042f5 100644
--- a/numpy/core/code_generators/genapi.py
+++ b/numpy/core/code_generators/genapi.py
@@ -473,9 +473,9 @@ def fullapi_hash(api_dicts):
of the list of items in the API (as a string)."""
a = []
for d in api_dicts:
- for name, index in order_dict(d):
+ for name, data in order_dict(d):
a.extend(name)
- a.extend(str(index))
+ a.extend(','.join(map(str, data)))
return md5new(''.join(a).encode('ascii')).hexdigest()
diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py
index a590cfb48..415cbf7fc 100644
--- a/numpy/core/code_generators/generate_numpy_api.py
+++ b/numpy/core/code_generators/generate_numpy_api.py
@@ -8,8 +8,9 @@ from genapi import \
import numpy_api
+# use annotated api when running under cpychecker
h_template = r"""
-#ifdef _MULTIARRAYMODULE
+#if defined(_MULTIARRAYMODULE) || defined(WITH_CPYCHECKER_STEALS_REFERENCE_TO_ARG_ATTRIBUTE)
typedef struct {
PyObject_HEAD
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index e3c9cf28b..9f8d4c688 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -20,6 +20,12 @@ ReorderableNone = "PyUFunc_ReorderableNone"
class FullTypeDescr(object):
pass
+class FuncNameSuffix(object):
+ """Stores the suffix to append when generating functions names.
+ """
+ def __init__(self, suffix):
+ self.suffix = suffix
+
class TypeDescription(object):
"""Type signature for a ufunc.
@@ -795,6 +801,30 @@ defdict = {
None,
TD(flts),
),
+'ldexp' :
+ Ufunc(2, 1, None,
+ docstrings.get('numpy.core.umath.ldexp'),
+ None,
+ [TypeDescription('e', None, 'ei', 'e'),
+ TypeDescription('f', None, 'fi', 'f'),
+ TypeDescription('e', FuncNameSuffix('long'), 'el', 'e'),
+ TypeDescription('f', FuncNameSuffix('long'), 'fl', 'f'),
+ TypeDescription('d', None, 'di', 'd'),
+ TypeDescription('d', FuncNameSuffix('long'), 'dl', 'd'),
+ TypeDescription('g', None, 'gi', 'g'),
+ TypeDescription('g', FuncNameSuffix('long'), 'gl', 'g'),
+ ],
+ ),
+'frexp' :
+ Ufunc(1, 2, None,
+ docstrings.get('numpy.core.umath.frexp'),
+ None,
+ [TypeDescription('e', None, 'e', 'ei'),
+ TypeDescription('f', None, 'f', 'fi'),
+ TypeDescription('d', None, 'd', 'di'),
+ TypeDescription('g', None, 'g', 'gi'),
+ ],
+ )
}
if sys.version_info[0] >= 3:
@@ -854,7 +884,7 @@ def make_arrays(funcdict):
thedict = chartotype1 # one input and one output
for t in uf.type_descriptions:
- if t.func_data not in (None, FullTypeDescr):
+ if t.func_data not in (None, FullTypeDescr) and not isinstance(t.func_data, FuncNameSuffix):
funclist.append('NULL')
astype = ''
if not t.astype is None:
@@ -880,6 +910,10 @@ def make_arrays(funcdict):
tname = english_upper(chartoname[t.type])
datalist.append('(void *)NULL')
funclist.append('%s_%s_%s_%s' % (tname, t.in_, t.out, name))
+ elif isinstance(t.func_data, FuncNameSuffix):
+ datalist.append('(void *)NULL')
+ tname = english_upper(chartoname[t.type])
+ funclist.append('%s_%s_%s' % (tname, name, t.func_data.suffix))
else:
datalist.append('(void *)NULL')
tname = english_upper(chartoname[t.type])
diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py
index 4d302969e..804108397 100644
--- a/numpy/core/code_generators/ufunc_docstrings.py
+++ b/numpy/core/code_generators/ufunc_docstrings.py
@@ -3324,9 +3324,6 @@ add_newdoc('numpy.core.umath', 'true_divide',
""")
-# This doc is not currently used, but has been converted to a C string
-# that can be found in numpy/core/src/umath/umathmodule.c where the
-# frexp ufunc is constructed.
add_newdoc('numpy.core.umath', 'frexp',
"""
Decompose the elements of x into mantissa and twos exponent.
@@ -3372,9 +3369,6 @@ add_newdoc('numpy.core.umath', 'frexp',
""")
-# This doc is not currently used, but has been converted to a C string
-# that can be found in numpy/core/src/umath/umathmodule.c where the
-# ldexp ufunc is constructed.
add_newdoc('numpy.core.umath', 'ldexp',
"""
Returns x1 * 2**x2, element-wise.
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py
index 400e75eb5..0bf93390e 100644
--- a/numpy/core/function_base.py
+++ b/numpy/core/function_base.py
@@ -36,6 +36,8 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
The type of the output array. If `dtype` is not given, infer the data
type from the other input arguments.
+ .. versionadded:: 1.9.0
+
Returns
-------
samples : ndarray
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index 21ff8cd1a..78f79d5fe 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -203,12 +203,6 @@ typedef enum {
NPY_SAME_KIND_CASTING=3,
/* Allow any casts */
NPY_UNSAFE_CASTING=4,
-
- /*
- * Temporary internal definition only, will be removed in upcoming
- * release, see below
- * */
- NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND = 100,
} NPY_CASTING;
typedef enum {
diff --git a/numpy/core/include/numpy/npy_endian.h b/numpy/core/include/numpy/npy_endian.h
index 3ba03d0e3..a8ec57245 100644
--- a/numpy/core/include/numpy/npy_endian.h
+++ b/numpy/core/include/numpy/npy_endian.h
@@ -10,10 +10,22 @@
/* Use endian.h if available */
#include <endian.h>
- #define NPY_BYTE_ORDER __BYTE_ORDER
- #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
- #define NPY_BIG_ENDIAN __BIG_ENDIAN
-#else
+ #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN BIG_ENDIAN
+ #elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER _BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN _LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN _BIG_ENDIAN
+ #elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+ #define NPY_BYTE_ORDER __BYTE_ORDER
+ #define NPY_LITTLE_ENDIAN __LITTLE_ENDIAN
+ #define NPY_BIG_ENDIAN __BIG_ENDIAN
+ #endif
+#endif
+
+#ifndef NPY_BYTE_ORDER
/* Set endianness info using target CPU */
#include "npy_cpu.h"
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
index b7920460d..855ddf7fa 100644
--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
@@ -118,10 +118,6 @@ double npy_tanh(double x);
double npy_asin(double x);
double npy_acos(double x);
double npy_atan(double x);
-double npy_aexp(double x);
-double npy_alog(double x);
-double npy_asqrt(double x);
-double npy_afabs(double x);
double npy_log(double x);
double npy_log10(double x);
@@ -147,6 +143,8 @@ double npy_log2(double x);
double npy_atan2(double x, double y);
double npy_pow(double x, double y);
double npy_modf(double x, double* y);
+double npy_frexp(double x, int* y);
+double npy_ldexp(double n, int y);
double npy_copysign(double x, double y);
double npy_nextafter(double x, double y);
@@ -251,6 +249,8 @@ float npy_powf(float x, float y);
float npy_fmodf(float x, float y);
float npy_modff(float x, float* y);
+float npy_frexpf(float x, int* y);
+float npy_ldexpf(float x, int y);
float npy_copysignf(float x, float y);
float npy_nextafterf(float x, float y);
@@ -292,6 +292,8 @@ npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+npy_longdouble npy_frexpl(npy_longdouble x, int* y);
+npy_longdouble npy_ldexpl(npy_longdouble x, int y);
npy_longdouble npy_copysignl(npy_longdouble x, npy_longdouble y);
npy_longdouble npy_nextafterl(npy_longdouble x, npy_longdouble y);
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index 38e3dcf0f..a24a0d837 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -152,13 +152,13 @@ typedef struct _tagPyUFuncObject {
int check_return;
/* The name of the ufunc */
- char *name;
+ const char *name;
/* Array of type numbers, of size ('nargs' * 'ntypes') */
char *types;
/* Documentation string */
- char *doc;
+ const char *doc;
void *ptr;
PyObject *obj;
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 57784a51f..5d7407ce0 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -6,9 +6,11 @@ import warnings
import collections
from . import multiarray
from . import umath
-from .umath import *
+from .umath import (invert, sin, UFUNC_BUFSIZE_DEFAULT, ERR_IGNORE,
+ ERR_WARN, ERR_RAISE, ERR_CALL, ERR_PRINT, ERR_LOG,
+ ERR_DEFAULT, PINF, NAN)
from . import numerictypes
-from .numerictypes import *
+from .numerictypes import longlong, intc, int_, float_, complex_, bool_
if sys.version_info[0] >= 3:
import pickle
@@ -358,9 +360,6 @@ def extend_all(module):
if a not in adict:
__all__.append(a)
-extend_all(umath)
-extend_all(numerictypes)
-
newaxis = None
@@ -2834,6 +2833,10 @@ nan = NaN = NAN
False_ = bool_(False)
True_ = bool_(True)
+from .umath import *
+from .numerictypes import *
from . import fromnumeric
from .fromnumeric import *
extend_all(fromnumeric)
+extend_all(umath)
+extend_all(numerictypes)
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 5da042413..15f66fa6c 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -19,7 +19,7 @@ from setup_common import *
ENABLE_SEPARATE_COMPILATION = (os.environ.get('NPY_SEPARATE_COMPILATION', "1") != "0")
# Set to True to enable relaxed strides checking. This (mostly) means
# that `strides[dim]` is ignored if `shape[dim] == 1` when setting flags.
-NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "0") != "0")
+NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "1") != "0")
# XXX: ugly, we use a class to avoid calling twice some expensive functions in
# config.h/numpyconfig.h. I don't see a better way because distutils force
@@ -176,12 +176,11 @@ def check_math_capabilities(config, moredefs, mathlibs):
moredefs.append((fname2def(f), 1))
for dec, fn in OPTIONAL_FUNCTION_ATTRIBUTES:
- if config.check_func(fn, decl='int %s %s(void *);' % (dec, fn),
- call=False):
+ if config.check_gcc_function_attribute(dec, fn):
moredefs.append((fname2def(fn), 1))
for fn in OPTIONAL_VARIABLE_ATTRIBUTES:
- if config.check_func(fn, decl='int %s a;' % (fn), call=False):
+ if config.check_gcc_variable_attribute(fn):
m = fn.replace("(", "_").replace(")", "_")
moredefs.append((fname2def(m), 1))
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index d2532ccf0..8a0b1826b 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -3922,7 +3922,8 @@ NPY_NO_EXPORT PyArray_Descr @from@_Descr = {
/* elsize */
@num@ * sizeof(@fromtype@),
/* alignment */
- @num@ * _ALIGN(@fromtype@),
+ @num@ * _ALIGN(@fromtype@) > NPY_MAX_COPY_ALIGNMENT ?
+ NPY_MAX_COPY_ALIGNMENT : @num@ * _ALIGN(@fromtype@),
/* subarray */
NULL,
/* fields */
@@ -4264,7 +4265,8 @@ set_typeinfo(PyObject *dict)
#endif
NPY_@name@,
NPY_BITSOF_@name@,
- @num@ * _ALIGN(@type@),
+ @num@ * _ALIGN(@type@) > NPY_MAX_COPY_ALIGNMENT ?
+ NPY_MAX_COPY_ALIGNMENT : @num@ * _ALIGN(@type@),
(PyObject *) &Py@Name@ArrType_Type));
Py_DECREF(s);
diff --git a/numpy/core/src/multiarray/calculation.c b/numpy/core/src/multiarray/calculation.c
index 50938be4c..5563a2515 100644
--- a/numpy/core/src/multiarray/calculation.c
+++ b/numpy/core/src/multiarray/calculation.c
@@ -1182,7 +1182,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
NPY_NO_EXPORT PyObject *
PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
{
- if (PyArray_ISCOMPLEX(self)) {
+ if (PyArray_ISCOMPLEX(self) || PyArray_ISOBJECT(self)) {
if (out == NULL) {
return PyArray_GenericUnaryFunction(self,
n_ops.conjugate);
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 2b3d3c3d2..35b705aff 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -84,7 +84,7 @@ PyArray_GetAttrString_SuppressException(PyObject *obj, char *name)
-NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING = NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND;
+NPY_NO_EXPORT NPY_CASTING NPY_DEFAULT_ASSIGN_CASTING = NPY_SAME_KIND_CASTING;
NPY_NO_EXPORT PyArray_Descr *
@@ -676,7 +676,7 @@ _IsAligned(PyArrayObject *ap)
/* alignment 1 types should have a efficient alignment for copy loops */
if (PyArray_ISFLEXIBLE(ap) || PyArray_ISSTRING(ap)) {
- alignment = 16;
+ alignment = NPY_MAX_COPY_ALIGNMENT;
}
if (alignment == 1) {
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index 1db3bfe85..fa5fb6b67 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -624,63 +624,19 @@ type_num_unsigned_to_signed(int type_num)
}
}
-/*
- * NOTE: once the UNSAFE_CASTING -> SAME_KIND_CASTING transition is over,
- * we should remove NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND
- * and PyArray_CanCastTypeTo_impl should be renamed back to
- * PyArray_CanCastTypeTo.
- */
-static npy_bool
-PyArray_CanCastTypeTo_impl(PyArray_Descr *from, PyArray_Descr *to,
- NPY_CASTING casting);
-
/*NUMPY_API
* Returns true if data of type 'from' may be cast to data of type
* 'to' according to the rule 'casting'.
*/
NPY_NO_EXPORT npy_bool
PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
- NPY_CASTING casting)
-{
- /* fast path for basic types */
- if (NPY_LIKELY(from->type_num < NPY_OBJECT) &&
- NPY_LIKELY(from->type_num == to->type_num) &&
- NPY_LIKELY(from->byteorder == to->byteorder)) {
- return 1;
- }
- else if (casting == NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND) {
- npy_bool unsafe_ok, same_kind_ok;
- unsafe_ok = PyArray_CanCastTypeTo_impl(from, to, NPY_UNSAFE_CASTING);
- same_kind_ok = PyArray_CanCastTypeTo_impl(from, to,
- NPY_SAME_KIND_CASTING);
- if (unsafe_ok && !same_kind_ok) {
- char * msg = "Implicitly casting between incompatible kinds. In "
- "a future numpy release, this will raise an error. "
- "Use casting=\"unsafe\" if this is intentional.";
- if (DEPRECATE(msg) < 0) {
- /* We have no way to propagate an exception :-( */
- PyErr_Clear();
- PySys_WriteStderr("Sorry, you requested this warning "
- "be raised as an error, but we couldn't "
- "do it. (See issue #3806 in the numpy "
- "bug tracker.) So FYI, it was: "
- "DeprecationWarning: %s\n",
- msg);
- }
- }
- return unsafe_ok;
- }
- else {
- return PyArray_CanCastTypeTo_impl(from, to, casting);
- }
-}
-
-static npy_bool
-PyArray_CanCastTypeTo_impl(PyArray_Descr *from, PyArray_Descr *to,
NPY_CASTING casting)
{
- /* If unsafe casts are allowed */
- if (casting == NPY_UNSAFE_CASTING) {
+ /* Fast path for unsafe casts or basic types */
+ if (casting == NPY_UNSAFE_CASTING ||
+ (NPY_LIKELY(from->type_num < NPY_OBJECT) &&
+ NPY_LIKELY(from->type_num == to->type_num) &&
+ NPY_LIKELY(from->byteorder == to->byteorder))) {
return 1;
}
/* Equivalent types can be cast with any value of 'casting' */
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index d93995c8a..c57df147a 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -12,6 +12,7 @@
#include "npy_config.h"
#include "npy_pycompat.h"
+#include "multiarraymodule.h"
#include "common.h"
#include "ctors.h"
@@ -1054,12 +1055,12 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
fa->data = data;
/*
- * If the strides were provided to the function, need to
- * update the flags to get the right CONTIGUOUS, ALIGN properties
+ * always update the flags to get the right CONTIGUOUS, ALIGN properties
+ * not owned data and input strides may not be aligned and on some
+ * platforms (debian sparc) malloc does not provide enough alignment for
+ * long double types
*/
- if (strides != NULL) {
- PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_UPDATE_ALL);
- }
+ PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_UPDATE_ALL);
/*
* call the __array_finalize__
@@ -1069,7 +1070,7 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
if ((subtype != &PyArray_Type)) {
PyObject *res, *func, *args;
- func = PyObject_GetAttrString((PyObject *)fa, "__array_finalize__");
+ func = PyObject_GetAttr((PyObject *)fa, npy_ma_str_array_finalize);
if (func && func != Py_None) {
if (NpyCapsule_Check(func)) {
/* A C-function is stored here */
@@ -3368,7 +3369,7 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type,
#endif
) {
PyObject *newbuf;
- newbuf = PyObject_GetAttrString(buf, "__buffer__");
+ newbuf = PyObject_GetAttr(buf, npy_ma_str_buffer);
if (newbuf == NULL) {
Py_DECREF(type);
return NULL;
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 8b55c9fbd..238077b36 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -2369,11 +2369,8 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
{
int elsize = -1, alignment = -1;
int version = 4;
-#if defined(NPY_PY3K)
- int endian;
-#else
char endian;
-#endif
+ PyObject *endian_obj;
PyObject *subarray, *fields, *names = NULL, *metadata=NULL;
int incref_names = 1;
int int_dtypeflags = 0;
@@ -2390,68 +2387,39 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
}
switch (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))) {
case 9:
-#if defined(NPY_PY3K)
-#define _ARGSTR_ "(iCOOOiiiO)"
-#else
-#define _ARGSTR_ "(icOOOiiiO)"
-#endif
- if (!PyArg_ParseTuple(args, _ARGSTR_, &version, &endian,
+ if (!PyArg_ParseTuple(args, "(iOOOOiiiO)", &version, &endian_obj,
&subarray, &names, &fields, &elsize,
&alignment, &int_dtypeflags, &metadata)) {
+ PyErr_Clear();
return NULL;
-#undef _ARGSTR_
}
break;
case 8:
-#if defined(NPY_PY3K)
-#define _ARGSTR_ "(iCOOOiii)"
-#else
-#define _ARGSTR_ "(icOOOiii)"
-#endif
- if (!PyArg_ParseTuple(args, _ARGSTR_, &version, &endian,
+ if (!PyArg_ParseTuple(args, "(iOOOOiii)", &version, &endian_obj,
&subarray, &names, &fields, &elsize,
&alignment, &int_dtypeflags)) {
return NULL;
-#undef _ARGSTR_
}
break;
case 7:
-#if defined(NPY_PY3K)
-#define _ARGSTR_ "(iCOOOii)"
-#else
-#define _ARGSTR_ "(icOOOii)"
-#endif
- if (!PyArg_ParseTuple(args, _ARGSTR_, &version, &endian,
+ if (!PyArg_ParseTuple(args, "(iOOOOii)", &version, &endian_obj,
&subarray, &names, &fields, &elsize,
&alignment)) {
return NULL;
-#undef _ARGSTR_
}
break;
case 6:
-#if defined(NPY_PY3K)
-#define _ARGSTR_ "(iCOOii)"
-#else
-#define _ARGSTR_ "(icOOii)"
-#endif
- if (!PyArg_ParseTuple(args, _ARGSTR_, &version,
- &endian, &subarray, &fields,
+ if (!PyArg_ParseTuple(args, "(iOOOii)", &version,
+ &endian_obj, &subarray, &fields,
&elsize, &alignment)) {
- PyErr_Clear();
-#undef _ARGSTR_
+ return NULL;
}
break;
case 5:
version = 0;
-#if defined(NPY_PY3K)
-#define _ARGSTR_ "(COOii)"
-#else
-#define _ARGSTR_ "(cOOii)"
-#endif
- if (!PyArg_ParseTuple(args, _ARGSTR_,
- &endian, &subarray, &fields, &elsize,
+ if (!PyArg_ParseTuple(args, "(OOOii)",
+ &endian_obj, &subarray, &fields, &elsize,
&alignment)) {
-#undef _ARGSTR_
return NULL;
}
break;
@@ -2494,11 +2462,55 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
}
}
+ /* Parse endian */
+ if (PyUnicode_Check(endian_obj) || PyBytes_Check(endian_obj)) {
+ PyObject *tmp = NULL;
+ char *str;
+ Py_ssize_t len;
+
+ if (PyUnicode_Check(endian_obj)) {
+ tmp = PyUnicode_AsASCIIString(endian_obj);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ endian_obj = tmp;
+ }
+
+ if (PyBytes_AsStringAndSize(endian_obj, &str, &len) == -1) {
+ Py_XDECREF(tmp);
+ return NULL;
+ }
+ if (len != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "endian is not 1-char string in Numpy dtype unpickling");
+ Py_XDECREF(tmp);
+ return NULL;
+ }
+ endian = str[0];
+ Py_XDECREF(tmp);
+ }
+ else {
+ PyErr_SetString(PyExc_ValueError,
+ "endian is not a string in Numpy dtype unpickling");
+ return NULL;
+ }
if ((fields == Py_None && names != Py_None) ||
(names == Py_None && fields != Py_None)) {
PyErr_Format(PyExc_ValueError,
- "inconsistent fields and names");
+ "inconsistent fields and names in Numpy dtype unpickling");
+ return NULL;
+ }
+
+ if (names != Py_None && !PyTuple_Check(names)) {
+ PyErr_Format(PyExc_ValueError,
+ "non-tuple names in Numpy dtype unpickling");
+ return NULL;
+ }
+
+ if (fields != Py_None && !PyDict_Check(fields)) {
+ PyErr_Format(PyExc_ValueError,
+ "non-dict fields in Numpy dtype unpickling");
return NULL;
}
@@ -2563,13 +2575,82 @@ arraydescr_setstate(PyArray_Descr *self, PyObject *args)
}
if (fields != Py_None) {
- Py_XDECREF(self->fields);
- self->fields = fields;
- Py_INCREF(fields);
- Py_XDECREF(self->names);
- self->names = names;
- if (incref_names) {
- Py_INCREF(names);
+ /*
+ * Ensure names are of appropriate string type
+ */
+ Py_ssize_t i;
+ int names_ok = 1;
+ PyObject *name;
+
+ for (i = 0; i < PyTuple_GET_SIZE(names); ++i) {
+ name = PyTuple_GET_ITEM(names, i);
+ if (!PyUString_Check(name)) {
+ names_ok = 0;
+ break;
+ }
+ }
+
+ if (names_ok) {
+ Py_XDECREF(self->fields);
+ self->fields = fields;
+ Py_INCREF(fields);
+ Py_XDECREF(self->names);
+ self->names = names;
+ if (incref_names) {
+ Py_INCREF(names);
+ }
+ }
+ else {
+#if defined(NPY_PY3K)
+ /*
+ * To support pickle.load(f, encoding='bytes') for loading Py2
+ * generated pickles on Py3, we need to be more lenient and convert
+ * field names from byte strings to unicode.
+ */
+ PyObject *tmp, *new_name, *field;
+
+ tmp = PyDict_New();
+ if (tmp == NULL) {
+ return NULL;
+ }
+ Py_XDECREF(self->fields);
+ self->fields = tmp;
+
+ tmp = PyTuple_New(PyTuple_GET_SIZE(names));
+ if (tmp == NULL) {
+ return NULL;
+ }
+ Py_XDECREF(self->names);
+ self->names = tmp;
+
+ for (i = 0; i < PyTuple_GET_SIZE(names); ++i) {
+ name = PyTuple_GET_ITEM(names, i);
+ field = PyDict_GetItem(fields, name);
+ if (!field) {
+ return NULL;
+ }
+
+ if (PyUnicode_Check(name)) {
+ new_name = name;
+ Py_INCREF(new_name);
+ }
+ else {
+ new_name = PyUnicode_FromEncodedObject(name, "ASCII", "strict");
+ if (new_name == NULL) {
+ return NULL;
+ }
+ }
+
+ PyTuple_SET_ITEM(self->names, i, new_name);
+ if (PyDict_SetItem(self->fields, new_name, field) != 0) {
+ return NULL;
+ }
+ }
+#else
+ PyErr_Format(PyExc_ValueError,
+ "non-string names in Numpy dtype unpickling");
+ return NULL;
+#endif
}
}
diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
index b9063273f..38e7656f3 100644
--- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
+++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
@@ -1490,7 +1490,9 @@ mapiter_@name@(PyArrayMapIterObject *mit)
/* Constant information */
npy_intp fancy_dims[NPY_MAXDIMS];
npy_intp fancy_strides[NPY_MAXDIMS];
+#if @isget@
int iteraxis;
+#endif
char *baseoffset = mit->baseoffset;
char **outer_ptrs = mit->outer_ptrs;
@@ -1498,7 +1500,9 @@ mapiter_@name@(PyArrayMapIterObject *mit)
PyArrayObject *array= mit->array;
/* Fill constant information */
+#if @isget@
iteraxis = mit->iteraxes[0];
+#endif
for (i = 0; i < numiter; i++) {
fancy_dims[i] = mit->fancy_dims[i];
fancy_strides[i] = mit->fancy_strides[i];
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index e2b8ef700..9be2683e6 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -1047,7 +1047,7 @@ array_boolean_subscript(PyArrayObject *self,
Py_INCREF(dtype);
ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), dtype, 1,
&size, PyArray_STRIDES(ret), PyArray_BYTES(ret),
- 0, (PyObject *)self);
+ PyArray_FLAGS(self), (PyObject *)self);
if (ret == NULL) {
Py_DECREF(tmp);
@@ -1221,7 +1221,7 @@ array_assign_boolean_subscript(PyArrayObject *self,
if (needs_api) {
/*
- * FIXME?: most assignment operations stop after the first occurance
+ * FIXME?: most assignment operations stop after the first occurrence
* of an error. Boolean does not currently, but should at least
* report the error. (This is only relevant for things like str->int
* casts which call into python)
@@ -1436,7 +1436,7 @@ array_subscript(PyArrayObject *self, PyObject *op)
/*
* TODO: Should this be a view or not? The only reason not would be
* optimization (i.e. of array[...] += 1) I think.
- * Before, it was just self for a single Ellipis.
+ * Before, it was just self for a single ellipsis.
*/
result = PyArray_View(self, NULL, NULL);
/* A single ellipsis, so no need to decref */
@@ -1569,7 +1569,7 @@ array_subscript(PyArrayObject *self, PyObject *op)
PyArray_SHAPE(tmp_arr),
PyArray_STRIDES(tmp_arr),
PyArray_BYTES(tmp_arr),
- 0, /* TODO: Flags? */
+ PyArray_FLAGS(self),
(PyObject *)self);
if (result == NULL) {
@@ -1656,6 +1656,58 @@ array_assign_item(PyArrayObject *self, Py_ssize_t i, PyObject *op)
/*
+ * This fallback takes the old route of `arr.flat[index] = values`
+ * for one dimensional `arr`. The route can sometimes fail slightly
+ * differently (ValueError instead of IndexError), in which case we
+ * warn users about the change. But since it does not actually care *at all*
+ * about shapes, it should only fail for out of bound indexes or
+ * casting errors.
+ */
+NPY_NO_EXPORT int
+attempt_1d_fallback(PyArrayObject *self, PyObject *ind, PyObject *op)
+{
+ PyObject *err = PyErr_Occurred();
+ PyArrayIterObject *self_iter = NULL;
+
+ Py_INCREF(err);
+ PyErr_Clear();
+
+ self_iter = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
+ if (self_iter == NULL) {
+ goto fail;
+ }
+ if (iter_ass_subscript(self_iter, ind, op) < 0) {
+ goto fail;
+ }
+
+ Py_XDECREF((PyObject *)self_iter);
+ Py_DECREF(err);
+
+ if (DEPRECATE(
+ "assignment will raise an error in the future, most likely "
+ "because your index result shape does not match the value array "
+ "shape. You can use `arr.flat[index] = values` to keep the old "
+ "behaviour.") < 0) {
+ return -1;
+ }
+ return 0;
+
+ fail:
+ if (!PyErr_ExceptionMatches(err)) {
+ PyObject *err, *val, *tb;
+ PyErr_Fetch(&err, &val, &tb);
+ DEPRECATE_FUTUREWARNING(
+ "assignment exception type will change in the future");
+ PyErr_Restore(err, val, tb);
+ }
+
+ Py_XDECREF((PyObject *)self_iter);
+ Py_DECREF(err);
+ return -1;
+}
+
+
+/*
* General assignment with python indexing objects.
*/
static int
@@ -1746,9 +1798,21 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op)
Py_INCREF(op);
tmp_arr = (PyArrayObject *)op;
}
+
if (array_assign_boolean_subscript(self,
(PyArrayObject *)indices[0].object,
tmp_arr, NPY_CORDER) < 0) {
+ /*
+ * Deprecated case. The old boolean indexing seemed to have some
+ * check to allow wrong dimensional boolean arrays in all cases.
+ */
+ if (PyArray_NDIM(tmp_arr) > 1) {
+ if (attempt_1d_fallback(self, indices[0].object,
+ (PyObject*)tmp_arr) < 0) {
+ goto fail;
+ }
+ goto success;
+ }
goto fail;
}
goto success;
@@ -1899,14 +1963,36 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op)
tmp_arr, descr);
if (mit == NULL) {
- goto fail;
+ /*
+ * This is a deprecated special case to allow non-matching shapes
+ * for the index and value arrays.
+ */
+ if (index_type != HAS_FANCY || index_num != 1) {
+ /* This is not a "flat like" 1-d special case */
+ goto fail;
+ }
+ if (attempt_1d_fallback(self, indices[0].object, op) < 0) {
+ goto fail;
+ }
+ goto success;
}
if (tmp_arr == NULL) {
/* Fill extra op */
if (PyArray_CopyObject(mit->extra_op, op) < 0) {
- goto fail;
+ /*
+ * This is a deprecated special case to allow non-matching shapes
+ * for the index and value arrays.
+ */
+ if (index_type != HAS_FANCY || index_num != 1) {
+ /* This is not a "flat like" 1-d special case */
+ goto fail;
+ }
+ if (attempt_1d_fallback(self, indices[0].object, op) < 0) {
+ goto fail;
+ }
+ goto success;
}
}
@@ -2357,7 +2443,7 @@ PyArray_MapIterCheckIndices(PyArrayMapIterObject *mit)
NPY_BEGIN_THREADS_DEF;
if (mit->size == 0) {
- /* All indices got broadcasted away, do *not* check as it always was */
+ /* All indices got broadcast away, do *not* check as it always was */
return 0;
}
@@ -2580,7 +2666,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
* 1. No subspace iteration is necessary, so the extra_op can
* be included into the index iterator (it will be buffered)
* 2. Subspace iteration is necessary, so the extra op is iterated
- * independendly, and the iteration order is fixed at C (could
+ * independently, and the iteration order is fixed at C (could
* also use Fortran order if the array is Fortran order).
* In this case the subspace iterator is not buffered.
*
@@ -2773,7 +2859,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
NPY_ITER_GROWINNER;
/*
- * For a single 1-d operand, guarantee itertion order
+ * For a single 1-d operand, guarantee iteration order
* (scipy used this). Note that subspace may be used.
*/
if ((mit->numiter == 1) && (PyArray_NDIM(index_arrays[0]) == 1)) {
@@ -2985,7 +3071,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
fail:
/*
- * Check whether the operand was not broadcastable and replace the error
+ * Check whether the operand could not be broadcast and replace the error
* in that case. This should however normally be found early with a
* direct goto to broadcast_error
*/
@@ -3000,7 +3086,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
/* (j < 0 is currently impossible, extra_op is reshaped) */
j >= 0 &&
PyArray_DIM(extra_op, i) != mit->dimensions[j]) {
- /* extra_op cannot be broadcasted to the indexing result */
+ /* extra_op cannot be broadcast to the indexing result */
goto broadcast_error;
}
}
@@ -3060,7 +3146,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
* that most of this public API is currently not guaranteed
* to stay the same between versions. If you plan on using
* it, please consider adding more utility functions here
- * to accomodate new features.
+ * to accommodate new features.
*/
NPY_NO_EXPORT PyObject *
PyArray_MapIterArray(PyArrayObject * a, PyObject * index)
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 5fab174ba..a791c2c22 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -1670,6 +1670,13 @@ array_setstate(PyArrayObject *self, PyObject *args)
tmp = PyUnicode_AsLatin1String(rawdata);
Py_DECREF(rawdata);
rawdata = tmp;
+ if (tmp == NULL) {
+ /* More informative error message */
+ PyErr_SetString(PyExc_ValueError,
+ ("Failed to encode latin1 string when unpickling a Numpy array. "
+ "pickle.load(a, encoding='latin1') is assumed."));
+ return NULL;
+ }
}
#endif
diff --git a/numpy/core/src/multiarray/multiarray_tests.c.src b/numpy/core/src/multiarray/multiarray_tests.c.src
index bd0366bd5..a22319cfe 100644
--- a/numpy/core/src/multiarray/multiarray_tests.c.src
+++ b/numpy/core/src/multiarray/multiarray_tests.c.src
@@ -556,6 +556,42 @@ fail:
return NULL;
}
+/* check no elison for avoided increfs */
+static PyObject *
+incref_elide(PyObject *dummy, PyObject *args)
+{
+ PyObject *arg = NULL, *res, *tup;
+ if (!PyArg_ParseTuple(args, "O", &arg)) {
+ return NULL;
+ }
+
+ /* refcount 1 array but should not be elided */
+ arg = PyArray_NewCopy((PyArrayObject*)arg, NPY_KEEPORDER);
+ res = PyNumber_Add(arg, arg);
+
+ /* return original copy, should be equal to input */
+ tup = PyTuple_Pack(2, arg, res);
+ Py_DECREF(arg);
+ Py_DECREF(res);
+ return tup;
+}
+
+/* check no elison for get from list without incref */
+static PyObject *
+incref_elide_l(PyObject *dummy, PyObject *args)
+{
+ PyObject *arg = NULL, *r, *res;
+ if (!PyArg_ParseTuple(args, "O", &arg)) {
+ return NULL;
+ }
+ /* get item without increasing refcount, item may still be on the python
+ * stack but above the inaccessible top */
+ r = PyList_GetItem(arg, 4);
+ res = PyNumber_Add(r, r);
+
+ return res;
+}
+
#if !defined(NPY_PY3K)
static PyObject *
@@ -839,6 +875,12 @@ static PyMethodDef Multiarray_TestsMethods[] = {
{"test_inplace_increment",
inplace_increment,
METH_VARARGS, NULL},
+ {"incref_elide",
+ incref_elide,
+ METH_VARARGS, NULL},
+ {"incref_elide_l",
+ incref_elide_l,
+ METH_VARARGS, NULL},
#if !defined(NPY_PY3K)
{"test_int_subclass",
int_subclass,
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 682705a1b..65ef81bac 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -56,6 +56,7 @@ NPY_NO_EXPORT int NPY_NUMUSERTYPES = 0;
#include "common.h"
#include "ufunc_override.h"
#include "scalarmathmodule.h" /* for npy_mul_with_overflow_intp */
+#include "multiarraymodule.h"
/* Only here for API compatibility */
NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
@@ -1615,6 +1616,73 @@ _array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
"only 2 non-keyword arguments accepted");
return NULL;
}
+
+ /* super-fast path for ndarray argument calls */
+ if (PyTuple_GET_SIZE(args) == 0) {
+ goto full_path;
+ }
+ op = PyTuple_GET_ITEM(args, 0);
+ if (PyArray_CheckExact(op)) {
+ PyObject * dtype_obj = Py_None;
+ oparr = (PyArrayObject *)op;
+ /* get dtype which can be positional */
+ if (PyTuple_GET_SIZE(args) == 2) {
+ dtype_obj = PyTuple_GET_ITEM(args, 1);
+ }
+ else if (kws) {
+ dtype_obj = PyDict_GetItem(kws, npy_ma_str_dtype);
+ if (dtype_obj == NULL) {
+ dtype_obj = Py_None;
+ }
+ }
+ if (dtype_obj != Py_None) {
+ goto full_path;
+ }
+
+ /* array(ndarray) */
+ if (kws == NULL) {
+ ret = (PyArrayObject *)PyArray_NewCopy(oparr, order);
+ goto finish;
+ }
+ else {
+ /* fast path for copy=False rest default (np.asarray) */
+ PyObject * copy_obj, * order_obj, *ndmin_obj;
+ copy_obj = PyDict_GetItem(kws, npy_ma_str_copy);
+ if (copy_obj != Py_False) {
+ goto full_path;
+ }
+ copy = NPY_FALSE;
+
+ /* order does not matter for contiguous 1d arrays */
+ if (PyArray_NDIM((PyArrayObject*)op) > 1 ||
+ !PyArray_IS_C_CONTIGUOUS((PyArrayObject*)op)) {
+ order_obj = PyDict_GetItem(kws, npy_ma_str_order);
+ if (order_obj != Py_None && order_obj != NULL) {
+ goto full_path;
+ }
+ }
+
+ ndmin_obj = PyDict_GetItem(kws, npy_ma_str_ndmin);
+ if (ndmin_obj) {
+ ndmin = PyLong_AsLong(ndmin_obj);
+ if (ndmin == -1 && PyErr_Occurred()) {
+ goto clean_type;
+ }
+ else if (ndmin > NPY_MAXDIMS) {
+ goto full_path;
+ }
+ }
+
+ /* copy=False with default dtype, order and ndim */
+ if (STRIDING_OK(oparr, order)) {
+ ret = oparr;
+ Py_INCREF(ret);
+ goto finish;
+ }
+ }
+ }
+
+full_path:
if(!PyArg_ParseTupleAndKeywords(args, kws, "O|O&O&O&O&i", kwd,
&op,
PyArray_DescrConverter2, &type,
@@ -1839,7 +1907,7 @@ array_scalar(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
static char *kwlist[] = {"dtype","obj", NULL};
PyArray_Descr *typecode;
- PyObject *obj = NULL;
+ PyObject *obj = NULL, *tmpobj = NULL;
int alloc = 0;
void *dptr;
PyObject *ret;
@@ -1871,14 +1939,31 @@ array_scalar(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
alloc = 1;
}
else {
+#if defined(NPY_PY3K)
+ /* Backward compatibility with Python 2 Numpy pickles */
+ if (PyUnicode_Check(obj)) {
+ tmpobj = PyUnicode_AsLatin1String(obj);
+ obj = tmpobj;
+ if (tmpobj == NULL) {
+ /* More informative error message */
+ PyErr_SetString(PyExc_ValueError,
+ ("Failed to encode Numpy scalar data string to latin1. "
+ "pickle.load(a, encoding='latin1') is assumed if unpickling."));
+ return NULL;
+ }
+ }
+#endif
+
if (!PyString_Check(obj)) {
PyErr_SetString(PyExc_TypeError,
"initializing object must be a string");
+ Py_XDECREF(tmpobj);
return NULL;
}
if (PyString_GET_SIZE(obj) < typecode->elsize) {
PyErr_SetString(PyExc_ValueError,
"initialization string is too small");
+ Py_XDECREF(tmpobj);
return NULL;
}
dptr = PyString_AS_STRING(obj);
@@ -1890,6 +1975,7 @@ array_scalar(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
if (alloc) {
PyArray_free(dptr);
}
+ Py_XDECREF(tmpobj);
return ret;
}
@@ -4004,6 +4090,38 @@ set_flaginfo(PyObject *d)
return;
}
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_prepare = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_wrap = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_finalize = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_buffer = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_ufunc = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_order = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_copy = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_dtype = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_ndmin = NULL;
+
+static int
+intern_strings(void)
+{
+ npy_ma_str_array = PyUString_InternFromString("__array__");
+ npy_ma_str_array_prepare = PyUString_InternFromString("__array_prepare__");
+ npy_ma_str_array_wrap = PyUString_InternFromString("__array_wrap__");
+ npy_ma_str_array_finalize = PyUString_InternFromString("__array_finalize__");
+ npy_ma_str_buffer = PyUString_InternFromString("__buffer__");
+ npy_ma_str_ufunc = PyUString_InternFromString("__numpy_ufunc__");
+ npy_ma_str_order = PyUString_InternFromString("order");
+ npy_ma_str_copy = PyUString_InternFromString("copy");
+ npy_ma_str_dtype = PyUString_InternFromString("dtype");
+ npy_ma_str_ndmin = PyUString_InternFromString("ndmin");
+
+ return npy_ma_str_array && npy_ma_str_array_prepare &&
+ npy_ma_str_array_wrap && npy_ma_str_array_finalize &&
+ npy_ma_str_array_finalize && npy_ma_str_ufunc &&
+ npy_ma_str_order && npy_ma_str_copy && npy_ma_str_dtype &&
+ npy_ma_str_ndmin;
+}
+
#if defined(NPY_PY3K)
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
@@ -4176,6 +4294,10 @@ PyMODINIT_FUNC initmultiarray(void) {
set_flaginfo(d);
+ if (!intern_strings()) {
+ goto err;
+ }
+
if (set_typeinfo(d) != 0) {
goto err;
}
diff --git a/numpy/core/src/multiarray/multiarraymodule.h b/numpy/core/src/multiarray/multiarraymodule.h
index 5a3b14b0b..82ae24845 100644
--- a/numpy/core/src/multiarray/multiarraymodule.h
+++ b/numpy/core/src/multiarray/multiarraymodule.h
@@ -1,4 +1,15 @@
#ifndef _NPY_MULTIARRAY_H_
#define _NPY_MULTIARRAY_H_
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_prepare;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_wrap;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_finalize;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_buffer;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_ufunc;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_order;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_copy;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_dtype;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_ndmin;
+
#endif
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index 110bef248..4fa634098 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -1078,6 +1078,24 @@ gentype_richcompare(PyObject *self, PyObject *other, int cmp_op)
{
PyObject *arr, *ret;
+ /*
+ * If the other object is None, False is always right. This avoids
+ * the array None comparison, at least until deprecation it is fixed.
+ * After that, this may be removed and numpy false would be returned.
+ *
+ * NOTE: np.equal(NaT, None) evaluates to TRUE! This is an
+ * an inconsistency, which may has to be considered
+ * when the deprecation is finished.
+ */
+ if (other == Py_None) {
+ if (cmp_op == Py_EQ) {
+ Py_RETURN_FALSE;
+ }
+ if (cmp_op == Py_NE) {
+ Py_RETURN_TRUE;
+ }
+ }
+
arr = PyArray_FromScalar(self, NULL);
if (arr == NULL) {
return NULL;
diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c
index 2278b5d5b..7beadf1bc 100644
--- a/numpy/core/src/multiarray/shape.c
+++ b/numpy/core/src/multiarray/shape.c
@@ -780,7 +780,8 @@ PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute)
PyArray_DIMS(ret)[i] = PyArray_DIMS(ap)[permutation[i]];
PyArray_STRIDES(ret)[i] = PyArray_STRIDES(ap)[permutation[i]];
}
- PyArray_UpdateFlags(ret, NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS);
+ PyArray_UpdateFlags(ret, NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS |
+ NPY_ARRAY_ALIGNED);
return (PyObject *)ret;
}
diff --git a/numpy/core/src/npymath/npy_math.c.src b/numpy/core/src/npymath/npy_math.c.src
index 05af0b132..3a1be3745 100644
--- a/numpy/core/src/npymath/npy_math.c.src
+++ b/numpy/core/src/npymath/npy_math.c.src
@@ -343,6 +343,7 @@ double npy_log2(double x)
* asinh, acosh, atanh
*
* hypot, atan2, pow, fmod, modf
+ * ldexp, frexp
*
* We assume the above are always available in their double versions.
*
@@ -405,6 +406,26 @@ double npy_log2(double x)
}
#endif
+#ifdef ldexp@c@
+#undef ldexp@c@
+#endif
+#ifndef HAVE_LDEXP@C@
+@type@ npy_ldexp@c@(@type@ x, int exp)
+{
+ return (@type@) npy_ldexp((double)x, exp);
+}
+#endif
+
+#ifdef frexp@c@
+#undef frexp@c@
+#endif
+#ifndef HAVE_FREXP@C@
+@type@ npy_frexp@c@(@type@ x, int* exp)
+{
+ return (@type@) npy_frexp(x, exp);
+}
+#endif
+
/**end repeat**/
@@ -451,6 +472,20 @@ double npy_log2(double x)
}
#endif
+#ifdef HAVE_LDEXP@C@
+@type@ npy_ldexp@c@(@type@ x, int exp)
+{
+ return ldexp@c@(x, exp);
+}
+#endif
+
+#ifdef HAVE_FREXP@C@
+@type@ npy_frexp@c@(@type@ x, int* exp)
+{
+ return frexp@c@(x, exp);
+}
+#endif
+
/**end repeat**/
diff --git a/numpy/core/src/npysort/selection.c.src b/numpy/core/src/npysort/selection.c.src
index 920c07ec6..4167b2694 100644
--- a/numpy/core/src/npysort/selection.c.src
+++ b/numpy/core/src/npysort/selection.c.src
@@ -390,7 +390,10 @@ int
/* move pivot into position */
SWAP(SORTEE(low), SORTEE(hh));
- store_pivot(hh, kth, pivots, npiv);
+ /* kth pivot stored later */
+ if (hh != kth) {
+ store_pivot(hh, kth, pivots, npiv);
+ }
if (hh >= kth)
high = hh - 1;
@@ -400,10 +403,11 @@ int
/* two elements */
if (high == low + 1) {
- if (@TYPE@_LT(v[IDX(high)], v[IDX(low)]))
+ if (@TYPE@_LT(v[IDX(high)], v[IDX(low)])) {
SWAP(SORTEE(high), SORTEE(low))
- store_pivot(low, kth, pivots, npiv);
+ }
}
+ store_pivot(kth, kth, pivots, npiv);
return 0;
}
diff --git a/numpy/core/src/private/npy_config.h b/numpy/core/src/private/npy_config.h
index 453dbd065..71d448ee9 100644
--- a/numpy/core/src/private/npy_config.h
+++ b/numpy/core/src/private/npy_config.h
@@ -10,6 +10,17 @@
#undef HAVE_HYPOT
#endif
+/*
+ * largest alignment the copy loops might require
+ * required as string, void and complex types might get copied using larger
+ * instructions than required to operate on them. E.g. complex float is copied
+ * in 8 byte moves but arithmetic on them only loads in 4 byte moves.
+ * the sparc platform may need that alignment for long doubles.
+ * amd64 is not harmed much by the bloat as the system provides 16 byte
+ * alignment by default.
+ */
+#define NPY_MAX_COPY_ALIGNMENT 16
+
/* Safe to use ldexp and frexp for long double for MSVC builds */
#if (NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE) || defined(_MSC_VER)
#ifdef HAVE_LDEXP
diff --git a/numpy/core/src/private/ufunc_override.h b/numpy/core/src/private/ufunc_override.h
index 6b0f73fcf..c47c46a66 100644
--- a/numpy/core/src/private/ufunc_override.h
+++ b/numpy/core/src/private/ufunc_override.h
@@ -26,6 +26,7 @@ normalize___call___args(PyUFuncObject *ufunc, PyObject *args,
else {
obj = PyTuple_GetSlice(args, nin, nargs);
PyDict_SetItemString(*normal_kwds, "out", obj);
+ Py_DECREF(obj);
}
}
}
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index 89f1206b4..d747864f8 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -1743,25 +1743,22 @@ NPY_NO_EXPORT void
}
}
-#ifdef HAVE_FREXP@C@
NPY_NO_EXPORT void
@TYPE@_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
UNARY_LOOP_TWO_OUT {
const @type@ in1 = *(@type@ *)ip1;
- *((@type@ *)op1) = frexp@c@(in1, (int *)op2);
+ *((@type@ *)op1) = npy_frexp@c@(in1, (int *)op2);
}
}
-#endif
-#ifdef HAVE_LDEXP@C@
NPY_NO_EXPORT void
@TYPE@_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const int in2 = *(int *)ip2;
- *((@type@ *)op1) = ldexp@c@(in1, in2);
+ *((@type@ *)op1) = npy_ldexp@c@(in1, in2);
}
}
@@ -1778,7 +1775,7 @@ NPY_NO_EXPORT void
const long in2 = *(long *)ip2;
if (((int)in2) == in2) {
/* Range OK */
- *((@type@ *)op1) = ldexp@c@(in1, ((int)in2));
+ *((@type@ *)op1) = npy_ldexp@c@(in1, ((int)in2));
}
else {
/*
@@ -1786,15 +1783,14 @@ NPY_NO_EXPORT void
* given that exponent has less bits than npy_int.
*/
if (in2 > 0) {
- *((@type@ *)op1) = ldexp@c@(in1, NPY_MAX_INT);
+ *((@type@ *)op1) = npy_ldexp@c@(in1, NPY_MAX_INT);
}
else {
- *((@type@ *)op1) = ldexp@c@(in1, NPY_MIN_INT);
+ *((@type@ *)op1) = npy_ldexp@c@(in1, NPY_MIN_INT);
}
}
}
}
-#endif
#define @TYPE@_true_divide @TYPE@_divide
@@ -2059,25 +2055,22 @@ HALF_modf(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(f
}
}
-#ifdef HAVE_FREXPF
NPY_NO_EXPORT void
HALF_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
UNARY_LOOP_TWO_OUT {
const float in1 = npy_half_to_float(*(npy_half *)ip1);
- *((npy_half *)op1) = npy_float_to_half(frexpf(in1, (int *)op2));
+ *((npy_half *)op1) = npy_float_to_half(npy_frexpf(in1, (int *)op2));
}
}
-#endif
-#ifdef HAVE_LDEXPF
NPY_NO_EXPORT void
HALF_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
const float in1 = npy_half_to_float(*(npy_half *)ip1);
const int in2 = *(int *)ip2;
- *((npy_half *)op1) = npy_float_to_half(ldexpf(in1, in2));
+ *((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, in2));
}
}
@@ -2094,7 +2087,7 @@ HALF_ldexp_long(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UN
const long in2 = *(long *)ip2;
if (((int)in2) == in2) {
/* Range OK */
- *((npy_half *)op1) = npy_float_to_half(ldexpf(in1, ((int)in2)));
+ *((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, ((int)in2)));
}
else {
/*
@@ -2102,15 +2095,14 @@ HALF_ldexp_long(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UN
* given that exponent has less bits than npy_int.
*/
if (in2 > 0) {
- *((npy_half *)op1) = npy_float_to_half(ldexpf(in1, NPY_MAX_INT));
+ *((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, NPY_MAX_INT));
}
else {
- *((npy_half *)op1) = npy_float_to_half(ldexpf(in1, NPY_MIN_INT));
+ *((npy_half *)op1) = npy_float_to_half(npy_ldexpf(in1, NPY_MIN_INT));
}
}
}
}
-#endif
#define HALF_true_divide HALF_divide
@@ -2572,6 +2564,7 @@ OBJECT_@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUS
return;
}
ret = PyObject_IsTrue(ret_obj);
+ Py_DECREF(ret_obj);
if (ret == -1) {
#if @identity@ != -1
if (in1 == in2) {
@@ -2621,6 +2614,7 @@ OBJECT_sign(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED
}
ret = PyLong_FromLong(v);
if (PyErr_Occurred()) {
+ Py_DECREF(zero);
return;
}
Py_XDECREF(*out);
@@ -2635,6 +2629,7 @@ OBJECT_sign(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED
PyObject *ret = PyInt_FromLong(
PyObject_Compare(in1 ? in1 : Py_None, zero));
if (PyErr_Occurred()) {
+ Py_DECREF(zero);
return;
}
Py_XDECREF(*out);
diff --git a/numpy/core/src/umath/loops.h.src b/numpy/core/src/umath/loops.h.src
index fdc9230de..a6e775a3a 100644
--- a/numpy/core/src/umath/loops.h.src
+++ b/numpy/core/src/umath/loops.h.src
@@ -248,17 +248,13 @@ NPY_NO_EXPORT void
NPY_NO_EXPORT void
@TYPE@_modf(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
-#ifdef HAVE_FREXP@C@
NPY_NO_EXPORT void
@TYPE@_frexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
-#endif
-#ifdef HAVE_LDEXP@C@
NPY_NO_EXPORT void
@TYPE@_ldexp(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
NPY_NO_EXPORT void
@TYPE@_ldexp_long(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func));
-#endif
#define @TYPE@_true_divide @TYPE@_divide
diff --git a/numpy/core/src/umath/simd.inc.src b/numpy/core/src/umath/simd.inc.src
index 92dc0c659..5b111eb0d 100644
--- a/numpy/core/src/umath/simd.inc.src
+++ b/numpy/core/src/umath/simd.inc.src
@@ -37,7 +37,9 @@
((abs(args[1] - args[0]) >= (vsize)) || ((abs(args[1] - args[0]) == 0))))
#define IS_BLOCKABLE_REDUCE(esize, vsize) \
- (steps[1] == (esize) && abs(args[1] - args[0]) >= (vsize))
+ (steps[1] == (esize) && abs(args[1] - args[0]) >= (vsize) && \
+ npy_is_aligned(args[1], (esize)) && \
+ npy_is_aligned(args[0], (esize)))
#define IS_BLOCKABLE_BINARY(esize, vsize) \
(steps[0] == steps[1] && steps[1] == steps[2] && steps[2] == (esize) && \
@@ -480,14 +482,18 @@ sse2_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_i
/**end repeat1**/
-/* compress 4 vectors to 4/8 bytes in op with filled with 0 or 1 */
+/*
+ * compress 4 vectors to 4/8 bytes in op with filled with 0 or 1
+ * the last vector is passed as a pointer as MSVC 2010 is unable to ignore the
+ * calling convention leading to C2719 on 32 bit, see #4795
+ */
static NPY_INLINE void
-sse2_compress4_to_byte_@TYPE@(@vtype@ r1, @vtype@ r2, @vtype@ r3, @vtype@ r4,
+sse2_compress4_to_byte_@TYPE@(@vtype@ r1, @vtype@ r2, @vtype@ r3, @vtype@ * r4,
npy_bool * op)
{
const __m128i mask = @vpre@_set1_epi8(0x1);
__m128i ir1 = @vpre@_packs_epi32(@cast@(r1), @cast@(r2));
- __m128i ir2 = @vpre@_packs_epi32(@cast@(r3), @cast@(r4));
+ __m128i ir2 = @vpre@_packs_epi32(@cast@(r3), @cast@(*r4));
__m128i rr = @vpre@_packs_epi16(ir1, ir2);
#if @double@
rr = @vpre@_packs_epi16(rr, rr);
@@ -535,7 +541,7 @@ sse2_binary_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, @type@ * ip2, npy_intp n)
@vtype@ r2 = @vpre@_@VOP@_@vsuf@(b, b);
@vtype@ r3 = @vpre@_@VOP@_@vsuf@(c, c);
@vtype@ r4 = @vpre@_@VOP@_@vsuf@(d, d);
- sse2_compress4_to_byte_@TYPE@(r1, r2, r3, r4, &op[i]);
+ sse2_compress4_to_byte_@TYPE@(r1, r2, r3, &r4, &op[i]);
}
}
else {
@@ -552,7 +558,7 @@ sse2_binary_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, @type@ * ip2, npy_intp n)
@vtype@ r2 = @vpre@_@VOP@_@vsuf@(b1, b2);
@vtype@ r3 = @vpre@_@VOP@_@vsuf@(c1, c2);
@vtype@ r4 = @vpre@_@VOP@_@vsuf@(d1, d2);
- sse2_compress4_to_byte_@TYPE@(r1, r2, r3, r4, &op[i]);
+ sse2_compress4_to_byte_@TYPE@(r1, r2, r3, &r4, &op[i]);
}
}
LOOP_BLOCKED_END {
@@ -577,7 +583,7 @@ sse2_binary_scalar1_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, @type@ * ip2, npy
@vtype@ r2 = @vpre@_@VOP@_@vsuf@(s, b);
@vtype@ r3 = @vpre@_@VOP@_@vsuf@(s, c);
@vtype@ r4 = @vpre@_@VOP@_@vsuf@(s, d);
- sse2_compress4_to_byte_@TYPE@(r1, r2, r3, r4, &op[i]);
+ sse2_compress4_to_byte_@TYPE@(r1, r2, r3, &r4, &op[i]);
}
LOOP_BLOCKED_END {
op[i] = sse2_ordered_cmp_@kind@_@TYPE@(ip1[0], ip2[i]);
@@ -601,7 +607,7 @@ sse2_binary_scalar2_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, @type@ * ip2, npy
@vtype@ r2 = @vpre@_@VOP@_@vsuf@(b, s);
@vtype@ r3 = @vpre@_@VOP@_@vsuf@(c, s);
@vtype@ r4 = @vpre@_@VOP@_@vsuf@(d, s);
- sse2_compress4_to_byte_@TYPE@(r1, r2, r3, r4, &op[i]);
+ sse2_compress4_to_byte_@TYPE@(r1, r2, r3, &r4, &op[i]);
}
LOOP_BLOCKED_END {
op[i] = sse2_ordered_cmp_@kind@_@TYPE@(ip1[i], ip2[0]);
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index d825f15e9..385d59f88 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -73,7 +73,7 @@ static int
_does_loop_use_arrays(void *data);
static int
-_extract_pyvals(PyObject *ref, char *name, int *bufsize,
+_extract_pyvals(PyObject *ref, const char *name, int *bufsize,
int *errmask, PyObject **errobj);
static int
@@ -237,7 +237,7 @@ static int PyUFunc_NUM_NODEFAULTS = 0;
#endif
static PyObject *
-_get_global_ext_obj(char * name)
+get_global_ext_obj(void)
{
PyObject *thedict;
PyObject *ref = NULL;
@@ -259,12 +259,12 @@ _get_global_ext_obj(char * name)
static int
-_get_bufsize_errmask(PyObject * extobj, char * ufunc_name,
+_get_bufsize_errmask(PyObject * extobj, const char *ufunc_name,
int *buffersize, int *errormask)
{
/* Get the buffersize and errormask */
if (extobj == NULL) {
- extobj = _get_global_ext_obj(ufunc_name);
+ extobj = get_global_ext_obj();
}
if (_extract_pyvals(extobj, ufunc_name,
buffersize, errormask, NULL) < 0) {
@@ -430,7 +430,7 @@ _find_array_prepare(PyObject *args, PyObject *kwds,
* if an error handling method is 'call'
*/
static int
-_extract_pyvals(PyObject *ref, char *name, int *bufsize,
+_extract_pyvals(PyObject *ref, const char *name, int *bufsize,
int *errmask, PyObject **errobj)
{
PyObject *retval;
@@ -518,41 +518,41 @@ _extract_pyvals(PyObject *ref, char *name, int *bufsize,
NPY_NO_EXPORT int
PyUFunc_GetPyValues(char *name, int *bufsize, int *errmask, PyObject **errobj)
{
- PyObject *ref = _get_global_ext_obj(name);
+ PyObject *ref = get_global_ext_obj();
return _extract_pyvals(ref, name, bufsize, errmask, errobj);
}
-#define _GETATTR_(str, rstr) do {if (strcmp(name, #str) == 0) \
+#define GETATTR(str, rstr) do {if (strcmp(name, #str) == 0) \
return PyObject_HasAttrString(op, "__" #rstr "__");} while (0);
static int
-_has_reflected_op(PyObject *op, char *name)
+_has_reflected_op(PyObject *op, const char *name)
{
- _GETATTR_(add, radd);
- _GETATTR_(subtract, rsub);
- _GETATTR_(multiply, rmul);
- _GETATTR_(divide, rdiv);
- _GETATTR_(true_divide, rtruediv);
- _GETATTR_(floor_divide, rfloordiv);
- _GETATTR_(remainder, rmod);
- _GETATTR_(power, rpow);
- _GETATTR_(left_shift, rlshift);
- _GETATTR_(right_shift, rrshift);
- _GETATTR_(bitwise_and, rand);
- _GETATTR_(bitwise_xor, rxor);
- _GETATTR_(bitwise_or, ror);
+ GETATTR(add, radd);
+ GETATTR(subtract, rsub);
+ GETATTR(multiply, rmul);
+ GETATTR(divide, rdiv);
+ GETATTR(true_divide, rtruediv);
+ GETATTR(floor_divide, rfloordiv);
+ GETATTR(remainder, rmod);
+ GETATTR(power, rpow);
+ GETATTR(left_shift, rlshift);
+ GETATTR(right_shift, rrshift);
+ GETATTR(bitwise_and, rand);
+ GETATTR(bitwise_xor, rxor);
+ GETATTR(bitwise_or, ror);
/* Comparisons */
- _GETATTR_(equal, eq);
- _GETATTR_(not_equal, ne);
- _GETATTR_(greater, lt);
- _GETATTR_(less, gt);
- _GETATTR_(greater_equal, le);
- _GETATTR_(less_equal, ge);
+ GETATTR(equal, eq);
+ GETATTR(not_equal, ne);
+ GETATTR(greater, lt);
+ GETATTR(less, gt);
+ GETATTR(greater_equal, le);
+ GETATTR(less_equal, ge);
return 0;
}
-#undef _GETATTR_
+#undef GETATTR
/* Return the position of next non-white-space char in the string */
@@ -779,7 +779,7 @@ static int get_ufunc_arguments(PyUFuncObject *ufunc,
int i, nargs, nin = ufunc->nin;
PyObject *obj, *context;
PyObject *str_key_obj = NULL;
- char *ufunc_name;
+ const char *ufunc_name;
int type_num;
int any_flexible = 0, any_object = 0, any_flexible_userloops = 0;
@@ -1762,7 +1762,7 @@ make_arr_prep_args(npy_intp nin, PyObject *args, PyObject *kwds)
* - ufunc_name: name of ufunc
*/
static int
-_check_ufunc_fperr(int errmask, PyObject *extobj, char* ufunc_name) {
+_check_ufunc_fperr(int errmask, PyObject *extobj, const char *ufunc_name) {
int fperr;
PyObject *errobj = NULL;
int ret;
@@ -1778,7 +1778,7 @@ _check_ufunc_fperr(int errmask, PyObject *extobj, char* ufunc_name) {
/* Get error object globals */
if (extobj == NULL) {
- extobj = _get_global_ext_obj(ufunc_name);
+ extobj = get_global_ext_obj();
}
if (_extract_pyvals(extobj, ufunc_name,
NULL, NULL, &errobj) < 0) {
@@ -1800,7 +1800,7 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
{
int nin, nout;
int i, j, idim, nop;
- char *ufunc_name;
+ const char *ufunc_name;
int retval = -1, subok = 1;
int needs_api = 0;
@@ -2325,7 +2325,7 @@ PyUFunc_GenericFunction(PyUFuncObject *ufunc,
{
int nin, nout;
int i, nop;
- char *ufunc_name;
+ const char *ufunc_name;
int retval = -1, subok = 1;
int need_fancy = 0;
@@ -2640,7 +2640,7 @@ reduce_type_resolver(PyUFuncObject *ufunc, PyArrayObject *arr,
int i, retcode;
PyArrayObject *op[3] = {arr, arr, NULL};
PyArray_Descr *dtypes[3] = {NULL, NULL, NULL};
- char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
+ const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
PyObject *type_tup = NULL;
*out_dtype = NULL;
@@ -2816,7 +2816,7 @@ PyUFunc_Reduce(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
PyArray_Descr *dtype;
PyArrayObject *result;
PyArray_AssignReduceIdentityFunc *assign_identity = NULL;
- char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
+ const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
/* These parameters come from a TLS global */
int buffersize = 0, errormask = 0;
@@ -2912,7 +2912,7 @@ PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
PyUFuncGenericFunction innerloop = NULL;
void *innerloopdata = NULL;
- char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
+ const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
/* These parameters come from extobj= or from a TLS global */
int buffersize = 0, errormask = 0;
@@ -3265,7 +3265,7 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind,
PyUFuncGenericFunction innerloop = NULL;
void *innerloopdata = NULL;
- char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
+ const char *ufunc_name = ufunc->name ? ufunc->name : "(unknown)";
char *opname = "reduceat";
/* These parameters come from extobj= or from a TLS global */
@@ -3750,7 +3750,7 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
}
for (i = 0; i < naxes; ++i) {
PyObject *tmp = PyTuple_GET_ITEM(axes_in, i);
- long axis = PyInt_AsLong(tmp);
+ int axis = PyArray_PyIntAsInt(tmp);
if (axis == -1 && PyErr_Occurred()) {
Py_XDECREF(otype);
Py_DECREF(mp);
@@ -3771,7 +3771,7 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
}
/* Try to interpret axis as an integer */
else {
- long axis = PyInt_AsLong(axes_in);
+ int axis = PyArray_PyIntAsInt(axes_in);
/* TODO: PyNumber_Index would be good to use here */
if (axis == -1 && PyErr_Occurred()) {
Py_XDECREF(otype);
@@ -4305,7 +4305,7 @@ NPY_NO_EXPORT PyObject *
PyUFunc_FromFuncAndData(PyUFuncGenericFunction *func, void **data,
char *types, int ntypes,
int nin, int nout, int identity,
- char *name, char *doc, int check_return)
+ const char *name, const char *doc, int check_return)
{
return PyUFunc_FromFuncAndDataAndSignature(func, data, types, ntypes,
nin, nout, identity, name, doc, check_return, NULL);
@@ -4316,7 +4316,7 @@ NPY_NO_EXPORT PyObject *
PyUFunc_FromFuncAndDataAndSignature(PyUFuncGenericFunction *func, void **data,
char *types, int ntypes,
int nin, int nout, int identity,
- char *name, char *doc,
+ const char *name, const char *doc,
int check_return, const char *signature)
{
PyUFuncObject *ufunc;
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index ffdb15bbe..3beb25cf1 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -58,7 +58,7 @@ PyUFunc_ValidateCasting(PyUFuncObject *ufunc,
PyArray_Descr **dtypes)
{
int i, nin = ufunc->nin, nop = nin + ufunc->nout;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -186,7 +186,7 @@ PyUFunc_SimpleBinaryComparisonTypeResolver(PyUFuncObject *ufunc,
PyArray_Descr **out_dtypes)
{
int i, type_num1, type_num2;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -292,7 +292,7 @@ PyUFunc_SimpleUnaryOperationTypeResolver(PyUFuncObject *ufunc,
PyArray_Descr **out_dtypes)
{
int i, type_num1;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -433,7 +433,7 @@ PyUFunc_SimpleBinaryOperationTypeResolver(PyUFuncObject *ufunc,
PyArray_Descr **out_dtypes)
{
int i, type_num1, type_num2;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -591,7 +591,7 @@ PyUFunc_AdditionTypeResolver(PyUFuncObject *ufunc,
{
int type_num1, type_num2;
int i;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -781,7 +781,7 @@ PyUFunc_SubtractionTypeResolver(PyUFuncObject *ufunc,
{
int type_num1, type_num2;
int i;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -963,7 +963,7 @@ PyUFunc_MultiplicationTypeResolver(PyUFuncObject *ufunc,
{
int type_num1, type_num2;
int i;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -1106,7 +1106,7 @@ PyUFunc_DivisionTypeResolver(PyUFuncObject *ufunc,
{
int type_num1, type_num2;
int i;
- char *ufunc_name;
+ const char *ufunc_name;
ufunc_name = ufunc->name ? ufunc->name : "<unnamed ufunc>";
@@ -1875,7 +1875,7 @@ linear_search_type_resolver(PyUFuncObject *self,
{
npy_intp i, j, nin = self->nin, nop = nin + self->nout;
int types[NPY_MAXARGS];
- char *ufunc_name;
+ const char *ufunc_name;
int no_castable_output, use_min_scalar;
/* For making a better error message on coercion error */
@@ -1984,7 +1984,7 @@ type_tuple_type_resolver(PyUFuncObject *self,
npy_intp i, j, n, nin = self->nin, nop = nin + self->nout;
int n_specified = 0;
int specified_types[NPY_MAXARGS], types[NPY_MAXARGS];
- char *ufunc_name;
+ const char *ufunc_name;
int no_castable_output, use_min_scalar;
/* For making a better error message on coercion error */
diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c
index 3ed7ee771..57b2bb239 100644
--- a/numpy/core/src/umath/umathmodule.c
+++ b/numpy/core/src/umath/umathmodule.c
@@ -54,16 +54,15 @@ object_ufunc_type_resolver(PyUFuncObject *ufunc,
PyArray_Descr **out_dtypes)
{
int i, nop = ufunc->nin + ufunc->nout;
- PyArray_Descr *obj_dtype;
- obj_dtype = PyArray_DescrFromType(NPY_OBJECT);
- if (obj_dtype == NULL) {
+ out_dtypes[0] = PyArray_DescrFromType(NPY_OBJECT);
+ if (out_dtypes[0] == NULL) {
return -1;
}
- for (i = 0; i < nop; ++i) {
- Py_INCREF(obj_dtype);
- out_dtypes[i] = obj_dtype;
+ for (i = 1; i < nop; ++i) {
+ Py_INCREF(out_dtypes[0]);
+ out_dtypes[i] = out_dtypes[0];
}
return 0;
@@ -202,182 +201,6 @@ ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUS
*****************************************************************************
*/
-/* Less automated additions to the ufuncs */
-
-static PyUFuncGenericFunction frexp_functions[] = {
-#ifdef HAVE_FREXPF
- HALF_frexp,
- FLOAT_frexp,
-#endif
- DOUBLE_frexp
-#ifdef HAVE_FREXPL
- ,LONGDOUBLE_frexp
-#endif
-};
-
-static void * blank3_data[] = { (void *)NULL, (void *)NULL, (void *)NULL};
-static void * blank6_data[] = { (void *)NULL, (void *)NULL, (void *)NULL,
- (void *)NULL, (void *)NULL, (void *)NULL};
-static char frexp_signatures[] = {
-#ifdef HAVE_FREXPF
- NPY_HALF, NPY_HALF, NPY_INT,
- NPY_FLOAT, NPY_FLOAT, NPY_INT,
-#endif
- NPY_DOUBLE, NPY_DOUBLE, NPY_INT
-#ifdef HAVE_FREXPL
- ,NPY_LONGDOUBLE, NPY_LONGDOUBLE, NPY_INT
-#endif
-};
-
-#if NPY_SIZEOF_LONG == NPY_SIZEOF_INT
-#define LDEXP_LONG(typ) typ##_ldexp
-#else
-#define LDEXP_LONG(typ) typ##_ldexp_long
-#endif
-
-static PyUFuncGenericFunction ldexp_functions[] = {
-#ifdef HAVE_LDEXPF
- HALF_ldexp,
- FLOAT_ldexp,
- LDEXP_LONG(HALF),
- LDEXP_LONG(FLOAT),
-#endif
- DOUBLE_ldexp,
- LDEXP_LONG(DOUBLE)
-#ifdef HAVE_LDEXPL
- ,
- LONGDOUBLE_ldexp,
- LDEXP_LONG(LONGDOUBLE)
-#endif
-};
-
-static const char frdoc[] =
- " Decompose the elements of x into mantissa and twos exponent.\n"
- "\n"
- " Returns (`mantissa`, `exponent`), where `x = mantissa * 2**exponent``.\n"
- " The mantissa is lies in the open interval(-1, 1), while the twos\n"
- " exponent is a signed integer.\n"
- "\n"
- " Parameters\n"
- " ----------\n"
- " x : array_like\n"
- " Array of numbers to be decomposed.\n"
- " out1: ndarray, optional\n"
- " Output array for the mantissa. Must have the same shape as `x`.\n"
- " out2: ndarray, optional\n"
- " Output array for the exponent. Must have the same shape as `x`.\n"
- "\n"
- " Returns\n"
- " -------\n"
- " (mantissa, exponent) : tuple of ndarrays, (float, int)\n"
- " `mantissa` is a float array with values between -1 and 1.\n"
- " `exponent` is an int array which represents the exponent of 2.\n"
- "\n"
- " See Also\n"
- " --------\n"
- " ldexp : Compute ``y = x1 * 2**x2``, the inverse of `frexp`.\n"
- "\n"
- " Notes\n"
- " -----\n"
- " Complex dtypes are not supported, they will raise a TypeError.\n"
- "\n"
- " Examples\n"
- " --------\n"
- " >>> x = np.arange(9)\n"
- " >>> y1, y2 = np.frexp(x)\n"
- " >>> y1\n"
- " array([ 0. , 0.5 , 0.5 , 0.75 , 0.5 , 0.625, 0.75 , 0.875,\n"
- " 0.5 ])\n"
- " >>> y2\n"
- " array([0, 1, 2, 2, 3, 3, 3, 3, 4])\n"
- " >>> y1 * 2**y2\n"
- " array([ 0., 1., 2., 3., 4., 5., 6., 7., 8.])\n"
- "\n";
-
-
-static char ldexp_signatures[] = {
-#ifdef HAVE_LDEXPF
- NPY_HALF, NPY_INT, NPY_HALF,
- NPY_FLOAT, NPY_INT, NPY_FLOAT,
- NPY_HALF, NPY_LONG, NPY_HALF,
- NPY_FLOAT, NPY_LONG, NPY_FLOAT,
-#endif
- NPY_DOUBLE, NPY_INT, NPY_DOUBLE,
- NPY_DOUBLE, NPY_LONG, NPY_DOUBLE
-#ifdef HAVE_LDEXPL
- ,NPY_LONGDOUBLE, NPY_INT, NPY_LONGDOUBLE
- ,NPY_LONGDOUBLE, NPY_LONG, NPY_LONGDOUBLE
-#endif
-};
-
-static const char lddoc[] =
- " Returns x1 * 2**x2, element-wise.\n"
- "\n"
- " The mantissas `x1` and twos exponents `x2` are used to construct\n"
- " floating point numbers ``x1 * 2**x2``.\n"
- "\n"
- " Parameters\n"
- " ----------\n"
- " x1 : array_like\n"
- " Array of multipliers.\n"
- " x2 : array_like, int\n"
- " Array of twos exponents.\n"
- " out : ndarray, optional\n"
- " Output array for the result.\n"
- "\n"
- " Returns\n"
- " -------\n"
- " y : ndarray or scalar\n"
- " The result of ``x1 * 2**x2``.\n"
- "\n"
- " See Also\n"
- " --------\n"
- " frexp : Return (y1, y2) from ``x = y1 * 2**y2``, inverse to `ldexp`.\n"
- "\n"
- " Notes\n"
- " -----\n"
- " Complex dtypes are not supported, they will raise a TypeError.\n"
- "\n"
- " `ldexp` is useful as the inverse of `frexp`, if used by itself it is\n"
- " more clear to simply use the expression ``x1 * 2**x2``.\n"
- "\n"
- " Examples\n"
- " --------\n"
- " >>> np.ldexp(5, np.arange(4))\n"
- " array([ 5., 10., 20., 40.], dtype=float32)\n"
- "\n"
- " >>> x = np.arange(6)\n"
- " >>> np.ldexp(*np.frexp(x))\n"
- " array([ 0., 1., 2., 3., 4., 5.])\n"
- "\n";
-
-
-static void
-InitOtherOperators(PyObject *dictionary) {
- PyObject *f;
- int num;
-
- num = sizeof(frexp_functions) / sizeof(frexp_functions[0]);
- f = PyUFunc_FromFuncAndData(frexp_functions, blank3_data,
- frexp_signatures, num,
- 1, 2, PyUFunc_None, "frexp", frdoc, 0);
- PyDict_SetItemString(dictionary, "frexp", f);
- Py_DECREF(f);
-
- num = sizeof(ldexp_functions) / sizeof(ldexp_functions[0]);
- f = PyUFunc_FromFuncAndData(ldexp_functions, blank6_data,
- ldexp_signatures, num,
- 2, 1, PyUFunc_None, "ldexp", lddoc, 0);
- PyDict_SetItemString(dictionary, "ldexp", f);
- Py_DECREF(f);
-
-#if defined(NPY_PY3K)
- f = PyDict_GetItemString(dictionary, "true_divide");
- PyDict_SetItemString(dictionary, "divide", f);
-#endif
- return;
-}
-
NPY_VISIBILITY_HIDDEN PyObject * npy_um_str_out = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_um_str_subok = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_um_str_array_prepare = NULL;
@@ -493,8 +316,6 @@ PyMODINIT_FUNC initumath(void)
/* Load the ufunc operators into the array module's namespace */
InitOperators(d);
- InitOtherOperators(d);
-
PyDict_SetItemString(d, "pi", s = PyFloat_FromDouble(NPY_PI));
Py_DECREF(s);
PyDict_SetItemString(d, "e", s = PyFloat_FromDouble(NPY_E));
@@ -537,6 +358,11 @@ PyMODINIT_FUNC initumath(void)
PyModule_AddObject(m, "NZERO", PyFloat_FromDouble(NPY_NZERO));
PyModule_AddObject(m, "NAN", PyFloat_FromDouble(NPY_NAN));
+#if defined(NPY_PY3K)
+ s = PyDict_GetItemString(d, "true_divide");
+ PyDict_SetItemString(d, "divide", s);
+#endif
+
s = PyDict_GetItemString(d, "conjugate");
s2 = PyDict_GetItemString(d, "remainder");
/* Setup the array object's numerical structures with appropriate
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index a1f4664a5..ef56766f5 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -12,7 +12,7 @@ from nose.plugins.skip import SkipTest
import numpy as np
from numpy.testing import (dec, run_module_suite, assert_raises,
- assert_warns, assert_array_equal)
+ assert_warns, assert_array_equal, assert_)
class _DeprecationTestCase(object):
@@ -249,6 +249,14 @@ class TestFloatNonIntegerArgumentDeprecation(_DeprecationTestCase):
self.assert_not_deprecated(mult, args=([1], np.int_(3)))
+ def test_reduce_axis_float_index(self):
+ d = np.zeros((3,3,3))
+ self.assert_deprecated(np.min, args=(d, 0.5))
+ self.assert_deprecated(np.min, num=1, args=(d, (0.5, 1)))
+ self.assert_deprecated(np.min, num=1, args=(d, (1, 2.2)))
+ self.assert_deprecated(np.min, num=2, args=(d, (.2, 1.2)))
+
+
class TestBooleanArgumentDeprecation(_DeprecationTestCase):
"""This tests that using a boolean as integer argument/indexing is
deprecated.
@@ -426,6 +434,26 @@ class TestComparisonDepreactions(_DeprecationTestCase):
assert_raises(FutureWarning, operator.eq, np.arange(3), None)
assert_raises(FutureWarning, operator.ne, np.arange(3), None)
+ def test_scalar_none_comparison(self):
+ # Scalars should still just return false and not give a warnings.
+ with warnings.catch_warnings(record=True) as w:
+ warnings.filterwarnings('always', '', FutureWarning)
+ assert_(not np.float32(1) == None)
+ assert_(not np.str_('test') == None)
+ # This is dubious (see below):
+ assert_(not np.datetime64('NaT') == None)
+
+ assert_(np.float32(1) != None)
+ assert_(np.str_('test') != None)
+ # This is dubious (see below):
+ assert_(np.datetime64('NaT') != None)
+ assert_(len(w) == 0)
+
+ # For documentaiton purpose, this is why the datetime is dubious.
+ # At the time of deprecation this was no behaviour change, but
+ # it has to be considered when the deprecations is done.
+ assert_(np.equal(np.datetime64('NaT'), None))
+
class TestIdentityComparisonDepreactions(_DeprecationTestCase):
"""This tests the equal and not_equal object ufuncs identity check
diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py
index 6b0b0a0b5..bb1341455 100644
--- a/numpy/core/tests/test_indexing.py
+++ b/numpy/core/tests/test_indexing.py
@@ -147,7 +147,7 @@ class TestIndexing(TestCase):
def test_boolean_assignment_value_mismatch(self):
# A boolean assignment should fail when the shape of the values
- # cannot be broadcasted to the subscription. (see also gh-3458)
+ # cannot be broadcast to the subscription. (see also gh-3458)
a = np.arange(4)
def f(a, v):
a[a > -1] = v
@@ -188,12 +188,12 @@ class TestIndexing(TestCase):
# If the strides are not reversed, the 0 in the arange comes last.
assert_equal(a[0], 0)
- # This also tests that the subspace buffer is initiliazed:
+ # This also tests that the subspace buffer is initialized:
a = np.ones((5, 2))
c = np.arange(10).reshape(5, 2)[::-1]
a[b, :] = c
assert_equal(a[0], [0, 1])
-
+
def test_reversed_strides_result_allocation(self):
# Test a bug when calculating the output strides for a result array
# when the subspace size was 1 (and test other cases as well)
@@ -285,6 +285,17 @@ class TestIndexing(TestCase):
assert_((a == 1).all())
+ def test_subclass_writeable(self):
+ d = np.rec.array([('NGC1001', 11), ('NGC1002', 1.), ('NGC1003', 1.)],
+ dtype=[('target', 'S20'), ('V_mag', '>f4')])
+ ind = np.array([False, True, True], dtype=bool)
+ assert_(d[ind].flags.writeable)
+ ind = np.array([0, 1])
+ assert_(d[ind].flags.writeable)
+ assert_(d[...].flags.writeable)
+ assert_(d[0].flags.writeable)
+
+
def test_memory_order(self):
# This is not necessary to preserve. Memory layouts for
# more complex indices are not as simple.
@@ -335,7 +346,7 @@ class TestIndexing(TestCase):
# Reference count of intp for index checks
a = np.array([0])
refcount = sys.getrefcount(np.dtype(np.intp))
- # item setting always checks indices in seperate function:
+ # item setting always checks indices in separate function:
a[np.array([0], dtype=np.intp)] = 1
a[np.array([0], dtype=np.uint8)] = 1
assert_raises(IndexError, a.__setitem__,
@@ -402,8 +413,14 @@ class TestBroadcastedAssignments(TestCase):
# Too large and not only ones.
assert_raises(ValueError, assign, a, s_[...], np.ones((2, 1)))
- assert_raises(ValueError, assign, a, s_[[1, 2, 3],], np.ones((2, 1)))
- assert_raises(ValueError, assign, a, s_[[[1], [2]],], np.ones((2,2,1)))
+
+ with warnings.catch_warnings():
+ # Will be a ValueError as well.
+ warnings.simplefilter("error", DeprecationWarning)
+ assert_raises(DeprecationWarning, assign, a, s_[[1, 2, 3],],
+ np.ones((2, 1)))
+ assert_raises(DeprecationWarning, assign, a, s_[[[1], [2]],],
+ np.ones((2,2,1)))
def test_simple_broadcasting_errors(self):
@@ -520,11 +537,11 @@ class TestMultiIndexingAutomated(TestCase):
These test use code to mimic the C-Code indexing for selection.
NOTE: * This still lacks tests for complex item setting.
- * If you change behavoir of indexing, you might want to modify
+ * If you change behavior of indexing, you might want to modify
these tests to try more combinations.
* Behavior was written to match numpy version 1.8. (though a
first version matched 1.7.)
- * Only tuple indicies are supported by the mimicing code.
+ * Only tuple indices are supported by the mimicking code.
(and tested as of writing this)
* Error types should match most of the time as long as there
is only one error. For multiple errors, what gets raised
@@ -547,7 +564,7 @@ class TestMultiIndexingAutomated(TestCase):
slice(4, -1, -2),
slice(None, None, -3),
# Some Fancy indexes:
- np.empty((0, 1, 1), dtype=np.intp), # empty broadcastable
+ np.empty((0, 1, 1), dtype=np.intp), # empty and can be broadcast
np.array([0, 1, -2]),
np.array([[2], [0], [1]]),
np.array([[0, -1], [0, 1]], dtype=np.dtype('intp').newbyteorder()),
@@ -594,7 +611,7 @@ class TestMultiIndexingAutomated(TestCase):
fancy_dim = 0
# NOTE: This is a funny twist (and probably OK to change).
# The boolean array has illegal indexes, but this is
- # allowed if the broadcasted fancy-indices are 0-sized.
+ # allowed if the broadcast fancy-indices are 0-sized.
# This variable is to catch that case.
error_unless_broadcast_to_empty = False
@@ -639,7 +656,7 @@ class TestMultiIndexingAutomated(TestCase):
if arr.ndim - ndim < 0:
# we can't take more dimensions then we have, not even for 0-d arrays.
# since a[()] makes sense, but not a[(),]. We will raise an error
- # lateron, unless a broadcasting error occurs first.
+ # later on, unless a broadcasting error occurs first.
raise IndexError
if ndim == 0 and not None in in_indices:
@@ -651,7 +668,7 @@ class TestMultiIndexingAutomated(TestCase):
for ax, indx in enumerate(in_indices):
if isinstance(indx, slice):
- # convert to an index array anways:
+ # convert to an index array
indx = np.arange(*indx.indices(arr.shape[ax]))
indices.append(['s', indx])
continue
@@ -684,7 +701,7 @@ class TestMultiIndexingAutomated(TestCase):
indx = flat_indx
else:
# This could be changed, a 0-d boolean index can
- # make sense (even outide the 0-d indexed array case)
+ # make sense (even outside the 0-d indexed array case)
# Note that originally this is could be interpreted as
# integer in the full integer special case.
raise IndexError
@@ -736,7 +753,7 @@ class TestMultiIndexingAutomated(TestCase):
arr = arr.transpose(*(fancy_axes + axes))
# We only have one 'f' index now and arr is transposed accordingly.
- # Now handle newaxes by reshaping...
+ # Now handle newaxis by reshaping...
ax = 0
for indx in indices:
if indx[0] == 'f':
@@ -754,7 +771,7 @@ class TestMultiIndexingAutomated(TestCase):
res = np.broadcast(*indx[1:]) # raises ValueError...
else:
res = indx[1]
- # unfortunatly the indices might be out of bounds. So check
+ # unfortunately the indices might be out of bounds. So check
# that first, and use mode='wrap' then. However only if
# there are any indices...
if res.size != 0:
@@ -892,7 +909,7 @@ class TestMultiIndexingAutomated(TestCase):
# spot and the simple ones in one other spot.
with warnings.catch_warnings():
# This is so that np.array(True) is not accepted in a full integer
- # index, when running the file seperatly.
+ # index, when running the file separately.
warnings.filterwarnings('error', '', DeprecationWarning)
for simple_pos in [0, 2, 3]:
tocheck = [self.fill_indices, self.complex_indices,
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index d02821cba..70398ee84 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -246,6 +246,43 @@ class TestArrayConstruction(TestCase):
r = np.array([[True, False], [True, False], [False, True]])
assert_equal(r, tgt.T)
+ def test_array_empty(self):
+ assert_raises(TypeError, np.array)
+
+ def test_array_copy_false(self):
+ d = np.array([1, 2, 3])
+ e = np.array(d, copy=False)
+ d[1] = 3
+ assert_array_equal(e, [1, 3, 3])
+ e = np.array(d, copy=False, order='F')
+ d[1] = 4
+ assert_array_equal(e, [1, 4, 3])
+ e[2] = 7
+ assert_array_equal(d, [1, 4, 7])
+
+ def test_array_copy_true(self):
+ d = np.array([[1,2,3], [1, 2, 3]])
+ e = np.array(d, copy=True)
+ d[0, 1] = 3
+ e[0, 2] = -7
+ assert_array_equal(e, [[1, 2, -7], [1, 2, 3]])
+ assert_array_equal(d, [[1, 3, 3], [1, 2, 3]])
+ e = np.array(d, copy=True, order='F')
+ d[0, 1] = 5
+ e[0, 2] = 7
+ assert_array_equal(e, [[1, 3, 7], [1, 2, 3]])
+ assert_array_equal(d, [[1, 5, 3], [1,2,3]])
+
+ def test_array_cont(self):
+ d = np.ones(10)[::2]
+ assert_(np.ascontiguousarray(d).flags.c_contiguous)
+ assert_(np.ascontiguousarray(d).flags.f_contiguous)
+ assert_(np.asfortranarray(d).flags.c_contiguous)
+ assert_(np.asfortranarray(d).flags.f_contiguous)
+ d = np.ones((10, 10))[::2,::2]
+ assert_(np.ascontiguousarray(d).flags.c_contiguous)
+ assert_(np.asfortranarray(d).flags.f_contiguous)
+
class TestAssignment(TestCase):
def test_assignment_broadcasting(self):
@@ -1394,6 +1431,12 @@ class TestMethods(TestCase):
d[i:].partition(0, kind=k)
assert_array_equal(d, tgt)
+ d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 9])
+ kth = [0, 3, 19, 20]
+ assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
+ assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))
+
d = np.array([2, 1])
d.partition(0, kind=k)
assert_raises(ValueError, d.partition, 2)
@@ -1589,6 +1632,18 @@ class TestMethods(TestCase):
assert_raises(ValueError, d.partition, 2, kind=k)
assert_raises(ValueError, d.argpartition, 2, kind=k)
+ def test_partition_fuzz(self):
+ # a few rounds of random data testing
+ for j in range(10, 30):
+ for i in range(1, j - 2):
+ d = np.arange(j)
+ np.random.shuffle(d)
+ d = d % np.random.randint(2, 30)
+ idx = np.random.randint(d.size)
+ kth = [0, idx, i, i + 1]
+ tgt = np.sort(d)[kth]
+ assert_array_equal(np.partition(d, kth)[kth], tgt,
+ err_msg="data: %r\n kth: %r" % (d, kth))
def test_flatten(self):
x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
@@ -1713,8 +1768,105 @@ class TestMethods(TestCase):
assert_equal(a.ravel(order='K'), [2, 3, 0, 1])
assert_(a.ravel(order='K').flags.owndata)
+ def test_conjugate(self):
+ a = np.array([1-1j, 1+1j, 23+23.0j])
+ ac = a.conj()
+ assert_equal(a.real, ac.real)
+ assert_equal(a.imag, -ac.imag)
+ assert_equal(ac, a.conjugate())
+ assert_equal(ac, np.conjugate(a))
+
+ a = np.array([1-1j, 1+1j, 23+23.0j], 'F')
+ ac = a.conj()
+ assert_equal(a.real, ac.real)
+ assert_equal(a.imag, -ac.imag)
+ assert_equal(ac, a.conjugate())
+ assert_equal(ac, np.conjugate(a))
+
+ a = np.array([1, 2, 3])
+ ac = a.conj()
+ assert_equal(a, ac)
+ assert_equal(ac, a.conjugate())
+ assert_equal(ac, np.conjugate(a))
+
+ a = np.array([1.0, 2.0, 3.0])
+ ac = a.conj()
+ assert_equal(a, ac)
+ assert_equal(ac, a.conjugate())
+ assert_equal(ac, np.conjugate(a))
+
+ a = np.array([1-1j, 1+1j, 1, 2.0], object)
+ ac = a.conj()
+ assert_equal(ac, [k.conjugate() for k in a])
+ assert_equal(ac, a.conjugate())
+ assert_equal(ac, np.conjugate(a))
+
+ a = np.array([1-1j, 1, 2.0, 'f'], object)
+ assert_raises(AttributeError, lambda: a.conj())
+ assert_raises(AttributeError, lambda: a.conjugate())
+
class TestBinop(object):
+ def test_inplace(self):
+ # test refcount 1 inplace conversion
+ assert_array_almost_equal(np.array([0.5]) * np.array([1.0, 2.0]),
+ [0.5, 1.0])
+
+ d = np.array([0.5, 0.5])[::2]
+ assert_array_almost_equal(d * (d * np.array([1.0, 2.0])),
+ [0.25, 0.5])
+
+ a = np.array([0.5])
+ b = np.array([0.5])
+ c = a + b
+ c = a - b
+ c = a * b
+ c = a / b
+ assert_equal(a, b)
+ assert_almost_equal(c, 1.)
+
+ c = a + b * 2. / b * a - a / b
+ assert_equal(a, b)
+ assert_equal(c, 0.5)
+
+ # true divide
+ a = np.array([5])
+ b = np.array([3])
+ c = (a * a) / b
+
+ assert_almost_equal(c, 25 / 3)
+ assert_equal(a, 5)
+ assert_equal(b, 3)
+
+ def test_extension_incref_elide(self):
+ # test extension (e.g. cython) calling PyNumber_* slots without
+ # increasing the reference counts
+ #
+ # def incref_elide(a):
+ # d = input.copy() # refcount 1
+ # return d, d + d # PyNumber_Add without increasing refcount
+ from numpy.core.multiarray_tests import incref_elide
+ d = np.ones(5)
+ orig, res = incref_elide(d)
+ # the return original should not be changed to an inplace operation
+ assert_array_equal(orig, d)
+ assert_array_equal(res, d + d)
+
+ def test_extension_incref_elide_stack(self):
+ # scanning if the refcount == 1 object is on the python stack to check
+ # that we are called directly from python is flawed as object may still
+ # be above the stack pointer and we have no access to the top of it
+ #
+ # def incref_elide_l(d):
+ # return l[4] + l[4] # PyNumber_Add without increasing refcount
+ from numpy.core.multiarray_tests import incref_elide_l
+ # padding with 1 makes sure the object on the stack is not overwriten
+ l = [1, 1, 1, 1, np.ones(5)]
+ res = incref_elide_l(l)
+ # the return original should not be changed to an inplace operation
+ assert_array_equal(l[4], np.ones(5))
+ assert_array_equal(res, l[4] + l[4])
+
def test_ufunc_override_rop_precedence(self):
# Check that __rmul__ and other right-hand operations have
# precedence over __numpy_ufunc__
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index 40bbe5aec..483484467 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -5,6 +5,7 @@ import platform
from decimal import Decimal
import warnings
import itertools
+import platform
import numpy as np
from numpy.core import *
@@ -931,6 +932,7 @@ class TestNonzero(TestCase):
assert_equal(np.nonzero(x['a']), ([0, 1, 1, 2], [2, 0, 1, 1]))
assert_equal(np.nonzero(x['b']), ([0, 0, 1, 2, 2], [0, 2, 0, 1, 2]))
+ assert_(not x['a'].T.flags.aligned)
assert_equal(np.count_nonzero(x['a'].T), 4)
assert_equal(np.count_nonzero(x['b'].T), 5)
assert_equal(np.nonzero(x['a'].T), ([0, 1, 1, 2], [1, 1, 2, 0]))
@@ -1047,8 +1049,17 @@ class TestArrayComparisons(TestCase):
def assert_array_strict_equal(x, y):
assert_array_equal(x, y)
- # Check flags
- assert_(x.flags == y.flags)
+ # Check flags, debian sparc and win32 don't provide 16 byte alignment
+ if (x.dtype.alignment > 8 and
+ 'sparc' not in platform.platform().lower() and
+ sys.platform != 'win32'):
+ assert_(x.flags == y.flags)
+ else:
+ assert_(x.flags.owndata == y.flags.owndata)
+ assert_(x.flags.writeable == y.flags.writeable)
+ assert_(x.flags.c_contiguous == y.flags.c_contiguous)
+ assert_(x.flags.f_contiguous == y.flags.f_contiguous)
+ assert_(x.flags.updateifcopy == y.flags.updateifcopy)
# check endianness
assert_(x.dtype.isnative == y.dtype.isnative)
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 9f40d7b54..c7eaad984 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -181,7 +181,7 @@ class TestRegression(TestCase):
assert_(np.all(b[yb] > 0.5))
def test_endian_where(self,level=rlevel):
- """GitHuB issue #369"""
+ """GitHub issue #369"""
net = np.zeros(3, dtype='>f4')
net[1] = 0.00458849
net[2] = 0.605202
@@ -290,7 +290,7 @@ class TestRegression(TestCase):
def test_tobytes_FORTRANORDER_discontiguous(self,level=rlevel):
"""Fix in r2836"""
- # Create discontiguous Fortran-ordered array
+ # Create non-contiguous Fortran ordered array
x = np.array(np.random.rand(3, 3), order='F')[:, :2]
assert_array_almost_equal(x.ravel(), np.fromstring(x.tobytes()))
@@ -311,7 +311,7 @@ class TestRegression(TestCase):
self.assertRaises(ValueError, bfb)
def test_nonarray_assignment(self):
- # See also Issue gh-2870, test for nonarray assignment
+ # See also Issue gh-2870, test for non-array assignment
# and equivalent unsafe casted array assignment
a = np.arange(10)
b = np.ones(10, dtype=bool)
@@ -398,6 +398,41 @@ class TestRegression(TestCase):
assert_raises(KeyError, np.lexsort, BuggySequence())
+ def test_pickle_py2_bytes_encoding(self):
+ # Check that arrays and scalars pickled on Py2 are
+ # unpickleable on Py3 using encoding='bytes'
+
+ test_data = [
+ # (original, py2_pickle)
+ (np.unicode_('\u6f2c'),
+ asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+ "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\n"
+ "I0\ntp6\nbS',o\\x00\\x00'\np7\ntp8\nRp9\n.")),
+
+ (np.array([9e123], dtype=np.float64),
+ asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\n"
+ "p1\n(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\n"
+ "p7\n(S'f8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'<'\np11\nNNNI-1\nI-1\n"
+ "I0\ntp12\nbI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np13\ntp14\nb.")),
+
+ (np.array([(9e123,)], dtype=[('name', float)]),
+ asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n"
+ "(I0\ntp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n"
+ "(S'V8'\np8\nI0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nN(S'name'\np12\ntp13\n"
+ "(dp14\ng12\n(g7\n(S'f8'\np15\nI0\nI1\ntp16\nRp17\n(I3\nS'<'\np18\nNNNI-1\n"
+ "I-1\nI0\ntp19\nbI0\ntp20\nsI8\nI1\nI0\ntp21\n"
+ "bI00\nS'O\\x81\\xb7Z\\xaa:\\xabY'\np22\ntp23\nb.")),
+ ]
+
+ if sys.version_info[:2] >= (3, 4):
+ # encoding='bytes' was added in Py3.4
+ for original, data in test_data:
+ result = pickle.loads(data, encoding='bytes')
+ assert_equal(result, original)
+
+ if isinstance(result, np.ndarray) and result.dtype.names:
+ for name in result.dtype.names:
+ assert_(isinstance(name, str))
def test_pickle_dtype(self,level=rlevel):
"""Ticket #251"""
@@ -560,7 +595,7 @@ class TestRegression(TestCase):
assert_(a.reshape(5, 1).strides[0] == 0)
def test_reshape_zero_size(self, level=rlevel):
- """Github Issue #2700, setting shape failed for 0-sized arrays"""
+ """GitHub Issue #2700, setting shape failed for 0-sized arrays"""
a = np.ones((0, 2))
a.shape = (-1, 2)
@@ -568,7 +603,7 @@ class TestRegression(TestCase):
# With NPY_RELAXED_STRIDES_CHECKING the test becomes superfluous.
@dec.skipif(np.ones(1).strides[0] == np.iinfo(np.intp).max)
def test_reshape_trailing_ones_strides(self):
- # Github issue gh-2949, bad strides for trailing ones of new shape
+ # GitHub issue gh-2949, bad strides for trailing ones of new shape
a = np.zeros(12, dtype=np.int32)[::2] # not contiguous
strides_c = (16, 8, 8, 8)
strides_f = (8, 24, 48, 48)
@@ -756,8 +791,12 @@ class TestRegression(TestCase):
s = np.ones(10, dtype=float)
x = np.array((15,), dtype=float)
def ia(x, s, v): x[(s>0)]=v
- self.assertRaises(ValueError, ia, x, s, np.zeros(9, dtype=float))
- self.assertRaises(ValueError, ia, x, s, np.zeros(11, dtype=float))
+ # After removing deprecation, the following are ValueErrors.
+ # This might seem odd as compared to the value error below. This
+ # is due to the fact that the new code always uses "nonzero" logic
+ # and the boolean special case is not taken.
+ self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float))
+ self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float))
# Old special case (different code path):
self.assertRaises(ValueError, ia, x.flat, s, np.zeros(9, dtype=float))
@@ -844,7 +883,7 @@ class TestRegression(TestCase):
cnt0_b = cnt(b)
cnt0_c = cnt(c)
- # -- 0d -> 1d broadcasted slice assignment
+ # -- 0d -> 1-d broadcast slice assignment
arr = np.zeros(5, dtype=np.object_)
@@ -861,7 +900,7 @@ class TestRegression(TestCase):
del arr
- # -- 1d -> 2d broadcasted slice assignment
+ # -- 1-d -> 2-d broadcast slice assignment
arr = np.zeros((5, 2), dtype=np.object_)
arr0 = np.zeros(2, dtype=np.object_)
@@ -880,7 +919,7 @@ class TestRegression(TestCase):
del arr, arr0
- # -- 2d copying + flattening
+ # -- 2-d copying + flattening
arr = np.zeros((5, 2), dtype=np.object_)
@@ -1025,8 +1064,8 @@ class TestRegression(TestCase):
b = np.zeros((2, 1), dtype = np.single)
try:
a.compress([True, False], axis = 1, out = b)
- raise AssertionError("compress with an out which cannot be " \
- "safely casted should not return "\
+ raise AssertionError("compress with an out which cannot be "
+ "safely casted should not return "
"successfully")
except TypeError:
pass
@@ -1794,6 +1833,67 @@ class TestRegression(TestCase):
bytestring = "\x01 ".encode('ascii')
assert_equal(bytestring[0:1], '\x01'.encode('ascii'))
+ def test_pickle_py2_array_latin1_hack(self):
+ # Check that unpickling hacks in Py3 that support
+ # encoding='latin1' work correctly.
+
+ # Python2 output for pickle.dumps(numpy.array([129], dtype='b'))
+ data = asbytes("cnumpy.core.multiarray\n_reconstruct\np0\n(cnumpy\nndarray\np1\n(I0\n"
+ "tp2\nS'b'\np3\ntp4\nRp5\n(I1\n(I1\ntp6\ncnumpy\ndtype\np7\n(S'i1'\np8\n"
+ "I0\nI1\ntp9\nRp10\n(I3\nS'|'\np11\nNNNI-1\nI-1\nI0\ntp12\nbI00\nS'\\x81'\n"
+ "p13\ntp14\nb.")
+ if sys.version_info[0] >= 3:
+ # This should work:
+ result = pickle.loads(data, encoding='latin1')
+ assert_array_equal(result, np.array([129], dtype='b'))
+ # Should not segfault:
+ assert_raises(Exception, pickle.loads, data, encoding='koi8-r')
+
+ def test_pickle_py2_scalar_latin1_hack(self):
+ # Check that scalar unpickling hack in Py3 that supports
+ # encoding='latin1' work correctly.
+
+ # Python2 output for pickle.dumps(...)
+ datas = [
+ # (original, python2_pickle, koi8r_validity)
+ (np.unicode_('\u6bd2'),
+ asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n"
+ "(S'U1'\np2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI4\nI4\nI0\n"
+ "tp6\nbS'\\xd2k\\x00\\x00'\np7\ntp8\nRp9\n."),
+ 'invalid'),
+
+ (np.float64(9e123),
+ asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'f8'\n"
+ "p2\nI0\nI1\ntp3\nRp4\n(I3\nS'<'\np5\nNNNI-1\nI-1\nI0\ntp6\n"
+ "bS'O\\x81\\xb7Z\\xaa:\\xabY'\np7\ntp8\nRp9\n."),
+ 'invalid'),
+
+ (np.bytes_(asbytes('\x9c')), # different 8-bit code point in KOI8-R vs latin1
+ asbytes("cnumpy.core.multiarray\nscalar\np0\n(cnumpy\ndtype\np1\n(S'S1'\np2\n"
+ "I0\nI1\ntp3\nRp4\n(I3\nS'|'\np5\nNNNI1\nI1\nI0\ntp6\nbS'\\x9c'\np7\n"
+ "tp8\nRp9\n."),
+ 'different'),
+ ]
+ if sys.version_info[0] >= 3:
+ for original, data, koi8r_validity in datas:
+ result = pickle.loads(data, encoding='latin1')
+ assert_equal(result, original)
+
+ # Decoding under non-latin1 encoding (e.g.) KOI8-R can
+ # produce bad results, but should not segfault.
+ if koi8r_validity == 'different':
+ # Unicode code points happen to lie within latin1,
+ # but are different in koi8-r, resulting to silent
+ # bogus results
+ result = pickle.loads(data, encoding='koi8-r')
+ assert_(result != original)
+ elif koi8r_validity == 'invalid':
+ # Unicode code points outside latin1, so results
+ # to an encoding exception
+ assert_raises(ValueError, pickle.loads, data, encoding='koi8-r')
+ else:
+ raise ValueError(koi8r_validity)
+
def test_structured_type_to_object(self):
a_rec = np.array([(0, 1), (3, 2)], dtype='i4,i8')
a_obj = np.empty((2,), dtype=object)
diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py
index d823e963f..afdc06c03 100644
--- a/numpy/core/tests/test_scalarmath.py
+++ b/numpy/core/tests/test_scalarmath.py
@@ -83,6 +83,18 @@ class TestBaseMath(TestCase):
np.add(1, inp2, out=out)
assert_almost_equal(out, exp1, 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)
+ o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
+ assert_almost_equal(d + d, d * 2)
+ np.add(d, d, out=o)
+ np.add(np.ones_like(d), d, out=o)
+ np.add(d, np.ones_like(d), out=o)
+ np.add(np.ones_like(d), d)
+ np.add(d, np.ones_like(d))
+
class TestPower(TestCase):
def test_small_types(self):
diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py
index 080606dce..eacc266be 100644
--- a/numpy/core/tests/test_ufunc.py
+++ b/numpy/core/tests/test_ufunc.py
@@ -14,6 +14,10 @@ class TestUfunc(TestCase):
import pickle
assert pickle.loads(pickle.dumps(np.sin)) is np.sin
+ # Check that ufunc not defined in the top level numpy namespace such as
+ # numpy.core.test_rational.test_add can also be pickled
+ assert pickle.loads(pickle.dumps(test_add)) is test_add
+
def test_pickle_withstring(self):
import pickle
astring = asbytes("cnumpy.core\n_ufunc_reconstruct\np0\n"
@@ -647,7 +651,6 @@ class TestUfunc(TestCase):
a = np.array(1).view(MyArray)
assert_(type(np.any(a)) is MyArray)
-
def test_casting_out_param(self):
# Test that it's possible to do casts on output
a = np.ones((200, 100), np.int64)
@@ -834,45 +837,20 @@ class TestUfunc(TestCase):
def test_safe_casting(self):
# In old versions of numpy, in-place operations used the 'unsafe'
- # casting rules. In some future version, 'same_kind' will become the
- # default.
+ # casting rules. In versions >= 1.10, 'same_kind' is the
+ # default and an exception is raised instead of a warning.
+ # when 'same_kind' is not satisfied.
a = np.array([1, 2, 3], dtype=int)
# Non-in-place addition is fine
assert_array_equal(assert_no_warnings(np.add, a, 1.1),
[2.1, 3.1, 4.1])
- assert_warns(DeprecationWarning, np.add, a, 1.1, out=a)
- assert_array_equal(a, [2, 3, 4])
+ assert_raises(TypeError, np.add, a, 1.1, out=a)
def add_inplace(a, b):
a += b
- assert_warns(DeprecationWarning, add_inplace, a, 1.1)
- assert_array_equal(a, [3, 4, 5])
- # Make sure that explicitly overriding the warning is allowed:
+ assert_raises(TypeError, add_inplace, a, 1.1)
+ # Make sure that explicitly overriding the exception is allowed:
assert_no_warnings(np.add, a, 1.1, out=a, casting="unsafe")
- assert_array_equal(a, [4, 5, 6])
-
- # There's no way to propagate exceptions from the place where we issue
- # this deprecation warning, so we must throw the exception away
- # entirely rather than cause it to be raised at some other point, or
- # trigger some other unsuspecting if (PyErr_Occurred()) { ...} at some
- # other location entirely.
- import warnings
- import sys
- if sys.version_info[0] >= 3:
- from io import StringIO
- else:
- from StringIO import StringIO
- with warnings.catch_warnings():
- warnings.simplefilter("error")
- old_stderr = sys.stderr
- try:
- sys.stderr = StringIO()
- # No error, but dumps to stderr
- a += 1.1
- # No error on the next bit of code executed either
- 1 + 1
- assert_("Implicitly casting" in sys.stderr.getvalue())
- finally:
- sys.stderr = old_stderr
+ assert_array_equal(a, [2, 3, 4])
def test_ufunc_custom_out(self):
# Test ufunc with built in input types and custom output type
@@ -1087,5 +1065,64 @@ class TestUfunc(TestCase):
self.assertRaises(TypeError, np.add.at, values, [0, 1], 1)
assert_array_equal(values, np.array(['a', 1], dtype=np.object))
+ def test_reduce_arguments(self):
+ f = np.add.reduce
+ d = np.ones((5,2), dtype=int)
+ o = np.ones((2,), dtype=d.dtype)
+ r = o * 5
+ assert_equal(f(d), r)
+ # a, axis=0, dtype=None, out=None, keepdims=False
+ assert_equal(f(d, axis=0), r)
+ assert_equal(f(d, 0), r)
+ assert_equal(f(d, 0, dtype=None), r)
+ assert_equal(f(d, 0, dtype='i'), r)
+ assert_equal(f(d, 0, 'i'), r)
+ assert_equal(f(d, 0, None), r)
+ assert_equal(f(d, 0, None, out=None), r)
+ assert_equal(f(d, 0, None, out=o), r)
+ assert_equal(f(d, 0, None, o), r)
+ assert_equal(f(d, 0, None, None), r)
+ assert_equal(f(d, 0, None, None, keepdims=False), r)
+ assert_equal(f(d, 0, None, None, True), r.reshape((1,) + r.shape))
+ # multiple keywords
+ assert_equal(f(d, axis=0, dtype=None, out=None, keepdims=False), r)
+ assert_equal(f(d, 0, dtype=None, out=None, keepdims=False), r)
+ assert_equal(f(d, 0, None, out=None, keepdims=False), r)
+
+ # too little
+ assert_raises(TypeError, f)
+ # too much
+ assert_raises(TypeError, f, d, 0, None, None, False, 1)
+ # invalid axis
+ assert_raises(TypeError, f, d, "invalid")
+ assert_raises(TypeError, f, d, axis="invalid")
+ assert_raises(TypeError, f, d, axis="invalid", dtype=None,
+ keepdims=True)
+ # invalid dtype
+ assert_raises(TypeError, f, d, 0, "invalid")
+ assert_raises(TypeError, f, d, dtype="invalid")
+ assert_raises(TypeError, f, d, dtype="invalid", out=None)
+ # invalid out
+ assert_raises(TypeError, f, d, 0, None, "invalid")
+ assert_raises(TypeError, f, d, out="invalid")
+ assert_raises(TypeError, f, d, out="invalid", dtype=None)
+ # keepdims boolean, no invalid value
+ # assert_raises(TypeError, f, d, 0, None, None, "invalid")
+ # assert_raises(TypeError, f, d, keepdims="invalid", axis=0, dtype=None)
+ # invalid mix
+ assert_raises(TypeError, f, d, 0, keepdims="invalid", dtype="invalid",
+ out=None)
+
+ # invalid keyord
+ assert_raises(TypeError, f, d, 0, keepdims=True, invalid="invalid",
+ out=None)
+ assert_raises(TypeError, f, d, invalid=0)
+ assert_raises(TypeError, f, d, axis=0, dtype=None, keepdims=True,
+ out=None, invalid=0)
+ assert_raises(TypeError, f, d, axis=0, dtype=None,
+ out=None, invalid=0)
+ assert_raises(TypeError, f, d, axis=0, dtype=None, invalid=0)
+
+
if __name__ == "__main__":
run_module_suite()
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index b3ddc2398..483dcb04b 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -753,6 +753,13 @@ class TestMinMax(TestCase):
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):
@@ -785,6 +792,17 @@ class TestAbsoluteNegative(TestCase):
np.negative(inp, out=out)
assert_array_equal(out, -1*inp, 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 TestSpecialMethods(TestCase):
def test_wrap(self):
diff --git a/numpy/distutils/command/autodist.py b/numpy/distutils/command/autodist.py
index 1b9b1dd57..5a9470b9b 100644
--- a/numpy/distutils/command/autodist.py
+++ b/numpy/distutils/command/autodist.py
@@ -41,3 +41,37 @@ main()
}
"""
return cmd.try_compile(body, None, None)
+
+
+def check_gcc_function_attribute(cmd, attribute, name):
+ """Return True if the given function attribute is supported."""
+ cmd._check_compiler()
+ body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s %s(void*);
+
+int
+main()
+{
+}
+""" % (attribute, name)
+ return cmd.try_compile(body, None, None) != 0
+
+def check_gcc_variable_attribute(cmd, attribute):
+ """Return True if the given variable attribute is supported."""
+ cmd._check_compiler()
+ body = """
+#pragma GCC diagnostic error "-Wattributes"
+#pragma clang diagnostic error "-Wattributes"
+
+int %s foo;
+
+int
+main()
+{
+ return 0;
+}
+""" % (attribute, )
+ return cmd.try_compile(body, None, None) != 0
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py
index 0086e3632..4c407bee0 100644
--- a/numpy/distutils/command/config.py
+++ b/numpy/distutils/command/config.py
@@ -16,7 +16,10 @@ from distutils.ccompiler import CompileError, LinkError
import distutils
from numpy.distutils.exec_command import exec_command
from numpy.distutils.mingw32ccompiler import generate_manifest
-from numpy.distutils.command.autodist import check_inline, check_compiler_gcc4
+from numpy.distutils.command.autodist import (check_gcc_function_attribute,
+ check_gcc_variable_attribute,
+ check_inline,
+ check_compiler_gcc4)
from numpy.distutils.compat import get_exception
LANG_EXT['f77'] = '.f'
@@ -59,17 +62,28 @@ class config(old_config):
e = get_exception()
msg = """\
Could not initialize compiler instance: do you have Visual Studio
-installed ? If you are trying to build with mingw, please use python setup.py
-build -c mingw32 instead ). If you have Visual Studio installed, check it is
-correctly installed, and the right version (VS 2008 for python 2.6, VS 2003 for
-2.5, etc...). Original exception was: %s, and the Compiler
-class was %s
+installed? If you are trying to build with MinGW, please use "python setup.py
+build -c mingw32" instead. If you have Visual Studio installed, check it is
+correctly installed, and the right version (VS 2008 for python 2.6, 2.7 and 3.2,
+VS 2010 for >= 3.3).
+
+Original exception was: %s, and the Compiler class was %s
============================================================================""" \
% (e, self.compiler.__class__.__name__)
print ("""\
============================================================================""")
raise distutils.errors.DistutilsPlatformError(msg)
+ # After MSVC is initialized, add an explicit /MANIFEST to linker
+ # flags. See issues gh-4245 and gh-4101 for details. Also
+ # relevant are issues 4431 and 16296 on the Python bug tracker.
+ from distutils import msvc9compiler
+ if msvc9compiler.get_build_version() >= 10:
+ for ldflags in [self.compiler.ldflags_shared,
+ self.compiler.ldflags_shared_debug]:
+ if '/MANIFEST' not in ldflags:
+ ldflags.append('/MANIFEST')
+
if not isinstance(self.fcompiler, FCompiler):
self.fcompiler = new_fcompiler(compiler=self.fcompiler,
dry_run=self.dry_run, force=1,
@@ -402,6 +416,12 @@ int main ()
"""Return True if the C compiler is gcc >= 4."""
return check_compiler_gcc4(self)
+ def check_gcc_function_attribute(self, attribute, name):
+ return check_gcc_function_attribute(self, attribute, name)
+
+ def check_gcc_variable_attribute(self, attribute):
+ return check_gcc_variable_attribute(self, attribute)
+
def get_output(self, body, headers=None, include_dirs=None,
libraries=None, library_dirs=None,
lang="c", use_tee=None):
diff --git a/numpy/f2py/tests/test_array_from_pyobj.py b/numpy/f2py/tests/test_array_from_pyobj.py
index 3a148e72c..2dcb9e834 100644
--- a/numpy/f2py/tests/test_array_from_pyobj.py
+++ b/numpy/f2py/tests/test_array_from_pyobj.py
@@ -4,6 +4,7 @@ import unittest
import os
import sys
import copy
+import platform
import nose
@@ -81,37 +82,45 @@ class Intent(object):
intent = Intent()
-class Type(object):
- _type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT',
- 'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG',
- 'FLOAT', 'DOUBLE', 'LONGDOUBLE', 'CFLOAT', 'CDOUBLE',
- 'CLONGDOUBLE']
- _type_cache = {}
-
- _cast_dict = {'BOOL':['BOOL']}
- _cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE']
- _cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE']
- _cast_dict['BYTE'] = ['BYTE']
- _cast_dict['UBYTE'] = ['UBYTE']
- _cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT']
- _cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT']
- _cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT']
- _cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT']
-
- _cast_dict['LONG'] = _cast_dict['INT'] + ['LONG']
- _cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG']
-
- _cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG']
- _cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG']
-
- _cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT']
- _cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE']
- _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE']
-
- _cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT']
+_type_names = ['BOOL', 'BYTE', 'UBYTE', 'SHORT', 'USHORT', 'INT', 'UINT',
+ 'LONG', 'ULONG', 'LONGLONG', 'ULONGLONG',
+ 'FLOAT', 'DOUBLE', 'CFLOAT']
+
+_cast_dict = {'BOOL':['BOOL']}
+_cast_dict['BYTE'] = _cast_dict['BOOL'] + ['BYTE']
+_cast_dict['UBYTE'] = _cast_dict['BOOL'] + ['UBYTE']
+_cast_dict['BYTE'] = ['BYTE']
+_cast_dict['UBYTE'] = ['UBYTE']
+_cast_dict['SHORT'] = _cast_dict['BYTE'] + ['UBYTE', 'SHORT']
+_cast_dict['USHORT'] = _cast_dict['UBYTE'] + ['BYTE', 'USHORT']
+_cast_dict['INT'] = _cast_dict['SHORT'] + ['USHORT', 'INT']
+_cast_dict['UINT'] = _cast_dict['USHORT'] + ['SHORT', 'UINT']
+
+_cast_dict['LONG'] = _cast_dict['INT'] + ['LONG']
+_cast_dict['ULONG'] = _cast_dict['UINT'] + ['ULONG']
+
+_cast_dict['LONGLONG'] = _cast_dict['LONG'] + ['LONGLONG']
+_cast_dict['ULONGLONG'] = _cast_dict['ULONG'] + ['ULONGLONG']
+
+_cast_dict['FLOAT'] = _cast_dict['SHORT'] + ['USHORT', 'FLOAT']
+_cast_dict['DOUBLE'] = _cast_dict['INT'] + ['UINT', 'FLOAT', 'DOUBLE']
+
+_cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT']
+
+# (debian) sparc system malloc does not provide the alignment required by
+# 16 byte long double types this means the inout intent cannot be satisfied and
+# several tests fail as the alignment flag can be randomly true or fals
+# when numpy gains an aligned allocator the tests could be enabled again
+if 'sparc' not in platform.platform().lower() and sys.platform != 'win32':
+ _type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE'])
+ _cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \
+ ['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE']
+ _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + \
+ ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE']
_cast_dict['CDOUBLE'] = _cast_dict['DOUBLE'] + ['CFLOAT', 'CDOUBLE']
- _cast_dict['CLONGDOUBLE'] = _cast_dict['LONGDOUBLE'] + ['CFLOAT', 'CDOUBLE', 'CLONGDOUBLE']
+class Type(object):
+ _type_cache = {}
def __new__(cls, name):
if isinstance(name, dtype):
@@ -138,15 +147,15 @@ class Type(object):
self.dtypechar = typeinfo[self.NAME][0]
def cast_types(self):
- return [self.__class__(_m) for _m in self._cast_dict[self.NAME]]
+ return [self.__class__(_m) for _m in _cast_dict[self.NAME]]
def all_types(self):
- return [self.__class__(_m) for _m in self._type_names]
+ return [self.__class__(_m) for _m in _type_names]
def smaller_types(self):
bits = typeinfo[self.NAME][3]
types = []
- for name in self._type_names:
+ for name in _type_names:
if typeinfo[name][3]<bits:
types.append(Type(name))
return types
@@ -154,7 +163,7 @@ class Type(object):
def equal_types(self):
bits = typeinfo[self.NAME][3]
types = []
- for name in self._type_names:
+ for name in _type_names:
if name==self.NAME: continue
if typeinfo[name][3]==bits:
types.append(Type(name))
@@ -163,7 +172,7 @@ class Type(object):
def larger_types(self):
bits = typeinfo[self.NAME][3]
types = []
- for name in self._type_names:
+ for name in _type_names:
if typeinfo[name][3]>bits:
types.append(Type(name))
return types
@@ -532,7 +541,7 @@ class _test_shared_memory:
assert_(obj.dtype.type is self.type.dtype) # obj type is changed inplace!
-for t in Type._type_names:
+for t in _type_names:
exec('''\
class test_%s_gen(unittest.TestCase,
_test_shared_memory
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 0a1d05f77..618a93bb9 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -337,6 +337,11 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
smin[i] = smin[i] - .5
smax[i] = smax[i] + .5
+ # avoid rounding issues for comparisons when dealing with inexact types
+ if np.issubdtype(sample.dtype, np.inexact):
+ edge_dt = sample.dtype
+ else:
+ edge_dt = float
# Create edge arrays
for i in arange(D):
if isscalar(bins[i]):
@@ -345,9 +350,9 @@ def histogramdd(sample, bins=10, range=None, normed=False, weights=None):
"Element at index %s in `bins` should be a positive "
"integer." % i)
nbin[i] = bins[i] + 2 # +2 for outlier bins
- edges[i] = linspace(smin[i], smax[i], nbin[i]-1)
+ edges[i] = linspace(smin[i], smax[i], nbin[i]-1, dtype=edge_dt)
else:
- edges[i] = asarray(bins[i], float)
+ edges[i] = asarray(bins[i], edge_dt)
nbin[i] = len(edges[i]) + 1 # +1 for outlier bins
dedges[i] = diff(edges[i])
if np.any(np.asarray(dedges[i]) <= 0):
diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py
index f5ac35e54..7260a35b8 100644
--- a/numpy/lib/nanfunctions.py
+++ b/numpy/lib/nanfunctions.py
@@ -33,6 +33,10 @@ def _replace_nan(a, val):
marking the locations where NaNs were present. If `a` is not of
inexact type, do nothing and return `a` together with a mask of None.
+ Note that scalars will end up as array scalars, which is important
+ for using the result as the value of the out argument in some
+ operations.
+
Parameters
----------
a : array-like
@@ -1037,7 +1041,7 @@ def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
avg = _divide_by_count(avg, cnt)
# Compute squared deviation from mean.
- arr -= avg
+ np.subtract(arr, avg, out=arr, casting='unsafe')
arr = _copyto(arr, 0, mask)
if issubclass(arr.dtype.type, np.complexfloating):
sqr = np.multiply(arr, arr.conj(), out=arr).real
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index fe855a71a..0e49dd31c 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -288,8 +288,7 @@ def load(file, mmap_mode=None):
Parameters
----------
file : file-like object or string
- The file to read. Compressed files with the filename extension
- ``.gz`` are acceptable. File-like objects must support the
+ The file to read. File-like objects must support the
``seek()`` and ``read()`` methods. Pickled files require that the
file-like object support the ``readline()`` method as well.
mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index ee38b3573..ac677a308 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -1070,6 +1070,13 @@ class TestHistogram(TestCase):
h, b = histogram(a, weights=np.ones(10, float))
assert_(issubdtype(h.dtype, float))
+ def test_f32_rounding(self):
+ # gh-4799, check that the rounding of the edges works with float32
+ x = np.array([276.318359 , -69.593948 , 21.329449], dtype=np.float32)
+ y = np.array([5005.689453, 4481.327637, 6010.369629], dtype=np.float32)
+ counts_hist, xedges, yedges = np.histogram2d(x, y, bins=100)
+ assert_equal(counts_hist.sum(), 3.)
+
def test_weights(self):
v = rand(100)
w = np.ones(100) * 5
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
index 49ad1ba5b..03e238261 100644
--- a/numpy/lib/tests/test_io.py
+++ b/numpy/lib/tests/test_io.py
@@ -4,9 +4,7 @@ import sys
import gzip
import os
import threading
-import shutil
-import contextlib
-from tempfile import mkstemp, mkdtemp, NamedTemporaryFile
+from tempfile import mkstemp, NamedTemporaryFile
import time
import warnings
import gc
@@ -24,13 +22,7 @@ from numpy.ma.testutils import (
assert_raises, assert_raises_regex, run_module_suite
)
from numpy.testing import assert_warns, assert_, build_err_msg
-
-
-@contextlib.contextmanager
-def tempdir(change_dir=False):
- tmpdir = mkdtemp()
- yield tmpdir
- shutil.rmtree(tmpdir)
+from numpy.testing.utils import tempdir
class TextIO(BytesIO):
@@ -202,7 +194,7 @@ class TestSavezLoad(RoundtripTest, TestCase):
def test_big_arrays(self):
L = (1 << 31) + 100000
a = np.empty(L, dtype=np.uint8)
- with tempdir() as tmpdir:
+ with tempdir(prefix="numpy_test_big_arrays_") as tmpdir:
tmp = os.path.join(tmpdir, "file.npz")
np.savez(tmp, a=a)
del a
@@ -311,7 +303,7 @@ class TestSavezLoad(RoundtripTest, TestCase):
# Check that zipfile owns file and can close it.
# This needs to pass a file name to load for the
# test.
- with tempdir() as tmpdir:
+ with tempdir(prefix="numpy_test_closing_zipfile_after_load_") as tmpdir:
fd, tmp = mkstemp(suffix='.npz', dir=tmpdir)
os.close(fd)
np.savez(tmp, lab='place holder')
diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py
index e9dbef70f..739061a5d 100644
--- a/numpy/lib/tests/test_twodim_base.py
+++ b/numpy/lib/tests/test_twodim_base.py
@@ -311,6 +311,40 @@ def test_tril_triu_ndim3():
yield assert_equal, a_triu_observed.dtype, a.dtype
yield assert_equal, a_tril_observed.dtype, a.dtype
+def test_tril_triu_with_inf():
+ # Issue 4859
+ arr = np.array([[1, 1, np.inf],
+ [1, 1, 1],
+ [np.inf, 1, 1]])
+ out_tril = np.array([[1, 0, 0],
+ [1, 1, 0],
+ [np.inf, 1, 1]])
+ out_triu = out_tril.T
+ assert_array_equal(np.triu(arr), out_triu)
+ assert_array_equal(np.tril(arr), out_tril)
+
+
+def test_tril_triu_dtype():
+ # Issue 4916
+ # tril and triu should return the same dtype as input
+ for c in np.typecodes['All']:
+ if c == 'V':
+ continue
+ arr = np.zeros((3, 3), dtype=c)
+ assert_equal(np.triu(arr).dtype, arr.dtype)
+ assert_equal(np.tril(arr).dtype, arr.dtype)
+
+ # check special cases
+ arr = np.array([['2001-01-01T12:00', '2002-02-03T13:56'],
+ ['2004-01-01T12:00', '2003-01-03T13:45']],
+ dtype='datetime64')
+ assert_equal(np.triu(arr).dtype, arr.dtype)
+ assert_equal(np.tril(arr).dtype, arr.dtype)
+
+ arr = np.zeros((3,3), dtype='f4,f4')
+ assert_equal(np.triu(arr).dtype, arr.dtype)
+ assert_equal(np.tril(arr).dtype, arr.dtype)
+
def test_mask_indices():
# simple test without offset
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index 2861e1c4a..40a140b6b 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -387,7 +387,6 @@ def tri(N, M=None, k=0, dtype=float):
dtype : dtype, optional
Data type of the returned array. The default is float.
-
Returns
-------
tri : ndarray of shape (N, M)
@@ -452,7 +451,9 @@ def tril(m, k=0):
"""
m = asanyarray(m)
- return multiply(tri(*m.shape[-2:], k=k, dtype=bool), m, dtype=m.dtype)
+ mask = tri(*m.shape[-2:], k=k, dtype=bool)
+
+ return where(mask, m, zeros(1, m.dtype))
def triu(m, k=0):
@@ -478,7 +479,9 @@ def triu(m, k=0):
"""
m = asanyarray(m)
- return multiply(~tri(*m.shape[-2:], k=k-1, dtype=bool), m, dtype=m.dtype)
+ mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
+
+ return where(mask, zeros(1, m.dtype), m)
# Originally borrowed from John Hunter and matplotlib
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 5c566b92c..00164b851 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -843,8 +843,7 @@ class _MaskedUnaryOperation:
d = getdata(a)
# Case 1.1. : Domained function
if self.domain is not None:
- with np.errstate():
- np.seterr(divide='ignore', invalid='ignore')
+ with np.errstate(divide='ignore', invalid='ignore'):
result = self.f(d, *args, **kwargs)
# Make a mask
m = ~umath.isfinite(result)
@@ -932,8 +931,7 @@ class _MaskedBinaryOperation:
else:
m = umath.logical_or(ma, mb)
# Get the result
- with np.errstate():
- np.seterr(divide='ignore', invalid='ignore')
+ with np.errstate(divide='ignore', invalid='ignore'):
result = self.f(da, db, *args, **kwargs)
# check it worked
if result is NotImplemented:
@@ -945,11 +943,8 @@ class _MaskedBinaryOperation:
return result
# Case 2. : array
# Revert result to da where masked
- if m.any():
- np.copyto(result, 0, casting='unsafe', where=m)
- # This only makes sense if the operation preserved the dtype
- if result.dtype == da.dtype:
- result += m * da
+ if m is not nomask:
+ np.copyto(result, da, casting='unsafe', where=m)
# Transforms to a (subclass of) MaskedArray
result = result.view(get_masked_subclass(a, b))
result._mask = m
@@ -1073,8 +1068,7 @@ class _DomainedBinaryOperation:
(da, db) = (getdata(a, subok=False), getdata(b, subok=False))
(ma, mb) = (getmask(a), getmask(b))
# Get the result
- with np.errstate():
- np.seterr(divide='ignore', invalid='ignore')
+ with np.errstate(divide='ignore', invalid='ignore'):
result = self.f(da, db, *args, **kwargs)
# check it worked
if result is NotImplemented:
@@ -1094,8 +1088,7 @@ class _DomainedBinaryOperation:
else:
return result
# When the mask is True, put back da
- np.copyto(result, 0, casting='unsafe', where=m)
- result += m * da
+ np.copyto(result, da, casting='unsafe', where=m)
result = result.view(get_masked_subclass(a, b))
result._mask = m
if isinstance(b, MaskedArray):
@@ -3840,8 +3833,7 @@ class MaskedArray(ndarray):
"Raise self to the power other, in place."
other_data = getdata(other)
other_mask = getmask(other)
- with np.errstate():
- np.seterr(divide='ignore', invalid='ignore')
+ with np.errstate(divide='ignore', invalid='ignore'):
ndarray.__ipow__(self._data, np.where(self._mask, 1, other_data))
invalid = np.logical_not(np.isfinite(self._data))
if invalid.any():
@@ -5029,6 +5021,10 @@ class MaskedArray(ndarray):
endwith : {True, False}, optional
Whether missing values (if any) should be forced in the upper indices
(at the end of the array) (True) or lower indices (at the beginning).
+ When the array contains unmasked values of the largest (or smallest if
+ False) representable value of the datatype the ordering of these values
+ and the masked values is undefined. To enforce the masked values are
+ at the end (beginning) in this case one must sort the mask.
fill_value : {var}, optional
Value used internally for the masked values.
If ``fill_value`` is not None, it supersedes ``endwith``.
@@ -5594,9 +5590,8 @@ class mvoid(MaskedArray):
"""
#
def __new__(self, data, mask=nomask, dtype=None, fill_value=None,
- hardmask=False):
- dtype = dtype or data.dtype
- _data = np.array(data, dtype=dtype)
+ hardmask=False, copy=False, subok=True):
+ _data = np.array(data, copy=copy, subok=subok, dtype=dtype)
_data = _data.view(self)
_data._hardmask = hardmask
if mask is not nomask:
@@ -6116,8 +6111,7 @@ def power(a, b, third=None):
else:
basetype = MaskedArray
# Get the result and view it as a (subclass of) MaskedArray
- with np.errstate():
- np.seterr(divide='ignore', invalid='ignore')
+ with np.errstate(divide='ignore', invalid='ignore'):
result = np.where(m, fa, umath.power(fa, fb)).view(basetype)
result._update_from(a)
# Find where we're in trouble w/ NaNs and Infs
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index e6f659041..34951875d 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -194,8 +194,7 @@ class TestMaskedArray(TestCase):
def test_fix_invalid(self):
# Checks fix_invalid.
- with np.errstate():
- np.seterr(invalid='ignore')
+ with np.errstate(invalid='ignore'):
data = masked_array([np.nan, 0., 1.], mask=[0, 0, 1])
data_fixed = fix_invalid(data)
assert_equal(data_fixed._data, [data.fill_value, 0., 1.])
@@ -815,7 +814,7 @@ class TestMaskedArrayArithmetic(TestCase):
res = count(ott)
self.assertTrue(res.dtype.type is np.intp)
assert_equal(3, res)
-
+
ott = ott.reshape((2, 2))
res = count(ott)
assert_(res.dtype.type is np.intp)
@@ -3523,8 +3522,15 @@ class TestMaskedFields(TestCase):
assert_equal_records(a[-2]._mask, a._mask[-2])
def test_setitem(self):
- # Issue 2403
+ # Issue 4866: check that one can set individual items in [record][col]
+ # and [col][record] order
ndtype = np.dtype([('a', float), ('b', int)])
+ ma = np.ma.MaskedArray([(1.0, 1), (2.0, 2)], dtype=ndtype)
+ ma['a'][1] = 3.0
+ assert_equal(ma['a'], np.array([1.0, 3.0]))
+ ma[1]['a'] = 4.0
+ assert_equal(ma['a'], np.array([1.0, 4.0]))
+ # Issue 2403
mdtype = np.dtype([('a', bool), ('b', bool)])
# soft mask
control = np.array([(False, True), (True, True)], dtype=mdtype)
diff --git a/numpy/ma/tests/test_old_ma.py b/numpy/ma/tests/test_old_ma.py
index 87c2133d7..047f91c77 100644
--- a/numpy/ma/tests/test_old_ma.py
+++ b/numpy/ma/tests/test_old_ma.py
@@ -607,8 +607,7 @@ class TestMa(TestCase):
def test_testScalarArithmetic(self):
xm = array(0, mask=1)
#TODO FIXME: Find out what the following raises a warning in r8247
- with np.errstate():
- np.seterr(divide='ignore')
+ with np.errstate(divide='ignore'):
self.assertTrue((1 / array(0)).mask)
self.assertTrue((1 + xm).mask)
self.assertTrue((-xm).mask)
diff --git a/numpy/polynomial/polynomial.py b/numpy/polynomial/polynomial.py
index 60aaff83f..92cc83821 100644
--- a/numpy/polynomial/polynomial.py
+++ b/numpy/polynomial/polynomial.py
@@ -113,7 +113,7 @@ def polyline(off, scl) :
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> P.polyline(1,-1)
array([ 1, -1])
>>> P.polyval(1, P.polyline(1,-1)) # should be 0
@@ -176,7 +176,7 @@ def polyfromroots(roots) :
Examples
--------
- >>> import numpy.polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> P.polyfromroots((-1,0,1)) # x(x - 1)(x + 1) = x^3 - x
array([ 0., -1., 0., 1.])
>>> j = complex(0,1)
@@ -225,7 +225,7 @@ def polyadd(c1, c2):
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c1 = (1,2,3)
>>> c2 = (3,2,1)
>>> sum = P.polyadd(c1,c2); sum
@@ -270,7 +270,7 @@ def polysub(c1, c2):
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c1 = (1,2,3)
>>> c2 = (3,2,1)
>>> P.polysub(c1,c2)
@@ -352,7 +352,7 @@ def polymul(c1, c2):
Examples
--------
- >>> import numpy.polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c1 = (1,2,3)
>>> c2 = (3,2,1)
>>> P.polymul(c1,c2)
@@ -389,7 +389,7 @@ def polydiv(c1, c2):
Examples
--------
- >>> import numpy.polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c1 = (1,2,3)
>>> c2 = (3,2,1)
>>> P.polydiv(c1,c2)
@@ -513,7 +513,7 @@ def polyder(c, m=1, scl=1, axis=0):
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c = (1,2,3,4) # 1 + 2x + 3x**2 + 4x**3
>>> P.polyder(c) # (d/dx)(c) = 2 + 6x + 12x**2
array([ 2., 6., 12.])
@@ -624,7 +624,7 @@ def polyint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> c = (1,2,3)
>>> P.polyint(c) # should return array([0, 1, 1, 1])
array([ 0., 1., 1., 1.])
@@ -1310,7 +1310,7 @@ def polyfit(x, y, deg, rcond=None, full=False, w=None):
Examples
--------
- >>> from numpy import polynomial as P
+ >>> from numpy.polynomial import polynomial as P
>>> x = np.linspace(-1,1,51) # x "data": [-1, -0.96, ..., 0.96, 1]
>>> y = x**3 - x + np.random.randn(len(x)) # x^3 - x + N(0,1) "noise"
>>> c, stats = P.polyfit(x,y,3,full=True)
diff --git a/numpy/polynomial/polytemplate.py b/numpy/polynomial/polytemplate.py
deleted file mode 100644
index e68dd18ef..000000000
--- a/numpy/polynomial/polytemplate.py
+++ /dev/null
@@ -1,927 +0,0 @@
-"""
-Template for the Chebyshev and Polynomial classes.
-
-This module houses a Python string module Template object (see, e.g.,
-http://docs.python.org/library/string.html#template-strings) used by
-the `polynomial` and `chebyshev` modules to implement their respective
-`Polynomial` and `Chebyshev` classes. It provides a mechanism for easily
-creating additional specific polynomial classes (e.g., Legendre, Jacobi,
-etc.) in the future, such that all these classes will have a common API.
-
-"""
-from __future__ import division, absolute_import, print_function
-
-import string
-import sys
-import warnings
-from number import Number
-
-from numpy import ModuleDeprecationWarning
-
-warnings.warn("The polytemplate module will be removed in Numpy 1.10.0.",
- ModuleDeprecationWarning)
-
-polytemplate = string.Template('''
-from __future__ import division, absolute_import, print_function
-import numpy as np
-import warnings
-from . import polyutils as pu
-
-class $name(pu.PolyBase) :
- """A $name series class.
-
- $name instances provide the standard Python numerical methods '+',
- '-', '*', '//', '%', 'divmod', '**', and '()' as well as the listed
- methods.
-
- Parameters
- ----------
- coef : array_like
- $name coefficients, in increasing order. For example,
- ``(1, 2, 3)`` implies ``P_0 + 2P_1 + 3P_2`` where the
- ``P_i`` are a graded polynomial basis.
- domain : (2,) array_like, optional
- Domain to use. The interval ``[domain[0], domain[1]]`` is mapped to
- the interval ``[window[0], window[1]]`` by shifting and scaling.
- The default value is $domain.
- window : (2,) array_like, optional
- Window, see ``domain`` for its use. The default value is $domain.
- .. versionadded:: 1.6.0
-
- Attributes
- ----------
- coef : (N,) ndarray
- $name coefficients, from low to high.
- domain : (2,) ndarray
- Domain that is mapped to ``window``.
- window : (2,) ndarray
- Window that ``domain`` is mapped to.
-
- Class Attributes
- ----------------
- maxpower : int
- Maximum power allowed, i.e., the largest number ``n`` such that
- ``p(x)**n`` is allowed. This is to limit runaway polynomial size.
- domain : (2,) ndarray
- Default domain of the class.
- window : (2,) ndarray
- Default window of the class.
-
- Notes
- -----
- It is important to specify the domain in many cases, for instance in
- fitting data, because many of the important properties of the
- polynomial basis only hold in a specified interval and consequently
- the data must be mapped into that interval in order to benefit.
-
- Examples
- --------
-
- """
- # Limit runaway size. T_n^m has degree n*2^m
- maxpower = 16
- # Default domain
- domain = np.array($domain)
- # Default window
- window = np.array($domain)
- # Don't let participate in array operations. Value doesn't matter.
- __array_priority__ = 1000
- # Not hashable
- __hash__ = None
-
- def has_samecoef(self, other):
- """Check if coefficients match.
-
- Parameters
- ----------
- other : class instance
- The other class must have the ``coef`` attribute.
-
- Returns
- -------
- bool : boolean
- True if the coefficients are the same, False otherwise.
-
- Notes
- -----
- .. versionadded:: 1.6.0
-
- """
- if len(self.coef) != len(other.coef):
- return False
- elif not np.all(self.coef == other.coef):
- return False
- else:
- return True
-
- def has_samedomain(self, other):
- """Check if domains match.
-
- Parameters
- ----------
- other : class instance
- The other class must have the ``domain`` attribute.
-
- Returns
- -------
- bool : boolean
- True if the domains are the same, False otherwise.
-
- Notes
- -----
- .. versionadded:: 1.6.0
-
- """
- return np.all(self.domain == other.domain)
-
- def has_samewindow(self, other):
- """Check if windows match.
-
- Parameters
- ----------
- other : class instance
- The other class must have the ``window`` attribute.
-
- Returns
- -------
- bool : boolean
- True if the windows are the same, False otherwise.
-
- Notes
- -----
- .. versionadded:: 1.6.0
-
- """
- return np.all(self.window == other.window)
-
- def has_sametype(self, other):
- """Check if types match.
-
- Parameters
- ----------
- other : object
- Class instance.
-
- Returns
- -------
- bool : boolean
- True if other is same class as self
-
- Notes
- -----
- .. versionadded:: 1.7.0
-
- """
- return isinstance(other, self.__class__)
-
- def __init__(self, coef, domain=$domain, window=$domain) :
- [coef, dom, win] = pu.as_series([coef, domain, window], trim=False)
- if len(dom) != 2 :
- raise ValueError("Domain has wrong number of elements.")
- if len(win) != 2 :
- raise ValueError("Window has wrong number of elements.")
- self.coef = coef
- self.domain = dom
- self.window = win
-
- def __repr__(self):
- format = "%s(%s, %s, %s)"
- coef = repr(self.coef)[6:-1]
- domain = repr(self.domain)[6:-1]
- window = repr(self.window)[6:-1]
- return format % ('$name', coef, domain, window)
-
- def __str__(self) :
- format = "%s(%s)"
- coef = str(self.coef)
- return format % ('$nick', coef)
-
- # Pickle and copy
-
- def __getstate__(self) :
- ret = self.__dict__.copy()
- ret['coef'] = self.coef.copy()
- ret['domain'] = self.domain.copy()
- ret['window'] = self.window.copy()
- return ret
-
- def __setstate__(self, dict) :
- self.__dict__ = dict
-
- # Call
-
- def __call__(self, arg) :
- off, scl = pu.mapparms(self.domain, self.window)
- arg = off + scl*arg
- return ${nick}val(arg, self.coef)
-
- def __iter__(self) :
- return iter(self.coef)
-
- def __len__(self) :
- return len(self.coef)
-
- # Numeric properties.
-
- def __neg__(self) :
- return self.__class__(-self.coef, self.domain, self.window)
-
- def __pos__(self) :
- return self
-
- def __add__(self, other) :
- """Returns sum"""
- if isinstance(other, pu.PolyBase):
- if not self.has_sametype(other):
- raise TypeError("Polynomial types differ")
- elif not self.has_samedomain(other):
- raise TypeError("Domains differ")
- elif not self.has_samewindow(other):
- raise TypeError("Windows differ")
- else:
- coef = ${nick}add(self.coef, other.coef)
- else :
- try :
- coef = ${nick}add(self.coef, other)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __sub__(self, other) :
- """Returns difference"""
- if isinstance(other, pu.PolyBase):
- if not self.has_sametype(other):
- raise TypeError("Polynomial types differ")
- elif not self.has_samedomain(other):
- raise TypeError("Domains differ")
- elif not self.has_samewindow(other):
- raise TypeError("Windows differ")
- else:
- coef = ${nick}sub(self.coef, other.coef)
- else :
- try :
- coef = ${nick}sub(self.coef, other)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __mul__(self, other) :
- """Returns product"""
- if isinstance(other, pu.PolyBase):
- if not self.has_sametype(other):
- raise TypeError("Polynomial types differ")
- elif not self.has_samedomain(other):
- raise TypeError("Domains differ")
- elif not self.has_samewindow(other):
- raise TypeError("Windows differ")
- else:
- coef = ${nick}mul(self.coef, other.coef)
- else :
- try :
- coef = ${nick}mul(self.coef, other)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __div__(self, other):
- # set to __floordiv__, /, for now.
- return self.__floordiv__(other)
-
- def __truediv__(self, other) :
- # there is no true divide if the rhs is not a Number, although it
- # could return the first n elements of an infinite series.
- # It is hard to see where n would come from, though.
- if not isinstance(other, Number) or isinstance(other, bool):
- form = "unsupported types for true division: '%s', '%s'"
- raise TypeError(form % (type(self), type(other)))
- return self.__floordiv__(other)
-
- def __floordiv__(self, other) :
- """Returns the quotient."""
- if isinstance(other, pu.PolyBase):
- if not self.has_sametype(other):
- raise TypeError("Polynomial types differ")
- elif not self.has_samedomain(other):
- raise TypeError("Domains differ")
- elif not self.has_samewindow(other):
- raise TypeError("Windows differ")
- else:
- quo, rem = ${nick}div(self.coef, other.coef)
- else :
- try :
- quo, rem = ${nick}div(self.coef, other)
- except :
- return NotImplemented
- return self.__class__(quo, self.domain, self.window)
-
- def __mod__(self, other) :
- """Returns the remainder."""
- if isinstance(other, pu.PolyBase):
- if not self.has_sametype(other):
- raise TypeError("Polynomial types differ")
- elif not self.has_samedomain(other):
- raise TypeError("Domains differ")
- elif not self.has_samewindow(other):
- raise TypeError("Windows differ")
- else:
- quo, rem = ${nick}div(self.coef, other.coef)
- else :
- try :
- quo, rem = ${nick}div(self.coef, other)
- except :
- return NotImplemented
- return self.__class__(rem, self.domain, self.window)
-
- def __divmod__(self, other) :
- """Returns quo, remainder"""
- if isinstance(other, self.__class__) :
- if not self.has_samedomain(other):
- raise TypeError("Domains are not equal")
- elif not self.has_samewindow(other):
- raise TypeError("Windows are not equal")
- else:
- quo, rem = ${nick}div(self.coef, other.coef)
- else :
- try :
- quo, rem = ${nick}div(self.coef, other)
- except :
- return NotImplemented
- quo = self.__class__(quo, self.domain, self.window)
- rem = self.__class__(rem, self.domain, self.window)
- return quo, rem
-
- def __pow__(self, other) :
- try :
- coef = ${nick}pow(self.coef, other, maxpower = self.maxpower)
- except :
- raise
- return self.__class__(coef, self.domain, self.window)
-
- def __radd__(self, other) :
- try :
- coef = ${nick}add(other, self.coef)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __rsub__(self, other):
- try :
- coef = ${nick}sub(other, self.coef)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __rmul__(self, other) :
- try :
- coef = ${nick}mul(other, self.coef)
- except :
- return NotImplemented
- return self.__class__(coef, self.domain, self.window)
-
- def __rdiv__(self, other):
- # set to __floordiv__ /.
- return self.__rfloordiv__(other)
-
- def __rtruediv__(self, other) :
- # An instance of PolyBase is not considered a
- # Number.
- return NotImplemented
-
- def __rfloordiv__(self, other) :
- try :
- quo, rem = ${nick}div(other, self.coef)
- except:
- return NotImplemented
- return self.__class__(quo, self.domain, self.window)
-
- def __rmod__(self, other) :
- try :
- quo, rem = ${nick}div(other, self.coef)
- except :
- return NotImplemented
- return self.__class__(rem, self.domain, self.window)
-
- def __rdivmod__(self, other) :
- try :
- quo, rem = ${nick}div(other, self.coef)
- except :
- return NotImplemented
- quo = self.__class__(quo, self.domain, self.window)
- rem = self.__class__(rem, self.domain, self.window)
- return quo, rem
-
- # Enhance me
- # some augmented arithmetic operations could be added here
-
- def __eq__(self, other) :
- res = isinstance(other, self.__class__) \
- and self.has_samecoef(other) \
- and self.has_samedomain(other) \
- and self.has_samewindow(other)
- return res
-
- def __ne__(self, other) :
- return not self.__eq__(other)
-
- #
- # Extra methods.
- #
-
- def copy(self) :
- """Return a copy.
-
- Return a copy of the current $name instance.
-
- Returns
- -------
- new_instance : $name
- Copy of current instance.
-
- """
- return self.__class__(self.coef, self.domain, self.window)
-
- def degree(self) :
- """The degree of the series.
-
- Notes
- -----
- .. versionadded:: 1.5.0
-
- """
- return len(self) - 1
-
- def cutdeg(self, deg) :
- """Truncate series to the given degree.
-
- Reduce the degree of the $name series to `deg` by discarding the
- high order terms. If `deg` is greater than the current degree a
- copy of the current series is returned. This can be useful in least
- squares where the coefficients of the high degree terms may be very
- small.
-
- Parameters
- ----------
- deg : non-negative int
- The series is reduced to degree `deg` by discarding the high
- order terms. The value of `deg` must be a non-negative integer.
-
- Returns
- -------
- new_instance : $name
- New instance of $name with reduced degree.
-
- Notes
- -----
- .. versionadded:: 1.5.0
-
- """
- return self.truncate(deg + 1)
-
- def trim(self, tol=0) :
- """Remove small leading coefficients
-
- Remove leading coefficients until a coefficient is reached whose
- absolute value greater than `tol` or the beginning of the series is
- reached. If all the coefficients would be removed the series is set to
- ``[0]``. A new $name instance is returned with the new coefficients.
- The current instance remains unchanged.
-
- Parameters
- ----------
- tol : non-negative number.
- All trailing coefficients less than `tol` will be removed.
-
- Returns
- -------
- new_instance : $name
- Contains the new set of coefficients.
-
- """
- coef = pu.trimcoef(self.coef, tol)
- return self.__class__(coef, self.domain, self.window)
-
- def truncate(self, size) :
- """Truncate series to length `size`.
-
- Reduce the $name series to length `size` by discarding the high
- degree terms. The value of `size` must be a positive integer. This
- can be useful in least squares where the coefficients of the
- high degree terms may be very small.
-
- Parameters
- ----------
- size : positive int
- The series is reduced to length `size` by discarding the high
- degree terms. The value of `size` must be a positive integer.
-
- Returns
- -------
- new_instance : $name
- New instance of $name with truncated coefficients.
-
- """
- isize = int(size)
- if isize != size or isize < 1 :
- raise ValueError("size must be a positive integer")
- if isize >= len(self.coef) :
- coef = self.coef
- else :
- coef = self.coef[:isize]
- return self.__class__(coef, self.domain, self.window)
-
- def convert(self, domain=None, kind=None, window=None) :
- """Convert to different class and/or domain.
-
- Parameters
- ----------
- domain : array_like, optional
- The domain of the converted series. If the value is None,
- the default domain of `kind` is used.
- kind : class, optional
- The polynomial series type class to which the current instance
- should be converted. If kind is None, then the class of the
- current instance is used.
- window : array_like, optional
- The window of the converted series. If the value is None,
- the default window of `kind` is used.
-
- Returns
- -------
- new_series_instance : `kind`
- The returned class can be of different type than the current
- instance and/or have a different domain.
-
- Notes
- -----
- Conversion between domains and class types can result in
- numerically ill defined series.
-
- Examples
- --------
-
- """
- if kind is None:
- kind = $name
- if domain is None:
- domain = kind.domain
- if window is None:
- window = kind.window
- return self(kind.identity(domain, window=window))
-
- def mapparms(self) :
- """Return the mapping parameters.
-
- The returned values define a linear map ``off + scl*x`` that is
- applied to the input arguments before the series is evaluated. The
- map depends on the ``domain`` and ``window``; if the current
- ``domain`` is equal to the ``window`` the resulting map is the
- identity. If the coefficients of the ``$name`` instance are to be
- used by themselves outside this class, then the linear function
- must be substituted for the ``x`` in the standard representation of
- the base polynomials.
-
- Returns
- -------
- off, scl : floats or complex
- The mapping function is defined by ``off + scl*x``.
-
- Notes
- -----
- If the current domain is the interval ``[l_1, r_1]`` and the window
- is ``[l_2, r_2]``, then the linear mapping function ``L`` is
- defined by the equations::
-
- L(l_1) = l_2
- L(r_1) = r_2
-
- """
- return pu.mapparms(self.domain, self.window)
-
- def integ(self, m=1, k=[], lbnd=None) :
- """Integrate.
-
- Return an instance of $name that is the definite integral of the
- current series. Refer to `${nick}int` for full documentation.
-
- Parameters
- ----------
- m : non-negative int
- The number of integrations to perform.
- k : array_like
- Integration constants. The first constant is applied to the
- first integration, the second to the second, and so on. The
- list of values must less than or equal to `m` in length and any
- missing values are set to zero.
- lbnd : Scalar
- The lower bound of the definite integral.
-
- Returns
- -------
- integral : $name
- The integral of the series using the same domain.
-
- See Also
- --------
- ${nick}int : similar function.
- ${nick}der : similar function for derivative.
-
- """
- off, scl = self.mapparms()
- if lbnd is None :
- lbnd = 0
- else :
- lbnd = off + scl*lbnd
- coef = ${nick}int(self.coef, m, k, lbnd, 1./scl)
- return self.__class__(coef, self.domain, self.window)
-
- def deriv(self, m=1):
- """Differentiate.
-
- Return an instance of $name that is the derivative of the current
- series. Refer to `${nick}der` for full documentation.
-
- Parameters
- ----------
- m : non-negative int
- The number of integrations to perform.
-
- Returns
- -------
- derivative : $name
- The derivative of the series using the same domain.
-
- See Also
- --------
- ${nick}der : similar function.
- ${nick}int : similar function for integration.
-
- """
- off, scl = self.mapparms()
- coef = ${nick}der(self.coef, m, scl)
- return self.__class__(coef, self.domain, self.window)
-
- def roots(self) :
- """Return list of roots.
-
- Return ndarray of roots for this series. See `${nick}roots` for
- full documentation. Note that the accuracy of the roots is likely to
- decrease the further outside the domain they lie.
-
- See Also
- --------
- ${nick}roots : similar function
- ${nick}fromroots : function to go generate series from roots.
-
- """
- roots = ${nick}roots(self.coef)
- return pu.mapdomain(roots, self.window, self.domain)
-
- def linspace(self, n=100, domain=None):
- """Return x,y values at equally spaced points in domain.
-
- Returns x, y values at `n` linearly spaced points across domain.
- Here y is the value of the polynomial at the points x. By default
- the domain is the same as that of the $name instance. This method
- is intended mostly as a plotting aid.
-
- Parameters
- ----------
- n : int, optional
- Number of point pairs to return. The default value is 100.
- domain : {None, array_like}
- If not None, the specified domain is used instead of that of
- the calling instance. It should be of the form ``[beg,end]``.
- The default is None.
-
- Returns
- -------
- x, y : ndarrays
- ``x`` is equal to linspace(self.domain[0], self.domain[1], n)
- ``y`` is the polynomial evaluated at ``x``.
-
- .. versionadded:: 1.5.0
-
- """
- if domain is None:
- domain = self.domain
- x = np.linspace(domain[0], domain[1], n)
- y = self(x)
- return x, y
-
-
-
- @staticmethod
- def fit(x, y, deg, domain=None, rcond=None, full=False, w=None,
- window=$domain):
- """Least squares fit to data.
-
- Return a `$name` instance that is the least squares fit to the data
- `y` sampled at `x`. Unlike `${nick}fit`, the domain of the returned
- instance can be specified and this will often result in a superior
- fit with less chance of ill conditioning. Support for NA was added
- in version 1.7.0. See `${nick}fit` for full documentation of the
- implementation.
-
- Parameters
- ----------
- x : array_like, shape (M,)
- x-coordinates of the M sample points ``(x[i], y[i])``.
- y : array_like, shape (M,) or (M, K)
- y-coordinates of the sample points. Several data sets of sample
- points sharing the same x-coordinates can be fitted at once by
- passing in a 2D-array that contains one dataset per column.
- deg : int
- Degree of the fitting polynomial.
- domain : {None, [beg, end], []}, optional
- Domain to use for the returned $name instance. If ``None``,
- then a minimal domain that covers the points `x` is chosen. If
- ``[]`` the default domain ``$domain`` is used. The default
- value is $domain in numpy 1.4.x and ``None`` in later versions.
- The ``[]`` value was added in numpy 1.5.0.
- rcond : float, optional
- Relative condition number of the fit. Singular values smaller
- than this relative to the largest singular value will be
- ignored. The default value is len(x)*eps, where eps is the
- relative precision of the float type, about 2e-16 in most
- cases.
- full : bool, optional
- Switch determining nature of return value. When it is False
- (the default) just the coefficients are returned, when True
- diagnostic information from the singular value decomposition is
- also returned.
- w : array_like, shape (M,), optional
- Weights. If not None the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products
- ``w[i]*y[i]`` all have the same variance. The default value is
- None.
- .. versionadded:: 1.5.0
- window : {[beg, end]}, optional
- Window to use for the returned $name instance. The default
- value is ``$domain``
- .. versionadded:: 1.6.0
-
- Returns
- -------
- least_squares_fit : instance of $name
- The $name instance is the least squares fit to the data and
- has the domain specified in the call.
-
- [residuals, rank, singular_values, rcond] : only if `full` = True
- Residuals of the least squares fit, the effective rank of the
- scaled Vandermonde matrix and its singular values, and the
- specified value of `rcond`. For more details, see
- `linalg.lstsq`.
-
- See Also
- --------
- ${nick}fit : similar function
-
- """
- if domain is None:
- domain = pu.getdomain(x)
- elif type(domain) is list and len(domain) == 0:
- domain = $domain
-
- if type(window) is list and len(window) == 0:
- window = $domain
-
- xnew = pu.mapdomain(x, domain, window)
- res = ${nick}fit(xnew, y, deg, w=w, rcond=rcond, full=full)
- if full :
- [coef, status] = res
- return $name(coef, domain=domain, window=window), status
- else :
- coef = res
- return $name(coef, domain=domain, window=window)
-
- @staticmethod
- def fromroots(roots, domain=$domain, window=$domain) :
- """Return $name instance with specified roots.
-
- Returns an instance of $name representing the product
- ``(x - r[0])*(x - r[1])*...*(x - r[n-1])``, where ``r`` is the
- list of roots.
-
- Parameters
- ----------
- roots : array_like
- List of roots.
- domain : {array_like, None}, optional
- Domain for the resulting instance of $name. If none the domain
- is the interval from the smallest root to the largest. The
- default is $domain.
- window : array_like, optional
- Window for the resulting instance of $name. The default value
- is $domain.
-
- Returns
- -------
- object : $name instance
- Series with the specified roots.
-
- See Also
- --------
- ${nick}fromroots : equivalent function
-
- """
- [roots] = pu.as_series([roots], trim=False)
- if domain is None :
- domain = pu.getdomain(roots)
- deg = len(roots)
- off, scl = pu.mapparms(domain, window)
- rnew = off + scl*roots
- coef = ${nick}fromroots(rnew) / scl**deg
- return $name(coef, domain=domain, window=window)
-
- @staticmethod
- def identity(domain=$domain, window=$domain) :
- """Identity function.
-
- If ``p`` is the returned $name object, then ``p(x) == x`` for all
- values of x.
-
- Parameters
- ----------
- domain : array_like
- The resulting array must be of the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the domain.
- window : array_like
- The resulting array must be if the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the window.
-
- Returns
- -------
- identity : $name instance
-
- """
- off, scl = pu.mapparms(window, domain)
- coef = ${nick}line(off, scl)
- return $name(coef, domain, window)
-
- @staticmethod
- def basis(deg, domain=$domain, window=$domain):
- """$name polynomial of degree `deg`.
-
- Returns an instance of the $name polynomial of degree `d`.
-
- Parameters
- ----------
- deg : int
- Degree of the $name polynomial. Must be >= 0.
- domain : array_like
- The resulting array must be of the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the domain.
- window : array_like
- The resulting array must be if the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the window.
-
- Returns
- p : $name instance
-
- Notes
- -----
- .. versionadded:: 1.7.0
-
- """
- ideg = int(deg)
- if ideg != deg or ideg < 0:
- raise ValueError("deg must be non-negative integer")
- return $name([0]*ideg + [1], domain, window)
-
- @staticmethod
- def cast(series, domain=$domain, window=$domain):
- """Convert instance to equivalent $name series.
-
- The `series` is expected to be an instance of some polynomial
- series of one of the types supported by by the numpy.polynomial
- module, but could be some other class that supports the convert
- method.
-
- Parameters
- ----------
- series : series
- The instance series to be converted.
- domain : array_like
- The resulting array must be of the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the domain.
- window : array_like
- The resulting array must be if the form ``[beg, end]``, where
- ``beg`` and ``end`` are the endpoints of the window.
-
- Returns
- p : $name instance
- A $name series equal to the `poly` series.
-
- See Also
- --------
- convert -- similar instance method
-
- Notes
- -----
- .. versionadded:: 1.7.0
-
- """
- return series.convert(domain, $name, window)
-
-''')
diff --git a/numpy/random/mtrand/mtrand.pyx b/numpy/random/mtrand/mtrand.pyx
index c2603543d..55138cba7 100644
--- a/numpy/random/mtrand/mtrand.pyx
+++ b/numpy/random/mtrand/mtrand.pyx
@@ -3752,8 +3752,9 @@ cdef class RandomState:
Parameters
----------
- lam : float
- Expectation of interval, should be >= 0.
+ lam : float or sequence of float
+ Expectation of interval, should be >= 0. A sequence of expectation
+ intervals must be broadcastable over the requested size.
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. Default is None, in which case a
@@ -3793,6 +3794,10 @@ cdef class RandomState:
>>> count, bins, ignored = plt.hist(s, 14, normed=True)
>>> plt.show()
+ Draw each 100 values for lambda 100 and 500:
+
+ >>> s = np.random.poisson(lam=(100., 500.), size=(100, 2))
+
"""
cdef ndarray olam
cdef double flam
diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py
index ddf21e2bc..bd184d922 100644
--- a/numpy/testing/utils.py
+++ b/numpy/testing/utils.py
@@ -10,6 +10,9 @@ import re
import operator
import warnings
from functools import partial
+import shutil
+import contextlib
+from tempfile import mkdtemp
from .nosetester import import_nose
from numpy.core import float32, empty, arange, array_repr, ndarray
@@ -219,7 +222,7 @@ def build_err_msg(arrays, err_msg, header='Items are not equal:',
def assert_equal(actual,desired,err_msg='',verbose=True):
"""
- Raise an assertion if two objects are not equal.
+ Raises an AssertionError if two objects are not equal.
Given two objects (scalars, lists, tuples, dictionaries or numpy arrays),
check that all elements of these objects are equal. An exception is raised
@@ -371,7 +374,8 @@ def print_assert_equal(test_string, actual, desired):
def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
"""
- Raise an assertion if two items are not equal up to desired precision.
+ Raises an AssertionError if two items are not equal up to desired
+ precision.
.. note:: It is recommended to use one of `assert_allclose`,
`assert_array_almost_equal_nulp` or `assert_array_max_ulp`
@@ -488,7 +492,8 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True):
"""
- Raise an assertion if two items are not equal up to significant digits.
+ Raises an AssertionError if two items are not equal up to significant
+ digits.
.. note:: It is recommended to use one of `assert_allclose`,
`assert_array_almost_equal_nulp` or `assert_array_max_ulp`
@@ -669,7 +674,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True,
def assert_array_equal(x, y, err_msg='', verbose=True):
"""
- Raise an assertion if two array_like objects are not equal.
+ Raises an AssertionError if two array_like objects are not equal.
Given two array_like objects, check that the shape is equal and all
elements of these objects are equal. An exception is raised at
@@ -735,7 +740,8 @@ def assert_array_equal(x, y, err_msg='', verbose=True):
def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
"""
- Raise an assertion if two objects are not equal up to desired precision.
+ Raises an AssertionError if two objects are not equal up to desired
+ precision.
.. note:: It is recommended to use one of `assert_allclose`,
`assert_array_almost_equal_nulp` or `assert_array_max_ulp`
@@ -838,7 +844,8 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
def assert_array_less(x, y, err_msg='', verbose=True):
"""
- Raise an assertion if two array_like objects are not ordered by less than.
+ Raises an AssertionError if two array_like objects are not ordered by less
+ than.
Given two array_like objects, check that the shape is equal and all
elements of the first object are strictly smaller than those of the
@@ -1240,7 +1247,8 @@ def _assert_valid_refcount(op):
def assert_allclose(actual, desired, rtol=1e-7, atol=0,
err_msg='', verbose=True):
"""
- Raise an assertion if two objects are not equal up to desired tolerance.
+ Raises an AssertionError if two objects are not equal up to desired
+ tolerance.
The test is equivalent to ``allclose(actual, desired, rtol, atol)``.
It compares the difference between `actual` and `desired` to
@@ -1692,3 +1700,16 @@ def _gen_alignment_data(dtype=float32, type='binary', max_size=24):
class IgnoreException(Exception):
"Ignoring this exception due to disabled feature"
+
+
+@contextlib.contextmanager
+def tempdir(*args, **kwargs):
+ """Context manager to provide a temporary test folder.
+
+ All arguments are passed as this to the underlying tempfile.mkdtemp
+ function.
+
+ """
+ tmpdir = mkdtemp(*args, **kwargs)
+ yield tmpdir
+ shutil.rmtree(tmpdir)