summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release/1.8.0-notes.rst130
-rw-r--r--numpy/core/fromnumeric.py4
-rw-r--r--numpy/core/include/numpy/ufuncobject.h5
-rw-r--r--numpy/core/numeric.py2
-rw-r--r--numpy/core/setup_common.py1
-rw-r--r--numpy/core/src/multiarray/common.h46
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c2
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c1
-rw-r--r--numpy/core/src/multiarray/nditer_constr.c38
-rw-r--r--numpy/core/src/multiarray/number.c20
-rw-r--r--numpy/core/src/umath/test_rational.c.src3
-rw-r--r--numpy/core/src/umath/ufunc_object.c15
-rw-r--r--numpy/core/src/umath/umathmodule.c1
-rw-r--r--numpy/core/tests/test_api.py24
-rw-r--r--numpy/core/tests/test_multiarray.py2
-rw-r--r--numpy/core/tests/test_numeric.py19
-rw-r--r--numpy/core/tests/test_regression.py10
-rwxr-xr-xnumpy/f2py/crackfortran.py2
-rw-r--r--numpy/linalg/linalg.py11
-rw-r--r--numpy/linalg/tests/test_linalg.py62
-rwxr-xr-xruntests.py85
21 files changed, 400 insertions, 83 deletions
diff --git a/doc/release/1.8.0-notes.rst b/doc/release/1.8.0-notes.rst
index 05d797089..b1adbf87e 100644
--- a/doc/release/1.8.0-notes.rst
+++ b/doc/release/1.8.0-notes.rst
@@ -385,3 +385,133 @@ deprecated. Previously float indices and function arguments such as axes or
shapes were truncated to integers without warning. For example
`arr.reshape(3., -1)` or `arr[0.]` will trigger a deprecation warning in
NumPy 1.8., and in some future version of NumPy they will raise an error.
+
+
+Authors
+=======
+
+This release contains work by the following people who contributed at least
+one patch to this release. The names are in alphabetical order by first name:
+
+* 87
+* Adam Ginsburg +
+* Adam Griffiths +
+* Alexander Belopolsky +
+* Alex Barth +
+* Alex Ford +
+* Andreas Hilboll +
+* Andreas Kloeckner +
+* Andreas Schwab +
+* Andrew Horton +
+* argriffing +
+* Arink Verma +
+* Bago Amirbekian +
+* Bartosz Telenczuk +
+* bebert218 +
+* Benjamin Root +
+* Bill Spotz +
+* Bradley M. Froehle
+* Carwyn Pelley +
+* Charles Harris
+* Chris
+* Christian Brueffer +
+* Christoph Dann +
+* Christoph Gohlke
+* Dan Hipschman +
+* Daniel +
+* Dan Miller +
+* daveydave400 +
+* David Cournapeau
+* David Warde-Farley
+* Denis Laxalde
+* dmuellner +
+* Edward Catmur +
+* Egor Zindy +
+* endolith
+* Eric Firing
+* Eric Fode
+* Eric Moore +
+* Eric Price +
+* Fazlul Shahriar +
+* Félix Hartmann +
+* Fernando Perez
+* Frank B +
+* Frank Breitling +
+* Frederic
+* Gabriel
+* GaelVaroquaux
+* Guillaume Gay +
+* Han Genuit
+* HaroldMills +
+* hklemm +
+* jamestwebber +
+* Jason Madden +
+* Jay Bourque
+* jeromekelleher +
+* Jesús Gómez +
+* jmozmoz +
+* jnothman +
+* Johannes Schönberger +
+* John Benediktsson +
+* John Salvatier +
+* John Stechschulte +
+* Jonathan Waltman +
+* Joon Ro +
+* Jos de Kloe +
+* Joseph Martinot-Lagarde +
+* Josh Warner (Mac) +
+* Jostein Bø Fløystad +
+* Juan Luis Cano Rodríguez +
+* Julian Taylor +
+* Julien Phalip +
+* K.-Michael Aye +
+* Kumar Appaiah +
+* Lars Buitinck
+* Leon Weber +
+* Luis Pedro Coelho
+* Marcin Juszkiewicz
+* Mark Wiebe
+* Marten van Kerkwijk +
+* Martin Baeuml +
+* Martin Spacek
+* Martin Teichmann +
+* Matt Davis +
+* Matthew Brett
+* Maximilian Albert +
+* m-d-w +
+* Michael Droettboom
+* mwtoews +
+* Nathaniel J. Smith
+* Nicolas Scheffer +
+* Nils Werner +
+* ochoadavid +
+* Ondřej Čertík
+* ovillellas +
+* Paul Ivanov
+* Pauli Virtanen
+* peterjc
+* Ralf Gommers
+* Raul Cota +
+* Richard Hattersley +
+* Robert Costa +
+* Robert Kern
+* Rob Ruana +
+* Ronan Lamy
+* Sandro Tosi
+* Sascha Peilicke +
+* Sebastian Berg
+* Skipper Seabold
+* Stefan van der Walt
+* Steve +
+* Takafumi Arakaki +
+* Thomas Robitaille +
+* Tomas Tomecek +
+* Travis E. Oliphant
+* Valentin Haenel
+* Vladimir Rutsky +
+* Warren Weckesser
+* Yaroslav Halchenko
+* Yury V. Zaytsev +
+
+A total of 119 people contributed to this release.
+People with a "+" by their names contributed a patch for the first time.
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index abfa99e80..152cceb1b 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -615,7 +615,7 @@ def partition(a, kth, axis=-1, kind='introselect', order=None):
a = asanyarray(a).flatten()
axis = 0
else:
- a = asanyarray(a).copy()
+ a = asanyarray(a).copy(order="K")
a.partition(kth, axis=axis, kind=kind, order=order)
return a
@@ -784,7 +784,7 @@ def sort(a, axis=-1, kind='quicksort', order=None):
a = asanyarray(a).flatten()
axis = 0
else:
- a = asanyarray(a).copy()
+ a = asanyarray(a).copy(order="K")
a.sort(axis, kind, order)
return a
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index 423fbc279..a6307df91 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -258,14 +258,11 @@ typedef struct _tagPyUFuncObject {
#define UFUNC_FPE_UNDERFLOW 4
#define UFUNC_FPE_INVALID 8
-/* Error mode that avoids look-up (no checking) */
-#define UFUNC_ERR_DEFAULT 0
-
#define UFUNC_OBJ_ISOBJECT 1
#define UFUNC_OBJ_NEEDS_API 2
/* Default user error mode */
-#define UFUNC_ERR_DEFAULT2 \
+#define UFUNC_ERR_DEFAULT \
(UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) + \
(UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) + \
(UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID)
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index f43f93d64..1ed339401 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -2741,7 +2741,7 @@ class errstate(object):
def _setdef():
- defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT2, None]
+ defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None]
umath.seterrobj(defval)
# set the default values
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index 4633aef84..bad3607fa 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -116,7 +116,6 @@ OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'),
("__builtin_bswap32", '5u'),
("__builtin_bswap64", '5u'),
("__builtin_expect", '5, 0'),
- ("__builtin_ctz", '5'),
("_mm_load_ps", '(float*)0', "xmmintrin.h"), # SSE
("_mm_load_pd", '(double*)0', "emmintrin.h"), # SSE2
]
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index 4b23b9442..5d77170ea 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -119,20 +119,10 @@ npy_is_aligned(const void * p, const npy_uintp alignment)
*/
static NPY_INLINE char *
npy_memchr(char * haystack, char needle,
- npy_intp stride, npy_intp size, npy_intp * subloopsize, int invert)
+ npy_intp stride, npy_intp size, npy_intp * psubloopsize, int invert)
{
char * p = haystack;
- char * const end = haystack + size;
- if (stride == 0) {
- if (!invert) {
- p = (*p != needle) ? end : haystack;
- }
- else {
- p = (*p == needle) ? end : haystack;
- }
- *subloopsize = (p - haystack);
- return haystack;
- }
+ npy_intp subloopsize = 0;
if (!invert) {
/*
@@ -140,38 +130,36 @@ npy_memchr(char * haystack, char needle,
* performance less important here.
* memchr has large setup cost if 0 byte is close to start.
*/
- while (p < end && *p != needle) {
+ while (subloopsize < size && *p != needle) {
+ subloopsize++;
p += stride;
}
}
else {
/* usually find elements to skip path */
-#if (defined HAVE___BUILTIN_CTZ && defined NPY_CPU_HAVE_UNALIGNED_ACCESS)
+#if defined NPY_CPU_HAVE_UNALIGNED_ACCESS
if (needle == 0 && stride == 1) {
- while (p < end - (size % sizeof(unsigned int))) {
+ /* iterate until last multiple of 4 */
+ char * block_end = haystack + size - (size % sizeof(unsigned int));
+ while (p < block_end) {
unsigned int v = *(unsigned int*)p;
- if (v == 0) {
- p += sizeof(unsigned int);
- continue;
+ if (v != 0) {
+ break;
}
- p += __builtin_ctz(v) / 8;
- *subloopsize = (p - haystack) / stride;
- return p;
+ p += sizeof(unsigned int);
}
+ /* handle rest */
+ subloopsize = (p - haystack);
}
#endif
- while (p < end && *p == needle) {
+ while (subloopsize < size && *p == needle) {
+ subloopsize++;
p += stride;
}
}
- /* division is very expensive */
- if (NPY_LIKELY(stride == 1)) {
- *subloopsize = (p - haystack);
- }
- else {
- *subloopsize = (p - haystack) / stride;
- }
+ *psubloopsize = subloopsize;
+
return p;
}
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index a75a1c22e..4f0202ffb 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -1396,7 +1396,7 @@ static int min_scalar_type_num(char *valueptr, int type_num,
break;
}
case NPY_CLONGDOUBLE: {
- npy_cdouble value = *(npy_cdouble *)valueptr;
+ npy_clongdouble value = *(npy_clongdouble *)valueptr;
/*
if (value.imag == 0) {
return min_scalar_type_num((char *)&value.real,
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index ea879c226..a89e27595 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -1548,6 +1548,7 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order)
PyArray_FLAGS(arr),
(PyObject *)arr);
if (ret == NULL) {
+ Py_DECREF(arr);
return NULL;
}
/* steals a reference to arr --- so don't increment here */
diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c
index 053777f6a..a12457a1e 100644
--- a/numpy/core/src/multiarray/nditer_constr.c
+++ b/numpy/core/src/multiarray/nditer_constr.c
@@ -1161,11 +1161,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
/* Check the readonly/writeonly flags, and fill in op_itflags */
if (!npyiter_check_per_op_flags(op_flags[iop], &op_itflags[iop])) {
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
/* Extract the operand which is for masked iteration */
@@ -1174,11 +1170,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
PyErr_SetString(PyExc_ValueError,
"Only one iterator operand may receive an "
"ARRAYMASK flag");
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
maskop = iop;
@@ -1199,11 +1191,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
&op_dtype[iop],
flags,
op_flags[iop], &op_itflags[iop])) {
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
}
@@ -1217,13 +1205,9 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
}
}
if (all_null) {
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
PyErr_SetString(PyExc_ValueError,
"At least one iterator operand must be non-NULL");
- return 0;
+ goto fail_nop;
}
}
@@ -1232,17 +1216,26 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
"An iterator operand was flagged as WRITEMASKED, "
"but no ARRAYMASK operand was given to supply "
"the mask");
- return 0;
+ goto fail_nop;
}
else if (!any_writemasked_ops && maskop >= 0) {
PyErr_SetString(PyExc_ValueError,
"An iterator operand was flagged as the ARRAYMASK, "
"but no WRITEMASKED operands were given to use "
"the mask");
- return 0;
+ goto fail_nop;
}
return 1;
+
+ fail_nop:
+ iop = nop;
+ fail_iop:
+ for (i = 0; i < iop; ++i) {
+ Py_XDECREF(op[i]);
+ Py_XDECREF(op_dtype[i]);
+ }
+ return 0;
}
static const char *
@@ -1565,6 +1558,7 @@ npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, npyiter_opitflags *op_itf
NAD_SHAPE(axisdata) = 1;
NAD_INDEX(axisdata) = 0;
memcpy(NAD_PTRS(axisdata), op_dataptr, NPY_SIZEOF_INTP*nop);
+ memset(NAD_STRIDES(axisdata), 0, NPY_SIZEOF_INTP*nop);
}
/* Now process the operands, filling in the axisdata */
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index 2ad65bbe8..bb281835b 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -771,6 +771,7 @@ array_int(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
@@ -812,6 +813,7 @@ array_float(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_float(pv);
@@ -831,14 +833,19 @@ array_long(PyArrayObject *v)
return NULL;
}
pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v);
+ if (pv == NULL) {
+ return NULL;
+ }
if (Py_TYPE(pv)->tp_as_number == 0) {
PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
"scalar object is not a number");
+ Py_DECREF(pv);
return NULL;
}
if (Py_TYPE(pv)->tp_as_number->nb_long == 0) {
PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
"scalar number to long");
+ Py_DECREF(pv);
return NULL;
}
/*
@@ -849,6 +856,7 @@ array_long(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_long(pv);
@@ -866,14 +874,19 @@ array_oct(PyArrayObject *v)
return NULL;
}
pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v);
+ if (pv == NULL) {
+ return NULL;
+ }
if (Py_TYPE(pv)->tp_as_number == 0) {
PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
"scalar object is not a number");
+ Py_DECREF(pv);
return NULL;
}
if (Py_TYPE(pv)->tp_as_number->nb_oct == 0) {
PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
"scalar number to oct");
+ Py_DECREF(pv);
return NULL;
}
/*
@@ -884,6 +897,7 @@ array_oct(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_oct(pv);
@@ -901,14 +915,19 @@ array_hex(PyArrayObject *v)
return NULL;
}
pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v);
+ if (pv == NULL) {
+ return NULL;
+ }
if (Py_TYPE(pv)->tp_as_number == 0) {
PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
"scalar object is not a number");
+ Py_DECREF(pv);
return NULL;
}
if (Py_TYPE(pv)->tp_as_number->nb_hex == 0) {
PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
"scalar number to hex");
+ Py_DECREF(pv);
return NULL;
}
/*
@@ -919,6 +938,7 @@ array_hex(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_hex(pv);
diff --git a/numpy/core/src/umath/test_rational.c.src b/numpy/core/src/umath/test_rational.c.src
index 1650dd1d3..d8f90f9e5 100644
--- a/numpy/core/src/umath/test_rational.c.src
+++ b/numpy/core/src/umath/test_rational.c.src
@@ -1242,12 +1242,15 @@ PyMODINIT_FUNC inittest_rational(void) {
PyErr_Format(PyExc_AssertionError, \
"ufunc %s takes %d arguments, our loop takes %ld", \
#name, ufunc->nargs, sizeof(_types)/sizeof(int)); \
+ Py_DECREF(ufunc); \
goto fail; \
} \
if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, npy_rational, \
rational_ufunc_##name, _types, 0) < 0) { \
+ Py_DECREF(ufunc); \
goto fail; \
} \
+ Py_DECREF(ufunc); \
}
#define REGISTER_UFUNC_BINARY_RATIONAL(name) \
REGISTER_UFUNC(name, {npy_rational, npy_rational, npy_rational})
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index e419a6611..a47d9a96c 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -432,10 +432,17 @@ _extract_pyvals(PyObject *ref, char *name, int *bufsize,
{
PyObject *retval;
+ /* default errobj case, skips dictionary lookup */
if (ref == NULL) {
- *errmask = UFUNC_ERR_DEFAULT;
- *errobj = Py_BuildValue("NO", PyBytes_FromString(name), Py_None);
- *bufsize = NPY_BUFSIZE;
+ if (errmask) {
+ *errmask = UFUNC_ERR_DEFAULT;
+ }
+ if (errobj) {
+ *errobj = Py_BuildValue("NO", PyBytes_FromString(name), Py_None);
+ }
+ if (bufsize) {
+ *bufsize = NPY_BUFSIZE;
+ }
return 0;
}
@@ -5076,7 +5083,7 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
}
else {
Py_INCREF(PyArray_DESCR(op1_array));
- array_operands[2] = new_array_op(op1_array, iter->dataptr);
+ array_operands[1] = new_array_op(op1_array, iter->dataptr);
array_operands[2] = NULL;
}
diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c
index 0b789de26..8c95cebf5 100644
--- a/numpy/core/src/umath/umathmodule.c
+++ b/numpy/core/src/umath/umathmodule.c
@@ -403,7 +403,6 @@ PyMODINIT_FUNC initumath(void)
ADDCONST(ERR_PRINT);
ADDCONST(ERR_LOG);
ADDCONST(ERR_DEFAULT);
- ADDCONST(ERR_DEFAULT2);
ADDCONST(SHIFT_DIVIDEBYZERO);
ADDCONST(SHIFT_OVERFLOW);
diff --git a/numpy/core/tests/test_api.py b/numpy/core/tests/test_api.py
index d642a2237..a1a3f896c 100644
--- a/numpy/core/tests/test_api.py
+++ b/numpy/core/tests/test_api.py
@@ -122,13 +122,13 @@ def test_array_array():
# Try with lists...
assert_equal(np.array([None] * 10, dtype=np.float64),
- np.empty((10,), dtype=np.float64) + np.nan)
+ np.full((10,), np.nan, dtype=np.float64))
assert_equal(np.array([[None]] * 10, dtype=np.float64),
- np.empty((10, 1), dtype=np.float64) + np.nan)
+ np.full((10, 1), np.nan, dtype=np.float64))
assert_equal(np.array([[None] * 10], dtype=np.float64),
- np.empty((1, 10), dtype=np.float64) + np.nan)
+ np.full((1, 10), np.nan, dtype=np.float64))
assert_equal(np.array([[None] * 10] * 10, dtype=np.float64),
- np.empty((10, 10), dtype=np.float64) + np.nan)
+ np.full((10, 10), np.nan, dtype=np.float64))
assert_equal(np.array([1.0] * 10, dtype=np.float64),
np.ones((10,), dtype=np.float64))
@@ -141,13 +141,13 @@ def test_array_array():
# Try with tuples
assert_equal(np.array((None,) * 10, dtype=np.float64),
- np.empty((10,), dtype=np.float64) + np.nan)
+ np.full((10,), np.nan, dtype=np.float64))
assert_equal(np.array([(None,)] * 10, dtype=np.float64),
- np.empty((10, 1), dtype=np.float64) + np.nan)
+ np.full((10, 1), np.nan, dtype=np.float64))
assert_equal(np.array([(None,) * 10], dtype=np.float64),
- np.empty((1, 10), dtype=np.float64) + np.nan)
+ np.full((1, 10), np.nan, dtype=np.float64))
assert_equal(np.array([(None,) * 10] * 10, dtype=np.float64),
- np.empty((10, 10), dtype=np.float64) + np.nan)
+ np.full((10, 10), np.nan, dtype=np.float64))
assert_equal(np.array((1.0,) * 10, dtype=np.float64),
np.ones((10,), dtype=np.float64))
@@ -332,6 +332,14 @@ def test_copyto():
assert_raises(TypeError, np.copyto, [1, 2, 3], [2, 3, 4])
def test_copyto_permut():
+ # test explicit overflow case
+ pad = 500
+ l = [True] * pad + [True, True, True, True]
+ r = np.zeros(len(l)-pad)
+ d = np.ones(len(l)-pad)
+ mask = np.array(l)[pad:]
+ np.copyto(r, d, where=mask[::-1])
+
# test all permutation of possible masks, 9 should be sufficient for
# current 4 byte unrolled code
power = 9
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 9f333a4a2..9d191da35 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1624,7 +1624,7 @@ class TestBinop(object):
# Check behavior against both bare ndarray objects and a
# ndarray subclasses with and without their own override
- obj = cls((1,))
+ obj = cls((1,), buffer=np.ones(1,))
arr_objs = [np.array([1]),
np.array([2]).view(OtherNdarraySubclass),
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index 5a3de8edd..ac341468c 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -8,6 +8,7 @@ import itertools
import numpy as np
from numpy.core import *
+from numpy.core import umath
from numpy.random import rand, randint, randn
from numpy.testing import *
from numpy.core.multiarray import dot as dot_
@@ -439,6 +440,24 @@ class TestSeterr(TestCase):
np.seterrobj(olderrobj)
del self.called
+ def test_errobj_noerrmask(self):
+ # errmask = 0 has a special code path for the default
+ olderrobj = np.geterrobj()
+ try:
+ # set errobj to something non default
+ np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT,
+ umath.ERR_DEFAULT + 1, None])
+ #call a ufunc
+ np.isnan(np.array([6]))
+ # same with the default, lots of times to get rid of possible
+ # pre-existing stack in the code
+ for i in range(10000):
+ np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, umath.ERR_DEFAULT,
+ None])
+ np.isnan(np.array([6]))
+ finally:
+ np.seterrobj(olderrobj)
+
class TestFloatExceptions(TestCase):
def assert_raises_fpe(self, fpeerr, flop, x, y):
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 02cf1b8df..b98746e1b 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1654,6 +1654,14 @@ class TestRegression(TestCase):
assert_raises(TypeError, oct, a)
assert_raises(TypeError, hex, a)
+ # Test the same for a circular reference.
+ b = np.array(a, dtype=object)
+ a[()] = b
+ assert_raises(TypeError, int, a)
+ # Numpy has no tp_traverse currently, so circular references
+ # cannot be detected. So resolve it:
+ a[()] = 0
+
# This was causing a to become like the above
a = np.array(0, dtype=object)
a[...] += 1
@@ -1661,7 +1669,7 @@ class TestRegression(TestCase):
def test_object_array_self_copy(self):
# An object array being copied into itself DECREF'ed before INCREF'ing
- # causing segmentation faults (gh-3787)
+ # causing segmentation faults (gh-3787)
a = np.array(object(), dtype=object)
np.copyto(a, a)
assert_equal(sys.getrefcount(a[()]), 2)
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index 34b6192e4..d0d8aa8fa 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -2402,7 +2402,7 @@ def expr2name(a, block, args=[]):
na='e_'
for c in a:
c = c.lower()
- if c not in string.lowercase+string.digits: c='_'
+ if c not in string.ascii_lowercase+string.digits: c='_'
na=na+c
if na[-1]=='_': na=na+'e'
else: na=na+'_e'
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index aa3bdea34..1b82c7cc0 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -914,7 +914,7 @@ def eigvalsh(a, UPLO='L'):
A complex- or real-valued matrix whose eigenvalues are to be
computed.
UPLO : {'L', 'U'}, optional
- Same as `lower`, wth 'L' for lower and 'U' for upper triangular.
+ Same as `lower`, with 'L' for lower and 'U' for upper triangular.
Deprecated.
Returns
@@ -950,6 +950,9 @@ def eigvalsh(a, UPLO='L'):
array([ 0.17157288+0.j, 5.82842712+0.j])
"""
+ UPLO = UPLO.upper()
+ if UPLO not in ('L', 'U'):
+ raise ValueError("UPLO argument must be 'L' or 'U'")
extobj = get_linalg_error_extobj(
_raise_linalgerror_eigenvalues_nonconvergence)
@@ -1194,7 +1197,9 @@ def eigh(a, UPLO='L'):
[ 0.00000000+0.38268343j, 0.00000000-0.92387953j]])
"""
- UPLO = asbytes(UPLO)
+ UPLO = UPLO.upper()
+ if UPLO not in ('L', 'U'):
+ raise ValueError("UPLO argument must be 'L' or 'U'")
a, wrap = _makearray(a)
_assertRankAtLeast2(a)
@@ -1203,7 +1208,7 @@ def eigh(a, UPLO='L'):
extobj = get_linalg_error_extobj(
_raise_linalgerror_eigenvalues_nonconvergence)
- if 'L' == UPLO:
+ if UPLO == 'L':
gufunc = _umath_linalg.eigh_lo
else:
gufunc = _umath_linalg.eigh_up
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index d40157904..dd4cbcc4f 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -50,7 +50,7 @@ def get_complex_dtype(dtype):
def get_rtol(dtype):
# Choose a safe rtol
- if dtype in (np.single, csingle):
+ if dtype in (single, csingle):
return 1e-5
else:
return 1e-11
@@ -616,7 +616,7 @@ class TestLstsq(LinalgTestCase, LinalgNonsquareTestCase):
expect_resids.shape = (1,)
assert_equal(residuals.shape, expect_resids.shape)
else:
- expect_resids = type(x)([])
+ expect_resids = np.array([]).view(type(x))
assert_almost_equal(residuals, expect_resids)
assert_(np.issubdtype(residuals.dtype, np.floating))
assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
@@ -707,6 +707,34 @@ class TestEigvalsh(HermitianTestCase, HermitianGeneralizedTestCase):
for dtype in [single, double, csingle, cdouble]:
yield check, dtype
+ def test_invalid(self):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+ assert_raises(ValueError, np.linalg.eigvalsh, x, UPLO="lrong")
+ assert_raises(ValueError, np.linalg.eigvalsh, x, "lower")
+ assert_raises(ValueError, np.linalg.eigvalsh, x, "upper")
+
+ def test_UPLO(self):
+ Klo = np.array([[0, 0],[1, 0]], dtype=np.double)
+ Kup = np.array([[0, 1],[0, 0]], dtype=np.double)
+ tgt = np.array([-1, 1], dtype=np.double)
+ rtol = get_rtol(np.double)
+
+ # Check default is 'L'
+ w = np.linalg.eigvalsh(Klo)
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'L'
+ w = np.linalg.eigvalsh(Klo, UPLO='L')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'l'
+ w = np.linalg.eigvalsh(Klo, UPLO='l')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'U'
+ w = np.linalg.eigvalsh(Kup, UPLO='U')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'u'
+ w = np.linalg.eigvalsh(Kup, UPLO='u')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+
class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
def do(self, a, b):
@@ -728,7 +756,7 @@ class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
assert_allclose(dot_generalized(a, evc2),
np.asarray(ev2)[...,None,:] * np.asarray(evc2),
- rtol=get_rtol(ev.dtype))
+ rtol=get_rtol(ev.dtype), err_msg=repr(a))
def test_types(self):
def check(dtype):
@@ -739,6 +767,34 @@ class TestEigh(HermitianTestCase, HermitianGeneralizedTestCase):
for dtype in [single, double, csingle, cdouble]:
yield check, dtype
+ def test_invalid(self):
+ x = np.array([[1, 0.5], [0.5, 1]], dtype=np.float32)
+ assert_raises(ValueError, np.linalg.eigh, x, UPLO="lrong")
+ assert_raises(ValueError, np.linalg.eigh, x, "lower")
+ assert_raises(ValueError, np.linalg.eigh, x, "upper")
+
+ def test_UPLO(self):
+ Klo = np.array([[0, 0],[1, 0]], dtype=np.double)
+ Kup = np.array([[0, 1],[0, 0]], dtype=np.double)
+ tgt = np.array([-1, 1], dtype=np.double)
+ rtol = get_rtol(np.double)
+
+ # Check default is 'L'
+ w, v = np.linalg.eigh(Klo)
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'L'
+ w, v = np.linalg.eigh(Klo, UPLO='L')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'l'
+ w, v = np.linalg.eigh(Klo, UPLO='l')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'U'
+ w, v = np.linalg.eigh(Kup, UPLO='U')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+ # Check 'u'
+ w, v = np.linalg.eigh(Kup, UPLO='u')
+ assert_allclose(np.sort(w), tgt, rtol=rtol)
+
class _TestNorm(object):
diff --git a/runtests.py b/runtests.py
index c50de3b37..738cd7769 100755
--- a/runtests.py
+++ b/runtests.py
@@ -12,6 +12,16 @@ Examples::
$ python runtests.py --ipython
$ python runtests.py --python somescript.py
+Run a debugger:
+
+ $ gdb --args python runtests.py [...other args...]
+
+Generate C code coverage listing under build/lcov/:
+(requires http://ltp.sourceforge.net/coverage/lcov.php)
+
+ $ python runtests.py --gcov [...other args...]
+ $ python runtests.py --lcov-html
+
"""
#
@@ -64,6 +74,13 @@ def main(argv):
parser.add_argument("--coverage", action="store_true", default=False,
help=("report coverage of project code. HTML output goes "
"under build/coverage"))
+ parser.add_argument("--gcov", action="store_true", default=False,
+ help=("enable C code coverage via gcov (requires GCC). "
+ "gcov output goes to build/**/*.gc*"))
+ parser.add_argument("--lcov-html", action="store_true", default=False,
+ help=("produce HTML for C code coverage information "
+ "from a previous run with --gcov. "
+ "HTML output goes to build/lcov/"))
parser.add_argument("--mode", "-m", default="fast",
help="'fast', 'full', or something that could be "
"passed to nosetests -A [default: fast]")
@@ -87,10 +104,18 @@ def main(argv):
help="Arguments to pass to Nose, Python or shell")
args = parser.parse_args(argv)
+ if args.lcov_html:
+ # generate C code coverage output
+ lcov_generate()
+ sys.exit(0)
+
if args.pythonpath:
for p in reversed(args.pythonpath.split(os.pathsep)):
sys.path.insert(0, p)
+ if args.gcov:
+ gcov_reset_counters()
+
if not args.no_build:
site_dir = build_project(args)
sys.path.insert(0, site_dir)
@@ -194,6 +219,7 @@ def main(argv):
else:
sys.exit(1)
+
def build_project(args):
"""
Build a dev version of the project.
@@ -220,10 +246,21 @@ def build_project(args):
# Always use ccache, if installed
env['PATH'] = os.pathsep.join(EXTRA_PATH + env.get('PATH', '').split(os.pathsep))
- if args.debug:
+ if args.debug or args.gcov:
# assume everyone uses gcc/gfortran
env['OPT'] = '-O0 -ggdb'
env['FOPT'] = '-O0 -ggdb'
+ if args.gcov:
+ import distutils.sysconfig
+ cvars = distutils.sysconfig.get_config_vars()
+ env['OPT'] = '-O0 -ggdb'
+ env['FOPT'] = '-O0 -ggdb'
+ env['CC'] = cvars['CC'] + ' --coverage'
+ env['CXX'] = cvars['CXX'] + ' --coverage'
+ env['F77'] = 'gfortran --coverage '
+ env['F90'] = 'gfortran --coverage '
+ env['LDSHARED'] = cvars['LDSHARED'] + ' --coverage'
+ env['LDFLAGS'] = " ".join(cvars['LDSHARED'].split()[1:]) + ' --coverage'
cmd += ["build"]
cmd += ['install', '--prefix=' + dst_dir]
@@ -270,6 +307,52 @@ def build_project(args):
return site_dir
+
+#
+# GCOV support
+#
+def gcov_reset_counters():
+ print("Removing previous GCOV .gcda files...")
+ build_dir = os.path.join(ROOT_DIR, 'build')
+ for dirpath, dirnames, filenames in os.walk(build_dir):
+ for fn in filenames:
+ if fn.endswith('.gcda') or fn.endswith('.da'):
+ pth = os.path.join(dirpath, fn)
+ os.unlink(pth)
+
+#
+# LCOV support
+#
+
+LCOV_OUTPUT_FILE = os.path.join(ROOT_DIR, 'build', 'lcov.out')
+LCOV_HTML_DIR = os.path.join(ROOT_DIR, 'build', 'lcov')
+
+def lcov_generate():
+ try: os.unlink(LCOV_OUTPUT_FILE)
+ except OSError: pass
+ try: shutil.rmtree(LCOV_HTML_DIR)
+ except OSError: pass
+
+ print("Capturing lcov info...")
+ subprocess.call(['lcov', '-q', '-c',
+ '-d', os.path.join(ROOT_DIR, 'build'),
+ '-b', ROOT_DIR,
+ '--output-file', LCOV_OUTPUT_FILE])
+
+ print("Generating lcov HTML output...")
+ ret = subprocess.call(['genhtml', '-q', LCOV_OUTPUT_FILE,
+ '--output-directory', LCOV_HTML_DIR,
+ '--legend', '--highlight'])
+ if ret != 0:
+ print("genhtml failed!")
+ else:
+ print("HTML output generated under build/lcov/")
+
+
+#
+# Python 3 support
+#
+
if sys.version_info[0] >= 3:
import builtins
exec_ = getattr(builtins, "exec")