summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/linalg/tests/test_linalg.py32
-rw-r--r--numpy/linalg/umath_linalg.c.src26
2 files changed, 52 insertions, 6 deletions
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index aefb61b14..d40157904 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -105,6 +105,9 @@ SQUARE_CASES = [
LinalgCase("8x8",
np.random.rand(8, 8),
np.random.rand(8)),
+ LinalgCase("1x1",
+ np.random.rand(1, 1),
+ np.random.rand(1)),
LinalgCase("nonarray",
[[1, 2], [3, 4]],
[2, 1]),
@@ -150,6 +153,12 @@ NONSQUARE_CASES = [
LinalgCase("8x11",
np.random.rand(8, 11),
np.random.rand(11)),
+ LinalgCase("1x5",
+ np.random.rand(1, 5),
+ np.random.rand(5)),
+ LinalgCase("5x1",
+ np.random.rand(5, 1),
+ np.random.rand(1)),
]
HERMITIAN_CASES = [
@@ -177,7 +186,10 @@ HERMITIAN_CASES = [
None),
LinalgCase("hmatrix_a_and_b",
matrix([[1., 2.], [2., 1.]]),
- None)
+ None),
+ LinalgCase("hmatrix_1x1",
+ np.random.rand(1, 1),
+ None),
]
@@ -247,6 +259,24 @@ def _stride_comb_iter(x):
assert np.all(xi == x)
yield xi, "stride_" + "_".join(["%+d" % j for j in repeats])
+ # generate also zero strides if possible
+ if x.ndim >= 1 and x.shape[-1] == 1:
+ s = list(x.strides)
+ s[-1] = 0
+ xi = np.lib.stride_tricks.as_strided(x, strides=s)
+ yield xi, "stride_xxx_0"
+ if x.ndim >= 2 and x.shape[-2] == 1:
+ s = list(x.strides)
+ s[-2] = 0
+ xi = np.lib.stride_tricks.as_strided(x, strides=s)
+ yield xi, "stride_xxx_0_x"
+ if x.ndim >= 2 and x.shape[:-2] == (1, 1):
+ s = list(x.strides)
+ s[-1] = 0
+ s[-2] = 0
+ xi = np.lib.stride_tricks.as_strided(x, strides=s)
+ yield xi, "stride_xxx_0_0"
+
for src in (SQUARE_CASES,
NONSQUARE_CASES,
HERMITIAN_CASES,
diff --git a/numpy/linalg/umath_linalg.c.src b/numpy/linalg/umath_linalg.c.src
index 3c2b316e2..b38038fc2 100644
--- a/numpy/linalg/umath_linalg.c.src
+++ b/numpy/linalg/umath_linalg.c.src
@@ -812,24 +812,32 @@ linearize_@TYPE@_matrix(void *dst_in,
@typ@ *dst = (@typ@ *) dst_in;
if (dst) {
- int i;
+ int i, j;
@typ@* rv = dst;
fortran_int columns = (fortran_int)data->columns;
fortran_int column_strides =
(fortran_int)(data->column_strides/sizeof(@typ@));
fortran_int one = 1;
for (i=0; i< data->rows; i++) {
- if (column_strides >= 0) {
+ if (column_strides > 0) {
FNAME(@copy@)(&columns,
(void*)src, &column_strides,
(void*)dst, &one);
}
- else {
+ else if (column_strides < 0) {
FNAME(@copy@)(&columns,
(void*)((@typ@*)src + (columns-1)*column_strides),
&column_strides,
(void*)dst, &one);
}
+ else {
+ /* Zero stride has undefined behavior in some BLAS
+ implementations (e.g. OSX Accelerate), so do it
+ manually */
+ for (j = 0; j < columns; ++j) {
+ memcpy((@typ@*)dst + j, (@typ@*)src, sizeof(@typ@));
+ }
+ }
src += data->row_strides/sizeof(@typ@);
dst += data->columns;
}
@@ -855,17 +863,25 @@ delinearize_@TYPE@_matrix(void *dst_in,
(fortran_int)(data->column_strides/sizeof(@typ@));
fortran_int one = 1;
for (i=0; i < data->rows; i++) {
- if (column_strides >= 0) {
+ if (column_strides > 0) {
FNAME(@copy@)(&columns,
(void*)src, &one,
(void*)dst, &column_strides);
}
- else {
+ else if (column_strides < 0) {
FNAME(@copy@)(&columns,
(void*)src, &one,
(void*)((@typ@*)dst + (columns-1)*column_strides),
&column_strides);
}
+ else {
+ /* Zero stride has undefined behavior in some BLAS
+ implementations (e.g. OSX Accelerate), so do it
+ manually */
+ if (columns > 0) {
+ memcpy((@typ@*)dst, (@typ@*)src + (columns-1), sizeof(@typ@));
+ }
+ }
src += data->columns;
dst += data->row_strides/sizeof(@typ@);
}