Remove trailing whitespace.
[cython.git] / tests / run / numpy_test.pyx
1 # cannot be named "numpy" in order to not clash with the numpy module!
2
3 cimport numpy as np
4
5 def little_endian():
6     cdef int endian_detector = 1
7     return (<char*>&endian_detector)[0] != 0
8
9 if little_endian():
10     my_endian = '<'
11     other_endian = '>'
12 else:
13     my_endian = '>'
14     other_endian = '<'
15
16 try:
17     import numpy as np
18     __doc__ = u"""
19
20     >>> assert_dtype_sizes()
21
22     >>> basic()
23     [[0 1 2 3 4]
24      [5 6 7 8 9]]
25     2 0 9 5
26
27     >>> three_dim()
28     [[[  0.   1.   2.   3.]
29       [  4.   5.   6.   7.]]
30     <_BLANKLINE_>
31      [[  8.   9.  10.  11.]
32       [ 12.  13.  14.  15.]]
33     <_BLANKLINE_>
34      [[ 16.  17.  18.  19.]
35       [ 20.  21.  22.  23.]]]
36     6.0 0.0 13.0 8.0
37
38     >>> obj_array()
39     [a 1 {}]
40     a 1 {}
41
42     Test various forms of slicing, picking etc.
43     >>> a = np.arange(10, dtype='l').reshape(2, 5)
44     >>> print_long_2d(a)
45     0 1 2 3 4
46     5 6 7 8 9
47     >>> print_long_2d(a[::-1, ::-1])
48     9 8 7 6 5
49     4 3 2 1 0
50     >>> print_long_2d(a[1:2, 1:3])
51     6 7
52     >>> print_long_2d(a[::2, ::2])
53     0 2 4
54     >>> print_long_2d(a[::4, :])
55     0 1 2 3 4
56     >>> print_long_2d(a[:, 1:5:2])
57     1 3
58     6 8
59     >>> print_long_2d(a[:, 5:1:-2])
60     4 2
61     9 7
62     >>> print_long_2d(a[:, [3, 1]])
63     3 1
64     8 6
65     >>> print_long_2d(a.T)
66     0 5
67     1 6
68     2 7
69     3 8
70     4 9
71
72     Write to slices
73     >>> b = a.copy()
74     >>> put_range_long_1d(b[:, 3])
75     >>> print b
76     [[0 1 2 0 4]
77      [5 6 7 1 9]]
78     >>> put_range_long_1d(b[::-1, 3])
79     >>> print b
80     [[0 1 2 1 4]
81      [5 6 7 0 9]]
82     >>> a = np.zeros(9, dtype='l')
83     >>> put_range_long_1d(a[1::3])
84     >>> print a
85     [0 0 0 0 1 0 0 2 0]
86
87     Write to picked subarrays. This should NOT change the original
88     array as picking creates a new mutable copy.
89     >>> a = np.zeros(10, dtype='l').reshape(2, 5)
90     >>> put_range_long_1d(a[[0, 0, 1, 1, 0], [0, 1, 2, 4, 3]])
91     >>> print a
92     [[0 0 0 0 0]
93      [0 0 0 0 0]]
94
95     Test contiguous access modes:
96     >>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C')
97     >>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F')
98     >>> test_c_contig(c_arr)
99     0 1 2 3
100     4 5 6 7
101     8 9 10 11
102     >>> test_f_contig(f_arr)
103     0 1 2 3
104     4 5 6 7
105     8 9 10 11
106     >>> test_c_contig(f_arr)
107     Traceback (most recent call last):
108        ...
109     ValueError: ndarray is not C contiguous
110     >>> test_f_contig(c_arr)
111     Traceback (most recent call last):
112        ...
113     ValueError: ndarray is not Fortran contiguous
114     >>> test_c_contig(c_arr[::2,::2])
115     Traceback (most recent call last):
116        ...
117     ValueError: ndarray is not C contiguous
118
119     >>> test_dtype('b', inc1_byte)
120     >>> test_dtype('B', inc1_ubyte)
121     >>> test_dtype('h', inc1_short)
122     >>> test_dtype('H', inc1_ushort)
123     >>> test_dtype('i', inc1_int)
124     >>> test_dtype('I', inc1_uint)
125     >>> test_dtype('l', inc1_long)
126     >>> test_dtype('L', inc1_ulong)
127
128     >>> test_dtype('f', inc1_float)
129     >>> test_dtype('d', inc1_double)
130     >>> test_dtype('g', inc1_longdouble)
131     >>> test_dtype('O', inc1_object)
132     >>> test_dtype('F', inc1_cfloat) # numpy format codes differ from buffer ones here
133     >>> test_dtype('D', inc1_cdouble)
134     >>> test_dtype('G', inc1_clongdouble)
135     >>> test_dtype('F', inc1_cfloat_struct)
136     >>> test_dtype('D', inc1_cdouble_struct)
137     >>> test_dtype('G', inc1_clongdouble_struct)
138
139     >>> test_dtype(np.int, inc1_int_t)
140     >>> test_dtype(np.long, inc1_long_t)
141     >>> test_dtype(np.float, inc1_float_t)
142     >>> test_dtype(np.double, inc1_double_t)
143     >>> test_dtype(np.intp, inc1_intp_t)
144     >>> test_dtype(np.uintp, inc1_uintp_t)
145
146     >>> test_dtype(np.longdouble, inc1_longdouble_t)
147
148     >>> test_dtype(np.int32, inc1_int32_t)
149     >>> test_dtype(np.float64, inc1_float64_t)
150
151     Endian tests:
152     >>> test_dtype('%si' % my_endian, inc1_int)
153     >>> test_dtype('%si' % other_endian, inc1_int)
154     Traceback (most recent call last):
155        ...
156     ValueError: Non-native byte order not supported
157
158
159
160     >>> test_recordarray()
161
162     >>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
163             ('a', np.dtype('i,i')),\
164             ('b', np.dtype('i,i'))\
165         ]))))
166     array([((0, 0), (0, 0)), ((1, 2), (1, 4)), ((1, 2), (1, 4))],
167           dtype=[('a', [('f0', '!i4'), ('f1', '!i4')]), ('b', [('f0', '!i4'), ('f1', '!i4')])])
168
169     >>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
170             ('a', np.dtype('i,f')),\
171             ('b', np.dtype('i,i'))\
172         ]))))
173     Traceback (most recent call last):
174         ...
175     ValueError: Buffer dtype mismatch, expected 'int' but got 'float' in 'DoubleInt.y'
176
177     >>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=False))))
178     array([(22, 23)],
179           dtype=[('f0', '|i1'), ('f1', '!i4')])
180     >>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
181     array([(22, 23)],
182           dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')])
183
184     >>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True))))
185     Traceback (most recent call last):
186         ...
187     ValueError: Buffer dtype mismatch; next field is at offset 4 but 1 expected
188
189     >>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False))))
190     Traceback (most recent call last):
191         ...
192     ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected
193
194
195     >>> test_good_cast()
196     True
197     >>> test_bad_cast()
198     Traceback (most recent call last):
199         ...
200     ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes)
201
202     >>> test_complextypes()
203     1,1
204     1,1
205     8,16
206
207     >>> test_point_record()
208     array([(0.0, 0.0), (1.0, -1.0), (2.0, -2.0)],
209           dtype=[('x', '!f8'), ('y', '!f8')])
210
211 """
212 except:
213     __doc__ = u""
214
215
216 def assert_dtype_sizes():
217     assert sizeof(np.int8_t) == 1
218     assert sizeof(np.int16_t) == 2
219     assert sizeof(np.int32_t) == 4
220     assert sizeof(np.int64_t) == 8
221     assert sizeof(np.uint8_t) == 1
222     assert sizeof(np.uint16_t) == 2
223     assert sizeof(np.uint32_t) == 4
224     assert sizeof(np.uint64_t) == 8
225     assert sizeof(np.float32_t) == 4
226     assert sizeof(np.float64_t) == 8
227     assert sizeof(np.complex64_t) == 8
228     assert sizeof(np.complex128_t) == 16
229
230 def ndarray_str(arr):
231     u"""
232     Since Py2.3 doctest don't support <BLANKLINE>, manually replace blank lines
233     with <_BLANKLINE_>
234     """
235     return unicode(arr).replace(u'\n\n', u'\n<_BLANKLINE_>\n')
236
237 def basic():
238     cdef object[int, ndim=2] buf = np.arange(10, dtype=b'i').reshape((2, 5))
239     print buf
240     print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0]
241
242 def three_dim():
243     cdef object[double, ndim=3] buf = np.arange(24, dtype=b'd').reshape((3,2,4))
244     print ndarray_str(buf)
245     print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0]
246
247 def obj_array():
248     cdef object[object, ndim=1] buf = np.array([b"a", 1, {}])
249     print buf
250     print buf[0], buf[1], buf[2]
251
252
253 def print_long_2d(np.ndarray[long, ndim=2] arr):
254     cdef int i, j
255     for i in range(arr.shape[0]):
256         print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
257
258 def put_range_long_1d(np.ndarray[long] arr):
259     u"""Writes 0,1,2,... to array and returns array"""
260     cdef int value = 0, i
261     for i in range(arr.shape[0]):
262         arr[i] = value
263         value += 1
264
265 def test_c_contig(np.ndarray[int, ndim=2, mode=b'c'] arr):
266     cdef int i, j
267     for i in range(arr.shape[0]):
268         print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
269
270 def test_f_contig(np.ndarray[int, ndim=2, mode=b'fortran'] arr):
271     cdef int i, j
272     for i in range(arr.shape[0]):
273         print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])])
274
275 # Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes
276 def inc1_byte(np.ndarray[char] arr):                    arr[1] += 1
277 def inc1_ubyte(np.ndarray[unsigned char] arr):          arr[1] += 1
278 def inc1_short(np.ndarray[short] arr):                  arr[1] += 1
279 def inc1_ushort(np.ndarray[unsigned short] arr):        arr[1] += 1
280 def inc1_int(np.ndarray[int] arr):                      arr[1] += 1
281 def inc1_uint(np.ndarray[unsigned int] arr):            arr[1] += 1
282 def inc1_long(np.ndarray[long] arr):                    arr[1] += 1
283 def inc1_ulong(np.ndarray[unsigned long] arr):          arr[1] += 1
284 def inc1_longlong(np.ndarray[long long] arr):           arr[1] += 1
285 def inc1_ulonglong(np.ndarray[unsigned long long] arr): arr[1] += 1
286
287 def inc1_float(np.ndarray[float] arr):                  arr[1] += 1
288 def inc1_double(np.ndarray[double] arr):                arr[1] += 1
289 def inc1_longdouble(np.ndarray[long double] arr):       arr[1] += 1
290
291 def inc1_cfloat(np.ndarray[float complex] arr):            arr[1] = arr[1] + 1 + 1j
292 def inc1_cdouble(np.ndarray[double complex] arr):          arr[1] = (arr[1] + 1) + 1j
293 def inc1_clongdouble(np.ndarray[long double complex] arr): arr[1] = arr[1] + (1 + 1j)
294
295 def inc1_cfloat_struct(np.ndarray[np.cfloat_t] arr):
296     arr[1].real += 1
297     arr[1].imag += 1
298
299 def inc1_cdouble_struct(np.ndarray[np.cdouble_t] arr):
300     arr[1].real += 1
301     arr[1].imag += 1
302
303 def inc1_clongdouble_struct(np.ndarray[np.clongdouble_t] arr):
304     cdef long double x
305     x = arr[1].real + 1
306     arr[1].real = x
307     arr[1].imag = arr[1].imag + 1
308
309 def inc1_object(np.ndarray[object] arr):
310     o = arr[1]
311     o += 1
312     arr[1] = o # unfortunately, += segfaults for objects
313
314
315 def inc1_int_t(np.ndarray[np.int_t] arr):               arr[1] += 1
316 def inc1_long_t(np.ndarray[np.long_t] arr):             arr[1] += 1
317 def inc1_float_t(np.ndarray[np.float_t] arr):           arr[1] += 1
318 def inc1_double_t(np.ndarray[np.double_t] arr):         arr[1] += 1
319 def inc1_longdouble_t(np.ndarray[np.longdouble_t] arr): arr[1] += 1
320 def inc1_intp_t(np.ndarray[np.intp_t] arr):             arr[1] += 1
321 def inc1_uintp_t(np.ndarray[np.uintp_t] arr):           arr[1] += 1
322
323 # The tests below only work on platforms that has the given types
324 def inc1_int32_t(np.ndarray[np.int32_t] arr):           arr[1] += 1
325 def inc1_float64_t(np.ndarray[np.float64_t] arr):       arr[1] += 1
326
327
328 def test_dtype(dtype, inc1):
329     if dtype in ("g", np.longdouble,
330                  "G", np.clongdouble):
331         if sizeof(double) == sizeof(long double): # MSVC
332             return
333     if dtype in (b'F', b'D', b'G'):
334         a = np.array([0, 10+10j], dtype=dtype)
335         inc1(a)
336         if a[1] != (11 + 11j): print u"failed!", a[1]
337     else:
338         a = np.array([0, 10], dtype=dtype)
339         inc1(a)
340         if a[1] != 11: print u"failed!"
341
342 cdef struct DoubleInt:
343     int x, y
344
345 def test_recordarray():
346     cdef object[DoubleInt] arr
347     arr = np.array([(5,5), (4, 6)], dtype=np.dtype(b'i,i'))
348     cdef DoubleInt rec
349     rec = arr[0]
350     if rec.x != 5: print u"failed"
351     if rec.y != 5: print u"failed"
352     rec.y += 5
353     arr[1] = rec
354     arr[0].x -= 2
355     arr[0].y += 3
356     if arr[0].x != 3: print u"failed"
357     if arr[0].y != 8: print u"failed"
358     if arr[1].x != 5: print u"failed"
359     if arr[1].y != 10: print u"failed"
360
361 cdef struct NestedStruct:
362     DoubleInt a
363     DoubleInt b
364
365 cdef struct BadDoubleInt:
366     float x
367     int y
368
369 cdef struct BadNestedStruct:
370     DoubleInt a
371     BadDoubleInt b
372
373 def test_nested_dtypes(obj):
374     cdef object[NestedStruct] arr = obj
375     arr[1].a.x = 1
376     arr[1].a.y = 2
377     arr[1].b.x = arr[0].a.y + 1
378     arr[1].b.y = 4
379     arr[2] = arr[1]
380     return repr(arr).replace('<', '!').replace('>', '!')
381
382 def test_bad_nested_dtypes():
383     cdef object[BadNestedStruct] arr
384
385 def test_good_cast():
386     # Check that a signed int can round-trip through casted unsigned int access
387     cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype=b'i')
388     cdef unsigned int data = arr[0]
389     return -100 == <int>data
390
391 def test_bad_cast():
392     # This should raise an exception
393     cdef np.ndarray[int, cast=True] arr = np.array([1], dtype=b'b')
394
395 cdef packed struct PackedStruct:
396     char a
397     int b
398
399 cdef struct UnpackedStruct:
400     char a
401     int b
402
403 def test_packed_align(np.ndarray[PackedStruct] arr):
404     arr[0].a = 22
405     arr[0].b = 23
406     return repr(arr).replace('<', '!').replace('>', '!')
407
408 def test_unpacked_align(np.ndarray[UnpackedStruct] arr):
409     arr[0].a = 22
410     arr[0].b = 23
411     return repr(arr).replace('<', '!').replace('>', '!')
412
413 def test_complextypes():
414     cdef np.complex64_t x64 = 1, y64 = 1j
415     cdef np.complex128_t x128 = 1, y128 = 1j
416     x64 = x64 + y64
417     print "%.0f,%.0f" % (x64.real, x64.imag)
418     x128 = x128 + y128
419     print "%.0f,%.0f" % (x128.real, x128.imag)
420     print "%d,%d" % (sizeof(x64), sizeof(x128))
421
422
423 cdef struct Point:
424     np.float64_t x, y
425
426 def test_point_record():
427     cdef np.ndarray[Point] test
428     Point_dtype = np.dtype([('x', np.float64), ('y', np.float64)])
429     test = np.zeros(3, Point_dtype)
430     cdef int i
431     for i in range(3):
432         test[i].x = i
433         test[i].y = -i
434     print repr(test).replace('<', '!').replace('>', '!')
435
436 include "numpy_common.pxi"