Skip to content

Commit

Permalink
Merge pull request #26697 from charris/backport-25963
Browse files Browse the repository at this point in the history
BUG: Fix bug in numpy.pad()
  • Loading branch information
charris committed Jun 15, 2024
2 parents c193dcd + 8fa8191 commit 103f4dd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
18 changes: 15 additions & 3 deletions numpy/lib/_arraypad_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ def _get_stats(padded, axis, width_pair, length_pair, stat_func):
return left_stat, right_stat


def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
def _set_reflect_both(padded, axis, width_pair, method,
original_period, include_edge=False):
"""
Pad `axis` of `arr` with reflection.
Expand All @@ -308,6 +309,8 @@ def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
dimension.
method : str
Controls method of reflection; options are 'even' or 'odd'.
original_period : int
Original length of data on `axis` of `arr`.
include_edge : bool
If true, edge value is included in reflection, otherwise the edge
value forms the symmetric axis to the reflection.
Expand All @@ -320,11 +323,20 @@ def _set_reflect_both(padded, axis, width_pair, method, include_edge=False):
"""
left_pad, right_pad = width_pair
old_length = padded.shape[axis] - right_pad - left_pad

if include_edge:
# Avoid wrapping with only a subset of the original area
# by ensuring period can only be a multiple of the original
# area's length.
old_length = old_length // original_period * original_period
# Edge is included, we need to offset the pad amount by 1
edge_offset = 1
else:
# Avoid wrapping with only a subset of the original area
# by ensuring period can only be a multiple of the original
# area's length.
old_length = ((old_length - 1) // (original_period - 1)
* (original_period - 1) + 1)
edge_offset = 0 # Edge is not included, no need to offset pad amount
old_length -= 1 # but must be omitted from the chunk

Expand Down Expand Up @@ -865,7 +877,7 @@ def pad(array, pad_width, mode='constant', **kwargs):
# the length of the original values in the current dimension.
left_index, right_index = _set_reflect_both(
roi, axis, (left_index, right_index),
method, include_edge
method, array.shape[axis], include_edge
)

elif mode == "wrap":
Expand Down
36 changes: 36 additions & 0 deletions numpy/lib/tests/test_arraypad.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,42 @@ def test_check_03(self):
a = np.pad([1, 2, 3], 4, 'reflect')
b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
assert_array_equal(a, b)

def test_check_04(self):
a = np.pad([1, 2, 3], [1, 10], 'reflect')
b = np.array([2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1])
assert_array_equal(a, b)

def test_check_05(self):
a = np.pad([1, 2, 3, 4], [45, 10], 'reflect')
b = np.array(
[4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
2, 1, 2, 3, 4, 3, 2, 1, 2, 3,
4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
2, 1, 2, 3, 4, 3, 2, 1, 2])
assert_array_equal(a, b)

def test_check_06(self):
a = np.pad([1, 2, 3, 4], [15, 2], 'symmetric')
b = np.array(
[2, 3, 4, 4, 3, 2, 1, 1, 2, 3,
4, 4, 3, 2, 1, 1, 2, 3, 4, 4,
3]
)
assert_array_equal(a, b)

def test_check_07(self):
a = np.pad([1, 2, 3, 4, 5, 6], [45, 3], 'symmetric')
b = np.array(
[4, 5, 6, 6, 5, 4, 3, 2, 1, 1,
2, 3, 4, 5, 6, 6, 5, 4, 3, 2,
1, 1, 2, 3, 4, 5, 6, 6, 5, 4,
3, 2, 1, 1, 2, 3, 4, 5, 6, 6,
5, 4, 3, 2, 1, 1, 2, 3, 4, 5,
6, 6, 5, 4])
assert_array_equal(a, b)


class TestEmptyArray:
Expand Down

0 comments on commit 103f4dd

Please sign in to comment.