codekingpro/portable-devtools
115k
1from itertools import chain
2
3import pytest
4
5import numpy as np
6from numpy.testing import assert_array_equal, assert_equal, assert_raises
7
8
9def test_packbits():
10 # Copied from the docstring.
11 a = [[[1, 0, 1], [0, 1, 0]],
12 [[1, 1, 0], [0, 0, 1]]]
13 for dt in '?bBhHiIlLqQ':
14 arr = np.array(a, dtype=dt)
15 b = np.packbits(arr, axis=-1)
16 assert_equal(b.dtype, np.uint8)
17 assert_array_equal(b, np.array([[[160], [64]], [[192], [32]]]))
18
19 assert_raises(TypeError, np.packbits, np.array(a, dtype=float))
20
21
22def test_packbits_empty():
23 shapes = [
24 (0,), (10, 20, 0), (10, 0, 20), (0, 10, 20), (20, 0, 0), (0, 20, 0),
25 (0, 0, 20), (0, 0, 0),
26 ]
27 for dt in '?bBhHiIlLqQ':
28 for shape in shapes:
29 a = np.empty(shape, dtype=dt)
30 b = np.packbits(a)
31 assert_equal(b.dtype, np.uint8)
32 assert_equal(b.shape, (0,))
33
34
35def test_packbits_empty_with_axis():
36 # Original shapes and lists of packed shapes for different axes.
37 shapes = [
38 ((0,), [(0,)]),
39 ((10, 20, 0), [(2, 20, 0), (10, 3, 0), (10, 20, 0)]),
40 ((10, 0, 20), [(2, 0, 20), (10, 0, 20), (10, 0, 3)]),
41 ((0, 10, 20), [(0, 10, 20), (0, 2, 20), (0, 10, 3)]),
42 ((20, 0, 0), [(3, 0, 0), (20, 0, 0), (20, 0, 0)]),
43 ((0, 20, 0), [(0, 20, 0), (0, 3, 0), (0, 20, 0)]),
44 ((0, 0, 20), [(0, 0, 20), (0, 0, 20), (0, 0, 3)]),
45 ((0, 0, 0), [(0, 0, 0), (0, 0, 0), (0, 0, 0)]),
46 ]
47 for dt in '?bBhHiIlLqQ':
48 for in_shape, out_shapes in shapes:
49 for ax, out_shape in enumerate(out_shapes):
50 a = np.empty(in_shape, dtype=dt)
51 b = np.packbits(a, axis=ax)
52 assert_equal(b.dtype, np.uint8)
53 assert_equal(b.shape, out_shape)
54
55@pytest.mark.parametrize('bitorder', ('little', 'big'))
56def test_packbits_large(bitorder):
57 # test data large enough for 16 byte vectorization
58 a = np.array([1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
59 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1,
60 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,
61 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,
62 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1,
63 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1,
64 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1,
65 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1,
66 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0,
67 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1,
68 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
69 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1,
70 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0,
71 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
72 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0])
73 a = a.repeat(3)
74 for dtype in '?bBhHiIlLqQ':
75 arr = np.array(a, dtype=dtype)
76 b = np.packbits(arr, axis=None, bitorder=bitorder)
77 assert_equal(b.dtype, np.uint8)
78 r = [252, 127, 192, 3, 254, 7, 252, 0, 7, 31, 240, 0, 28, 1, 255, 252,
79 113, 248, 3, 255, 192, 28, 15, 192, 28, 126, 0, 224, 127, 255,
80 227, 142, 7, 31, 142, 63, 28, 126, 56, 227, 240, 0, 227, 128, 63,
81 224, 14, 56, 252, 112, 56, 255, 241, 248, 3, 240, 56, 224, 112,
82 63, 255, 255, 199, 224, 14, 0, 31, 143, 192, 3, 255, 199, 0, 1,
83 255, 224, 1, 255, 252, 126, 63, 0, 1, 192, 252, 14, 63, 0, 15,
84 199, 252, 113, 255, 3, 128, 56, 252, 14, 7, 0, 113, 255, 255, 142, 56, 227,
85 129, 248, 227, 129, 199, 31, 128]
86 if bitorder == 'big':
87 assert_array_equal(b, r)
88 # equal for size being multiple of 8
89 assert_array_equal(np.unpackbits(b, bitorder=bitorder)[:-4], a)
90
91 # check last byte of different remainders (16 byte vectorization)
92 b = [np.packbits(arr[:-i], axis=None)[-1] for i in range(1, 16)]
93 assert_array_equal(b, [128, 128, 128, 31, 30, 28, 24, 16, 0, 0, 0, 199,
94 198, 196, 192])
95
96 arr = arr.reshape(36, 25)
97 b = np.packbits(arr, axis=0)
98 assert_equal(b.dtype, np.uint8)
99 assert_array_equal(b, [[190, 186, 178, 178, 150, 215, 87, 83, 83, 195,
100 199, 206, 204, 204, 140, 140, 136, 136, 8, 40, 105,
101 107, 75, 74, 88],
102 [72, 216, 248, 241, 227, 195, 202, 90, 90, 83,
103 83, 119, 127, 109, 73, 64, 208, 244, 189, 45,
104 41, 104, 122, 90, 18],
105 [113, 120, 248, 216, 152, 24, 60, 52, 182, 150,
106 150, 150, 146, 210, 210, 246, 255, 255, 223,
107 151, 21, 17, 17, 131, 163],
108 [214, 210, 210, 64, 68, 5, 5, 1, 72, 88, 92,
109 92, 78, 110, 39, 181, 149, 220, 222, 218, 218,
110 202, 234, 170, 168],
111 [0, 128, 128, 192, 80, 112, 48, 160, 160, 224,
112 240, 208, 144, 128, 160, 224, 240, 208, 144,
113 144, 176, 240, 224, 192, 128]])
114
115 b = np.packbits(arr, axis=1)
116 assert_equal(b.dtype, np.uint8)
117 assert_array_equal(b, [[252, 127, 192, 0],
118 [ 7, 252, 15, 128],
119 [240, 0, 28, 0],
120 [255, 128, 0, 128],
121 [192, 31, 255, 128],
122 [142, 63, 0, 0],
123 [255, 240, 7, 0],
124 [ 7, 224, 14, 0],
125 [126, 0, 224, 0],
126 [255, 255, 199, 0],
127 [ 56, 28, 126, 0],
128 [113, 248, 227, 128],
129 [227, 142, 63, 0],
130 [ 0, 28, 112, 0],
131 [ 15, 248, 3, 128],
132 [ 28, 126, 56, 0],
133 [ 56, 255, 241, 128],
134 [240, 7, 224, 0],
135 [227, 129, 192, 128],
136 [255, 255, 254, 0],
137 [126, 0, 224, 0],
138 [ 3, 241, 248, 0],
139 [ 0, 255, 241, 128],
140 [128, 0, 255, 128],
141 [224, 1, 255, 128],
142 [248, 252, 126, 0],
143 [ 0, 7, 3, 128],
144 [224, 113, 248, 0],
145 [ 0, 252, 127, 128],
146 [142, 63, 224, 0],
147 [224, 14, 63, 0],
148 [ 7, 3, 128, 0],
149 [113, 255, 255, 128],
150 [ 28, 113, 199, 0],
151 [ 7, 227, 142, 0],
152 [ 14, 56, 252, 0]])
153
154 arr = arr.T.copy()
155 b = np.packbits(arr, axis=0)
156 assert_equal(b.dtype, np.uint8)
157 assert_array_equal(b, [[252, 7, 240, 255, 192, 142, 255, 7, 126, 255,
158 56, 113, 227, 0, 15, 28, 56, 240, 227, 255,
159 126, 3, 0, 128, 224, 248, 0, 224, 0, 142, 224,
160 7, 113, 28, 7, 14],
161 [127, 252, 0, 128, 31, 63, 240, 224, 0, 255,
162 28, 248, 142, 28, 248, 126, 255, 7, 129, 255,
163 0, 241, 255, 0, 1, 252, 7, 113, 252, 63, 14,
164 3, 255, 113, 227, 56],
165 [192, 15, 28, 0, 255, 0, 7, 14, 224, 199, 126,
166 227, 63, 112, 3, 56, 241, 224, 192, 254, 224,
167 248, 241, 255, 255, 126, 3, 248, 127, 224, 63,
168 128, 255, 199, 142, 252],
169 [0, 128, 0, 128, 128, 0, 0, 0, 0, 0, 0, 128, 0,
170 0, 128, 0, 128, 0, 128, 0, 0, 0, 128, 128,
171 128, 0, 128, 0, 128, 0, 0, 0, 128, 0, 0, 0]])
172
173 b = np.packbits(arr, axis=1)
174 assert_equal(b.dtype, np.uint8)
175 assert_array_equal(b, [[190, 72, 113, 214, 0],
176 [186, 216, 120, 210, 128],
177 [178, 248, 248, 210, 128],
178 [178, 241, 216, 64, 192],
179 [150, 227, 152, 68, 80],
180 [215, 195, 24, 5, 112],
181 [ 87, 202, 60, 5, 48],
182 [ 83, 90, 52, 1, 160],
183 [ 83, 90, 182, 72, 160],
184 [195, 83, 150, 88, 224],
185 [199, 83, 150, 92, 240],
186 [206, 119, 150, 92, 208],
187 [204, 127, 146, 78, 144],
188 [204, 109, 210, 110, 128],
189 [140, 73, 210, 39, 160],
190 [140, 64, 246, 181, 224],
191 [136, 208, 255, 149, 240],
192 [136, 244, 255, 220, 208],
193 [ 8, 189, 223, 222, 144],
194 [ 40, 45, 151, 218, 144],
195 [105, 41, 21, 218, 176],
196 [107, 104, 17, 202, 240],
197 [ 75, 122, 17, 234, 224],
198 [ 74, 90, 131, 170, 192],
199 [ 88, 18, 163, 168, 128]])
200
201 # result is the same if input is multiplied with a nonzero value
202 for dtype in 'bBhHiIlLqQ':
203 arr = np.array(a, dtype=dtype)
204 rnd = np.random.randint(low=np.iinfo(dtype).min,
205 high=np.iinfo(dtype).max, size=arr.size,
206 dtype=dtype)
207 rnd[rnd == 0] = 1
208 arr *= rnd.astype(dtype)
209 b = np.packbits(arr, axis=-1)
210 assert_array_equal(np.unpackbits(b)[:-4], a)
211
212 assert_raises(TypeError, np.packbits, np.array(a, dtype=float))
213
214
215def test_packbits_very_large():
216 # test some with a larger arrays gh-8637
217 # code is covered earlier but larger array makes crash on bug more likely
218 for s in range(950, 1050):
219 for dt in '?bBhHiIlLqQ':
220 x = np.ones((200, s), dtype=bool)
221 np.packbits(x, axis=1)
222
223
224def test_unpackbits():
225 # Copied from the docstring.
226 a = np.array([[2], [7], [23]], dtype=np.uint8)
227 b = np.unpackbits(a, axis=1)
228 assert_equal(b.dtype, np.uint8)
229 assert_array_equal(b, np.array([[0, 0, 0, 0, 0, 0, 1, 0],
230 [0, 0, 0, 0, 0, 1, 1, 1],
231 [0, 0, 0, 1, 0, 1, 1, 1]]))
232
233def test_pack_unpack_order():
234 a = np.array([[2], [7], [23]], dtype=np.uint8)
235 b = np.unpackbits(a, axis=1)
236 assert_equal(b.dtype, np.uint8)
237 b_little = np.unpackbits(a, axis=1, bitorder='little')
238 b_big = np.unpackbits(a, axis=1, bitorder='big')
239 assert_array_equal(b, b_big)
240 assert_array_equal(a, np.packbits(b_little, axis=1, bitorder='little'))
241 assert_array_equal(b[:, ::-1], b_little)
242 assert_array_equal(a, np.packbits(b_big, axis=1, bitorder='big'))
243 assert_raises(ValueError, np.unpackbits, a, bitorder='r')
244 assert_raises(TypeError, np.unpackbits, a, bitorder=10)
245
246
247def test_unpackbits_empty():
248 a = np.empty((0,), dtype=np.uint8)
249 b = np.unpackbits(a)
250 assert_equal(b.dtype, np.uint8)
251 assert_array_equal(b, np.empty((0,)))
252
253
254def test_unpackbits_empty_with_axis():
255 # Lists of packed shapes for different axes and unpacked shapes.
256 shapes = [
257 ([(0,)], (0,)),
258 ([(2, 24, 0), (16, 3, 0), (16, 24, 0)], (16, 24, 0)),
259 ([(2, 0, 24), (16, 0, 24), (16, 0, 3)], (16, 0, 24)),
260 ([(0, 16, 24), (0, 2, 24), (0, 16, 3)], (0, 16, 24)),
261 ([(3, 0, 0), (24, 0, 0), (24, 0, 0)], (24, 0, 0)),
262 ([(0, 24, 0), (0, 3, 0), (0, 24, 0)], (0, 24, 0)),
263 ([(0, 0, 24), (0, 0, 24), (0, 0, 3)], (0, 0, 24)),
264 ([(0, 0, 0), (0, 0, 0), (0, 0, 0)], (0, 0, 0)),
265 ]
266 for in_shapes, out_shape in shapes:
267 for ax, in_shape in enumerate(in_shapes):
268 a = np.empty(in_shape, dtype=np.uint8)
269 b = np.unpackbits(a, axis=ax)
270 assert_equal(b.dtype, np.uint8)
271 assert_equal(b.shape, out_shape)
272
273
274def test_unpackbits_large():
275 # test all possible numbers via comparison to already tested packbits
276 d = np.arange(277, dtype=np.uint8)
277 assert_array_equal(np.packbits(np.unpackbits(d)), d)
278 assert_array_equal(np.packbits(np.unpackbits(d[::2])), d[::2])
279 d = np.tile(d, (3, 1))
280 assert_array_equal(np.packbits(np.unpackbits(d, axis=1), axis=1), d)
281 d = d.T.copy()
282 assert_array_equal(np.packbits(np.unpackbits(d, axis=0), axis=0), d)
283
284
285class TestCount:
286 x = np.array([
287 [1, 0, 1, 0, 0, 1, 0],
288 [0, 1, 1, 1, 0, 0, 0],
289 [0, 0, 1, 0, 0, 1, 1],
290 [1, 1, 0, 0, 0, 1, 1],
291 [1, 0, 1, 0, 1, 0, 1],
292 [0, 0, 1, 1, 1, 0, 0],
293 [0, 1, 0, 1, 0, 1, 0],
294 ], dtype=np.uint8)
295 padded1 = np.zeros(57, dtype=np.uint8)
296 padded1[:49] = x.ravel()
297 padded1b = np.zeros(57, dtype=np.uint8)
298 padded1b[:49] = x[::-1].copy().ravel()
299 padded2 = np.zeros((9, 9), dtype=np.uint8)
300 padded2[:7, :7] = x
301
302 @pytest.mark.parametrize('bitorder', ('little', 'big'))
303 @pytest.mark.parametrize('count', chain(range(58), range(-1, -57, -1)))
304 def test_roundtrip(self, bitorder, count):
305 if count < 0:
306 # one extra zero of padding
307 cutoff = count - 1
308 else:
309 cutoff = count
310 # test complete invertibility of packbits and unpackbits with count
311 packed = np.packbits(self.x, bitorder=bitorder)
312 unpacked = np.unpackbits(packed, count=count, bitorder=bitorder)
313 assert_equal(unpacked.dtype, np.uint8)
314 assert_array_equal(unpacked, self.padded1[:cutoff])
315
316 @pytest.mark.parametrize('kwargs', [
317 {}, {'count': None},
318 ])
319 def test_count(self, kwargs):
320 packed = np.packbits(self.x)
321 unpacked = np.unpackbits(packed, **kwargs)
322 assert_equal(unpacked.dtype, np.uint8)
323 assert_array_equal(unpacked, self.padded1[:-1])
324
325 @pytest.mark.parametrize('bitorder', ('little', 'big'))
326 # delta==-1 when count<0 because one extra zero of padding
327 @pytest.mark.parametrize('count', chain(range(8), range(-1, -9, -1)))
328 def test_roundtrip_axis(self, bitorder, count):
329 if count < 0:
330 # one extra zero of padding
331 cutoff = count - 1
332 else:
333 cutoff = count
334 packed0 = np.packbits(self.x, axis=0, bitorder=bitorder)
335 unpacked0 = np.unpackbits(packed0, axis=0, count=count,
336 bitorder=bitorder)
337 assert_equal(unpacked0.dtype, np.uint8)
338 assert_array_equal(unpacked0, self.padded2[:cutoff, :self.x.shape[1]])
339
340 packed1 = np.packbits(self.x, axis=1, bitorder=bitorder)
341 unpacked1 = np.unpackbits(packed1, axis=1, count=count,
342 bitorder=bitorder)
343 assert_equal(unpacked1.dtype, np.uint8)
344 assert_array_equal(unpacked1, self.padded2[:self.x.shape[0], :cutoff])
345
346 @pytest.mark.parametrize('kwargs', [
347 {}, {'count': None},
348 {'bitorder': 'little'},
349 {'bitorder': 'little', 'count': None},
350 {'bitorder': 'big'},
351 {'bitorder': 'big', 'count': None},
352 ])
353 def test_axis_count(self, kwargs):
354 packed0 = np.packbits(self.x, axis=0)
355 unpacked0 = np.unpackbits(packed0, axis=0, **kwargs)
356 assert_equal(unpacked0.dtype, np.uint8)
357 if kwargs.get('bitorder', 'big') == 'big':
358 assert_array_equal(unpacked0, self.padded2[:-1, :self.x.shape[1]])
359 else:
360 assert_array_equal(unpacked0[::-1, :], self.padded2[:-1, :self.x.shape[1]])
361
362 packed1 = np.packbits(self.x, axis=1)
363 unpacked1 = np.unpackbits(packed1, axis=1, **kwargs)
364 assert_equal(unpacked1.dtype, np.uint8)
365 if kwargs.get('bitorder', 'big') == 'big':
366 assert_array_equal(unpacked1, self.padded2[:self.x.shape[0], :-1])
367 else:
368 assert_array_equal(unpacked1[:, ::-1], self.padded2[:self.x.shape[0], :-1])
369
370 def test_bad_count(self):
371 packed0 = np.packbits(self.x, axis=0)
372 assert_raises(ValueError, np.unpackbits, packed0, axis=0, count=-9)
373 packed1 = np.packbits(self.x, axis=1)
374 assert_raises(ValueError, np.unpackbits, packed1, axis=1, count=-9)
375 packed = np.packbits(self.x)
376 assert_raises(ValueError, np.unpackbits, packed, count=-57)
377 