Skip to content

BF: stride_tricks produces unbroadcastable array #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions nibabel/fileslice.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,15 @@ def strided_scalar(shape, scalar=0.):
strided_arr : array
Array of shape `shape` for which all values == `scalar`, built by
setting all strides of `strided_arr` to 0, so the scalar is broadcast
out to the full array `shape`.
out to the full array `shape`. `strided_arr` is flagged as not
`writeable`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still feel that we need a comment here - otherwise it's not obvious why this is true.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of comment are you thinking? Noting the numpy bug (with some level of detail, or reference to this PR) or the reasoning that setting one element of the array would set all (and thus is probably not the intended behavior)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just something like We set the array read-only to avoid a numpy error when broadcasting - see https://github.com/numpy/numpy/issues/6491.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.


The array is set read-only to avoid a numpy error when broadcasting -
see https://github.com/numpy/numpy/issues/6491
"""
shape = tuple(shape)
scalar = np.array(scalar)
strides = [0] * len(shape)
return np.lib.stride_tricks.as_strided(scalar, shape, strides)
strided_scalar = np.lib.stride_tricks.as_strided(scalar, shape, strides)
strided_scalar.flags.writeable = False
return strided_scalar
10 changes: 8 additions & 2 deletions nibabel/tests/test_fileslice.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,14 @@ def test_strided_scalar():
assert_equal(observed.shape, shape)
assert_equal(observed.dtype, expected.dtype)
assert_array_equal(observed.strides, 0)
observed[..., 0] = 99
assert_array_equal(observed, expected * 0 + 99)
# Strided scalars are set as not writeable
# This addresses a numpy 1.10 breakage of broadcasting a strided
# array without resizing (see GitHub PR #358)
assert_false(observed.flags.writeable)
def setval(x):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment explaining reason for test?

x[..., 0] = 99
# RuntimeError for numpy < 1.10
assert_raises((RuntimeError, ValueError), setval, observed)
# Default scalar value is 0
assert_array_equal(strided_scalar((2, 3, 4)), np.zeros((2, 3, 4)))

Expand Down