Cython has moved to github.
cython-devel
view tests/run/numpy_test.pyx @ 1235:5de00fce9b73
Buffers: NumPy record array support, format string parsing improvements
| author | Dag Sverre Seljebotn <dagss@student.matnat.uio.no> |
|---|---|
| date | Sat Oct 11 18:48:15 2008 +0200 (3 years ago) |
| parents | 7456abecfbd5 |
| children | d0c4b0a150ca |
line source
1 # cannot be named "numpy" in order to not clash with the numpy module!
3 cimport numpy as np
5 try:
6 import numpy as np
7 __doc__ = """
9 >>> basic()
10 [[0 1 2 3 4]
11 [5 6 7 8 9]]
12 2 0 9 5
14 >>> three_dim()
15 [[[ 0. 1. 2. 3.]
16 [ 4. 5. 6. 7.]]
17 <_BLANKLINE_>
18 [[ 8. 9. 10. 11.]
19 [ 12. 13. 14. 15.]]
20 <_BLANKLINE_>
21 [[ 16. 17. 18. 19.]
22 [ 20. 21. 22. 23.]]]
23 6.0 0.0 13.0 8.0
25 >>> obj_array()
26 [a 1 {}]
27 a 1 {}
29 Test various forms of slicing, picking etc.
30 >>> a = np.arange(10, dtype='l').reshape(2, 5)
31 >>> print_long_2d(a)
32 0 1 2 3 4
33 5 6 7 8 9
34 >>> print_long_2d(a[::-1, ::-1])
35 9 8 7 6 5
36 4 3 2 1 0
37 >>> print_long_2d(a[1:2, 1:3])
38 6 7
39 >>> print_long_2d(a[::2, ::2])
40 0 2 4
41 >>> print_long_2d(a[::4, :])
42 0 1 2 3 4
43 >>> print_long_2d(a[:, 1:5:2])
44 1 3
45 6 8
46 >>> print_long_2d(a[:, 5:1:-2])
47 4 2
48 9 7
49 >>> print_long_2d(a[:, [3, 1]])
50 3 1
51 8 6
52 >>> print_long_2d(a.T)
53 0 5
54 1 6
55 2 7
56 3 8
57 4 9
59 Write to slices
60 >>> b = a.copy()
61 >>> put_range_long_1d(b[:, 3])
62 >>> print b
63 [[0 1 2 0 4]
64 [5 6 7 1 9]]
65 >>> put_range_long_1d(b[::-1, 3])
66 >>> print b
67 [[0 1 2 1 4]
68 [5 6 7 0 9]]
69 >>> a = np.zeros(9, dtype='l')
70 >>> put_range_long_1d(a[1::3])
71 >>> print a
72 [0 0 0 0 1 0 0 2 0]
74 Write to picked subarrays. This should NOT change the original
75 array as picking creates a new mutable copy.
76 >>> a = np.zeros(10, dtype='l').reshape(2, 5)
77 >>> put_range_long_1d(a[[0, 0, 1, 1, 0], [0, 1, 2, 4, 3]])
78 >>> print a
79 [[0 0 0 0 0]
80 [0 0 0 0 0]]
82 Test contiguous access modes:
83 >>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C')
84 >>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F')
85 >>> test_c_contig(c_arr)
86 0 1 2 3
87 4 5 6 7
88 8 9 10 11
89 >>> test_f_contig(f_arr)
90 0 1 2 3
91 4 5 6 7
92 8 9 10 11
93 >>> test_c_contig(f_arr)
94 Traceback (most recent call last):
95 ...
96 ValueError: ndarray is not C contiguous
97 >>> test_f_contig(c_arr)
98 Traceback (most recent call last):
99 ...
100 ValueError: ndarray is not Fortran contiguous
101 >>> test_c_contig(c_arr[::2,::2])
102 Traceback (most recent call last):
103 ...
104 ValueError: ndarray is not C contiguous
106 >>> test_dtype('b', inc1_byte)
107 >>> test_dtype('B', inc1_ubyte)
108 >>> test_dtype('h', inc1_short)
109 >>> test_dtype('H', inc1_ushort)
110 >>> test_dtype('i', inc1_int)
111 >>> test_dtype('I', inc1_uint)
112 >>> test_dtype('l', inc1_long)
113 >>> test_dtype('L', inc1_ulong)
114 >>> test_dtype('f', inc1_float)
115 >>> test_dtype('d', inc1_double)
116 >>> test_dtype('g', inc1_longdouble)
117 >>> test_dtype('O', inc1_object)
118 >>> test_dtype('F', inc1_cfloat) # numpy format codes differ from buffer ones here
119 >>> test_dtype('D', inc1_cdouble)
120 >>> test_dtype('G', inc1_clongdouble)
122 >>> test_dtype(np.int, inc1_int_t)
123 >>> test_dtype(np.long, inc1_long_t)
124 >>> test_dtype(np.float, inc1_float_t)
125 >>> test_dtype(np.double, inc1_double_t)
127 >>> test_dtype(np.longdouble, inc1_longdouble_t)
129 >>> test_dtype(np.int32, inc1_int32_t)
130 >>> test_dtype(np.float64, inc1_float64_t)
132 >>> test_recordarray()
134 >>> test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
135 ('a', np.dtype('i,i')),\
136 ('b', np.dtype('i,i'))\
137 ])))
138 array([((0, 0), (0, 0)), ((1, 2), (1, 4)), ((1, 2), (1, 4))],
139 dtype=[('a', [('f0', '<i4'), ('f1', '<i4')]), ('b', [('f0', '<i4'), ('f1', '<i4')])])
141 >>> test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\
142 ('a', np.dtype('i,f')),\
143 ('b', np.dtype('i,i'))\
144 ])))
145 Traceback (most recent call last):
146 ...
147 ValueError: Buffer datatype mismatch (expected 'i', got 'f}T{ii}')
149 >>> test_good_cast()
150 True
151 >>> test_bad_cast()
152 Traceback (most recent call last):
153 ...
154 ValueError: Attempted cast of buffer to datatype of different size.
156 """
157 except:
158 __doc__ = ""
160 def ndarray_str(arr):
161 """
162 Since Py2.3 doctest don't support <BLANKLINE>, manually replace blank lines
163 with <_BLANKLINE_>
164 """
165 return str(arr).replace('\n\n', '\n<_BLANKLINE_>\n')
167 def basic():
168 cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5))
169 print buf
170 print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0]
172 def three_dim():
173 cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4))
174 print ndarray_str(buf)
175 print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0]
177 def obj_array():
178 cdef object[object, ndim=1] buf = np.array(["a", 1, {}])
179 print buf
180 print buf[0], buf[1], buf[2]
183 def print_long_2d(np.ndarray[long, ndim=2] arr):
184 cdef int i, j
185 for i in range(arr.shape[0]):
186 print " ".join([str(arr[i, j]) for j in range(arr.shape[1])])
188 def put_range_long_1d(np.ndarray[long] arr):
189 """Writes 0,1,2,... to array and returns array"""
190 cdef int value = 0, i
191 for i in range(arr.shape[0]):
192 arr[i] = value
193 value += 1
195 def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr):
196 cdef int i, j
197 for i in range(arr.shape[0]):
198 print " ".join([str(arr[i, j]) for j in range(arr.shape[1])])
200 def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr):
201 cdef int i, j
202 for i in range(arr.shape[0]):
203 print " ".join([str(arr[i, j]) for j in range(arr.shape[1])])
205 cdef struct cfloat:
206 float real
207 float imag
209 cdef struct cdouble:
210 double real
211 double imag
213 cdef struct clongdouble:
214 long double real
215 long double imag
217 # Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes
218 def inc1_byte(np.ndarray[char] arr): arr[1] += 1
219 def inc1_ubyte(np.ndarray[unsigned char] arr): arr[1] += 1
220 def inc1_short(np.ndarray[short] arr): arr[1] += 1
221 def inc1_ushort(np.ndarray[unsigned short] arr): arr[1] += 1
222 def inc1_int(np.ndarray[int] arr): arr[1] += 1
223 def inc1_uint(np.ndarray[unsigned int] arr): arr[1] += 1
224 def inc1_long(np.ndarray[long] arr): arr[1] += 1
225 def inc1_ulong(np.ndarray[unsigned long] arr): arr[1] += 1
226 def inc1_longlong(np.ndarray[long long] arr): arr[1] += 1
227 def inc1_ulonglong(np.ndarray[unsigned long long] arr): arr[1] += 1
229 def inc1_float(np.ndarray[float] arr): arr[1] += 1
230 def inc1_double(np.ndarray[double] arr): arr[1] += 1
231 def inc1_longdouble(np.ndarray[long double] arr): arr[1] += 1
233 def inc1_cfloat(np.ndarray[cfloat] arr):
234 arr[1].real += 1
235 arr[1].imag += 1
237 def inc1_cdouble(np.ndarray[cdouble] arr):
238 arr[1].real += 1
239 arr[1].imag += 1
241 def inc1_clongdouble(np.ndarray[clongdouble] arr):
242 cdef long double x
243 x = arr[1].real + 1
244 arr[1].real = x
245 arr[1].imag = arr[1].imag + 1
247 def inc1_object(np.ndarray[object] arr):
248 o = arr[1]
249 o += 1
250 arr[1] = o # unfortunately, += segfaults for objects
253 def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1
254 def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1
255 def inc1_float_t(np.ndarray[np.float_t] arr): arr[1] += 1
256 def inc1_double_t(np.ndarray[np.double_t] arr): arr[1] += 1
257 def inc1_longdouble_t(np.ndarray[np.longdouble_t] arr): arr[1] += 1
259 # The tests below only work on platforms that has the given types
260 def inc1_int32_t(np.ndarray[np.int32_t] arr): arr[1] += 1
261 def inc1_float64_t(np.ndarray[np.float64_t] arr): arr[1] += 1
264 def test_dtype(dtype, inc1):
265 if dtype in ('F', 'D', 'G'):
266 a = np.array([0, 10+10j], dtype=dtype)
267 inc1(a)
268 if a[1] != (11 + 11j): print "failed!", a[1]
269 else:
270 a = np.array([0, 10], dtype=dtype)
271 inc1(a)
272 if a[1] != 11: print "failed!"
274 cdef struct DoubleInt:
275 int x, y
277 def test_recordarray():
278 cdef object[DoubleInt] arr
279 arr = np.array([(5,5), (4, 6)], dtype=np.dtype('i,i'))
280 cdef DoubleInt rec
281 rec = arr[0]
282 if rec.x != 5: print "failed"
283 if rec.y != 5: print "failed"
284 rec.y += 5
285 arr[1] = rec
286 arr[0].x -= 2
287 arr[0].y += 3
288 if arr[0].x != 3: print "failed"
289 if arr[0].y != 8: print "failed"
290 if arr[1].x != 5: print "failed"
291 if arr[1].y != 10: print "failed"
293 cdef struct NestedStruct:
294 DoubleInt a
295 DoubleInt b
297 cdef struct BadDoubleInt:
298 float x
299 int y
301 cdef struct BadNestedStruct:
302 DoubleInt a
303 BadDoubleInt b
305 def test_nested_dtypes(obj):
306 cdef object[NestedStruct] arr = obj
307 arr[1].a.x = 1
308 arr[1].a.y = 2
309 arr[1].b.x = arr[0].a.y + 1
310 arr[1].b.y = 4
311 arr[2] = arr[1]
312 return arr
314 def test_bad_nested_dtypes():
315 cdef object[BadNestedStruct] arr
317 def test_good_cast():
318 # Check that a signed int can round-trip through casted unsigned int access
319 cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i')
320 cdef unsigned int data = arr[0]
321 return -100 == <int>data
323 def test_bad_cast():
324 # This should raise an exception
325 cdef np.ndarray[long, cast=True] arr = np.array([1], dtype='b')
