1# mode: run
2# tag: numpy
3
4cimport cython
5from cython.view cimport array
6
7import numpy as np
8cimport numpy as np
9
10
11def test_shape_stride_suboffset():
12    u'''
13    >>> test_shape_stride_suboffset()
14    5 7 11
15    77 11 1
16    -1 -1 -1
17    <BLANKLINE>
18    5 7 11
19    1 5 35
20    -1 -1 -1
21    <BLANKLINE>
22    5 7 11
23    77 11 1
24    -1 -1 -1
25    '''
26    cdef char[:,:,:] larr = array((5,7,11), 1, 'c')
27    print larr.shape[0], larr.shape[1], larr.shape[2]
28    print larr.strides[0], larr.strides[1], larr.strides[2]
29    print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2]
30    print
31
32    larr = array((5,7,11), 1, 'c', mode='fortran')
33    print larr.shape[0], larr.shape[1], larr.shape[2]
34    print larr.strides[0], larr.strides[1], larr.strides[2]
35    print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2]
36    print
37
38    cdef char[:,:,:] c_contig = larr.copy()
39    print c_contig.shape[0], c_contig.shape[1], c_contig.shape[2]
40    print c_contig.strides[0], c_contig.strides[1], c_contig.strides[2]
41    print c_contig.suboffsets[0], c_contig.suboffsets[1], c_contig.suboffsets[2]
42
43
44def test_copy_to():
45    u'''
46    >>> test_copy_to()
47    0 1 2 3 4 5 6 7
48    0 1 2 3 4 5 6 7
49    0 1 2 3 4 5 6 7
50    '''
51    cdef int[:, :, :] from_mvs, to_mvs
52    from_mvs = np.arange(8, dtype=np.int32).reshape(2,2,2)
53
54    cdef int *from_data = <int *> from_mvs._data
55    print ' '.join(str(from_data[i]) for i in range(2*2*2))
56
57    to_mvs = array((2,2,2), sizeof(int), 'i')
58    to_mvs[...] = from_mvs
59
60    # TODO Mark: remove this _data attribute
61    cdef int *to_data = <int*>to_mvs._data
62    print ' '.join(str(from_data[i]) for i in range(2*2*2))
63    print ' '.join(str(to_data[i]) for i in range(2*2*2))
64
65
66def test_overlapping_copy():
67    """
68    >>> test_overlapping_copy()
69    """
70    cdef int i, array[10]
71    for i in range(10):
72        array[i] = i
73
74    cdef int[:] slice = array
75    slice[...] = slice[::-1]
76
77    for i in range(10):
78        assert slice[i] == 10 - 1 - i
79
80
81def test_copy_return_type():
82    """
83    >>> test_copy_return_type()
84    60.0
85    60.0
86    """
87    cdef double[:, :, :] a = np.arange(5 * 5 * 5, dtype=np.float64).reshape(5, 5, 5)
88    cdef double[:, ::1] c_contig = a[..., 0].copy()
89    cdef double[::1, :] f_contig = a[..., 0].copy_fortran()
90
91    print(c_contig[2, 2])
92    print(f_contig[2, 2])
93
94
95def test_partly_overlapping():
96    """
97    >>> test_partly_overlapping()
98    """
99    cdef int i, array[10]
100    for i in range(10):
101        array[i] = i
102
103    cdef int[:] slice = array
104    cdef int[:] slice2 = slice[:5]
105    slice2[...] = slice[4:9]
106
107    for i in range(5):
108        assert slice2[i] == i + 4
109
110@cython.nonecheck(True)
111def test_nonecheck1():
112    u'''
113    >>> test_nonecheck1()
114    Traceback (most recent call last):
115      ...
116    UnboundLocalError: local variable 'uninitialized' referenced before assignment
117    '''
118    cdef int[:,:,:] uninitialized
119    print uninitialized.is_c_contig()
120
121@cython.nonecheck(True)
122def test_nonecheck2():
123    u'''
124    >>> test_nonecheck2()
125    Traceback (most recent call last):
126      ...
127    UnboundLocalError: local variable 'uninitialized' referenced before assignment
128    '''
129    cdef int[:,:,:] uninitialized
130    print uninitialized.is_f_contig()
131
132@cython.nonecheck(True)
133def test_nonecheck3():
134    u'''
135    >>> test_nonecheck3()
136    Traceback (most recent call last):
137      ...
138    UnboundLocalError: local variable 'uninitialized' referenced before assignment
139    '''
140    cdef int[:,:,:] uninitialized
141    uninitialized.copy()
142
143@cython.nonecheck(True)
144def test_nonecheck4():
145    u'''
146    >>> test_nonecheck4()
147    Traceback (most recent call last):
148      ...
149    UnboundLocalError: local variable 'uninitialized' referenced before assignment
150    '''
151    cdef int[:,:,:] uninitialized
152    uninitialized.copy_fortran()
153
154@cython.nonecheck(True)
155def test_nonecheck5():
156    u'''
157    >>> test_nonecheck5()
158    Traceback (most recent call last):
159      ...
160    UnboundLocalError: local variable 'uninitialized' referenced before assignment
161    '''
162    cdef int[:,:,:] uninitialized
163    uninitialized._data
164
165def test_copy_mismatch():
166    u'''
167    >>> test_copy_mismatch()
168    Traceback (most recent call last):
169       ...
170    ValueError: got differing extents in dimension 0 (got 2 and 3)
171    '''
172    cdef int[:,:,::1] mv1  = array((2,2,3), sizeof(int), 'i')
173    cdef int[:,:,::1] mv2  = array((3,2,3), sizeof(int), 'i')
174
175    mv1[...] = mv2
176
177
178def test_is_contiguous():
179    u"""
180    >>> test_is_contiguous()
181    one sized is_c/f_contig True True
182    is_c/f_contig False True
183    f_contig.copy().is_c/f_contig True False
184    f_contig.copy_fortran().is_c/f_contig False True
185    one sized strided contig True True
186    strided False
187    """
188    cdef int[::1, :, :] fort_contig = array((1,1,1), sizeof(int), 'i', mode='fortran')
189    cdef int[:,:,:] strided = fort_contig
190
191    print 'one sized is_c/f_contig', fort_contig.is_c_contig(), fort_contig.is_f_contig()
192    fort_contig = array((2,2,2), sizeof(int), 'i', mode='fortran')
193    print 'is_c/f_contig', fort_contig.is_c_contig(), fort_contig.is_f_contig()
194
195    print 'f_contig.copy().is_c/f_contig', fort_contig.copy().is_c_contig(), \
196                                           fort_contig.copy().is_f_contig()
197    print 'f_contig.copy_fortran().is_c/f_contig', \
198           fort_contig.copy_fortran().is_c_contig(), \
199           fort_contig.copy_fortran().is_f_contig()
200
201    print 'one sized strided contig', strided.is_c_contig(), strided.is_f_contig()
202
203    print 'strided', strided[::2].is_c_contig()
204
205
206def call():
207    u'''
208    >>> call()
209    1000 2000 3000
210    1000
211    2000 3000
212    3000
213    1 1 1000
214    '''
215    cdef int[::1] mv1, mv2, mv3
216    cdef array arr = array((3,), sizeof(int), 'i')
217    mv1 = arr
218    cdef int *data
219    data = <int*>arr.data
220    data[0] = 1000
221    data[1] = 2000
222    data[2] = 3000
223
224    print (<int*>mv1._data)[0] , (<int*>mv1._data)[1] , (<int*>mv1._data)[2]
225
226    mv2 = mv1.copy()
227
228    print (<int*>mv2._data)[0]
229
230
231    print (<int*>mv2._data)[1] , (<int*>mv2._data)[2]
232
233    mv3 = mv2
234
235    cdef int *mv3_data = <int*>mv3._data
236
237    print (<int*>mv1._data)[2]
238
239    mv3_data[0] = 1
240
241    print (<int*>mv3._data)[0] , (<int*>mv2._data)[0] , (<int*>mv1._data)[0]
242
243    assert len(mv1) == 3
244    assert len(mv2) == 3
245    assert len(mv3) == 3
246
247
248def two_dee():
249    u'''
250    >>> two_dee()
251    1 2 3 4
252    -4 -4
253    1 2 3 -4
254    1 2 3 -4
255    '''
256    cdef long[:,::1] mv1, mv2, mv3
257    cdef array arr = array((2,2), sizeof(long), 'l')
258
259    assert len(arr) == 2
260
261    try:
262        _ = len(mv1)
263    except UnboundLocalError:
264        pass
265    else:
266        assert False, "UnboundLocalError not raised for uninitialised memory view"
267
268    cdef long *arr_data
269    arr_data = <long*>arr.data
270
271    mv1 = arr
272
273    arr_data[0] = 1
274    arr_data[1] = 2
275    arr_data[2] = 3
276    arr_data[3] = 4
277
278    print (<long*>mv1._data)[0] , (<long*>mv1._data)[1] , (<long*>mv1._data)[2] , (<long*>mv1._data)[3]
279
280    mv2 = mv1
281
282    arr_data = <long*>mv2._data
283
284    arr_data[3] = -4
285
286    print (<long*>mv2._data)[3] , (<long*>mv1._data)[3]
287
288    mv3 = mv2.copy()
289
290    print (<long*>mv2._data)[0] , (<long*>mv2._data)[1] , (<long*>mv2._data)[2] , (<long*>mv2._data)[3]
291
292    print (<long*>mv3._data)[0] , (<long*>mv3._data)[1] , (<long*>mv3._data)[2] , (<long*>mv3._data)[3]
293
294
295def fort_two_dee():
296    u'''
297    >>> fort_two_dee()
298    1 2 3 4
299    -4 -4
300    1 2 3 -4
301    1 3 2 -4
302    1 2 3 -4
303    '''
304    cdef array arr = array((2,2), sizeof(long), 'l', mode='fortran')
305    cdef long[::1,:] mv1, mv2, mv4
306    cdef long[:, ::1] mv3
307
308    cdef long *arr_data
309    arr_data = <long*>arr.data
310
311    mv1 = arr
312
313    arr_data[0] = 1
314    arr_data[1] = 2
315    arr_data[2] = 3
316    arr_data[3] = 4
317
318    print (<long*>mv1._data)[0], (<long*>mv1._data)[1], (<long*>mv1._data)[2], (<long*>mv1._data)[3]
319
320    mv2 = mv1
321
322    arr_data = <long*>mv2._data
323
324    arr_data[3] = -4
325
326    print (<long*>mv2._data)[3], (<long*>mv1._data)[3]
327
328    mv3 = mv2.copy()
329
330    print (<long*>mv2._data)[0], (<long*>mv2._data)[1], (<long*>mv2._data)[2], (<long*>mv2._data)[3]
331
332    print (<long*>mv3._data)[0], (<long*>mv3._data)[1], (<long*>mv3._data)[2], (<long*>mv3._data)[3]
333
334    mv4 = mv3.copy_fortran()
335
336    print (<long*>mv4._data)[0], (<long*>mv4._data)[1], (<long*>mv4._data)[2], (<long*>mv4._data)[3]
337