summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/function_base.py5
-rw-r--r--numpy/core/src/multiarray/mapping.c28
-rw-r--r--numpy/doc/broadcasting.py9
-rw-r--r--numpy/linalg/linalg.py15
-rw-r--r--numpy/linalg/tests/test_linalg.py30
5 files changed, 58 insertions, 29 deletions
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py
index fb72bada5..799b1418d 100644
--- a/numpy/core/function_base.py
+++ b/numpy/core/function_base.py
@@ -71,7 +71,10 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):
--------
arange : Similar to `linspace`, but uses a step size (instead of the
number of samples).
- logspace : Samples uniformly distributed in log space.
+ geomspace : Similar to `linspace`, but with numbers spaced evenly on a log
+ scale (a geometric progression).
+ logspace : Similar to `geomspace`, but with the end points specified as
+ logarithms.
Examples
--------
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/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 ac3183e16..ccc437663 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
@@ -2127,7 +2122,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:
@@ -2158,7 +2152,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 30db5f2fe..ce4a37b09 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),))
+
@pytest.mark.parametrize('dt', [np.dtype(c) for c in '?bBhHiIqQefdgFDGO'])
class TestMatrixPower(object):