codekingpro/portable-devtools
115k
1"""Tests for the array padding functions.
2
3"""
4import pytest
5
6import numpy as np
7from numpy.lib._arraypad_impl import _as_pairs
8from numpy.testing import assert_allclose, assert_array_equal, assert_equal
9
10_numeric_dtypes = (
11 np._core.sctypes["uint"]
12 + np._core.sctypes["int"]
13 + np._core.sctypes["float"]
14 + np._core.sctypes["complex"]
15)
16_all_modes = {
17 'constant': {'constant_values': 0},
18 'edge': {},
19 'linear_ramp': {'end_values': 0},
20 'maximum': {'stat_length': None},
21 'mean': {'stat_length': None},
22 'median': {'stat_length': None},
23 'minimum': {'stat_length': None},
24 'reflect': {'reflect_type': 'even'},
25 'symmetric': {'reflect_type': 'even'},
26 'wrap': {},
27 'empty': {}
28}
29
30
31class TestAsPairs:
32 def test_single_value(self):
33 """Test casting for a single value."""
34 expected = np.array([[3, 3]] * 10)
35 for x in (3, [3], [[3]]):
36 result = _as_pairs(x, 10)
37 assert_equal(result, expected)
38 # Test with dtype=object
39 obj = object()
40 assert_equal(
41 _as_pairs(obj, 10),
42 np.array([[obj, obj]] * 10)
43 )
44
45 def test_two_values(self):
46 """Test proper casting for two different values."""
47 # Broadcasting in the first dimension with numbers
48 expected = np.array([[3, 4]] * 10)
49 for x in ([3, 4], [[3, 4]]):
50 result = _as_pairs(x, 10)
51 assert_equal(result, expected)
52 # and with dtype=object
53 obj = object()
54 assert_equal(
55 _as_pairs(["a", obj], 10),
56 np.array([["a", obj]] * 10)
57 )
58
59 # Broadcasting in the second / last dimension with numbers
60 assert_equal(
61 _as_pairs([[3], [4]], 2),
62 np.array([[3, 3], [4, 4]])
63 )
64 # and with dtype=object
65 assert_equal(
66 _as_pairs([["a"], [obj]], 2),
67 np.array([["a", "a"], [obj, obj]])
68 )
69
70 def test_with_none(self):
71 expected = ((None, None), (None, None), (None, None))
72 assert_equal(
73 _as_pairs(None, 3, as_index=False),
74 expected
75 )
76 assert_equal(
77 _as_pairs(None, 3, as_index=True),
78 expected
79 )
80
81 def test_pass_through(self):
82 """Test if `x` already matching desired output are passed through."""
83 expected = np.arange(12).reshape((6, 2))
84 assert_equal(
85 _as_pairs(expected, 6),
86 expected
87 )
88
89 def test_as_index(self):
90 """Test results if `as_index=True`."""
91 assert_equal(
92 _as_pairs([2.6, 3.3], 10, as_index=True),
93 np.array([[3, 3]] * 10, dtype=np.intp)
94 )
95 assert_equal(
96 _as_pairs([2.6, 4.49], 10, as_index=True),
97 np.array([[3, 4]] * 10, dtype=np.intp)
98 )
99 for x in (-3, [-3], [[-3]], [-3, 4], [3, -4], [[-3, 4]], [[4, -3]],
100 [[1, 2]] * 9 + [[1, -2]]):
101 with pytest.raises(ValueError, match="negative values"):
102 _as_pairs(x, 10, as_index=True)
103
104 def test_exceptions(self):
105 """Ensure faulty usage is discovered."""
106 with pytest.raises(ValueError, match="more dimensions than allowed"):
107 _as_pairs([[[3]]], 10)
108 with pytest.raises(ValueError, match="could not be broadcast"):
109 _as_pairs([[1, 2], [3, 4]], 3)
110 with pytest.raises(ValueError, match="could not be broadcast"):
111 _as_pairs(np.ones((2, 3)), 3)
112
113
114class TestConditionalShortcuts:
115 @pytest.mark.parametrize("mode", _all_modes.keys())
116 def test_zero_padding_shortcuts(self, mode):
117 test = np.arange(120).reshape(4, 5, 6)
118 pad_amt = [(0, 0) for _ in test.shape]
119 assert_array_equal(test, np.pad(test, pad_amt, mode=mode))
120
121 @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',])
122 def test_shallow_statistic_range(self, mode):
123 test = np.arange(120).reshape(4, 5, 6)
124 pad_amt = [(1, 1) for _ in test.shape]
125 assert_array_equal(np.pad(test, pad_amt, mode='edge'),
126 np.pad(test, pad_amt, mode=mode, stat_length=1))
127
128 @pytest.mark.parametrize("mode", ['maximum', 'mean', 'median', 'minimum',])
129 def test_clip_statistic_range(self, mode):
130 test = np.arange(30).reshape(5, 6)
131 pad_amt = [(3, 3) for _ in test.shape]
132 assert_array_equal(np.pad(test, pad_amt, mode=mode),
133 np.pad(test, pad_amt, mode=mode, stat_length=30))
134
135
136class TestStatistic:
137 def test_check_mean_stat_length(self):
138 a = np.arange(100).astype('f')
139 a = np.pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), ))
140 b = np.array(
141 [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
142 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
143 0.5, 0.5, 0.5, 0.5, 0.5,
144
145 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
146 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
147 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
148 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
149 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
150 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
151 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
152 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
153 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
154 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
155
156 98., 98., 98., 98., 98., 98., 98., 98., 98., 98.,
157 98., 98., 98., 98., 98., 98., 98., 98., 98., 98.
158 ])
159 assert_array_equal(a, b)
160
161 def test_check_maximum_1(self):
162 a = np.arange(100)
163 a = np.pad(a, (25, 20), 'maximum')
164 b = np.array(
165 [99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
166 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
167 99, 99, 99, 99, 99,
168
169 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
170 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
171 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
172 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
173 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
174 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
175 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
176 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
177 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
178 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
179
180 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
181 99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
182 )
183 assert_array_equal(a, b)
184
185 def test_check_maximum_2(self):
186 a = np.arange(100) + 1
187 a = np.pad(a, (25, 20), 'maximum')
188 b = np.array(
189 [100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
190 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
191 100, 100, 100, 100, 100,
192
193 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
194 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
195 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
196 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
197 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
198 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
199 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
200 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
201 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
202 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
203
204 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
205 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
206 )
207 assert_array_equal(a, b)
208
209 def test_check_maximum_stat_length(self):
210 a = np.arange(100) + 1
211 a = np.pad(a, (25, 20), 'maximum', stat_length=10)
212 b = np.array(
213 [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
214 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
215 10, 10, 10, 10, 10,
216
217 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
218 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
219 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
220 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
221 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
222 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
223 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
224 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
225 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
226 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
227
228 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
229 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
230 )
231 assert_array_equal(a, b)
232
233 def test_check_minimum_1(self):
234 a = np.arange(100)
235 a = np.pad(a, (25, 20), 'minimum')
236 b = np.array(
237 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0,
240
241 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
242 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
243 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
244 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
245 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
246 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
247 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
248 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
249 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
250 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
251
252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
254 )
255 assert_array_equal(a, b)
256
257 def test_check_minimum_2(self):
258 a = np.arange(100) + 2
259 a = np.pad(a, (25, 20), 'minimum')
260 b = np.array(
261 [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
262 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
263 2, 2, 2, 2, 2,
264
265 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
266 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
267 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
268 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
269 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
270 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
271 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
272 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
273 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
274 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
275
276 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
277 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
278 )
279 assert_array_equal(a, b)
280
281 def test_check_minimum_stat_length(self):
282 a = np.arange(100) + 1
283 a = np.pad(a, (25, 20), 'minimum', stat_length=10)
284 b = np.array(
285 [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
286 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
287 1, 1, 1, 1, 1,
288
289 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
290 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
291 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
292 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
293 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
294 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
295 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
296 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
297 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
298 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
299
300 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
301 91, 91, 91, 91, 91, 91, 91, 91, 91, 91]
302 )
303 assert_array_equal(a, b)
304
305 def test_check_median(self):
306 a = np.arange(100).astype('f')
307 a = np.pad(a, (25, 20), 'median')
308 b = np.array(
309 [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
310 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
311 49.5, 49.5, 49.5, 49.5, 49.5,
312
313 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
314 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
315 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
316 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
317 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
318 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
319 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
320 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
321 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
322 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
323
324 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
325 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
326 )
327 assert_array_equal(a, b)
328
329 def test_check_median_01(self):
330 a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
331 a = np.pad(a, 1, 'median')
332 b = np.array(
333 [[4, 4, 5, 4, 4],
334
335 [3, 3, 1, 4, 3],
336 [5, 4, 5, 9, 5],
337 [8, 9, 8, 2, 8],
338
339 [4, 4, 5, 4, 4]]
340 )
341 assert_array_equal(a, b)
342
343 def test_check_median_02(self):
344 a = np.array([[3, 1, 4], [4, 5, 9], [9, 8, 2]])
345 a = np.pad(a.T, 1, 'median').T
346 b = np.array(
347 [[5, 4, 5, 4, 5],
348
349 [3, 3, 1, 4, 3],
350 [5, 4, 5, 9, 5],
351 [8, 9, 8, 2, 8],
352
353 [5, 4, 5, 4, 5]]
354 )
355 assert_array_equal(a, b)
356
357 def test_check_median_stat_length(self):
358 a = np.arange(100).astype('f')
359 a[1] = 2.
360 a[97] = 96.
361 a = np.pad(a, (25, 20), 'median', stat_length=(3, 5))
362 b = np.array(
363 [ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.,
364 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.,
365 2., 2., 2., 2., 2.,
366
367 0., 2., 2., 3., 4., 5., 6., 7., 8., 9.,
368 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
369 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
370 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
371 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
372 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
373 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
374 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
375 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
376 90., 91., 92., 93., 94., 95., 96., 96., 98., 99.,
377
378 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.,
379 96., 96., 96., 96., 96., 96., 96., 96., 96., 96.]
380 )
381 assert_array_equal(a, b)
382
383 def test_check_mean_shape_one(self):
384 a = [[4, 5, 6]]
385 a = np.pad(a, (5, 7), 'mean', stat_length=2)
386 b = np.array(
387 [[4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
388 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
389 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
390 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
391 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
392
393 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
394
395 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
396 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
397 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
398 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
399 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
400 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6],
401 [4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6]]
402 )
403 assert_array_equal(a, b)
404
405 def test_check_mean_2(self):
406 a = np.arange(100).astype('f')
407 a = np.pad(a, (25, 20), 'mean')
408 b = np.array(
409 [49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
410 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
411 49.5, 49.5, 49.5, 49.5, 49.5,
412
413 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.,
414 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.,
415 20., 21., 22., 23., 24., 25., 26., 27., 28., 29.,
416 30., 31., 32., 33., 34., 35., 36., 37., 38., 39.,
417 40., 41., 42., 43., 44., 45., 46., 47., 48., 49.,
418 50., 51., 52., 53., 54., 55., 56., 57., 58., 59.,
419 60., 61., 62., 63., 64., 65., 66., 67., 68., 69.,
420 70., 71., 72., 73., 74., 75., 76., 77., 78., 79.,
421 80., 81., 82., 83., 84., 85., 86., 87., 88., 89.,
422 90., 91., 92., 93., 94., 95., 96., 97., 98., 99.,
423
424 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5,
425 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5, 49.5]
426 )
427 assert_array_equal(a, b)
428
429 @pytest.mark.parametrize("mode", [
430 "mean",
431 "median",
432 "minimum",
433 "maximum"
434 ])
435 def test_same_prepend_append(self, mode):
436 """ Test that appended and prepended values are equal """
437 # This test is constructed to trigger floating point rounding errors in
438 # a way that caused gh-11216 for mode=='mean'
439 a = np.array([-1, 2, -1]) + np.array([0, 1e-12, 0], dtype=np.float64)
440 a = np.pad(a, (1, 1), mode)
441 assert_equal(a[0], a[-1])
442
443 @pytest.mark.parametrize("mode", ["mean", "median", "minimum", "maximum"])
444 @pytest.mark.parametrize(
445 "stat_length", [-2, (-2,), (3, -1), ((5, 2), (-2, 3)), ((-4,), (2,))]
446 )
447 def test_check_negative_stat_length(self, mode, stat_length):
448 arr = np.arange(30).reshape((6, 5))
449 match = "index can't contain negative values"
450 with pytest.raises(ValueError, match=match):
451 np.pad(arr, 2, mode, stat_length=stat_length)
452
453 def test_simple_stat_length(self):
454 a = np.arange(30)
455 a = np.reshape(a, (6, 5))
456 a = np.pad(a, ((2, 3), (3, 2)), mode='mean', stat_length=(3,))
457 b = np.array(
458 [[6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
459 [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
460
461 [1, 1, 1, 0, 1, 2, 3, 4, 3, 3],
462 [6, 6, 6, 5, 6, 7, 8, 9, 8, 8],
463 [11, 11, 11, 10, 11, 12, 13, 14, 13, 13],
464 [16, 16, 16, 15, 16, 17, 18, 19, 18, 18],
465 [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
466 [26, 26, 26, 25, 26, 27, 28, 29, 28, 28],
467
468 [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
469 [21, 21, 21, 20, 21, 22, 23, 24, 23, 23],
470 [21, 21, 21, 20, 21, 22, 23, 24, 23, 23]]
471 )
472 assert_array_equal(a, b)
473
474 @pytest.mark.filterwarnings("ignore:Mean of empty slice:RuntimeWarning")
475 @pytest.mark.filterwarnings(
476 "ignore:invalid value encountered in( scalar)? divide:RuntimeWarning"
477 )
478 @pytest.mark.parametrize("mode", ["mean", "median"])
479 def test_zero_stat_length_valid(self, mode):
480 arr = np.pad([1., 2.], (1, 2), mode, stat_length=0)
481 expected = np.array([np.nan, 1., 2., np.nan, np.nan])
482 assert_equal(arr, expected)
483
484 @pytest.mark.parametrize("mode", ["minimum", "maximum"])
485 def test_zero_stat_length_invalid(self, mode):
486 match = "stat_length of 0 yields no value for padding"
487 with pytest.raises(ValueError, match=match):
488 np.pad([1., 2.], 0, mode, stat_length=0)
489 with pytest.raises(ValueError, match=match):
490 np.pad([1., 2.], 0, mode, stat_length=(1, 0))
491 with pytest.raises(ValueError, match=match):
492 np.pad([1., 2.], 1, mode, stat_length=0)
493 with pytest.raises(ValueError, match=match):
494 np.pad([1., 2.], 1, mode, stat_length=(1, 0))
495
496
497class TestConstant:
498 def test_check_constant(self):
499 a = np.arange(100)
500 a = np.pad(a, (25, 20), 'constant', constant_values=(10, 20))
501 b = np.array(
502 [10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
503 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
504 10, 10, 10, 10, 10,
505
506 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
507 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
508 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
509 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
510 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
511 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
512 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
513 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
514 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
515 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
516
517 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
518 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
519 )
520 assert_array_equal(a, b)
521
522 def test_check_constant_zeros(self):
523 a = np.arange(100)
524 a = np.pad(a, (25, 20), 'constant')
525 b = np.array(
526 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
528 0, 0, 0, 0, 0,
529
530 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
531 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
532 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
533 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
534 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
535 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
536 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
537 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
538 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
539 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
540
541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
543 )
544 assert_array_equal(a, b)
545
546 def test_check_constant_float(self):
547 # If input array is int, but constant_values are float, the dtype of
548 # the array to be padded is kept
549 arr = np.arange(30).reshape(5, 6)
550 test = np.pad(arr, (1, 2), mode='constant',
551 constant_values=1.1)
552 expected = np.array(
553 [[1, 1, 1, 1, 1, 1, 1, 1, 1],
554
555 [1, 0, 1, 2, 3, 4, 5, 1, 1],
556 [1, 6, 7, 8, 9, 10, 11, 1, 1],
557 [1, 12, 13, 14, 15, 16, 17, 1, 1],
558 [1, 18, 19, 20, 21, 22, 23, 1, 1],
559 [1, 24, 25, 26, 27, 28, 29, 1, 1],
560
561 [1, 1, 1, 1, 1, 1, 1, 1, 1],
562 [1, 1, 1, 1, 1, 1, 1, 1, 1]]
563 )
564 assert_allclose(test, expected)
565
566 def test_check_constant_float2(self):
567 # If input array is float, and constant_values are float, the dtype of
568 # the array to be padded is kept - here retaining the float constants
569 arr = np.arange(30).reshape(5, 6)
570 arr_float = arr.astype(np.float64)
571 test = np.pad(arr_float, ((1, 2), (1, 2)), mode='constant',
572 constant_values=1.1)
573 expected = np.array(
574 [[1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1],
575
576 [1.1, 0. , 1. , 2. , 3. , 4. , 5. , 1.1, 1.1], # noqa: E203
577 [1.1, 6. , 7. , 8. , 9. , 10. , 11. , 1.1, 1.1], # noqa: E203
578 [1.1, 12. , 13. , 14. , 15. , 16. , 17. , 1.1, 1.1], # noqa: E203
579 [1.1, 18. , 19. , 20. , 21. , 22. , 23. , 1.1, 1.1], # noqa: E203
580 [1.1, 24. , 25. , 26. , 27. , 28. , 29. , 1.1, 1.1], # noqa: E203
581
582 [1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1],
583 [1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1]]
584 )
585 assert_allclose(test, expected)
586
587 def test_check_constant_float3(self):
588 a = np.arange(100, dtype=float)
589 a = np.pad(a, (25, 20), 'constant', constant_values=(-1.1, -1.2))
590 b = np.array(
591 [-1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
592 -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1, -1.1,
593 -1.1, -1.1, -1.1, -1.1, -1.1,
594
595 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
596 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
597 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
598 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
599 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
600 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
601 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
602 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
603 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
604 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
605
606 -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2,
607 -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2, -1.2]
608 )
609 assert_allclose(a, b)
610
611 def test_check_constant_odd_pad_amount(self):
612 arr = np.arange(30).reshape(5, 6)
613 test = np.pad(arr, ((1,), (2,)), mode='constant',
614 constant_values=3)
615 expected = np.array(
616 [[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
617
618 [3, 3, 0, 1, 2, 3, 4, 5, 3, 3],
619 [3, 3, 6, 7, 8, 9, 10, 11, 3, 3],
620 [3, 3, 12, 13, 14, 15, 16, 17, 3, 3],
621 [3, 3, 18, 19, 20, 21, 22, 23, 3, 3],
622 [3, 3, 24, 25, 26, 27, 28, 29, 3, 3],
623
624 [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]]
625 )
626 assert_allclose(test, expected)
627
628 def test_check_constant_pad_2d(self):
629 arr = np.arange(4).reshape(2, 2)
630 test = np.pad(arr, ((1, 2), (1, 3)), mode='constant',
631 constant_values=((1, 2), (3, 4)))
632 expected = np.array(
633 [[3, 1, 1, 4, 4, 4],
634 [3, 0, 1, 4, 4, 4],
635 [3, 2, 3, 4, 4, 4],
636 [3, 2, 2, 4, 4, 4],
637 [3, 2, 2, 4, 4, 4]]
638 )
639 assert_allclose(test, expected)
640
641 def test_check_large_integers(self):
642 uint64_max = 2 ** 64 - 1
643 arr = np.full(5, uint64_max, dtype=np.uint64)
644 test = np.pad(arr, 1, mode="constant", constant_values=arr.min())
645 expected = np.full(7, uint64_max, dtype=np.uint64)
646 assert_array_equal(test, expected)
647
648 int64_max = 2 ** 63 - 1
649 arr = np.full(5, int64_max, dtype=np.int64)
650 test = np.pad(arr, 1, mode="constant", constant_values=arr.min())
651 expected = np.full(7, int64_max, dtype=np.int64)
652 assert_array_equal(test, expected)
653
654 def test_check_object_array(self):
655 arr = np.empty(1, dtype=object)
656 obj_a = object()
657 arr[0] = obj_a
658 obj_b = object()
659 obj_c = object()
660 arr = np.pad(arr, pad_width=1, mode='constant',
661 constant_values=(obj_b, obj_c))
662
663 expected = np.empty((3,), dtype=object)
664 expected[0] = obj_b
665 expected[1] = obj_a
666 expected[2] = obj_c
667
668 assert_array_equal(arr, expected)
669
670 def test_pad_empty_dimension(self):
671 arr = np.zeros((3, 0, 2))
672 result = np.pad(arr, [(0,), (2,), (1,)], mode="constant")
673 assert result.shape == (3, 4, 4)
674
675
676class TestLinearRamp:
677 def test_check_simple(self):
678 a = np.arange(100).astype('f')
679 a = np.pad(a, (25, 20), 'linear_ramp', end_values=(4, 5))
680 b = np.array(
681 [4.00, 3.84, 3.68, 3.52, 3.36, 3.20, 3.04, 2.88, 2.72, 2.56,
682 2.40, 2.24, 2.08, 1.92, 1.76, 1.60, 1.44, 1.28, 1.12, 0.96,
683 0.80, 0.64, 0.48, 0.32, 0.16,
684
685 0.00, 1.00, 2.00, 3.00, 4.00, 5.00, 6.00, 7.00, 8.00, 9.00,
686 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0,
687 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
688 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0,
689 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0,
690 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0,
691 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0,
692 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
693 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0,
694 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0,
695
696 94.3, 89.6, 84.9, 80.2, 75.5, 70.8, 66.1, 61.4, 56.7, 52.0,
697 47.3, 42.6, 37.9, 33.2, 28.5, 23.8, 19.1, 14.4, 9.7, 5.]
698 )
699 assert_allclose(a, b, rtol=1e-5, atol=1e-5)
700
701 def test_check_2d(self):
702 arr = np.arange(20).reshape(4, 5).astype(np.float64)
703 test = np.pad(arr, (2, 2), mode='linear_ramp', end_values=(0, 0))
704 expected = np.array(
705 [[0., 0., 0., 0., 0., 0., 0., 0., 0.],
706 [0., 0., 0., 0.5, 1., 1.5, 2., 1., 0.],
707 [0., 0., 0., 1., 2., 3., 4., 2., 0.],
708 [0., 2.5, 5., 6., 7., 8., 9., 4.5, 0.],
709 [0., 5., 10., 11., 12., 13., 14., 7., 0.],
710 [0., 7.5, 15., 16., 17., 18., 19., 9.5, 0.],
711 [0., 3.75, 7.5, 8., 8.5, 9., 9.5, 4.75, 0.],
712 [0., 0., 0., 0., 0., 0., 0., 0., 0.]])
713 assert_allclose(test, expected)
714
715 @pytest.mark.xfail(exceptions=(AssertionError,))
716 def test_object_array(self):
717 from fractions import Fraction
718 arr = np.array([Fraction(1, 2), Fraction(-1, 2)])
719 actual = np.pad(arr, (2, 3), mode='linear_ramp', end_values=0)
720
721 # deliberately chosen to have a non-power-of-2 denominator such that
722 # rounding to floats causes a failure.
723 expected = np.array([
724 Fraction( 0, 12),
725 Fraction( 3, 12),
726 Fraction( 6, 12),
727 Fraction(-6, 12),
728 Fraction(-4, 12),
729 Fraction(-2, 12),
730 Fraction(-0, 12),
731 ])
732 assert_equal(actual, expected)
733
734 def test_end_values(self):
735 """Ensure that end values are exact."""
736 a = np.pad(np.ones(10).reshape(2, 5), (223, 123), mode="linear_ramp")
737 assert_equal(a[:, 0], 0.)
738 assert_equal(a[:, -1], 0.)
739 assert_equal(a[0, :], 0.)
740 assert_equal(a[-1, :], 0.)
741
742 @pytest.mark.parametrize("dtype", _numeric_dtypes)
743 def test_negative_difference(self, dtype):
744 """
745 Check correct behavior of unsigned dtypes if there is a negative
746 difference between the edge to pad and `end_values`. Check both cases
747 to be independent of implementation. Test behavior for all other dtypes
748 in case dtype casting interferes with complex dtypes. See gh-14191.
749 """
750 x = np.array([3], dtype=dtype)
751 result = np.pad(x, 3, mode="linear_ramp", end_values=0)
752 expected = np.array([0, 1, 2, 3, 2, 1, 0], dtype=dtype)
753 assert_equal(result, expected)
754
755 x = np.array([0], dtype=dtype)
756 result = np.pad(x, 3, mode="linear_ramp", end_values=3)
757 expected = np.array([3, 2, 1, 0, 1, 2, 3], dtype=dtype)
758 assert_equal(result, expected)
759
760
761class TestReflect:
762 def test_check_simple(self):
763 a = np.arange(100)
764 a = np.pad(a, (25, 20), 'reflect')
765 b = np.array(
766 [25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
767 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
768 5, 4, 3, 2, 1,
769
770 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
771 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
772 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
773 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
774 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
775 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
776 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
777 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
778 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
779 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
780
781 98, 97, 96, 95, 94, 93, 92, 91, 90, 89,
782 88, 87, 86, 85, 84, 83, 82, 81, 80, 79]
783 )
784 assert_array_equal(a, b)
785
786 def test_check_odd_method(self):
787 a = np.arange(100)
788 a = np.pad(a, (25, 20), 'reflect', reflect_type='odd')
789 b = np.array(
790 [-25, -24, -23, -22, -21, -20, -19, -18, -17, -16,
791 -15, -14, -13, -12, -11, -10, -9, -8, -7, -6,
792 -5, -4, -3, -2, -1,
793
794 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
795 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
796 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
797 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
798 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
799 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
800 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
801 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
802 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
803 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
804
805 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
806 110, 111, 112, 113, 114, 115, 116, 117, 118, 119]
807 )
808 assert_array_equal(a, b)
809
810 def test_check_large_pad(self):
811 a = [[4, 5, 6], [6, 7, 8]]
812 a = np.pad(a, (5, 7), 'reflect')
813 b = np.array(
814 [[7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
815 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
816 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
817 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
818 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
819
820 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
821 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
822
823 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
824 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
825 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
826 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
827 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
828 [7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7, 8, 7, 6, 7],
829 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
830 )
831 assert_array_equal(a, b)
832
833 def test_check_shape(self):
834 a = [[4, 5, 6]]
835 a = np.pad(a, (5, 7), 'reflect')
836 b = np.array(
837 [[5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
838 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
839 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
840 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
841 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
842
843 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
844
845 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
846 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
847 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
848 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
849 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
850 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5],
851 [5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5, 6, 5, 4, 5]]
852 )
853 assert_array_equal(a, b)
854
855 def test_check_01(self):
856 a = np.pad([1, 2, 3], 2, 'reflect')
857 b = np.array([3, 2, 1, 2, 3, 2, 1])
858 assert_array_equal(a, b)
859
860 def test_check_02(self):
861 a = np.pad([1, 2, 3], 3, 'reflect')
862 b = np.array([2, 3, 2, 1, 2, 3, 2, 1, 2])
863 assert_array_equal(a, b)
864
865 def test_check_03(self):
866 a = np.pad([1, 2, 3], 4, 'reflect')
867 b = np.array([1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3])
868 assert_array_equal(a, b)
869
870 def test_check_04(self):
871 a = np.pad([1, 2, 3], [1, 10], 'reflect')
872 b = np.array([2, 1, 2, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 1])
873 assert_array_equal(a, b)
874
875 def test_check_05(self):
876 a = np.pad([1, 2, 3, 4], [45, 10], 'reflect')
877 b = np.array(
878 [4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
879 2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
880 2, 1, 2, 3, 4, 3, 2, 1, 2, 3,
881 4, 3, 2, 1, 2, 3, 4, 3, 2, 1,
882 2, 3, 4, 3, 2, 1, 2, 3, 4, 3,
883 2, 1, 2, 3, 4, 3, 2, 1, 2])
884 assert_array_equal(a, b)
885
886 def test_check_06(self):
887 a = np.pad([1, 2, 3, 4], [15, 2], 'symmetric')
888 b = np.array(
889 [2, 3, 4, 4, 3, 2, 1, 1, 2, 3,
890 4, 4, 3, 2, 1, 1, 2, 3, 4, 4,
891 3]
892 )
893 assert_array_equal(a, b)
894
895 def test_check_07(self):
896 a = np.pad([1, 2, 3, 4, 5, 6], [45, 3], 'symmetric')
897 b = np.array(
898 [4, 5, 6, 6, 5, 4, 3, 2, 1, 1,
899 2, 3, 4, 5, 6, 6, 5, 4, 3, 2,
900 1, 1, 2, 3, 4, 5, 6, 6, 5, 4,
901 3, 2, 1, 1, 2, 3, 4, 5, 6, 6,
902 5, 4, 3, 2, 1, 1, 2, 3, 4, 5,
903 6, 6, 5, 4])
904 assert_array_equal(a, b)
905
906
907class TestEmptyArray:
908 """Check how padding behaves on arrays with an empty dimension."""
909
910 @pytest.mark.parametrize(
911 # Keep parametrization ordered, otherwise pytest-xdist might believe
912 # that different tests were collected during parallelization
913 "mode", sorted(_all_modes.keys() - {"constant", "empty"})
914 )
915 def test_pad_empty_dimension(self, mode):
916 match = ("can't extend empty axis 0 using modes other than 'constant' "
917 "or 'empty'")
918 with pytest.raises(ValueError, match=match):
919 np.pad([], 4, mode=mode)
920 with pytest.raises(ValueError, match=match):
921 np.pad(np.ndarray(0), 4, mode=mode)
922 with pytest.raises(ValueError, match=match):
923 np.pad(np.zeros((0, 3)), ((1,), (0,)), mode=mode)
924
925 @pytest.mark.parametrize("mode", _all_modes.keys())
926 def test_pad_non_empty_dimension(self, mode):
927 result = np.pad(np.ones((2, 0, 2)), ((3,), (0,), (1,)), mode=mode)
928 assert result.shape == (8, 0, 4)
929
930
931class TestSymmetric:
932 def test_check_simple(self):
933 a = np.arange(100)
934 a = np.pad(a, (25, 20), 'symmetric')
935 b = np.array(
936 [24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
937 14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
938 4, 3, 2, 1, 0,
939
940 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
941 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
942 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
943 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
944 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
945 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
946 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
947 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
948 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
949 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
950
951 99, 98, 97, 96, 95, 94, 93, 92, 91, 90,
952 89, 88, 87, 86, 85, 84, 83, 82, 81, 80]
953 )
954 assert_array_equal(a, b)
955
956 def test_check_odd_method(self):
957 a = np.arange(100)
958 a = np.pad(a, (25, 20), 'symmetric', reflect_type='odd')
959 b = np.array(
960 [-24, -23, -22, -21, -20, -19, -18, -17, -16, -15,
961 -14, -13, -12, -11, -10, -9, -8, -7, -6, -5,
962 -4, -3, -2, -1, 0,
963
964 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
965 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
966 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
967 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
968 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
969 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
970 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
971 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
972 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
973 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
974
975 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
976 109, 110, 111, 112, 113, 114, 115, 116, 117, 118]
977 )
978 assert_array_equal(a, b)
979
980 def test_check_large_pad(self):
981 a = [[4, 5, 6], [6, 7, 8]]
982 a = np.pad(a, (5, 7), 'symmetric')
983 b = np.array(
984 [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
985 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
986 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
987 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
988 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
989
990 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
991 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
992
993 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
994 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
995 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
996 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
997 [7, 8, 8, 7, 6, 6, 7, 8, 8, 7, 6, 6, 7, 8, 8],
998 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
999 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
1000 )
1001
1002 assert_array_equal(a, b)
1003
1004 def test_check_large_pad_odd(self):
1005 a = [[4, 5, 6], [6, 7, 8]]
1006 a = np.pad(a, (5, 7), 'symmetric', reflect_type='odd')
1007 b = np.array(
1008 [[-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6],
1009 [-3, -2, -2, -1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6],
1010 [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8],
1011 [-1, 0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8],
1012 [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10],
1013
1014 [ 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10],
1015 [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12],
1016
1017 [ 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12],
1018 [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14],
1019 [ 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14],
1020 [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
1021 [ 7, 8, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16],
1022 [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18],
1023 [ 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18]]
1024 )
1025 assert_array_equal(a, b)
1026
1027 def test_check_shape(self):
1028 a = [[4, 5, 6]]
1029 a = np.pad(a, (5, 7), 'symmetric')
1030 b = np.array(
1031 [[5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1032 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1033 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1034 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1035 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1036
1037 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1038 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1039
1040 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1041 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1042 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1043 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1044 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6],
1045 [5, 6, 6, 5, 4, 4, 5, 6, 6, 5, 4, 4, 5, 6, 6]]
1046 )
1047 assert_array_equal(a, b)
1048
1049 def test_check_01(self):
1050 a = np.pad([1, 2, 3], 2, 'symmetric')
1051 b = np.array([2, 1, 1, 2, 3, 3, 2])
1052 assert_array_equal(a, b)
1053
1054 def test_check_02(self):
1055 a = np.pad([1, 2, 3], 3, 'symmetric')
1056 b = np.array([3, 2, 1, 1, 2, 3, 3, 2, 1])
1057 assert_array_equal(a, b)
1058
1059 def test_check_03(self):
1060 a = np.pad([1, 2, 3], 6, 'symmetric')
1061 b = np.array([1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1, 1, 2, 3])
1062 assert_array_equal(a, b)
1063
1064
1065class TestWrap:
1066 def test_check_simple(self):
1067 a = np.arange(100)
1068 a = np.pad(a, (25, 20), 'wrap')
1069 b = np.array(
1070 [75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
1071 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
1072 95, 96, 97, 98, 99,
1073
1074 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1075 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1076 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1077 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
1078 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
1079 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
1080 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
1081 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1082 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
1083 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
1084
1085 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1086 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
1087 )
1088 assert_array_equal(a, b)
1089
1090 def test_check_large_pad(self):
1091 a = np.arange(12)
1092 a = np.reshape(a, (3, 4))
1093 a = np.pad(a, (10, 12), 'wrap')
1094 b = np.array(
1095 [[10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1096 11, 8, 9, 10, 11, 8, 9, 10, 11],
1097 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1098 3, 0, 1, 2, 3, 0, 1, 2, 3],
1099 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1100 7, 4, 5, 6, 7, 4, 5, 6, 7],
1101 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1102 11, 8, 9, 10, 11, 8, 9, 10, 11],
1103 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1104 3, 0, 1, 2, 3, 0, 1, 2, 3],
1105 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1106 7, 4, 5, 6, 7, 4, 5, 6, 7],
1107 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1108 11, 8, 9, 10, 11, 8, 9, 10, 11],
1109 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1110 3, 0, 1, 2, 3, 0, 1, 2, 3],
1111 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1112 7, 4, 5, 6, 7, 4, 5, 6, 7],
1113 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1114 11, 8, 9, 10, 11, 8, 9, 10, 11],
1115
1116 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1117 3, 0, 1, 2, 3, 0, 1, 2, 3],
1118 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1119 7, 4, 5, 6, 7, 4, 5, 6, 7],
1120 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1121 11, 8, 9, 10, 11, 8, 9, 10, 11],
1122
1123 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1124 3, 0, 1, 2, 3, 0, 1, 2, 3],
1125 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1126 7, 4, 5, 6, 7, 4, 5, 6, 7],
1127 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1128 11, 8, 9, 10, 11, 8, 9, 10, 11],
1129 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1130 3, 0, 1, 2, 3, 0, 1, 2, 3],
1131 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1132 7, 4, 5, 6, 7, 4, 5, 6, 7],
1133 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1134 11, 8, 9, 10, 11, 8, 9, 10, 11],
1135 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1136 3, 0, 1, 2, 3, 0, 1, 2, 3],
1137 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1138 7, 4, 5, 6, 7, 4, 5, 6, 7],
1139 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1140 11, 8, 9, 10, 11, 8, 9, 10, 11],
1141 [2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2,
1142 3, 0, 1, 2, 3, 0, 1, 2, 3],
1143 [6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6,
1144 7, 4, 5, 6, 7, 4, 5, 6, 7],
1145 [10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10, 11, 8, 9, 10,
1146 11, 8, 9, 10, 11, 8, 9, 10, 11]]
1147 )
1148 assert_array_equal(a, b)
1149
1150 def test_check_01(self):
1151 a = np.pad([1, 2, 3], 3, 'wrap')
1152 b = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
1153 assert_array_equal(a, b)
1154
1155 def test_check_02(self):
1156 a = np.pad([1, 2, 3], 4, 'wrap')
1157 b = np.array([3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1])
1158 assert_array_equal(a, b)
1159
1160 def test_pad_with_zero(self):
1161 a = np.ones((3, 5))
1162 b = np.pad(a, (0, 5), mode="wrap")
1163 assert_array_equal(a, b[:-5, :-5])
1164
1165 def test_repeated_wrapping(self):
1166 """
1167 Check wrapping on each side individually if the wrapped area is longer
1168 than the original array.
1169 """
1170 a = np.arange(5)
1171 b = np.pad(a, (12, 0), mode="wrap")
1172 assert_array_equal(np.r_[a, a, a, a][3:], b)
1173
1174 a = np.arange(5)
1175 b = np.pad(a, (0, 12), mode="wrap")
1176 assert_array_equal(np.r_[a, a, a, a][:-3], b)
1177
1178 def test_repeated_wrapping_multiple_origin(self):
1179 """
1180 Assert that 'wrap' pads only with multiples of the original area if
1181 the pad width is larger than the original array.
1182 """
1183 a = np.arange(4).reshape(2, 2)
1184 a = np.pad(a, [(1, 3), (3, 1)], mode='wrap')
1185 b = np.array(
1186 [[3, 2, 3, 2, 3, 2],
1187 [1, 0, 1, 0, 1, 0],
1188 [3, 2, 3, 2, 3, 2],
1189 [1, 0, 1, 0, 1, 0],
1190 [3, 2, 3, 2, 3, 2],
1191 [1, 0, 1, 0, 1, 0]]
1192 )
1193 assert_array_equal(a, b)
1194
1195
1196class TestEdge:
1197 def test_check_simple(self):
1198 a = np.arange(12)
1199 a = np.reshape(a, (4, 3))
1200 a = np.pad(a, ((2, 3), (3, 2)), 'edge')
