summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src2
-rw-r--r--numpy/core/src/multiarray/mapping.c28
-rw-r--r--numpy/core/tests/test_regression.py7
-rw-r--r--numpy/doc/broadcasting.py9
-rw-r--r--numpy/linalg/linalg.py15
-rw-r--r--numpy/linalg/tests/test_linalg.py30
6 files changed, 62 insertions, 29 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index b4158ec8e..d622effe6 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -733,7 +733,7 @@ VOID_getitem(void *input, void *vap)
return (PyObject *)ret;
}
- return PyBytes_FromStringAndSize(PyArray_DATA(ap), descr->elsize);
+ return PyBytes_FromStringAndSize(ip, descr->elsize);
}
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index f338226c2..2fdb3ebf6 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -2915,20 +2915,20 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
Py_INCREF(extra_op_dtype);
mit->extra_op_dtype = extra_op_dtype;
- /* Create an iterator, just to broadcast the arrays?! */
- tmp_iter = NpyIter_MultiNew(mit->numiter, index_arrays,
- NPY_ITER_ZEROSIZE_OK |
- NPY_ITER_REFS_OK |
- NPY_ITER_MULTI_INDEX |
- NPY_ITER_DONT_NEGATE_STRIDES,
- NPY_KEEPORDER,
- NPY_UNSAFE_CASTING,
- tmp_op_flags, NULL);
- if (tmp_iter == NULL) {
- goto fail;
- }
-
if (PyArray_SIZE(subspace) == 1) {
+ /* Create an iterator, just to broadcast the arrays?! */
+ tmp_iter = NpyIter_MultiNew(mit->numiter, index_arrays,
+ NPY_ITER_ZEROSIZE_OK |
+ NPY_ITER_REFS_OK |
+ NPY_ITER_MULTI_INDEX |
+ NPY_ITER_DONT_NEGATE_STRIDES,
+ NPY_KEEPORDER,
+ NPY_UNSAFE_CASTING,
+ tmp_op_flags, NULL);
+ if (tmp_iter == NULL) {
+ goto fail;
+ }
+
/*
* nditer allows itemsize with npy_intp type, so it works
* here, but it would *not* work directly, since elsize
@@ -2941,6 +2941,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
"internal error: failed to find output array strides");
goto fail;
}
+ NpyIter_Deallocate(tmp_iter);
}
else {
/* Just use C-order strides (TODO: allow also F-order) */
@@ -2950,7 +2951,6 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
stride *= mit->dimensions[i];
}
}
- NpyIter_Deallocate(tmp_iter);
/* shape is set, and strides is set up to mit->nd, set rest */
PyArray_CreateSortedStridePerm(PyArray_NDIM(subspace),
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 5f4410d54..36478ddb7 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -2368,6 +2368,13 @@ class TestRegression(object):
del va
assert_equal(x, b'\x00\x00\x00\x00')
+ def test_void_getitem(self):
+ # Test fix for gh-11668.
+ assert_(np.array([b'a'], 'V1').astype('O') == b'a')
+ assert_(np.array([b'ab'], 'V2').astype('O') == b'ab')
+ assert_(np.array([b'abc'], 'V3').astype('O') == b'abc')
+ assert_(np.array([b'abcd'], 'V4').astype('O') == b'abcd')
+
def test_structarray_title(self):
# The following used to segfault on pypy, due to NPY_TITLE_KEY
# not working properly and resulting to double-decref of the
diff --git a/numpy/doc/broadcasting.py b/numpy/doc/broadcasting.py
index 1dc4f60bf..6c3a4bc75 100644
--- a/numpy/doc/broadcasting.py
+++ b/numpy/doc/broadcasting.py
@@ -53,9 +53,10 @@ dimensions are compatible when
2) one of them is 1
If these conditions are not met, a
-``ValueError: frames are not aligned`` exception is thrown, indicating that
-the arrays have incompatible shapes. The size of the resulting array
-is the maximum size along each dimension of the input arrays.
+``ValueError: operands could not be broadcast together`` exception is
+thrown, indicating that the arrays have incompatible shapes. The size of
+the resulting array is the maximum size along each dimension of the input
+arrays.
Arrays do not need to have the same *number* of dimensions. For example,
if you have a ``256x256x3`` array of RGB values, and you want to scale
@@ -124,7 +125,7 @@ An example of broadcasting in practice::
(5,)
>>> x + y
- <type 'exceptions.ValueError'>: shape mismatch: objects cannot be broadcast to a single shape
+ ValueError: operands could not be broadcast together with shapes (4,) (5,)
>>> xx.shape
(4, 1)
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index c3b76ada7..5f04620ac 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -133,11 +133,6 @@ def _linalgRealType(t):
"""Cast the type t to either double or cdouble."""
return double
-_complex_types_map = {single : csingle,
- double : cdouble,
- csingle : csingle,
- cdouble : cdouble}
-
def _commonType(*arrays):
# in lite version, use higher precision (always double or cdouble)
result_type = single
@@ -2115,7 +2110,6 @@ def lstsq(a, b, rcond="warn"):
if is_1d:
b = b[:, newaxis]
_assertRank2(a, b)
- _assertNoEmpty2d(a, b) # TODO: relax this constraint
m, n = a.shape[-2:]
m2, n_rhs = b.shape[-2:]
if m != m2:
@@ -2146,7 +2140,16 @@ def lstsq(a, b, rcond="warn"):
signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid'
extobj = get_linalg_error_extobj(_raise_linalgerror_lstsq)
+ if n_rhs == 0:
+ # lapack can't handle n_rhs = 0 - so allocate the array one larger in that axis
+ b = zeros(b.shape[:-2] + (m, n_rhs + 1), dtype=b.dtype)
x, resids, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj)
+ if m == 0:
+ x[...] = 0
+ if n_rhs == 0:
+ # remove the item we added
+ x = x[..., :n_rhs]
+ resids = resids[..., :n_rhs]
# remove the axis we added
if is_1d:
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index 0df673884..36b677ac3 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -875,14 +875,12 @@ class TestDet(DetCases):
class LstsqCases(LinalgSquareTestCase, LinalgNonsquareTestCase):
def do(self, a, b, tags):
- if 'size-0' in tags:
- assert_raises(LinAlgError, linalg.lstsq, a, b)
- return
-
arr = np.asarray(a)
m, n = arr.shape
u, s, vt = linalg.svd(a, 0)
x, residuals, rank, sv = linalg.lstsq(a, b, rcond=-1)
+ if m == 0:
+ assert_((x == 0).all())
if m <= n:
assert_almost_equal(b, dot(a, x))
assert_equal(rank, m)
@@ -923,6 +921,30 @@ class TestLstsq(LstsqCases):
# Warning should be raised exactly once (first command)
assert_(len(w) == 1)
+ @pytest.mark.parametrize(["m", "n", "n_rhs"], [
+ (4, 2, 2),
+ (0, 4, 1),
+ (0, 4, 2),
+ (4, 0, 1),
+ (4, 0, 2),
+ (4, 2, 0),
+ (0, 0, 0)
+ ])
+ def test_empty_a_b(self, m, n, n_rhs):
+ a = np.arange(m * n).reshape(m, n)
+ b = np.ones((m, n_rhs))
+ x, residuals, rank, s = linalg.lstsq(a, b, rcond=None)
+ if m == 0:
+ assert_((x == 0).all())
+ assert_equal(x.shape, (n, n_rhs))
+ assert_equal(residuals.shape, ((n_rhs,) if m > n else (0,)))
+ if m > n and n_rhs > 0:
+ # residuals are exactly the squared norms of b's columns
+ r = b - np.dot(a, x)
+ assert_almost_equal(residuals, (r * r).sum(axis=-2))
+ assert_equal(rank, min(m, n))
+ assert_equal(s.shape, (min(m, n),))
+
class TestMatrixPower(object):
R90 = array([[0, 1], [-1, 0]])