~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to numpy/core/src/arrayobject.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik, Riku Voipio, Tiziano Zito, Carlos Galisteo, Ondrej Certik
  • Date: 2008-07-08 15:08:16 UTC
  • mfrom: (0.1.21 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080708150816-ekf992jcp2k1eua3
Tags: 1:1.1.0-3
[ Riku Voipio ]
* debian/control: atlas is not available on armel, and after a quick look
  neither on alpha. I'd also suggest dropping
  libatlas-sse-dev|libatlas-sse2-dev|libatlas-3dnow-dev alternative combo
  away, these are potentially dangerous on buildd's. Ondrej: dropped.
  (Closes: #489568)

[ Tiziano Zito ]
* patch: build _dotblas.c when ATLAS is not installed, build-conflict with
  atlas, build-depend on blas+lapack only, as it used to be (Closes: #489726)

[ Carlos Galisteo ]
* debian/control
  - Added Homepage field.

[ Ondrej Certik ]
* Checked the package on i386 and amd64, both with and without atlas, all
  tests run and the numpy package is faster if atlas is around. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
1
/*
3
2
  Provide multidimensional arrays as a basic object type in python.
4
3
 
5
 
Based on Original Numeric implementation
6
 
Copyright (c) 1995, 1996, 1997 Jim Hugunin, hugunin@mit.edu
7
 
 
8
 
with contributions from many Numeric Python developers 1995-2004
9
 
 
10
 
Heavily modified in 2005 with inspiration from Numarray
11
 
 
12
 
by
13
 
 
14
 
Travis Oliphant,  oliphant@ee.byu.edu
15
 
Brigham Young Univeristy
16
 
 
17
 
maintainer email:  oliphant.travis@ieee.org
18
 
 
19
 
Numarray design (which provided guidance) by
20
 
Space Science Telescope Institute
 
4
  Based on Original Numeric implementation
 
5
  Copyright (c) 1995, 1996, 1997 Jim Hugunin, hugunin@mit.edu
 
6
 
 
7
  with contributions from many Numeric Python developers 1995-2004
 
8
 
 
9
  Heavily modified in 2005 with inspiration from Numarray
 
10
 
 
11
  by
 
12
 
 
13
  Travis Oliphant,  oliphant@ee.byu.edu
 
14
  Brigham Young Univeristy
 
15
 
 
16
  maintainer email:  oliphant.travis@ieee.org
 
17
 
 
18
  Numarray design (which provided guidance) by
 
19
  Space Science Telescope Institute
21
20
  (J. Todd Miller, Perry Greenfield, Rick White)
22
21
*/
 
22
/*#include <stdio.h>*/
23
23
 
24
24
/*OBJECT_API
25
 
 Get Priority from object
26
 
*/
 
25
 * Get Priority from object
 
26
 */
27
27
static double
28
28
PyArray_GetPriority(PyObject *obj, double default_)
29
29
{
30
 
        PyObject *ret;
31
 
        double priority=PyArray_PRIORITY;
32
 
 
33
 
        if (PyArray_CheckExact(obj))
34
 
                return priority;
35
 
 
36
 
        ret = PyObject_GetAttrString(obj, "__array_priority__");
37
 
        if (ret != NULL) priority = PyFloat_AsDouble(ret);
38
 
        if (PyErr_Occurred()) {
39
 
                PyErr_Clear();
40
 
                priority = default_;
41
 
        }
42
 
        Py_XDECREF(ret);
 
30
    PyObject *ret;
 
31
    double priority=PyArray_PRIORITY;
 
32
 
 
33
    if (PyArray_CheckExact(obj))
43
34
        return priority;
 
35
 
 
36
    ret = PyObject_GetAttrString(obj, "__array_priority__");
 
37
    if (ret != NULL) priority = PyFloat_AsDouble(ret);
 
38
    if (PyErr_Occurred()) {
 
39
        PyErr_Clear();
 
40
        priority = default_;
 
41
    }
 
42
    Py_XDECREF(ret);
 
43
    return priority;
44
44
}
45
45
 
46
46
static int
47
47
_check_object_rec(PyArray_Descr *descr)
48
48
{
49
 
        if (PyDataType_HASFIELDS(descr) && PyDataType_REFCHK(descr)) {
50
 
                PyErr_SetString(PyExc_TypeError, "Not supported for this data-type.");
51
 
                return -1;
52
 
        }
53
 
        return 0;
 
49
    if (PyDataType_HASFIELDS(descr) && PyDataType_REFCHK(descr)) {
 
50
        PyErr_SetString(PyExc_TypeError, "Not supported for this data-type.");
 
51
        return -1;
 
52
    }
 
53
    return 0;
54
54
}
55
55
 
56
56
/* Backward compatibility only */
57
57
/* In both Zero and One
58
58
 
59
 
 ***You must free the memory once you are done with it
60
 
    using PyDataMem_FREE(ptr) or you create a memory leak***
61
 
 
62
 
    If arr is an Object array you are getting a
63
 
    BORROWED reference to Zero or One.
64
 
    Do not DECREF.
65
 
    Please INCREF if you will be hanging on to it.
66
 
 
67
 
    The memory for the ptr still must be freed in any case;
 
59
***You must free the memory once you are done with it
 
60
using PyDataMem_FREE(ptr) or you create a memory leak***
 
61
 
 
62
If arr is an Object array you are getting a
 
63
BORROWED reference to Zero or One.
 
64
Do not DECREF.
 
65
Please INCREF if you will be hanging on to it.
 
66
 
 
67
The memory for the ptr still must be freed in any case;
68
68
*/
69
69
 
70
70
 
71
71
/*OBJECT_API
72
 
 Get pointer to zero of correct type for array.
 
72
  Get pointer to zero of correct type for array.
73
73
*/
74
74
static char *
75
75
PyArray_Zero(PyArrayObject *arr)
76
76
{
77
 
        char *zeroval;
78
 
        int ret, storeflags;
79
 
        PyObject *obj;
80
 
 
81
 
        if (_check_object_rec(arr->descr) < 0) return NULL;
82
 
        zeroval = PyDataMem_NEW(arr->descr->elsize);
83
 
        if (zeroval == NULL) {
84
 
                PyErr_SetNone(PyExc_MemoryError);
85
 
                return NULL;
86
 
        }
87
 
 
88
 
        obj=PyInt_FromLong((long) 0);
89
 
        if (PyArray_ISOBJECT(arr)) {
90
 
                memcpy(zeroval, &obj, sizeof(PyObject *));
91
 
                Py_DECREF(obj);
92
 
                return zeroval;
93
 
        }
94
 
        storeflags = arr->flags;
95
 
        arr->flags |= BEHAVED;
96
 
        ret = arr->descr->f->setitem(obj, zeroval, arr);
97
 
        arr->flags = storeflags;
 
77
    char *zeroval;
 
78
    int ret, storeflags;
 
79
    PyObject *obj;
 
80
 
 
81
    if (_check_object_rec(arr->descr) < 0) return NULL;
 
82
    zeroval = PyDataMem_NEW(arr->descr->elsize);
 
83
    if (zeroval == NULL) {
 
84
        PyErr_SetNone(PyExc_MemoryError);
 
85
        return NULL;
 
86
    }
 
87
 
 
88
    obj=PyInt_FromLong((long) 0);
 
89
    if (PyArray_ISOBJECT(arr)) {
 
90
        memcpy(zeroval, &obj, sizeof(PyObject *));
98
91
        Py_DECREF(obj);
99
 
        if (ret < 0) {
100
 
                PyDataMem_FREE(zeroval);
101
 
                return NULL;
102
 
        }
103
92
        return zeroval;
 
93
    }
 
94
    storeflags = arr->flags;
 
95
    arr->flags |= BEHAVED;
 
96
    ret = arr->descr->f->setitem(obj, zeroval, arr);
 
97
    arr->flags = storeflags;
 
98
    Py_DECREF(obj);
 
99
    if (ret < 0) {
 
100
        PyDataMem_FREE(zeroval);
 
101
        return NULL;
 
102
    }
 
103
    return zeroval;
104
104
}
105
105
 
106
106
/*OBJECT_API
107
 
 Get pointer to one of correct type for array
 
107
  Get pointer to one of correct type for array
108
108
*/
109
109
static char *
110
110
PyArray_One(PyArrayObject *arr)
111
111
{
112
 
        char *oneval;
113
 
        int ret, storeflags;
114
 
        PyObject *obj;
115
 
 
116
 
        if (_check_object_rec(arr->descr) < 0) return NULL;
117
 
        oneval = PyDataMem_NEW(arr->descr->elsize);
118
 
        if (oneval == NULL) {
119
 
                PyErr_SetNone(PyExc_MemoryError);
120
 
                return NULL;
121
 
        }
122
 
 
123
 
        obj = PyInt_FromLong((long) 1);
124
 
        if (PyArray_ISOBJECT(arr)) {
125
 
                memcpy(oneval, &obj, sizeof(PyObject *));
126
 
                Py_DECREF(obj);
127
 
                return oneval;
128
 
        }
129
 
 
130
 
        storeflags = arr->flags;
131
 
        arr->flags |= BEHAVED;
132
 
        ret = arr->descr->f->setitem(obj, oneval, arr);
133
 
        arr->flags = storeflags;
 
112
    char *oneval;
 
113
    int ret, storeflags;
 
114
    PyObject *obj;
 
115
 
 
116
    if (_check_object_rec(arr->descr) < 0) {
 
117
        return NULL;
 
118
    }
 
119
    oneval = PyDataMem_NEW(arr->descr->elsize);
 
120
    if (oneval == NULL) {
 
121
        PyErr_SetNone(PyExc_MemoryError);
 
122
        return NULL;
 
123
    }
 
124
 
 
125
    obj = PyInt_FromLong((long) 1);
 
126
    if (PyArray_ISOBJECT(arr)) {
 
127
        memcpy(oneval, &obj, sizeof(PyObject *));
134
128
        Py_DECREF(obj);
135
 
        if (ret < 0) {
136
 
                PyDataMem_FREE(oneval);
137
 
                return NULL;
138
 
        }
139
129
        return oneval;
 
130
    }
 
131
 
 
132
    storeflags = arr->flags;
 
133
    arr->flags |= BEHAVED;
 
134
    ret = arr->descr->f->setitem(obj, oneval, arr);
 
135
    arr->flags = storeflags;
 
136
    Py_DECREF(obj);
 
137
    if (ret < 0) {
 
138
        PyDataMem_FREE(oneval);
 
139
        return NULL;
 
140
    }
 
141
    return oneval;
140
142
}
141
143
 
142
144
/* End deprecated */
152
154
static void
153
155
PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
154
156
{
155
 
        PyObject **temp;
156
 
 
157
 
        if (!PyDataType_REFCHK(descr)) return;
158
 
 
159
 
        if (descr->type_num == PyArray_OBJECT) {
160
 
                temp = (PyObject **)data;
161
 
                Py_XINCREF(*temp);
162
 
        }
163
 
        else if (PyDescr_HASFIELDS(descr)) {
164
 
                PyObject *key, *value, *title=NULL;
165
 
                PyArray_Descr *new;
166
 
                int offset;
167
 
                Py_ssize_t pos=0;
168
 
                while (PyDict_Next(descr->fields, &pos, &key, &value)) {
169
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
170
 
                                              &title)) return;
171
 
                        PyArray_Item_INCREF(data + offset, new);
172
 
                }
173
 
        }
 
157
    PyObject **temp;
 
158
 
 
159
    if (!PyDataType_REFCHK(descr)) {
174
160
        return;
 
161
    }
 
162
    if (descr->type_num == PyArray_OBJECT) {
 
163
        temp = (PyObject **)data;
 
164
        Py_XINCREF(*temp);
 
165
    }
 
166
    else if (PyDescr_HASFIELDS(descr)) {
 
167
        PyObject *key, *value, *title=NULL;
 
168
        PyArray_Descr *new;
 
169
        int offset;
 
170
        Py_ssize_t pos=0;
 
171
 
 
172
        while (PyDict_Next(descr->fields, &pos, &key, &value)) {
 
173
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
174
                                  &title)) {
 
175
                return;
 
176
            }
 
177
            PyArray_Item_INCREF(data + offset, new);
 
178
        }
 
179
    }
 
180
    return;
175
181
}
176
182
 
177
183
/* XDECREF all objects found at this record */
180
186
static void
181
187
PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
182
188
{
183
 
        PyObject **temp;
184
 
 
185
 
        if (!PyDataType_REFCHK(descr)) return;
186
 
 
187
 
        if (descr->type_num == PyArray_OBJECT) {
188
 
                temp = (PyObject **)data;
189
 
                Py_XDECREF(*temp);
190
 
        }
191
 
        else if PyDescr_HASFIELDS(descr) {
192
 
                PyObject *key, *value, *title=NULL;
193
 
                PyArray_Descr *new;
194
 
                int offset;
195
 
                Py_ssize_t pos=0;
196
 
                while (PyDict_Next(descr->fields, &pos, &key, &value)) {
197
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
198
 
                                              &title)) return;
199
 
                        PyArray_Item_XDECREF(data + offset, new);
 
189
    PyObject **temp;
 
190
 
 
191
    if (!PyDataType_REFCHK(descr)) {
 
192
        return;
 
193
    }
 
194
 
 
195
    if (descr->type_num == PyArray_OBJECT) {
 
196
        temp = (PyObject **)data;
 
197
        Py_XDECREF(*temp);
 
198
    }
 
199
    else if PyDescr_HASFIELDS(descr) {
 
200
            PyObject *key, *value, *title=NULL;
 
201
            PyArray_Descr *new;
 
202
            int offset;
 
203
            Py_ssize_t pos=0;
 
204
            while (PyDict_Next(descr->fields, &pos, &key, &value)) {
 
205
                if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
206
                                      &title)) {
 
207
                    return;
200
208
                }
 
209
                PyArray_Item_XDECREF(data + offset, new);
 
210
            }
201
211
        }
202
 
        return;
 
212
    return;
203
213
}
204
214
 
205
215
/* C-API functions */
207
217
/* Used for arrays of python objects to increment the reference count of */
208
218
/* every python object in the array. */
209
219
/*OBJECT_API
210
 
 For object arrays, increment all internal references.
 
220
  For object arrays, increment all internal references.
211
221
*/
212
222
static int
213
223
PyArray_INCREF(PyArrayObject *mp)
214
224
{
215
 
        intp i, n;
216
 
        PyObject **data, **temp;
217
 
        PyArrayIterObject *it;
218
 
 
219
 
        if (!PyDataType_REFCHK(mp->descr)) return 0;
220
 
 
221
 
        if (mp->descr->type_num != PyArray_OBJECT) {
222
 
                it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
223
 
                if (it == NULL) return -1;
224
 
                while(it->index < it->size) {
225
 
                        PyArray_Item_INCREF(it->dataptr, mp->descr);
226
 
                        PyArray_ITER_NEXT(it);
227
 
                }
228
 
                Py_DECREF(it);
229
 
                return 0;
230
 
        }
231
 
 
232
 
        if (PyArray_ISONESEGMENT(mp)) {
233
 
                data = (PyObject **)mp->data;
234
 
                n = PyArray_SIZE(mp);
235
 
                if (PyArray_ISALIGNED(mp)) {
236
 
                        for(i=0; i<n; i++, data++) Py_XINCREF(*data);
237
 
                }
238
 
                else {
239
 
                        for (i=0; i<n; i++, data++) {
240
 
                                temp = data;
241
 
                                Py_XINCREF(*temp);
242
 
                        }
243
 
                }
244
 
        }
245
 
        else { /* handles misaligned data too */
246
 
                it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
247
 
                if (it == NULL) return -1;
248
 
                while(it->index < it->size) {
249
 
                        temp = (PyObject **)it->dataptr;
250
 
                        Py_XINCREF(*temp);
251
 
                        PyArray_ITER_NEXT(it);
252
 
                }
253
 
                Py_DECREF(it);
254
 
        }
255
 
        return 0;
 
225
    intp i, n;
 
226
    PyObject **data, **temp;
 
227
    PyArrayIterObject *it;
 
228
 
 
229
    if (!PyDataType_REFCHK(mp->descr)) {
 
230
        return 0;
 
231
    }
 
232
    if (mp->descr->type_num != PyArray_OBJECT) {
 
233
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
234
        if (it == NULL) {
 
235
            return -1;
 
236
        }
 
237
        while(it->index < it->size) {
 
238
            PyArray_Item_INCREF(it->dataptr, mp->descr);
 
239
            PyArray_ITER_NEXT(it);
 
240
        }
 
241
        Py_DECREF(it);
 
242
        return 0;
 
243
    }
 
244
 
 
245
    if (PyArray_ISONESEGMENT(mp)) {
 
246
        data = (PyObject **)mp->data;
 
247
        n = PyArray_SIZE(mp);
 
248
        if (PyArray_ISALIGNED(mp)) {
 
249
            for(i = 0; i < n; i++, data++) {
 
250
                Py_XINCREF(*data);
 
251
            }
 
252
        }
 
253
        else {
 
254
            for(i=0; i<n; i++, data++) {
 
255
                temp = data;
 
256
                Py_XINCREF(*temp);
 
257
            }
 
258
        }
 
259
    }
 
260
    else { /* handles misaligned data too */
 
261
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
262
        if (it == NULL) {
 
263
            return -1;
 
264
        }
 
265
        while(it->index < it->size) {
 
266
            temp = (PyObject **)it->dataptr;
 
267
            Py_XINCREF(*temp);
 
268
            PyArray_ITER_NEXT(it);
 
269
        }
 
270
        Py_DECREF(it);
 
271
    }
 
272
    return 0;
256
273
}
257
274
 
258
275
/*OBJECT_API
259
 
 Decrement all internal references for object arrays.
260
 
 (or arrays with object fields)
 
276
  Decrement all internal references for object arrays.
 
277
  (or arrays with object fields)
261
278
*/
262
279
static int
263
280
PyArray_XDECREF(PyArrayObject *mp)
264
281
{
265
 
        intp i, n;
266
 
        PyObject **data;
267
 
        PyObject **temp;
268
 
        PyArrayIterObject *it;
269
 
 
270
 
        if (!PyDataType_REFCHK(mp->descr)) return 0;
271
 
 
272
 
        if (mp->descr->type_num != PyArray_OBJECT) {
273
 
                it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
274
 
                if (it == NULL) return -1;
275
 
                while(it->index < it->size) {
276
 
                        PyArray_Item_XDECREF(it->dataptr, mp->descr);
277
 
                        PyArray_ITER_NEXT(it);
278
 
                }
279
 
                Py_DECREF(it);
280
 
                return 0;
281
 
        }
282
 
 
283
 
        if (PyArray_ISONESEGMENT(mp)) {
284
 
                data = (PyObject **)mp->data;
285
 
                n = PyArray_SIZE(mp);
286
 
                if (PyArray_ISALIGNED(mp)) {
287
 
                        for(i=0; i<n; i++, data++) Py_XDECREF(*data);
288
 
                }
289
 
                else {
290
 
                        for (i=0; i<n; i++, data++) {
291
 
                                temp = data;
292
 
                                Py_XDECREF(*temp);
293
 
                        }
294
 
                }
295
 
        }
296
 
        else { /* handles misaligned data too */
297
 
                it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
298
 
                if (it == NULL) return -1;
299
 
                while(it->index < it->size) {
300
 
                        temp = (PyObject **)it->dataptr;
301
 
                        Py_XDECREF(*temp);
302
 
                        PyArray_ITER_NEXT(it);
303
 
                }
304
 
                Py_DECREF(it);
305
 
        }
306
 
        return 0;
 
282
    intp i, n;
 
283
    PyObject **data;
 
284
    PyObject **temp;
 
285
    PyArrayIterObject *it;
 
286
 
 
287
    if (!PyDataType_REFCHK(mp->descr)) {
 
288
        return 0;
 
289
    }
 
290
    if (mp->descr->type_num != PyArray_OBJECT) {
 
291
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
292
        if (it == NULL) {
 
293
            return -1;
 
294
        }
 
295
        while(it->index < it->size) {
 
296
            PyArray_Item_XDECREF(it->dataptr, mp->descr);
 
297
            PyArray_ITER_NEXT(it);
 
298
        }
 
299
        Py_DECREF(it);
 
300
        return 0;
 
301
    }
 
302
 
 
303
    if (PyArray_ISONESEGMENT(mp)) {
 
304
        data = (PyObject **)mp->data;
 
305
        n = PyArray_SIZE(mp);
 
306
        if (PyArray_ISALIGNED(mp)) {
 
307
            for(i = 0; i < n; i++, data++) Py_XDECREF(*data);
 
308
        }
 
309
        else {
 
310
            for(i = 0; i < n; i++, data++) {
 
311
                temp = data;
 
312
                Py_XDECREF(*temp);
 
313
            }
 
314
        }
 
315
    }
 
316
    else { /* handles misaligned data too */
 
317
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
318
        if (it == NULL) {
 
319
            return -1;
 
320
        }
 
321
        while(it->index < it->size) {
 
322
            temp = (PyObject **)it->dataptr;
 
323
            Py_XDECREF(*temp);
 
324
            PyArray_ITER_NEXT(it);
 
325
        }
 
326
        Py_DECREF(it);
 
327
    }
 
328
    return 0;
307
329
}
308
330
 
309
331
static void
310
332
_strided_byte_copy(char *dst, intp outstrides, char *src, intp instrides,
311
333
                   intp N, int elsize)
312
334
{
313
 
        intp i, j;
314
 
        char *tout = dst;
315
 
        char *tin = src;
316
 
 
317
 
#define _FAST_MOVE(_type_)                                  \
318
 
        for (i=0; i<N; i++) {                               \
319
 
                ((_type_ *)tout)[0] = ((_type_ *)tin)[0];   \
320
 
                tin += instrides;                           \
321
 
                tout += outstrides;                         \
322
 
        }                                                   \
323
 
        return
324
 
 
325
 
        switch(elsize) {
326
 
        case 8:
327
 
                _FAST_MOVE(Float64);
328
 
        case 4:
329
 
                _FAST_MOVE(Int32);
330
 
        case 1:
331
 
                _FAST_MOVE(Int8);
332
 
        case 2:
333
 
                _FAST_MOVE(Int16);
334
 
        case 16:
335
 
                for (i=0; i<N; i++) {
336
 
                        ((Float64 *)tout)[0] = ((Float64 *)tin)[0];
337
 
                        ((Float64 *)tout)[1] = ((Float64 *)tin)[1];
338
 
                        tin += instrides;
339
 
                        tout += outstrides;
340
 
                }
341
 
                return;
342
 
        default:
343
 
                for (i=0; i<N; i++) {
344
 
                        for (j=0; j<elsize; j++) {
345
 
                                *tout++ = *tin++;
346
 
                        }
347
 
                        tin = tin + instrides - elsize;
348
 
                        tout = tout + outstrides - elsize;
349
 
                }
350
 
        }
 
335
    intp i, j;
 
336
    char *tout = dst;
 
337
    char *tin = src;
 
338
 
 
339
#define _FAST_MOVE(_type_)                              \
 
340
    for(i=0; i<N; i++) {                               \
 
341
        ((_type_ *)tout)[0] = ((_type_ *)tin)[0];       \
 
342
        tin += instrides;                               \
 
343
        tout += outstrides;                             \
 
344
    }                                                   \
 
345
    return
 
346
 
 
347
    switch(elsize) {
 
348
    case 8:
 
349
        _FAST_MOVE(Int64);
 
350
    case 4:
 
351
        _FAST_MOVE(Int32);
 
352
    case 1:
 
353
        _FAST_MOVE(Int8);
 
354
    case 2:
 
355
        _FAST_MOVE(Int16);
 
356
    case 16:
 
357
        for(i=0; i<N; i++) {
 
358
            ((Int64 *)tout)[0] = ((Int64 *)tin)[0];
 
359
            ((Int64 *)tout)[1] = ((Int64 *)tin)[1];
 
360
            tin += instrides;
 
361
            tout += outstrides;
 
362
        }
 
363
        return;
 
364
    default:
 
365
        for(i=0; i<N; i++) {
 
366
            for(j=0; j<elsize; j++) {
 
367
                *tout++ = *tin++;
 
368
            }
 
369
            tin = tin + instrides - elsize;
 
370
            tout = tout + outstrides - elsize;
 
371
        }
 
372
    }
351
373
#undef _FAST_MOVE
352
374
 
353
375
}
357
379
_unaligned_strided_byte_move(char *dst, intp outstrides, char *src,
358
380
                             intp instrides, intp N, int elsize)
359
381
{
360
 
        intp i;
361
 
        char *tout = dst;
362
 
        char *tin = src;
363
 
 
364
 
 
365
 
#define _MOVE_N_SIZE(size)                             \
366
 
        for (i=0; i<N; i++) {                          \
367
 
                memmove(tout, tin, size);              \
368
 
                tin += instrides;                      \
369
 
                tout += outstrides;                    \
370
 
        }                                              \
371
 
        return
372
 
 
373
 
        switch(elsize) {
374
 
        case 8:
375
 
                _MOVE_N_SIZE(8);
376
 
        case 4:
377
 
                _MOVE_N_SIZE(4);
378
 
        case 1:
379
 
                _MOVE_N_SIZE(1);
380
 
        case 2:
381
 
                _MOVE_N_SIZE(2);
382
 
        case 16:
383
 
                _MOVE_N_SIZE(16);
384
 
        default:
385
 
                _MOVE_N_SIZE(elsize);
386
 
        }
 
382
    intp i;
 
383
    char *tout = dst;
 
384
    char *tin = src;
 
385
 
 
386
 
 
387
#define _MOVE_N_SIZE(size)                      \
 
388
    for(i=0; i<N; i++) {                       \
 
389
        memmove(tout, tin, size);               \
 
390
        tin += instrides;                       \
 
391
        tout += outstrides;                     \
 
392
    }                                           \
 
393
    return
 
394
 
 
395
    switch(elsize) {
 
396
    case 8:
 
397
        _MOVE_N_SIZE(8);
 
398
    case 4:
 
399
        _MOVE_N_SIZE(4);
 
400
    case 1:
 
401
        _MOVE_N_SIZE(1);
 
402
    case 2:
 
403
        _MOVE_N_SIZE(2);
 
404
    case 16:
 
405
        _MOVE_N_SIZE(16);
 
406
    default:
 
407
        _MOVE_N_SIZE(elsize);
 
408
    }
387
409
#undef _MOVE_N_SIZE
388
410
 
389
411
}
392
414
_unaligned_strided_byte_copy(char *dst, intp outstrides, char *src,
393
415
                             intp instrides, intp N, int elsize)
394
416
{
395
 
        intp i;
396
 
        char *tout = dst;
397
 
        char *tin = src;
398
 
 
399
 
#define _COPY_N_SIZE(size)                             \
400
 
        for (i=0; i<N; i++) {                          \
401
 
                memcpy(tout, tin, size);               \
402
 
                tin += instrides;                      \
403
 
                tout += outstrides;                    \
404
 
        }                                              \
405
 
        return
406
 
 
407
 
        switch(elsize) {
408
 
        case 8:
409
 
                _COPY_N_SIZE(8);
410
 
        case 4:
411
 
                _COPY_N_SIZE(4);
412
 
        case 1:
413
 
                _COPY_N_SIZE(1);
414
 
        case 2:
415
 
                _COPY_N_SIZE(2);
416
 
        case 16:
417
 
                _COPY_N_SIZE(16);
418
 
        default:
419
 
                _COPY_N_SIZE(elsize);
420
 
        }
 
417
    intp i;
 
418
    char *tout = dst;
 
419
    char *tin = src;
 
420
 
 
421
#define _COPY_N_SIZE(size)                      \
 
422
    for(i=0; i<N; i++) {                       \
 
423
        memcpy(tout, tin, size);                \
 
424
        tin += instrides;                       \
 
425
        tout += outstrides;                     \
 
426
    }                                           \
 
427
    return
 
428
 
 
429
    switch(elsize) {
 
430
    case 8:
 
431
        _COPY_N_SIZE(8);
 
432
    case 4:
 
433
        _COPY_N_SIZE(4);
 
434
    case 1:
 
435
        _COPY_N_SIZE(1);
 
436
    case 2:
 
437
        _COPY_N_SIZE(2);
 
438
    case 16:
 
439
        _COPY_N_SIZE(16);
 
440
    default:
 
441
        _COPY_N_SIZE(elsize);
 
442
    }
421
443
#undef _COPY_N_SIZE
422
444
 
423
445
}
425
447
static void
426
448
_strided_byte_swap(void *p, intp stride, intp n, int size)
427
449
{
428
 
        char *a, *b, c=0;
429
 
        int j,m;
 
450
    char *a, *b, c=0;
 
451
    int j,m;
430
452
 
431
 
        switch(size) {
432
 
        case 1: /* no byteswap necessary */
433
 
                break;
434
 
        case 4:
435
 
                for (a = (char*)p ; n > 0; n--, a += stride-1) {
436
 
                        b = a + 3;
437
 
                        c = *a; *a++ = *b; *b-- = c;
438
 
                        c = *a; *a = *b; *b   = c;
439
 
                }
440
 
                break;
441
 
        case 8:
442
 
                for (a = (char*)p ; n > 0; n--, a += stride-3) {
443
 
                        b = a + 7;
444
 
                        c = *a; *a++ = *b; *b-- = c;
445
 
                        c = *a; *a++ = *b; *b-- = c;
446
 
                        c = *a; *a++ = *b; *b-- = c;
447
 
                        c = *a; *a = *b; *b   = c;
448
 
                }
449
 
                break;
450
 
        case 2:
451
 
                for (a = (char*)p ; n > 0; n--, a += stride) {
452
 
                        b = a + 1;
453
 
                        c = *a; *a = *b; *b = c;
454
 
                }
455
 
                break;
456
 
        default:
457
 
                m = size / 2;
458
 
                for (a = (char *)p ; n > 0; n--, a += stride-m) {
459
 
                        b = a + (size-1);
460
 
                        for (j=0; j<m; j++) {
461
 
                                c=*a; *a++ = *b; *b-- = c;
462
 
                        }
463
 
                }
464
 
                break;
465
 
        }
 
453
    switch(size) {
 
454
    case 1: /* no byteswap necessary */
 
455
        break;
 
456
    case 4:
 
457
        for(a = (char*)p ; n > 0; n--, a += stride-1) {
 
458
            b = a + 3;
 
459
            c = *a; *a++ = *b; *b-- = c;
 
460
            c = *a; *a = *b; *b   = c;
 
461
        }
 
462
        break;
 
463
    case 8:
 
464
        for(a = (char*)p ; n > 0; n--, a += stride-3) {
 
465
            b = a + 7;
 
466
            c = *a; *a++ = *b; *b-- = c;
 
467
            c = *a; *a++ = *b; *b-- = c;
 
468
            c = *a; *a++ = *b; *b-- = c;
 
469
            c = *a; *a = *b; *b   = c;
 
470
        }
 
471
        break;
 
472
    case 2:
 
473
        for(a = (char*)p ; n > 0; n--, a += stride) {
 
474
            b = a + 1;
 
475
            c = *a; *a = *b; *b = c;
 
476
        }
 
477
        break;
 
478
    default:
 
479
        m = size / 2;
 
480
        for(a = (char *)p ; n > 0; n--, a += stride-m) {
 
481
            b = a + (size-1);
 
482
            for(j=0; j<m; j++) {
 
483
                c=*a; *a++ = *b; *b-- = c;
 
484
            }
 
485
        }
 
486
        break;
 
487
    }
466
488
}
467
489
 
468
490
static void
469
491
byte_swap_vector(void *p, intp n, int size)
470
492
{
471
 
        _strided_byte_swap(p, (intp) size, n, size);
472
 
        return;
 
493
    _strided_byte_swap(p, (intp) size, n, size);
 
494
    return;
473
495
}
474
496
 
475
497
/* If numitems > 1, then dst must be contiguous */
477
499
copy_and_swap(void *dst, void *src, int itemsize, intp numitems,
478
500
              intp srcstrides, int swap)
479
501
{
480
 
        int i;
481
 
        char *s1 = (char *)src;
482
 
        char *d1 = (char *)dst;
483
 
 
484
 
 
485
 
        if ((numitems == 1) || (itemsize == srcstrides))
486
 
                memcpy(d1, s1, itemsize*numitems);
487
 
        else {
488
 
                for (i = 0; i < numitems; i++) {
489
 
                        memcpy(d1, s1, itemsize);
490
 
                        d1 += itemsize;
491
 
                        s1 += srcstrides;
492
 
                }
 
502
    int i;
 
503
    char *s1 = (char *)src;
 
504
    char *d1 = (char *)dst;
 
505
 
 
506
 
 
507
    if ((numitems == 1) || (itemsize == srcstrides))
 
508
        memcpy(d1, s1, itemsize*numitems);
 
509
    else {
 
510
        for(i = 0; i < numitems; i++) {
 
511
            memcpy(d1, s1, itemsize);
 
512
            d1 += itemsize;
 
513
            s1 += srcstrides;
493
514
        }
 
515
    }
494
516
 
495
 
        if (swap)
496
 
                byte_swap_vector(d1, numitems, itemsize);
 
517
    if (swap)
 
518
        byte_swap_vector(d1, numitems, itemsize);
497
519
}
498
520
 
499
521
 
517
539
static intp
518
540
PyArray_PyIntAsIntp(PyObject *o)
519
541
{
520
 
        longlong long_value = -1;
521
 
        PyObject *obj;
522
 
        static char *msg = "an integer is required";
523
 
        PyObject *arr;
524
 
        PyArray_Descr *descr;
525
 
        intp ret;
526
 
 
527
 
        if (!o) {
528
 
                PyErr_SetString(PyExc_TypeError, msg);
529
 
                return -1;
530
 
        }
531
 
 
532
 
        if (PyInt_Check(o)) {
533
 
                long_value = (longlong) PyInt_AS_LONG(o);
534
 
                goto finish;
535
 
        } else if (PyLong_Check(o)) {
536
 
                long_value = (longlong) PyLong_AsLongLong(o);
537
 
                goto finish;
538
 
        }
 
542
    longlong long_value = -1;
 
543
    PyObject *obj;
 
544
    static char *msg = "an integer is required";
 
545
    PyObject *arr;
 
546
    PyArray_Descr *descr;
 
547
    intp ret;
 
548
 
 
549
    if (!o) {
 
550
        PyErr_SetString(PyExc_TypeError, msg);
 
551
        return -1;
 
552
    }
 
553
 
 
554
    if (PyInt_Check(o)) {
 
555
        long_value = (longlong) PyInt_AS_LONG(o);
 
556
        goto finish;
 
557
    } else if (PyLong_Check(o)) {
 
558
        long_value = (longlong) PyLong_AsLongLong(o);
 
559
        goto finish;
 
560
    }
539
561
 
540
562
#if SIZEOF_INTP == SIZEOF_LONG
541
 
        descr = &LONG_Descr;
 
563
    descr = &LONG_Descr;
542
564
#elif SIZEOF_INTP == SIZEOF_INT
543
 
        descr = &INT_Descr;
 
565
    descr = &INT_Descr;
544
566
#else
545
 
        descr = &LONGLONG_Descr;
 
567
    descr = &LONGLONG_Descr;
546
568
#endif
547
 
        arr = NULL;
 
569
    arr = NULL;
548
570
 
549
 
        if (PyArray_Check(o)) {
550
 
                if (PyArray_SIZE(o)!=1 || !PyArray_ISINTEGER(o)) {
551
 
                        PyErr_SetString(PyExc_TypeError, msg);
552
 
                        return -1;
553
 
                }
554
 
                Py_INCREF(descr);
555
 
                arr = PyArray_CastToType((PyArrayObject *)o, descr, 0);
556
 
        }
557
 
        else if (PyArray_IsScalar(o, Integer)) {
558
 
                Py_INCREF(descr);
559
 
                arr = PyArray_FromScalar(o, descr);
560
 
        }
561
 
        if (arr != NULL) {
562
 
                ret = *((intp *)PyArray_DATA(arr));
563
 
                Py_DECREF(arr);
564
 
                return ret;
565
 
        }
 
571
    if (PyArray_Check(o)) {
 
572
        if (PyArray_SIZE(o)!=1 || !PyArray_ISINTEGER(o)) {
 
573
            PyErr_SetString(PyExc_TypeError, msg);
 
574
            return -1;
 
575
        }
 
576
        Py_INCREF(descr);
 
577
        arr = PyArray_CastToType((PyArrayObject *)o, descr, 0);
 
578
    }
 
579
    else if (PyArray_IsScalar(o, Integer)) {
 
580
        Py_INCREF(descr);
 
581
        arr = PyArray_FromScalar(o, descr);
 
582
    }
 
583
    if (arr != NULL) {
 
584
        ret = *((intp *)PyArray_DATA(arr));
 
585
        Py_DECREF(arr);
 
586
        return ret;
 
587
    }
566
588
 
567
589
#if (PY_VERSION_HEX >= 0x02050000)
568
 
        if (PyIndex_Check(o)) {
569
 
                PyObject* value = PyNumber_Index(o);
570
 
                if (value==NULL) {
571
 
                  return -1;
572
 
                }
573
 
                long_value = (longlong) PyInt_AsSsize_t(value);
574
 
                goto finish;
575
 
        }
 
590
    if (PyIndex_Check(o)) {
 
591
        PyObject* value = PyNumber_Index(o);
 
592
        if (value==NULL) {
 
593
            return -1;
 
594
        }
 
595
        long_value = (longlong) PyInt_AsSsize_t(value);
 
596
        goto finish;
 
597
    }
576
598
#endif
577
 
        if (o->ob_type->tp_as_number != NULL &&                 \
578
 
            o->ob_type->tp_as_number->nb_long != NULL) {
579
 
                obj = o->ob_type->tp_as_number->nb_long(o);
580
 
                if (obj != NULL) {
581
 
                        long_value = (longlong) PyLong_AsLongLong(obj);
582
 
                        Py_DECREF(obj);
583
 
                }
584
 
        }
585
 
        else if (o->ob_type->tp_as_number != NULL &&            \
586
 
                 o->ob_type->tp_as_number->nb_int != NULL) {
587
 
                obj = o->ob_type->tp_as_number->nb_int(o);
588
 
                if (obj != NULL) {
589
 
                        long_value = (longlong) PyLong_AsLongLong(obj);
590
 
                        Py_DECREF(obj);
591
 
                }
592
 
        }
593
 
        else {
594
 
                PyErr_SetString(PyExc_NotImplementedError,"");
595
 
        }
 
599
    if (o->ob_type->tp_as_number != NULL &&                 \
 
600
        o->ob_type->tp_as_number->nb_long != NULL) {
 
601
        obj = o->ob_type->tp_as_number->nb_long(o);
 
602
        if (obj != NULL) {
 
603
            long_value = (longlong) PyLong_AsLongLong(obj);
 
604
            Py_DECREF(obj);
 
605
        }
 
606
    }
 
607
    else if (o->ob_type->tp_as_number != NULL &&            \
 
608
             o->ob_type->tp_as_number->nb_int != NULL) {
 
609
        obj = o->ob_type->tp_as_number->nb_int(o);
 
610
        if (obj != NULL) {
 
611
            long_value = (longlong) PyLong_AsLongLong(obj);
 
612
            Py_DECREF(obj);
 
613
        }
 
614
    }
 
615
    else {
 
616
        PyErr_SetString(PyExc_NotImplementedError,"");
 
617
    }
596
618
 
597
619
 finish:
598
 
        if error_converting(long_value) {
599
 
                PyErr_SetString(PyExc_TypeError, msg);
600
 
                return -1;
 
620
    if error_converting(long_value) {
 
621
            PyErr_SetString(PyExc_TypeError, msg);
 
622
            return -1;
601
623
        }
602
624
 
603
625
#if (SIZEOF_LONGLONG > SIZEOF_INTP)
604
 
        if ((long_value < MIN_INTP) || (long_value > MAX_INTP)) {
605
 
                PyErr_SetString(PyExc_ValueError,
606
 
                                "integer won't fit into a C intp");
607
 
                return -1;
608
 
        }
 
626
    if ((long_value < MIN_INTP) || (long_value > MAX_INTP)) {
 
627
        PyErr_SetString(PyExc_ValueError,
 
628
                        "integer won't fit into a C intp");
 
629
        return -1;
 
630
    }
609
631
#endif
610
 
        return (intp) long_value;
 
632
    return (intp) long_value;
611
633
}
612
634
 
613
635
 
617
639
static int
618
640
PyArray_PyIntAsInt(PyObject *o)
619
641
{
620
 
        long long_value = -1;
621
 
        PyObject *obj;
622
 
        static char *msg = "an integer is required";
623
 
        PyObject *arr;
624
 
        PyArray_Descr *descr;
625
 
        int ret;
626
 
 
627
 
 
628
 
        if (!o) {
629
 
                PyErr_SetString(PyExc_TypeError, msg);
630
 
                return -1;
631
 
        }
632
 
 
633
 
        if (PyInt_Check(o)) {
634
 
                long_value = (long) PyInt_AS_LONG(o);
635
 
                goto finish;
636
 
        } else if (PyLong_Check(o)) {
637
 
                long_value = (long) PyLong_AsLong(o);
638
 
                goto finish;
639
 
        }
640
 
 
641
 
        descr = &INT_Descr;
642
 
        arr=NULL;
643
 
        if (PyArray_Check(o)) {
644
 
                if (PyArray_SIZE(o)!=1 || !PyArray_ISINTEGER(o)) {
645
 
                        PyErr_SetString(PyExc_TypeError, msg);
646
 
                        return -1;
647
 
                }
648
 
                Py_INCREF(descr);
649
 
                arr = PyArray_CastToType((PyArrayObject *)o, descr, 0);
650
 
        }
651
 
        if (PyArray_IsScalar(o, Integer)) {
652
 
                Py_INCREF(descr);
653
 
                arr = PyArray_FromScalar(o, descr);
654
 
        }
655
 
        if (arr != NULL) {
656
 
                ret = *((int *)PyArray_DATA(arr));
657
 
                Py_DECREF(arr);
658
 
                return ret;
659
 
        }
 
642
    long long_value = -1;
 
643
    PyObject *obj;
 
644
    static char *msg = "an integer is required";
 
645
    PyObject *arr;
 
646
    PyArray_Descr *descr;
 
647
    int ret;
 
648
 
 
649
 
 
650
    if (!o) {
 
651
        PyErr_SetString(PyExc_TypeError, msg);
 
652
        return -1;
 
653
    }
 
654
 
 
655
    if (PyInt_Check(o)) {
 
656
        long_value = (long) PyInt_AS_LONG(o);
 
657
        goto finish;
 
658
    } else if (PyLong_Check(o)) {
 
659
        long_value = (long) PyLong_AsLong(o);
 
660
        goto finish;
 
661
    }
 
662
 
 
663
    descr = &INT_Descr;
 
664
    arr=NULL;
 
665
    if (PyArray_Check(o)) {
 
666
        if (PyArray_SIZE(o)!=1 || !PyArray_ISINTEGER(o)) {
 
667
            PyErr_SetString(PyExc_TypeError, msg);
 
668
            return -1;
 
669
        }
 
670
        Py_INCREF(descr);
 
671
        arr = PyArray_CastToType((PyArrayObject *)o, descr, 0);
 
672
    }
 
673
    if (PyArray_IsScalar(o, Integer)) {
 
674
        Py_INCREF(descr);
 
675
        arr = PyArray_FromScalar(o, descr);
 
676
    }
 
677
    if (arr != NULL) {
 
678
        ret = *((int *)PyArray_DATA(arr));
 
679
        Py_DECREF(arr);
 
680
        return ret;
 
681
    }
660
682
#if (PY_VERSION_HEX >= 0x02050000)
661
 
        if (PyIndex_Check(o)) {
662
 
                PyObject* value = PyNumber_Index(o);
663
 
                long_value = (longlong) PyInt_AsSsize_t(value);
664
 
                goto finish;
665
 
        }
 
683
    if (PyIndex_Check(o)) {
 
684
        PyObject* value = PyNumber_Index(o);
 
685
        long_value = (longlong) PyInt_AsSsize_t(value);
 
686
        goto finish;
 
687
    }
666
688
#endif
667
 
        if (o->ob_type->tp_as_number != NULL &&         \
668
 
            o->ob_type->tp_as_number->nb_int != NULL) {
669
 
                obj = o->ob_type->tp_as_number->nb_int(o);
670
 
                if (obj == NULL) return -1;
671
 
                long_value = (long) PyLong_AsLong(obj);
672
 
                Py_DECREF(obj);
673
 
        }
674
 
        else if (o->ob_type->tp_as_number != NULL &&                    \
675
 
                 o->ob_type->tp_as_number->nb_long != NULL) {
676
 
                obj = o->ob_type->tp_as_number->nb_long(o);
677
 
                if (obj == NULL) return -1;
678
 
                long_value = (long) PyLong_AsLong(obj);
679
 
                Py_DECREF(obj);
680
 
        }
681
 
        else {
682
 
                PyErr_SetString(PyExc_NotImplementedError,"");
683
 
        }
 
689
    if (o->ob_type->tp_as_number != NULL &&         \
 
690
        o->ob_type->tp_as_number->nb_int != NULL) {
 
691
        obj = o->ob_type->tp_as_number->nb_int(o);
 
692
        if (obj == NULL) {
 
693
            return -1;
 
694
        }
 
695
        long_value = (long) PyLong_AsLong(obj);
 
696
        Py_DECREF(obj);
 
697
    }
 
698
    else if (o->ob_type->tp_as_number != NULL &&                    \
 
699
             o->ob_type->tp_as_number->nb_long != NULL) {
 
700
        obj = o->ob_type->tp_as_number->nb_long(o);
 
701
        if (obj == NULL) {
 
702
            return -1;
 
703
        }
 
704
        long_value = (long) PyLong_AsLong(obj);
 
705
        Py_DECREF(obj);
 
706
    }
 
707
    else {
 
708
        PyErr_SetString(PyExc_NotImplementedError,"");
 
709
    }
684
710
 
685
711
 finish:
686
 
        if error_converting(long_value) {
687
 
                PyErr_SetString(PyExc_TypeError, msg);
688
 
                return -1;
 
712
    if error_converting(long_value) {
 
713
            PyErr_SetString(PyExc_TypeError, msg);
 
714
            return -1;
689
715
        }
690
716
 
691
717
#if (SIZEOF_LONG > SIZEOF_INT)
692
 
        if ((long_value < INT_MIN) || (long_value > INT_MAX)) {
693
 
                PyErr_SetString(PyExc_ValueError,
694
 
                                "integer won't fit into a C int");
695
 
                return -1;
696
 
        }
 
718
    if ((long_value < INT_MIN) || (long_value > INT_MAX)) {
 
719
        PyErr_SetString(PyExc_ValueError,
 
720
                        "integer won't fit into a C int");
 
721
        return -1;
 
722
    }
697
723
#endif
698
 
        return (int) long_value;
 
724
    return (int) long_value;
699
725
}
700
726
 
701
727
static char *
702
728
index2ptr(PyArrayObject *mp, intp i)
703
729
{
704
 
        intp dim0;
705
 
        if(mp->nd == 0) {
706
 
                PyErr_SetString(PyExc_IndexError,
707
 
                                "0-d arrays can't be indexed");
708
 
                return NULL;
709
 
        }
710
 
        dim0 = mp->dimensions[0];
711
 
        if (i<0) i += dim0;
712
 
        if (i==0 && dim0 > 0)
713
 
                return mp->data;
714
 
 
715
 
        if (i>0 && i < dim0) {
716
 
                return mp->data+i*mp->strides[0];
717
 
        }
718
 
        PyErr_SetString(PyExc_IndexError,"index out of bounds");
 
730
    intp dim0;
 
731
    if(mp->nd == 0) {
 
732
        PyErr_SetString(PyExc_IndexError,
 
733
                        "0-d arrays can't be indexed");
719
734
        return NULL;
 
735
    }
 
736
    dim0 = mp->dimensions[0];
 
737
    if (i<0) i += dim0;
 
738
    if (i==0 && dim0 > 0)
 
739
        return mp->data;
 
740
 
 
741
    if (i>0 && i < dim0) {
 
742
        return mp->data+i*mp->strides[0];
 
743
    }
 
744
    PyErr_SetString(PyExc_IndexError,"index out of bounds");
 
745
    return NULL;
720
746
}
721
747
 
722
748
/*OBJECT_API
723
 
 Compute the size of an array (in number of items)
 
749
  Compute the size of an array (in number of items)
724
750
*/
725
751
static intp
726
752
PyArray_Size(PyObject *op)
727
753
{
728
 
        if (PyArray_Check(op)) {
729
 
                return PyArray_SIZE((PyArrayObject *)op);
730
 
        }
731
 
        else {
732
 
                return 0;
733
 
        }
 
754
    if (PyArray_Check(op)) {
 
755
        return PyArray_SIZE((PyArrayObject *)op);
 
756
    }
 
757
    else {
 
758
        return 0;
 
759
    }
734
760
}
735
761
 
736
762
static int
737
763
_copy_from0d(PyArrayObject *dest, PyArrayObject *src, int usecopy, int swap)
738
764
{
739
 
        char *aligned=NULL;
740
 
        char *sptr;
741
 
        int numcopies, nbytes;
742
 
        void (*myfunc)(char *, intp, char *, intp, intp, int);
743
 
        int retval=-1;
744
 
 
745
 
        NPY_BEGIN_THREADS_DEF
746
 
 
747
 
        numcopies = PyArray_SIZE(dest);
748
 
        if (numcopies < 1) return 0;
749
 
        nbytes = PyArray_ITEMSIZE(src);
750
 
 
751
 
        if (!PyArray_ISALIGNED(src)) {
752
 
                aligned = malloc((size_t)nbytes);
753
 
                if (aligned == NULL) {
754
 
                        PyErr_NoMemory();
755
 
                        return -1;
756
 
                }
757
 
                memcpy(aligned, src->data, (size_t) nbytes);
758
 
                usecopy = 1;
759
 
                sptr = aligned;
760
 
        }
761
 
        else sptr = src->data;
762
 
        if (PyArray_ISALIGNED(dest)) {
763
 
                myfunc = _strided_byte_copy;
764
 
        }
765
 
        else if (usecopy) {
766
 
                myfunc = _unaligned_strided_byte_copy;
767
 
        }
768
 
        else {
769
 
                myfunc = _unaligned_strided_byte_move;
770
 
        }
771
 
 
772
 
        if ((dest->nd < 2) || PyArray_ISONESEGMENT(dest)) {
773
 
                char *dptr;
774
 
                intp dstride;
775
 
 
776
 
                dptr = dest->data;
777
 
                if (dest->nd == 1)
778
 
                        dstride = dest->strides[0];
779
 
                else
780
 
                        dstride = nbytes;
781
 
                PyArray_XDECREF(dest);
782
 
 
783
 
                NPY_BEGIN_THREADS
784
 
 
785
 
                myfunc(dptr, dstride, sptr, 0, numcopies, (int) nbytes);
786
 
                if (swap)
787
 
                        _strided_byte_swap(dptr, dstride, numcopies, (int) nbytes);
788
 
 
789
 
                NPY_END_THREADS
790
 
 
791
 
                PyArray_INCREF(dest);
792
 
        }
793
 
        else {
794
 
                PyArrayIterObject *dit;
795
 
                int axis=-1;
796
 
                dit = (PyArrayIterObject *)\
797
 
                        PyArray_IterAllButAxis((PyObject *)dest, &axis);
798
 
                if (dit == NULL) goto finish;
799
 
                PyArray_XDECREF(dest);
800
 
                NPY_BEGIN_THREADS
801
 
                while(dit->index < dit->size) {
802
 
                        myfunc(dit->dataptr, PyArray_STRIDE(dest, axis),
803
 
                               sptr, 0,
804
 
                               PyArray_DIM(dest, axis), nbytes);
805
 
                        if (swap)
806
 
                                _strided_byte_swap(dit->dataptr,
807
 
                                                   PyArray_STRIDE(dest, axis),
808
 
                                                   PyArray_DIM(dest, axis), nbytes);
809
 
                        PyArray_ITER_NEXT(dit);
810
 
                }
811
 
                NPY_END_THREADS
812
 
                PyArray_INCREF(dest);
813
 
                Py_DECREF(dit);
814
 
        }
815
 
        retval = 0;
816
 
 finish:
817
 
        if (aligned != NULL) free(aligned);
818
 
        return retval;
 
765
    char *aligned=NULL;
 
766
    char *sptr;
 
767
    int numcopies, nbytes;
 
768
    void (*myfunc)(char *, intp, char *, intp, intp, int);
 
769
    int retval=-1;
 
770
    NPY_BEGIN_THREADS_DEF;
 
771
 
 
772
    numcopies = PyArray_SIZE(dest);
 
773
    if (numcopies < 1) {
 
774
        return 0;
 
775
    }
 
776
    nbytes = PyArray_ITEMSIZE(src);
 
777
 
 
778
    if (!PyArray_ISALIGNED(src)) {
 
779
        aligned = malloc((size_t)nbytes);
 
780
        if (aligned == NULL) {
 
781
            PyErr_NoMemory();
 
782
            return -1;
 
783
        }
 
784
        memcpy(aligned, src->data, (size_t) nbytes);
 
785
        usecopy = 1;
 
786
        sptr = aligned;
 
787
    }
 
788
    else {
 
789
        sptr = src->data;
 
790
    }
 
791
    if (PyArray_SAFEALIGNEDCOPY(dest)) {
 
792
        myfunc = _strided_byte_copy;
 
793
    }
 
794
    else if (usecopy) {
 
795
        myfunc = _unaligned_strided_byte_copy;
 
796
    }
 
797
    else {
 
798
        myfunc = _unaligned_strided_byte_move;
 
799
    }
 
800
 
 
801
    if ((dest->nd < 2) || PyArray_ISONESEGMENT(dest)) {
 
802
        char *dptr;
 
803
        intp dstride;
 
804
 
 
805
        dptr = dest->data;
 
806
        if (dest->nd == 1)
 
807
            dstride = dest->strides[0];
 
808
        else
 
809
            dstride = nbytes;
 
810
 
 
811
        /* Refcount note: src and dest may have different sizes */
 
812
        PyArray_INCREF(src);
 
813
        PyArray_XDECREF(dest);
 
814
        NPY_BEGIN_THREADS;
 
815
        myfunc(dptr, dstride, sptr, 0, numcopies, (int) nbytes);
 
816
        if (swap) {
 
817
            _strided_byte_swap(dptr, dstride, numcopies, (int) nbytes);
 
818
        }
 
819
        NPY_END_THREADS;
 
820
        PyArray_INCREF(dest);
 
821
        PyArray_XDECREF(src);
 
822
    }
 
823
    else {
 
824
        PyArrayIterObject *dit;
 
825
        int axis=-1;
 
826
        dit = (PyArrayIterObject *)\
 
827
              PyArray_IterAllButAxis((PyObject *)dest, &axis);
 
828
        if (dit == NULL) {
 
829
            goto finish;
 
830
        }
 
831
        /* Refcount note: src and dest may have different sizes */
 
832
        PyArray_INCREF(src);
 
833
        PyArray_XDECREF(dest);
 
834
        NPY_BEGIN_THREADS;
 
835
        while(dit->index < dit->size) {
 
836
            myfunc(dit->dataptr, PyArray_STRIDE(dest, axis),
 
837
                    sptr, 0,
 
838
                    PyArray_DIM(dest, axis), nbytes);
 
839
            if (swap) {
 
840
                _strided_byte_swap(dit->dataptr,
 
841
                        PyArray_STRIDE(dest, axis),
 
842
                        PyArray_DIM(dest, axis), nbytes);
 
843
            }
 
844
            PyArray_ITER_NEXT(dit);
 
845
        }
 
846
        NPY_END_THREADS;
 
847
        PyArray_INCREF(dest);
 
848
        PyArray_XDECREF(src);
 
849
        Py_DECREF(dit);
 
850
    }
 
851
    retval = 0;
 
852
 
 
853
finish:
 
854
    if (aligned != NULL) {
 
855
        free(aligned);
 
856
    }
 
857
    return retval;
819
858
}
820
859
 
821
 
/* Special-case of PyArray_CopyInto when dst is 1-d
822
 
   and contiguous (and aligned).
823
 
   PyArray_CopyInto requires broadcastable arrays while
824
 
   this one is a flattening operation...
 
860
/*
 
861
 * Special-case of PyArray_CopyInto when dst is 1-d
 
862
 * and contiguous (and aligned).
 
863
 * PyArray_CopyInto requires broadcastable arrays while
 
864
 * this one is a flattening operation...
825
865
 */
826
 
int _flat_copyinto(PyObject *dst, PyObject *src, NPY_ORDER order) {
827
 
        PyArrayIterObject *it;
828
 
        void (*myfunc)(char *, intp, char *, intp, intp, int);
829
 
        char *dptr;
830
 
        int axis;
831
 
        int elsize;
832
 
        intp nbytes;
833
 
        NPY_BEGIN_THREADS_DEF
834
 
 
835
 
 
836
 
        if (PyArray_NDIM(src) == 0) {
837
 
                PyArray_XDECREF((PyArrayObject *)dst);
838
 
                NPY_BEGIN_THREADS
839
 
                memcpy(PyArray_BYTES(dst), PyArray_BYTES(src),
840
 
                       PyArray_ITEMSIZE(src));
841
 
                NPY_END_THREADS
842
 
                PyArray_INCREF((PyArrayObject *)dst);
843
 
                return 0;
844
 
        }
845
 
 
846
 
        if (order == PyArray_FORTRANORDER) {
847
 
                axis = 0;
848
 
        }
849
 
        else {
850
 
                axis = PyArray_NDIM(src)-1;
851
 
        }
852
 
 
853
 
        it = (PyArrayIterObject *)PyArray_IterAllButAxis(src, &axis);
854
 
        if (it == NULL) return -1;
855
 
 
856
 
        if (PyArray_ISALIGNED(src)) {
857
 
                myfunc = _strided_byte_copy;
858
 
        }
859
 
        else {
860
 
                myfunc = _unaligned_strided_byte_copy;
861
 
        }
862
 
 
863
 
        dptr = PyArray_BYTES(dst);
864
 
        elsize = PyArray_ITEMSIZE(dst);
865
 
        nbytes = elsize * PyArray_DIM(src, axis);
 
866
int
 
867
_flat_copyinto(PyObject *dst, PyObject *src, NPY_ORDER order)
 
868
{
 
869
    PyArrayIterObject *it;
 
870
    PyObject *orig_src;
 
871
    void (*myfunc)(char *, intp, char *, intp, intp, int);
 
872
    char *dptr;
 
873
    int axis;
 
874
    int elsize;
 
875
    intp nbytes;
 
876
    NPY_BEGIN_THREADS_DEF;
 
877
 
 
878
 
 
879
    orig_src = src;
 
880
    if (PyArray_NDIM(src) == 0) {
 
881
        /* Refcount note: src and dst have the same size */
 
882
        PyArray_INCREF((PyArrayObject *)src);
866
883
        PyArray_XDECREF((PyArrayObject *)dst);
867
 
        NPY_BEGIN_THREADS
868
 
        while(it->index < it->size) {
869
 
                myfunc(dptr, elsize, it->dataptr,
870
 
                       PyArray_STRIDE(src,axis),
871
 
                       PyArray_DIM(src,axis), elsize);
872
 
                dptr += nbytes;
873
 
                PyArray_ITER_NEXT(it);
874
 
        }
875
 
        NPY_END_THREADS
876
 
        PyArray_INCREF((PyArrayObject *)dst);
877
 
 
878
 
        Py_DECREF(it);
 
884
        NPY_BEGIN_THREADS;
 
885
        memcpy(PyArray_BYTES(dst), PyArray_BYTES(src),
 
886
                PyArray_ITEMSIZE(src));
 
887
        NPY_END_THREADS;
879
888
        return 0;
 
889
    }
 
890
 
 
891
    axis = PyArray_NDIM(src)-1;
 
892
 
 
893
    if (order == PyArray_FORTRANORDER) {
 
894
        if (PyArray_NDIM(src) <= 2) {
 
895
            axis = 0;
 
896
        }
 
897
        /* fall back to a more general method */
 
898
        else {
 
899
            src = PyArray_Transpose((PyArrayObject *)orig_src, NULL);
 
900
        }
 
901
    }
 
902
 
 
903
    it = (PyArrayIterObject *)PyArray_IterAllButAxis(src, &axis);
 
904
    if (it == NULL) {
 
905
        if (src != orig_src) {
 
906
            Py_DECREF(src);
 
907
        }
 
908
        return -1;
 
909
    }
 
910
 
 
911
    if (PyArray_SAFEALIGNEDCOPY(src)) {
 
912
        myfunc = _strided_byte_copy;
 
913
    }
 
914
    else {
 
915
        myfunc = _unaligned_strided_byte_copy;
 
916
    }
 
917
 
 
918
    dptr = PyArray_BYTES(dst);
 
919
    elsize = PyArray_ITEMSIZE(dst);
 
920
    nbytes = elsize * PyArray_DIM(src, axis);
 
921
 
 
922
    /* Refcount note: src and dst have the same size */
 
923
    PyArray_INCREF((PyArrayObject *)src);
 
924
    PyArray_XDECREF((PyArrayObject *)dst);
 
925
    NPY_BEGIN_THREADS;
 
926
    while(it->index < it->size) {
 
927
        myfunc(dptr, elsize, it->dataptr,
 
928
                PyArray_STRIDE(src,axis),
 
929
                PyArray_DIM(src,axis), elsize);
 
930
        dptr += nbytes;
 
931
        PyArray_ITER_NEXT(it);
 
932
    }
 
933
    NPY_END_THREADS;
 
934
 
 
935
    if (src != orig_src) {
 
936
        Py_DECREF(src);
 
937
    }
 
938
    Py_DECREF(it);
 
939
    return 0;
880
940
}
881
941
 
882
942
 
885
945
                      void (*myfunc)(char *, intp, char *, intp, intp, int),
886
946
                      int swap)
887
947
{
888
 
        int maxaxis=-1, elsize;
889
 
        intp maxdim;
890
 
        PyArrayIterObject *dit, *sit;
891
 
        NPY_BEGIN_THREADS_DEF
892
 
 
893
 
        dit = (PyArrayIterObject *)                                     \
894
 
                PyArray_IterAllButAxis((PyObject *)dest, &maxaxis);
895
 
        sit = (PyArrayIterObject *)                                     \
896
 
                PyArray_IterAllButAxis((PyObject *)src, &maxaxis);
897
 
 
898
 
        maxdim = dest->dimensions[maxaxis];
899
 
 
900
 
        if ((dit == NULL) || (sit == NULL)) {
901
 
                Py_XDECREF(dit);
902
 
                Py_XDECREF(sit);
903
 
                return -1;
904
 
        }
905
 
        elsize = PyArray_ITEMSIZE(dest);
906
 
 
907
 
        PyArray_XDECREF(dest);
908
 
 
909
 
        NPY_BEGIN_THREADS
910
 
        while(dit->index < dit->size) {
911
 
                /* strided copy of elsize bytes */
912
 
                myfunc(dit->dataptr, dest->strides[maxaxis],
913
 
                       sit->dataptr, src->strides[maxaxis],
914
 
                       maxdim, elsize);
915
 
                if (swap) {
916
 
                        _strided_byte_swap(dit->dataptr,
917
 
                                           dest->strides[maxaxis],
918
 
                                           dest->dimensions[maxaxis],
919
 
                                           elsize);
920
 
                }
921
 
                PyArray_ITER_NEXT(dit);
922
 
                PyArray_ITER_NEXT(sit);
923
 
        }
924
 
        NPY_END_THREADS
925
 
 
926
 
        Py_DECREF(sit);
927
 
        Py_DECREF(dit);
928
 
        PyArray_INCREF(dest);
929
 
        return 0;
 
948
    int maxaxis=-1, elsize;
 
949
    intp maxdim;
 
950
    PyArrayIterObject *dit, *sit;
 
951
    NPY_BEGIN_THREADS_DEF;
 
952
 
 
953
    dit = (PyArrayIterObject *)
 
954
        PyArray_IterAllButAxis((PyObject *)dest, &maxaxis);
 
955
    sit = (PyArrayIterObject *)
 
956
        PyArray_IterAllButAxis((PyObject *)src, &maxaxis);
 
957
 
 
958
    maxdim = dest->dimensions[maxaxis];
 
959
 
 
960
    if ((dit == NULL) || (sit == NULL)) {
 
961
        Py_XDECREF(dit);
 
962
        Py_XDECREF(sit);
 
963
        return -1;
 
964
    }
 
965
    elsize = PyArray_ITEMSIZE(dest);
 
966
 
 
967
    /* Refcount note: src and dst have the same size */
 
968
    PyArray_INCREF(src);
 
969
    PyArray_XDECREF(dest);
 
970
 
 
971
    NPY_BEGIN_THREADS;
 
972
    while(dit->index < dit->size) {
 
973
        /* strided copy of elsize bytes */
 
974
        myfunc(dit->dataptr, dest->strides[maxaxis],
 
975
                sit->dataptr, src->strides[maxaxis],
 
976
                maxdim, elsize);
 
977
        if (swap) {
 
978
            _strided_byte_swap(dit->dataptr,
 
979
                    dest->strides[maxaxis],
 
980
                    dest->dimensions[maxaxis],
 
981
                    elsize);
 
982
        }
 
983
        PyArray_ITER_NEXT(dit);
 
984
        PyArray_ITER_NEXT(sit);
 
985
    }
 
986
    NPY_END_THREADS;
 
987
 
 
988
    Py_DECREF(sit);
 
989
    Py_DECREF(dit);
 
990
    return 0;
930
991
}
931
992
 
932
993
static int
934
995
                void (*myfunc)(char *, intp, char *, intp, intp, int),
935
996
                int swap)
936
997
{
937
 
        int elsize;
938
 
        PyArrayMultiIterObject *multi;
939
 
        int maxaxis; intp maxdim;
940
 
        NPY_BEGIN_THREADS_DEF
941
 
 
942
 
        elsize = PyArray_ITEMSIZE(dest);
943
 
        multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, dest, src);
944
 
        if (multi == NULL) return -1;
945
 
 
946
 
        if (multi->size != PyArray_SIZE(dest)) {
947
 
                PyErr_SetString(PyExc_ValueError,
948
 
                                "array dimensions are not "\
949
 
                                "compatible for copy");
950
 
                Py_DECREF(multi);
951
 
                return -1;
952
 
        }
953
 
 
954
 
        maxaxis = PyArray_RemoveSmallest(multi);
955
 
        if (maxaxis < 0) { /* copy 1 0-d array to another */
956
 
                PyArray_XDECREF(dest);
957
 
                memcpy(dest->data, src->data, elsize);
958
 
                if (swap) byte_swap_vector(dest->data, 1, elsize);
959
 
                PyArray_INCREF(dest);
960
 
                return 0;
961
 
        }
962
 
        maxdim = multi->dimensions[maxaxis];
963
 
 
 
998
    int elsize;
 
999
    PyArrayMultiIterObject *multi;
 
1000
    int maxaxis; intp maxdim;
 
1001
    NPY_BEGIN_THREADS_DEF;
 
1002
 
 
1003
    elsize = PyArray_ITEMSIZE(dest);
 
1004
    multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, dest, src);
 
1005
    if (multi == NULL) {
 
1006
        return -1;
 
1007
    }
 
1008
 
 
1009
    if (multi->size != PyArray_SIZE(dest)) {
 
1010
        PyErr_SetString(PyExc_ValueError,
 
1011
                "array dimensions are not "\
 
1012
                "compatible for copy");
 
1013
        Py_DECREF(multi);
 
1014
        return -1;
 
1015
    }
 
1016
 
 
1017
    maxaxis = PyArray_RemoveSmallest(multi);
 
1018
    if (maxaxis < 0) {
 
1019
        /*
 
1020
         * copy 1 0-d array to another
 
1021
         * Refcount note: src and dst have the same size
 
1022
         */
 
1023
        PyArray_INCREF(src);
964
1024
        PyArray_XDECREF(dest);
965
 
 
966
 
        NPY_BEGIN_THREADS
967
 
        while(multi->index < multi->size) {
968
 
                myfunc(multi->iters[0]->dataptr,
969
 
                       multi->iters[0]->strides[maxaxis],
970
 
                       multi->iters[1]->dataptr,
971
 
                       multi->iters[1]->strides[maxaxis],
972
 
                       maxdim, elsize);
973
 
                if (swap) {
974
 
                        _strided_byte_swap(multi->iters[0]->dataptr,
975
 
                                           multi->iters[0]->strides[maxaxis],
976
 
                                           maxdim, elsize);
977
 
                }
978
 
                PyArray_MultiIter_NEXT(multi);
 
1025
        memcpy(dest->data, src->data, elsize);
 
1026
        if (swap) {
 
1027
            byte_swap_vector(dest->data, 1, elsize);
979
1028
        }
980
 
        NPY_END_THREADS
981
 
 
982
 
        Py_DECREF(multi);
983
 
        PyArray_INCREF(dest);
984
1029
        return 0;
 
1030
    }
 
1031
    maxdim = multi->dimensions[maxaxis];
 
1032
 
 
1033
    /*
 
1034
     * Increment the source and decrement the destination
 
1035
     * reference counts
 
1036
     *
 
1037
     * Refcount note: src and dest may have different sizes
 
1038
     */
 
1039
    PyArray_INCREF(src);
 
1040
    PyArray_XDECREF(dest);
 
1041
 
 
1042
    NPY_BEGIN_THREADS;
 
1043
    while(multi->index < multi->size) {
 
1044
        myfunc(multi->iters[0]->dataptr,
 
1045
                multi->iters[0]->strides[maxaxis],
 
1046
                multi->iters[1]->dataptr,
 
1047
                multi->iters[1]->strides[maxaxis],
 
1048
                maxdim, elsize);
 
1049
        if (swap) {
 
1050
            _strided_byte_swap(multi->iters[0]->dataptr,
 
1051
                    multi->iters[0]->strides[maxaxis],
 
1052
                    maxdim, elsize);
 
1053
        }
 
1054
        PyArray_MultiIter_NEXT(multi);
 
1055
    }
 
1056
    NPY_END_THREADS;
 
1057
 
 
1058
    PyArray_INCREF(dest);
 
1059
    PyArray_XDECREF(src);
 
1060
 
 
1061
    Py_DECREF(multi);
 
1062
    return 0;
985
1063
}
986
1064
 
987
1065
/* If destination is not the right type, then src
998
1076
static int
999
1077
_array_copy_into(PyArrayObject *dest, PyArrayObject *src, int usecopy)
1000
1078
{
 
1079
    int swap;
 
1080
    void (*myfunc)(char *, intp, char *, intp, intp, int);
 
1081
    int simple;
 
1082
    int same;
 
1083
    NPY_BEGIN_THREADS_DEF;
 
1084
 
 
1085
 
 
1086
    if (!PyArray_EquivArrTypes(dest, src)) {
 
1087
        return PyArray_CastTo(dest, src);
 
1088
    }
 
1089
    if (!PyArray_ISWRITEABLE(dest)) {
 
1090
        PyErr_SetString(PyExc_RuntimeError,
 
1091
                "cannot write to array");
 
1092
        return -1;
 
1093
    }
 
1094
    same = PyArray_SAMESHAPE(dest, src);
 
1095
    simple = same && ((PyArray_ISCARRAY_RO(src) && PyArray_ISCARRAY(dest)) ||
 
1096
            (PyArray_ISFARRAY_RO(src) && PyArray_ISFARRAY(dest)));
 
1097
 
 
1098
    if (simple) {
 
1099
        /* Refcount note: src and dest have the same size */
 
1100
        PyArray_INCREF(src);
 
1101
        PyArray_XDECREF(dest);
 
1102
        NPY_BEGIN_THREADS;
 
1103
        if (usecopy) {
 
1104
            memcpy(dest->data, src->data, PyArray_NBYTES(dest));
 
1105
        }
 
1106
        else {
 
1107
            memmove(dest->data, src->data, PyArray_NBYTES(dest));
 
1108
        }
 
1109
        NPY_END_THREADS;
 
1110
        return 0;
 
1111
    }
 
1112
 
 
1113
    swap = PyArray_ISNOTSWAPPED(dest) != PyArray_ISNOTSWAPPED(src);
 
1114
 
 
1115
    if (src->nd == 0) {
 
1116
        return _copy_from0d(dest, src, usecopy, swap);
 
1117
    }
 
1118
 
 
1119
    if (PyArray_SAFEALIGNEDCOPY(dest) && PyArray_SAFEALIGNEDCOPY(src)) {
 
1120
        myfunc = _strided_byte_copy;
 
1121
    }
 
1122
    else if (usecopy) {
 
1123
        myfunc = _unaligned_strided_byte_copy;
 
1124
    }
 
1125
    else {
 
1126
        myfunc = _unaligned_strided_byte_move;
 
1127
    }
 
1128
    /*
 
1129
     * Could combine these because _broadcasted_copy would work as well.
 
1130
     * But, same-shape copying is so common we want to speed it up.
 
1131
     */
 
1132
    if (same) {
 
1133
        return _copy_from_same_shape(dest, src, myfunc, swap);
 
1134
    }
 
1135
    else {
 
1136
        return _broadcast_copy(dest, src, myfunc, swap);
 
1137
    }
 
1138
}
 
1139
 
 
1140
/*OBJECT_API
 
1141
 * Copy an Array into another array -- memory must not overlap
 
1142
 * Does not require src and dest to have "broadcastable" shapes
 
1143
 * (only the same number of elements).
 
1144
 */
 
1145
static int
 
1146
PyArray_CopyAnyInto(PyArrayObject *dest, PyArrayObject *src)
 
1147
{
 
1148
    int elsize, simple;
 
1149
    PyArrayIterObject *idest, *isrc;
 
1150
    void (*myfunc)(char *, intp, char *, intp, intp, int);
 
1151
    NPY_BEGIN_THREADS_DEF;
 
1152
 
 
1153
    if (!PyArray_EquivArrTypes(dest, src)) {
 
1154
        return PyArray_CastAnyTo(dest, src);
 
1155
    }
 
1156
    if (!PyArray_ISWRITEABLE(dest)) {
 
1157
        PyErr_SetString(PyExc_RuntimeError,
 
1158
                "cannot write to array");
 
1159
        return -1;
 
1160
    }
 
1161
    if (PyArray_SIZE(dest) != PyArray_SIZE(src)) {
 
1162
        PyErr_SetString(PyExc_ValueError,
 
1163
                "arrays must have the same number of elements"
 
1164
                " for copy");
 
1165
        return -1;
 
1166
    }
 
1167
 
 
1168
    simple = ((PyArray_ISCARRAY_RO(src) && PyArray_ISCARRAY(dest)) ||
 
1169
            (PyArray_ISFARRAY_RO(src) && PyArray_ISFARRAY(dest)));
 
1170
    if (simple) {
 
1171
        /* Refcount note: src and dest have the same size */
 
1172
        PyArray_INCREF(src);
 
1173
        PyArray_XDECREF(dest);
 
1174
        NPY_BEGIN_THREADS;
 
1175
        memcpy(dest->data, src->data, PyArray_NBYTES(dest));
 
1176
        NPY_END_THREADS;
 
1177
        return 0;
 
1178
    }
 
1179
 
 
1180
    if (PyArray_SAMESHAPE(dest, src)) {
1001
1181
        int swap;
1002
 
        void (*myfunc)(char *, intp, char *, intp, intp, int);
1003
 
        int simple;
1004
 
        int same;
1005
 
        NPY_BEGIN_THREADS_DEF
1006
 
 
1007
 
 
1008
 
        if (!PyArray_EquivArrTypes(dest, src)) {
1009
 
                return PyArray_CastTo(dest, src);
1010
 
        }
1011
 
 
1012
 
        if (!PyArray_ISWRITEABLE(dest)) {
1013
 
                PyErr_SetString(PyExc_RuntimeError,
1014
 
                                "cannot write to array");
1015
 
                return -1;
1016
 
        }
1017
 
 
1018
 
        same = PyArray_SAMESHAPE(dest, src);
1019
 
        simple = same && ((PyArray_ISCARRAY_RO(src) && PyArray_ISCARRAY(dest)) ||
1020
 
                          (PyArray_ISFARRAY_RO(src) && PyArray_ISFARRAY(dest)));
1021
 
 
1022
 
        if (simple) {
1023
 
                PyArray_XDECREF(dest);
1024
 
                NPY_BEGIN_THREADS
1025
 
                if (usecopy)
1026
 
                        memcpy(dest->data, src->data, PyArray_NBYTES(dest));
1027
 
                else
1028
 
                        memmove(dest->data, src->data, PyArray_NBYTES(dest));
1029
 
                NPY_END_THREADS
1030
 
                PyArray_INCREF(dest);
1031
 
                return 0;
1032
 
        }
1033
 
 
 
1182
 
 
1183
        if (PyArray_SAFEALIGNEDCOPY(dest) && PyArray_SAFEALIGNEDCOPY(src)) {
 
1184
            myfunc = _strided_byte_copy;
 
1185
        }
 
1186
        else {
 
1187
            myfunc = _unaligned_strided_byte_copy;
 
1188
        }
1034
1189
        swap = PyArray_ISNOTSWAPPED(dest) != PyArray_ISNOTSWAPPED(src);
1035
 
 
1036
 
        if (src->nd == 0) {
1037
 
                return _copy_from0d(dest, src, usecopy, swap);
1038
 
        }
1039
 
 
1040
 
        if (PyArray_ISALIGNED(dest) && PyArray_ISALIGNED(src)) {
1041
 
                myfunc = _strided_byte_copy;
1042
 
        }
1043
 
        else if (usecopy) {
1044
 
                myfunc = _unaligned_strided_byte_copy;
1045
 
        }
1046
 
        else {
1047
 
                myfunc = _unaligned_strided_byte_move;
1048
 
        }
1049
 
 
1050
 
        /* Could combine these because _broadcasted_copy would work as well.
1051
 
           But, same-shape copying is so common we want to speed it up.
1052
 
        */
1053
 
        if (same) {
1054
 
                return _copy_from_same_shape(dest, src, myfunc, swap);
1055
 
        }
1056
 
        else {
1057
 
                return _broadcast_copy(dest, src, myfunc, swap);
1058
 
        }
1059
 
}
1060
 
 
1061
 
/*OBJECT_API
1062
 
 Copy an Array into another array -- memory must not overlap
1063
 
 Does not require src and dest to have "broadcastable" shapes
1064
 
 (only the same number of elements).
1065
 
*/
1066
 
static int
1067
 
PyArray_CopyAnyInto(PyArrayObject *dest, PyArrayObject *src)
1068
 
{
1069
 
        int elsize, simple;
1070
 
        PyArrayIterObject *idest, *isrc;
1071
 
        void (*myfunc)(char *, intp, char *, intp, intp, int);
1072
 
        NPY_BEGIN_THREADS_DEF
1073
 
 
1074
 
        if (!PyArray_EquivArrTypes(dest, src)) {
1075
 
                return PyArray_CastAnyTo(dest, src);
1076
 
        }
1077
 
 
1078
 
        if (!PyArray_ISWRITEABLE(dest)) {
1079
 
                PyErr_SetString(PyExc_RuntimeError,
1080
 
                                "cannot write to array");
1081
 
                return -1;
1082
 
        }
1083
 
 
1084
 
        if (PyArray_SIZE(dest) != PyArray_SIZE(src)) {
1085
 
                PyErr_SetString(PyExc_ValueError,
1086
 
                                "arrays must have the same number of elements"
1087
 
                                " for copy");
1088
 
                return -1;
1089
 
        }
1090
 
 
1091
 
        simple = ((PyArray_ISCARRAY_RO(src) && PyArray_ISCARRAY(dest)) ||
1092
 
                  (PyArray_ISFARRAY_RO(src) && PyArray_ISFARRAY(dest)));
1093
 
 
1094
 
        if (simple) {
1095
 
                PyArray_XDECREF(dest);
1096
 
                NPY_BEGIN_THREADS
1097
 
                memcpy(dest->data, src->data, PyArray_NBYTES(dest));
1098
 
                NPY_END_THREADS
1099
 
                PyArray_INCREF(dest);
1100
 
                return 0;
1101
 
        }
1102
 
 
1103
 
        if (PyArray_SAMESHAPE(dest, src)) {
1104
 
                int swap;
1105
 
                if (PyArray_ISALIGNED(dest) && PyArray_ISALIGNED(src)) {
1106
 
                        myfunc = _strided_byte_copy;
1107
 
                }
1108
 
                else {
1109
 
                        myfunc = _unaligned_strided_byte_copy;
1110
 
                }
1111
 
                swap = PyArray_ISNOTSWAPPED(dest) != PyArray_ISNOTSWAPPED(src);
1112
 
                return _copy_from_same_shape(dest, src, myfunc, swap);
1113
 
        }
1114
 
 
1115
 
        /* Otherwise we have to do an iterator-based copy */
1116
 
        idest = (PyArrayIterObject *)PyArray_IterNew((PyObject *)dest);
1117
 
        if (idest == NULL) return -1;
1118
 
        isrc = (PyArrayIterObject *)PyArray_IterNew((PyObject *)src);
1119
 
        if (isrc == NULL) {Py_DECREF(idest); return -1;}
1120
 
        elsize = dest->descr->elsize;
1121
 
        PyArray_XDECREF(dest);
1122
 
        NPY_BEGIN_THREADS
1123
 
        while(idest->index < idest->size) {
1124
 
                memcpy(idest->dataptr, isrc->dataptr, elsize);
1125
 
                PyArray_ITER_NEXT(idest);
1126
 
                PyArray_ITER_NEXT(isrc);
1127
 
        }
1128
 
        NPY_END_THREADS
1129
 
        PyArray_INCREF(dest);
 
1190
        return _copy_from_same_shape(dest, src, myfunc, swap);
 
1191
    }
 
1192
 
 
1193
    /* Otherwise we have to do an iterator-based copy */
 
1194
    idest = (PyArrayIterObject *)PyArray_IterNew((PyObject *)dest);
 
1195
    if (idest == NULL) {
 
1196
        return -1;
 
1197
    }
 
1198
    isrc = (PyArrayIterObject *)PyArray_IterNew((PyObject *)src);
 
1199
    if (isrc == NULL) {
1130
1200
        Py_DECREF(idest);
1131
 
        Py_DECREF(isrc);
1132
 
        return 0;
 
1201
        return -1;
 
1202
    }
 
1203
    elsize = dest->descr->elsize;
 
1204
    /* Refcount note: src and dest have the same size */
 
1205
    PyArray_INCREF(src);
 
1206
    PyArray_XDECREF(dest);
 
1207
    NPY_BEGIN_THREADS;
 
1208
    while(idest->index < idest->size) {
 
1209
        memcpy(idest->dataptr, isrc->dataptr, elsize);
 
1210
        PyArray_ITER_NEXT(idest);
 
1211
        PyArray_ITER_NEXT(isrc);
 
1212
    }
 
1213
    NPY_END_THREADS;
 
1214
    Py_DECREF(idest);
 
1215
    Py_DECREF(isrc);
 
1216
    return 0;
1133
1217
}
1134
1218
 
1135
1219
/*OBJECT_API
1136
 
 Copy an Array into another array -- memory must not overlap.
1137
 
*/
 
1220
 * Copy an Array into another array -- memory must not overlap.
 
1221
 */
1138
1222
static int
1139
1223
PyArray_CopyInto(PyArrayObject *dest, PyArrayObject *src)
1140
1224
{
1141
 
        return _array_copy_into(dest, src, 1);
 
1225
    return _array_copy_into(dest, src, 1);
1142
1226
}
1143
1227
 
1144
1228
 
1145
1229
/*OBJECT_API
1146
 
 Move the memory of one array into another.
1147
 
*/
 
1230
 * Move the memory of one array into another.
 
1231
 */
1148
1232
static int
1149
1233
PyArray_MoveInto(PyArrayObject *dest, PyArrayObject *src)
1150
1234
{
1151
 
        return _array_copy_into(dest, src, 0);
 
1235
    return _array_copy_into(dest, src, 0);
1152
1236
}
1153
1237
 
1154
1238
 
1156
1240
static int
1157
1241
PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object)
1158
1242
{
1159
 
        PyArrayObject *src;
1160
 
        PyObject *r;
1161
 
        int ret;
1162
 
 
1163
 
        /* Special code to mimic Numeric behavior for
1164
 
           character arrays.
1165
 
        */
1166
 
        if (dest->descr->type == PyArray_CHARLTR && dest->nd > 0 \
1167
 
            && PyString_Check(src_object)) {
1168
 
                int n_new, n_old;
1169
 
                char *new_string;
1170
 
                PyObject *tmp;
1171
 
                n_new = dest->dimensions[dest->nd-1];
1172
 
                n_old = PyString_Size(src_object);
1173
 
                if (n_new > n_old) {
1174
 
                        new_string = (char *)malloc(n_new);
1175
 
                        memmove(new_string,
1176
 
                                PyString_AS_STRING(src_object),
1177
 
                                n_old);
1178
 
                        memset(new_string+n_old, ' ', n_new-n_old);
1179
 
                        tmp = PyString_FromStringAndSize(new_string, n_new);
1180
 
                        free(new_string);
1181
 
                        src_object = tmp;
1182
 
                }
1183
 
        }
1184
 
 
1185
 
        if (PyArray_Check(src_object)) {
1186
 
                src = (PyArrayObject *)src_object;
1187
 
                Py_INCREF(src);
1188
 
        }
1189
 
        else if (!PyArray_IsScalar(src_object, Generic) && 
1190
 
                 PyArray_HasArrayInterface(src_object, r)) {
1191
 
                src = (PyArrayObject *)r;
1192
 
        }
1193
 
        else {
1194
 
                PyArray_Descr* dtype;
1195
 
                dtype = dest->descr;
1196
 
                Py_INCREF(dtype);
1197
 
                src = (PyArrayObject *)PyArray_FromAny(src_object, dtype, 0,
1198
 
                                                       dest->nd,
1199
 
                                                       FORTRAN_IF(dest), 
1200
 
                                                       NULL);
1201
 
        }
1202
 
        if (src == NULL) return -1;
1203
 
        
1204
 
        ret = PyArray_MoveInto(dest, src);
1205
 
        Py_DECREF(src);
1206
 
        return ret;
 
1243
    PyArrayObject *src;
 
1244
    PyObject *r;
 
1245
    int ret;
 
1246
 
 
1247
    /*
 
1248
     * Special code to mimic Numeric behavior for
 
1249
     * character arrays.
 
1250
     */
 
1251
    if (dest->descr->type == PyArray_CHARLTR && dest->nd > 0 \
 
1252
        && PyString_Check(src_object)) {
 
1253
        int n_new, n_old;
 
1254
        char *new_string;
 
1255
        PyObject *tmp;
 
1256
 
 
1257
        n_new = dest->dimensions[dest->nd-1];
 
1258
        n_old = PyString_Size(src_object);
 
1259
        if (n_new > n_old) {
 
1260
            new_string = (char *)malloc(n_new);
 
1261
            memmove(new_string,
 
1262
                    PyString_AS_STRING(src_object),
 
1263
                    n_old);
 
1264
            memset(new_string+n_old, ' ', n_new-n_old);
 
1265
            tmp = PyString_FromStringAndSize(new_string, n_new);
 
1266
            free(new_string);
 
1267
            src_object = tmp;
 
1268
        }
 
1269
    }
 
1270
 
 
1271
    if (PyArray_Check(src_object)) {
 
1272
        src = (PyArrayObject *)src_object;
 
1273
        Py_INCREF(src);
 
1274
    }
 
1275
    else if (!PyArray_IsScalar(src_object, Generic) &&
 
1276
             PyArray_HasArrayInterface(src_object, r)) {
 
1277
        src = (PyArrayObject *)r;
 
1278
    }
 
1279
    else {
 
1280
        PyArray_Descr* dtype;
 
1281
        dtype = dest->descr;
 
1282
        Py_INCREF(dtype);
 
1283
        src = (PyArrayObject *)PyArray_FromAny(src_object, dtype, 0,
 
1284
                                               dest->nd,
 
1285
                                               FORTRAN_IF(dest),
 
1286
                                               NULL);
 
1287
    }
 
1288
    if (src == NULL) {
 
1289
        return -1;
 
1290
    }
 
1291
 
 
1292
    ret = PyArray_MoveInto(dest, src);
 
1293
    Py_DECREF(src);
 
1294
    return ret;
1207
1295
}
1208
1296
 
1209
1297
 
1213
1301
 
1214
1302
/* steals reference to descr -- and enforces native byteorder on it.*/
1215
1303
/*OBJECT_API
1216
 
 Like FromDimsAndData but uses the Descr structure instead of typecode
1217
 
 as input.
 
1304
  Like FromDimsAndData but uses the Descr structure instead of typecode
 
1305
  as input.
1218
1306
*/
1219
1307
static PyObject *
1220
1308
PyArray_FromDimsAndDataAndDescr(int nd, int *d,
1221
1309
                                PyArray_Descr *descr,
1222
1310
                                char *data)
1223
1311
{
1224
 
        PyObject *ret;
 
1312
    PyObject *ret;
1225
1313
#if SIZEOF_INTP != SIZEOF_INT
1226
 
        int i;
1227
 
        intp newd[MAX_DIMS];
 
1314
    int i;
 
1315
    intp newd[MAX_DIMS];
1228
1316
#endif
1229
1317
 
1230
 
        if (!PyArray_ISNBO(descr->byteorder))
1231
 
                descr->byteorder = '=';
 
1318
    if (!PyArray_ISNBO(descr->byteorder))
 
1319
        descr->byteorder = '=';
1232
1320
 
1233
1321
#if SIZEOF_INTP != SIZEOF_INT
1234
 
        for (i=0; i<nd; i++) newd[i] = (intp) d[i];
1235
 
        ret = PyArray_NewFromDescr(&PyArray_Type, descr,
1236
 
                                   nd, newd,
1237
 
                                   NULL, data,
1238
 
                                   (data ? CARRAY : 0), NULL);
 
1322
    for(i=0; i<nd; i++) newd[i] = (intp) d[i];
 
1323
    ret = PyArray_NewFromDescr(&PyArray_Type, descr,
 
1324
                               nd, newd,
 
1325
                               NULL, data,
 
1326
                               (data ? CARRAY : 0), NULL);
1239
1327
#else
1240
 
        ret = PyArray_NewFromDescr(&PyArray_Type, descr,
1241
 
                                   nd, (intp *)d,
1242
 
                                   NULL, data,
1243
 
                                   (data ? CARRAY : 0), NULL);
 
1328
    ret = PyArray_NewFromDescr(&PyArray_Type, descr,
 
1329
                               nd, (intp *)d,
 
1330
                               NULL, data,
 
1331
                               (data ? CARRAY : 0), NULL);
1244
1332
#endif
1245
 
        return ret;
 
1333
    return ret;
1246
1334
}
1247
1335
 
1248
1336
/*OBJECT_API
1249
 
 Construct an empty array from dimensions and typenum
 
1337
  Construct an empty array from dimensions and typenum
1250
1338
*/
1251
1339
static PyObject *
1252
1340
PyArray_FromDims(int nd, int *d, int type)
1253
1341
{
1254
 
        PyObject *ret;
1255
 
        ret = PyArray_FromDimsAndDataAndDescr(nd, d,
1256
 
                                              PyArray_DescrFromType(type),
1257
 
                                              NULL);
1258
 
        /* Old FromDims set memory to zero --- some algorithms
1259
 
           relied on that.  Better keep it the same. If
1260
 
           Object type, then it's already been set to zero, though.
1261
 
        */
1262
 
        if (ret && (PyArray_DESCR(ret)->type_num != PyArray_OBJECT)) {
1263
 
                memset(PyArray_DATA(ret), 0, PyArray_NBYTES(ret));
1264
 
        }
1265
 
        return ret;
 
1342
    PyObject *ret;
 
1343
    ret = PyArray_FromDimsAndDataAndDescr(nd, d,
 
1344
                                          PyArray_DescrFromType(type),
 
1345
                                          NULL);
 
1346
    /* Old FromDims set memory to zero --- some algorithms
 
1347
       relied on that.  Better keep it the same. If
 
1348
       Object type, then it's already been set to zero, though.
 
1349
    */
 
1350
    if (ret && (PyArray_DESCR(ret)->type_num != PyArray_OBJECT)) {
 
1351
        memset(PyArray_DATA(ret), 0, PyArray_NBYTES(ret));
 
1352
    }
 
1353
    return ret;
1266
1354
}
1267
1355
 
1268
1356
/* end old calls */
1269
1357
 
1270
1358
 
1271
1359
/*OBJECT_API
1272
 
 Copy an array.
 
1360
  Copy an array.
1273
1361
*/
1274
1362
static PyObject *
1275
1363
PyArray_NewCopy(PyArrayObject *m1, NPY_ORDER fortran)
1276
1364
{
1277
 
        PyArrayObject *ret;
1278
 
        if (fortran == PyArray_ANYORDER)
1279
 
                fortran = PyArray_ISFORTRAN(m1);
1280
 
 
1281
 
        Py_INCREF(m1->descr);
1282
 
        ret = (PyArrayObject *)PyArray_NewFromDescr(m1->ob_type,
1283
 
                                                    m1->descr,
1284
 
                                                    m1->nd,
1285
 
                                                    m1->dimensions,
1286
 
                                                    NULL, NULL,
1287
 
                                                    fortran,
1288
 
                                                    (PyObject *)m1);
1289
 
        if (ret == NULL) return NULL;
1290
 
        if (PyArray_CopyInto(ret, m1) == -1) {
1291
 
                Py_DECREF(ret);
1292
 
                return NULL;
1293
 
        }
1294
 
 
1295
 
        return (PyObject *)ret;
 
1365
    PyArrayObject *ret;
 
1366
    if (fortran == PyArray_ANYORDER)
 
1367
        fortran = PyArray_ISFORTRAN(m1);
 
1368
 
 
1369
    Py_INCREF(m1->descr);
 
1370
    ret = (PyArrayObject *)PyArray_NewFromDescr(m1->ob_type,
 
1371
                                                m1->descr,
 
1372
                                                m1->nd,
 
1373
                                                m1->dimensions,
 
1374
                                                NULL, NULL,
 
1375
                                                fortran,
 
1376
                                                (PyObject *)m1);
 
1377
    if (ret == NULL) {
 
1378
        return NULL;
 
1379
    }
 
1380
    if (PyArray_CopyInto(ret, m1) == -1) {
 
1381
        Py_DECREF(ret);
 
1382
        return NULL;
 
1383
    }
 
1384
 
 
1385
    return (PyObject *)ret;
1296
1386
}
1297
1387
 
1298
1388
static PyObject *array_big_item(PyArrayObject *, intp);
1299
1389
 
1300
1390
/* Does nothing with descr (cannot be NULL) */
1301
1391
/*OBJECT_API
1302
 
 Get scalar-equivalent to a region of memory described by a descriptor.
 
1392
  Get scalar-equivalent to a region of memory described by a descriptor.
1303
1393
*/
1304
1394
static PyObject *
1305
1395
PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base)
1306
1396
{
1307
 
        PyTypeObject *type;
1308
 
        PyObject *obj;
1309
 
        void *destptr;
1310
 
        PyArray_CopySwapFunc *copyswap;
1311
 
        int type_num;
1312
 
        int itemsize;
1313
 
        int swap;
 
1397
    PyTypeObject *type;
 
1398
    PyObject *obj;
 
1399
    void *destptr;
 
1400
    PyArray_CopySwapFunc *copyswap;
 
1401
    int type_num;
 
1402
    int itemsize;
 
1403
    int swap;
1314
1404
 
1315
 
        type_num = descr->type_num;
1316
 
        if (type_num == PyArray_BOOL)
1317
 
                PyArrayScalar_RETURN_BOOL_FROM_LONG(*(Bool*)data);
1318
 
        else if (PyDataType_FLAGCHK(descr, NPY_USE_GETITEM)) {
1319
 
                return descr->f->getitem(data, base);
1320
 
        }
1321
 
        itemsize = descr->elsize;
1322
 
        copyswap = descr->f->copyswap;
1323
 
        type = descr->typeobj;
1324
 
        swap = !PyArray_ISNBO(descr->byteorder);
1325
 
        if PyTypeNum_ISSTRING(type_num) { /* Eliminate NULL bytes */
1326
 
                char *dptr = data;
1327
 
                dptr += itemsize-1;
1328
 
                while(itemsize && *dptr-- == 0) itemsize--;
1329
 
                if (type_num == PyArray_UNICODE && itemsize) {
1330
 
                        /* make sure itemsize is a multiple of 4 */
1331
 
                        /* so round up to nearest multiple */
1332
 
                        itemsize = (((itemsize-1) >> 2) + 1) << 2;
1333
 
                }
1334
 
        }
1335
 
        if (type->tp_itemsize != 0)  /* String type */
1336
 
                obj = type->tp_alloc(type, itemsize);
1337
 
        else
1338
 
                obj = type->tp_alloc(type, 0);
1339
 
        if (obj == NULL) return NULL;
1340
 
        if PyTypeNum_ISFLEXIBLE(type_num) {
1341
 
                if (type_num == PyArray_STRING) {
1342
 
                        destptr = PyString_AS_STRING(obj);
1343
 
                        ((PyStringObject *)obj)->ob_shash = -1;
1344
 
                        ((PyStringObject *)obj)->ob_sstate =    \
1345
 
                                SSTATE_NOT_INTERNED;
1346
 
                        memcpy(destptr, data, itemsize);
1347
 
                        return obj;
1348
 
                }
1349
 
                else if (type_num == PyArray_UNICODE) {
1350
 
                        PyUnicodeObject *uni = (PyUnicodeObject*)obj;
1351
 
                        int length = itemsize >> 2;
 
1405
    type_num = descr->type_num;
 
1406
    if (type_num == PyArray_BOOL)
 
1407
        PyArrayScalar_RETURN_BOOL_FROM_LONG(*(Bool*)data);
 
1408
    else if (PyDataType_FLAGCHK(descr, NPY_USE_GETITEM)) {
 
1409
        return descr->f->getitem(data, base);
 
1410
    }
 
1411
    itemsize = descr->elsize;
 
1412
    copyswap = descr->f->copyswap;
 
1413
    type = descr->typeobj;
 
1414
    swap = !PyArray_ISNBO(descr->byteorder);
 
1415
    if PyTypeNum_ISSTRING(type_num) { /* Eliminate NULL bytes */
 
1416
            char *dptr = data;
 
1417
            dptr += itemsize-1;
 
1418
            while(itemsize && *dptr-- == 0) itemsize--;
 
1419
            if (type_num == PyArray_UNICODE && itemsize) {
 
1420
                /* make sure itemsize is a multiple of 4 */
 
1421
                /* so round up to nearest multiple */
 
1422
                itemsize = (((itemsize-1) >> 2) + 1) << 2;
 
1423
            }
 
1424
        }
 
1425
    if (type->tp_itemsize != 0)  /* String type */
 
1426
        obj = type->tp_alloc(type, itemsize);
 
1427
    else
 
1428
        obj = type->tp_alloc(type, 0);
 
1429
    if (obj == NULL) {
 
1430
        return NULL;
 
1431
    }
 
1432
    if PyTypeNum_ISFLEXIBLE(type_num) {
 
1433
            if (type_num == PyArray_STRING) {
 
1434
                destptr = PyString_AS_STRING(obj);
 
1435
                ((PyStringObject *)obj)->ob_shash = -1;
 
1436
                ((PyStringObject *)obj)->ob_sstate =    \
 
1437
                    SSTATE_NOT_INTERNED;
 
1438
                memcpy(destptr, data, itemsize);
 
1439
                return obj;
 
1440
            }
 
1441
            else if (type_num == PyArray_UNICODE) {
 
1442
                PyUnicodeObject *uni = (PyUnicodeObject*)obj;
 
1443
                int length = itemsize >> 2;
1352
1444
#ifndef Py_UNICODE_WIDE
1353
 
                        char *buffer;
1354
 
                        int alloc=0;
1355
 
                        length *= 2;
 
1445
                char *buffer;
 
1446
                int alloc=0;
 
1447
                length *= 2;
1356
1448
#endif
1357
 
                        /* Need an extra slot and need to use
1358
 
                           Python memory manager */
1359
 
                        uni->str = NULL;
1360
 
                        destptr = PyMem_NEW(Py_UNICODE,length+1);
1361
 
                        if (destptr == NULL) {
1362
 
                                Py_DECREF(obj);
1363
 
                                return PyErr_NoMemory();
1364
 
                        }
1365
 
                        uni->str = (Py_UNICODE *)destptr;
1366
 
                        uni->str[0] = 0;
1367
 
                        uni->str[length] = 0;
1368
 
                        uni->length = length;
1369
 
                        uni->hash = -1;
1370
 
                        uni->defenc = NULL;
 
1449
                /* Need an extra slot and need to use
 
1450
                   Python memory manager */
 
1451
                uni->str = NULL;
 
1452
                destptr = PyMem_NEW(Py_UNICODE,length+1);
 
1453
                if (destptr == NULL) {
 
1454
                    Py_DECREF(obj);
 
1455
                    return PyErr_NoMemory();
 
1456
                }
 
1457
                uni->str = (Py_UNICODE *)destptr;
 
1458
                uni->str[0] = 0;
 
1459
                uni->str[length] = 0;
 
1460
                uni->length = length;
 
1461
                uni->hash = -1;
 
1462
                uni->defenc = NULL;
1371
1463
#ifdef Py_UNICODE_WIDE
1372
 
                        memcpy(destptr, data, itemsize);
1373
 
                        if (swap)
1374
 
                                byte_swap_vector(destptr, length, 4);
 
1464
                memcpy(destptr, data, itemsize);
 
1465
                if (swap)
 
1466
                    byte_swap_vector(destptr, length, 4);
1375
1467
#else
1376
 
                        /* need aligned data buffer */
1377
 
                        if (!PyArray_ISBEHAVED(base)) {
1378
 
                                buffer = _pya_malloc(itemsize);
1379
 
                                if (buffer == NULL)
1380
 
                                        return PyErr_NoMemory();
1381
 
                                alloc = 1;
1382
 
                                memcpy(buffer, data, itemsize);
1383
 
                                if (!PyArray_ISNOTSWAPPED(base)) {
1384
 
                                        byte_swap_vector(buffer,
1385
 
                                                         itemsize >> 2, 4);
1386
 
                                }
1387
 
                        }
1388
 
                        else buffer = data;
 
1468
                /* need aligned data buffer */
 
1469
                if ((swap) || ((((intp)data) % descr->alignment) != 0)) {
 
1470
                    buffer = _pya_malloc(itemsize);
 
1471
                    if (buffer == NULL)
 
1472
                        return PyErr_NoMemory();
 
1473
                    alloc = 1;
 
1474
                    memcpy(buffer, data, itemsize);
 
1475
                    if (swap) {
 
1476
                        byte_swap_vector(buffer,
 
1477
                                         itemsize >> 2, 4);
 
1478
                    }
 
1479
                }
 
1480
                else buffer = data;
1389
1481
 
1390
 
                        /* Allocated enough for 2-characters per itemsize.
1391
 
                           Now convert from the data-buffer
1392
 
                         */
1393
 
                        length = PyUCS2Buffer_FromUCS4(uni->str,
1394
 
                                                       (PyArray_UCS4 *)buffer,
1395
 
                                                       itemsize >> 2);
1396
 
                        if (alloc) _pya_free(buffer);
1397
 
                        /* Resize the unicode result */
1398
 
                        if (MyPyUnicode_Resize(uni, length) < 0) {
1399
 
                                Py_DECREF(obj);
1400
 
                                return NULL;
1401
 
                        }
 
1482
                /* Allocated enough for 2-characters per itemsize.
 
1483
                   Now convert from the data-buffer
 
1484
                */
 
1485
                length = PyUCS2Buffer_FromUCS4(uni->str,
 
1486
                                               (PyArray_UCS4 *)buffer,
 
1487
                                               itemsize >> 2);
 
1488
                if (alloc) _pya_free(buffer);
 
1489
                /* Resize the unicode result */
 
1490
                if (MyPyUnicode_Resize(uni, length) < 0) {
 
1491
                    Py_DECREF(obj);
 
1492
                    return NULL;
 
1493
                }
1402
1494
#endif
 
1495
                return obj;
 
1496
            }
 
1497
            else {
 
1498
                PyVoidScalarObject *vobj = (PyVoidScalarObject *)obj;
 
1499
                vobj->base = NULL;
 
1500
                vobj->descr = descr;
 
1501
                Py_INCREF(descr);
 
1502
                vobj->obval = NULL;
 
1503
                vobj->ob_size = itemsize;
 
1504
                vobj->flags = BEHAVED | OWNDATA;
 
1505
                swap = 0;
 
1506
                if (descr->names) {
 
1507
                    if (base) {
 
1508
                        Py_INCREF(base);
 
1509
                        vobj->base = base;
 
1510
                        vobj->flags = PyArray_FLAGS(base);
 
1511
                        vobj->flags &= ~OWNDATA;
 
1512
                        vobj->obval = data;
1403
1513
                        return obj;
1404
 
                }
1405
 
                else {
1406
 
                        PyVoidScalarObject *vobj = (PyVoidScalarObject *)obj;
1407
 
                        vobj->base = NULL;
1408
 
                        vobj->descr = descr;
1409
 
                        Py_INCREF(descr);
1410
 
                        vobj->obval = NULL;
1411
 
                        vobj->ob_size = itemsize;
1412
 
                        vobj->flags = BEHAVED | OWNDATA;
1413
 
                        swap = 0;
1414
 
                        if (descr->names) {
1415
 
                                if (base) {
1416
 
                                        Py_INCREF(base);
1417
 
                                        vobj->base = base;
1418
 
                                        vobj->flags = PyArray_FLAGS(base);
1419
 
                                        vobj->flags &= ~OWNDATA;
1420
 
                                        vobj->obval = data;
1421
 
                                        return obj;
1422
 
                                }
1423
 
                        }
1424
 
                        destptr = PyDataMem_NEW(itemsize);
1425
 
                        if (destptr == NULL) {
1426
 
                                Py_DECREF(obj);
1427
 
                                return PyErr_NoMemory();
1428
 
                        }
1429
 
                        vobj->obval = destptr;
1430
 
                }
1431
 
        }
1432
 
        else {
1433
 
                destptr = scalar_value(obj, descr);
1434
 
        }
1435
 
        /* copyswap for OBJECT increments the reference count */
1436
 
        copyswap(destptr, data, swap, base);
1437
 
        return obj;
 
1514
                    }
 
1515
                }
 
1516
                destptr = PyDataMem_NEW(itemsize);
 
1517
                if (destptr == NULL) {
 
1518
                    Py_DECREF(obj);
 
1519
                    return PyErr_NoMemory();
 
1520
                }
 
1521
                vobj->obval = destptr;
 
1522
            }
 
1523
        }
 
1524
    else {
 
1525
        destptr = scalar_value(obj, descr);
 
1526
    }
 
1527
    /* copyswap for OBJECT increments the reference count */
 
1528
    copyswap(destptr, data, swap, base);
 
1529
    return obj;
1438
1530
}
1439
1531
 
1440
1532
/* returns an Array-Scalar Object of the type of arr
1451
1543
/* Return Array Scalar if 0-d array object is encountered */
1452
1544
 
1453
1545
/*OBJECT_API
1454
 
 Return either an array or the appropriate Python object if the array
1455
 
 is 0d and matches a Python type.
 
1546
  Return either an array or the appropriate Python object if the array
 
1547
  is 0d and matches a Python type.
1456
1548
*/
1457
1549
static PyObject *
1458
1550
PyArray_Return(PyArrayObject *mp)
1459
1551
{
1460
1552
 
1461
 
        if (mp == NULL) return NULL;
1462
 
 
1463
 
        if (PyErr_Occurred()) {
1464
 
                Py_XDECREF(mp);
1465
 
                return NULL;
1466
 
        }
1467
 
 
1468
 
        if (!PyArray_Check(mp)) return (PyObject *)mp;
1469
 
 
1470
 
        if (mp->nd == 0) {
1471
 
                PyObject *ret;
1472
 
                ret = PyArray_ToScalar(mp->data, mp);
1473
 
                Py_DECREF(mp);
1474
 
                return ret;
1475
 
        }
1476
 
        else {
1477
 
                return (PyObject *)mp;
1478
 
        }
 
1553
    if (mp == NULL) {
 
1554
        return NULL;
 
1555
    }
 
1556
    if (PyErr_Occurred()) {
 
1557
        Py_XDECREF(mp);
 
1558
        return NULL;
 
1559
    }
 
1560
    if (!PyArray_Check(mp)) {
 
1561
        return (PyObject *)mp;
 
1562
    }
 
1563
    if (mp->nd == 0) {
 
1564
        PyObject *ret;
 
1565
        ret = PyArray_ToScalar(mp->data, mp);
 
1566
        Py_DECREF(mp);
 
1567
        return ret;
 
1568
    }
 
1569
    else {
 
1570
        return (PyObject *)mp;
 
1571
    }
1479
1572
}
1480
1573
 
1481
1574
 
1485
1578
static void
1486
1579
PyArray_InitArrFuncs(PyArray_ArrFuncs *f)
1487
1580
{
1488
 
        int i;
1489
 
        for (i=0; i<PyArray_NTYPES; i++) {
1490
 
                f->cast[i] = NULL;
1491
 
        }
1492
 
        f->getitem = NULL;
1493
 
        f->setitem = NULL;
1494
 
        f->copyswapn = NULL;
1495
 
        f->copyswap = NULL;
1496
 
        f->compare = NULL;
1497
 
        f->argmax = NULL;
1498
 
        f->dotfunc = NULL;
1499
 
        f->scanfunc = NULL;
1500
 
        f->fromstr = NULL;
1501
 
        f->nonzero = NULL;
1502
 
        f->fill = NULL;
1503
 
        f->fillwithscalar = NULL;
1504
 
        for (i=0; i<PyArray_NSORTS; i++) {
1505
 
                f->sort[i] = NULL;
1506
 
                f->argsort[i] = NULL;
1507
 
        }
1508
 
        f->castdict = NULL;
1509
 
        f->scalarkind = NULL;
1510
 
        f->cancastscalarkindto = NULL;
1511
 
        f->cancastto = NULL;
 
1581
    int i;
 
1582
 
 
1583
    for(i = 0; i < PyArray_NTYPES; i++) {
 
1584
        f->cast[i] = NULL;
 
1585
    }
 
1586
    f->getitem = NULL;
 
1587
    f->setitem = NULL;
 
1588
    f->copyswapn = NULL;
 
1589
    f->copyswap = NULL;
 
1590
    f->compare = NULL;
 
1591
    f->argmax = NULL;
 
1592
    f->dotfunc = NULL;
 
1593
    f->scanfunc = NULL;
 
1594
    f->fromstr = NULL;
 
1595
    f->nonzero = NULL;
 
1596
    f->fill = NULL;
 
1597
    f->fillwithscalar = NULL;
 
1598
    for(i = 0; i < PyArray_NSORTS; i++) {
 
1599
        f->sort[i] = NULL;
 
1600
        f->argsort[i] = NULL;
 
1601
    }
 
1602
    f->castdict = NULL;
 
1603
    f->scalarkind = NULL;
 
1604
    f->cancastscalarkindto = NULL;
 
1605
    f->cancastto = NULL;
1512
1606
}
1513
1607
 
1514
1608
static Bool
1515
1609
_default_nonzero(void *ip, void *arr)
1516
1610
{
1517
 
        int elsize = PyArray_ITEMSIZE(arr);
1518
 
        char *ptr = ip;
1519
 
        while (elsize--) {
1520
 
                if (*ptr++ != 0) return TRUE;
 
1611
    int elsize = PyArray_ITEMSIZE(arr);
 
1612
    char *ptr = ip;
 
1613
    while (elsize--) {
 
1614
        if (*ptr++ != 0) {
 
1615
            return TRUE;
1521
1616
        }
1522
 
        return FALSE;
 
1617
    }
 
1618
    return FALSE;
 
1619
}
 
1620
 
 
1621
static void
 
1622
_default_copyswapn(void *dst, npy_intp dstride, void *src,
 
1623
                   npy_intp sstride, npy_intp n, int swap, void *arr)
 
1624
{
 
1625
    npy_intp i;
 
1626
    PyArray_CopySwapFunc *copyswap;
 
1627
    char *dstptr = dst;
 
1628
    char *srcptr = src;
 
1629
 
 
1630
    copyswap = PyArray_DESCR(arr)->f->copyswap;
 
1631
 
 
1632
    for(i = 0; i < n; i++) {
 
1633
        copyswap(dstptr, srcptr, swap, arr);
 
1634
        dstptr += dstride;
 
1635
        srcptr += sstride;
 
1636
    }
1523
1637
}
1524
1638
 
1525
1639
/*
1534
1648
static int
1535
1649
PyArray_TypeNumFromName(char *str)
1536
1650
{
1537
 
        int i;
1538
 
        PyArray_Descr *descr;
1539
 
 
1540
 
        for (i=0; i<NPY_NUMUSERTYPES; i++) {
1541
 
                descr = userdescrs[i];
1542
 
                if (strcmp(descr->typeobj->tp_name, str) == 0)
1543
 
                        return descr->type_num;
1544
 
        }
1545
 
 
1546
 
        return PyArray_NOTYPE;
 
1651
    int i;
 
1652
    PyArray_Descr *descr;
 
1653
 
 
1654
    for(i=0; i<NPY_NUMUSERTYPES; i++) {
 
1655
        descr = userdescrs[i];
 
1656
        if (strcmp(descr->typeobj->tp_name, str) == 0)
 
1657
            return descr->type_num;
 
1658
    }
 
1659
 
 
1660
    return PyArray_NOTYPE;
1547
1661
}
1548
1662
 
1549
1663
/*
1552
1666
  defined in arraytypes.inc
1553
1667
*/
1554
1668
/*MULTIARRAY_API
1555
 
 Register Data type
1556
 
 Does not change the reference count of descr
 
1669
  Register Data type
 
1670
  Does not change the reference count of descr
1557
1671
*/
1558
1672
static int
1559
1673
PyArray_RegisterDataType(PyArray_Descr *descr)
1560
1674
{
1561
 
        PyArray_Descr *descr2;
1562
 
        int typenum;
1563
 
        int i;
1564
 
        PyArray_ArrFuncs *f;
 
1675
    PyArray_Descr *descr2;
 
1676
    int typenum;
 
1677
    int i;
 
1678
    PyArray_ArrFuncs *f;
1565
1679
 
1566
 
        /* See if this type is already registered */
1567
 
        for (i=0; i<NPY_NUMUSERTYPES; i++) {
1568
 
                descr2 = userdescrs[i];
1569
 
                if (descr2 == descr)
1570
 
                        return descr->type_num;
1571
 
        }
1572
 
        typenum = PyArray_USERDEF + NPY_NUMUSERTYPES;
1573
 
        descr->type_num = typenum;
1574
 
        if (descr->elsize == 0) {
1575
 
                PyErr_SetString(PyExc_ValueError, "cannot register a" \
1576
 
                                "flexible data-type");
1577
 
                return -1;
1578
 
        }
1579
 
        f = descr->f;
1580
 
        if (f->nonzero == NULL) {
1581
 
                f->nonzero = _default_nonzero;
1582
 
        }
1583
 
        if (f->copyswap == NULL || f->getitem == NULL ||
1584
 
            f->copyswapn == NULL || f->setitem == NULL) {
1585
 
                PyErr_SetString(PyExc_ValueError, "a required array function" \
1586
 
                                " is missing.");
1587
 
                return -1;
1588
 
        }
1589
 
        if (descr->typeobj == NULL) {
1590
 
                PyErr_SetString(PyExc_ValueError, "missing typeobject");
1591
 
                return -1;
1592
 
        }
1593
 
        userdescrs = realloc(userdescrs,
1594
 
                             (NPY_NUMUSERTYPES+1)*sizeof(void *));
1595
 
        if (userdescrs == NULL) {
1596
 
                PyErr_SetString(PyExc_MemoryError, "RegisterDataType");
1597
 
                return -1;
1598
 
        }
1599
 
        userdescrs[NPY_NUMUSERTYPES++] = descr;
1600
 
        return typenum;
 
1680
    /* See if this type is already registered */
 
1681
    for(i=0; i<NPY_NUMUSERTYPES; i++) {
 
1682
        descr2 = userdescrs[i];
 
1683
        if (descr2 == descr)
 
1684
            return descr->type_num;
 
1685
    }
 
1686
    typenum = PyArray_USERDEF + NPY_NUMUSERTYPES;
 
1687
    descr->type_num = typenum;
 
1688
    if (descr->elsize == 0) {
 
1689
        PyErr_SetString(PyExc_ValueError, "cannot register a" \
 
1690
                        "flexible data-type");
 
1691
        return -1;
 
1692
    }
 
1693
    f = descr->f;
 
1694
    if (f->nonzero == NULL) {
 
1695
        f->nonzero = _default_nonzero;
 
1696
    }
 
1697
    if (f->copyswapn == NULL) {
 
1698
        f->copyswapn = _default_copyswapn;
 
1699
    }
 
1700
    if (f->copyswap == NULL || f->getitem == NULL ||
 
1701
        f->setitem == NULL) {
 
1702
        PyErr_SetString(PyExc_ValueError, "a required array function"   \
 
1703
                        " is missing.");
 
1704
        return -1;
 
1705
    }
 
1706
    if (descr->typeobj == NULL) {
 
1707
        PyErr_SetString(PyExc_ValueError, "missing typeobject");
 
1708
        return -1;
 
1709
    }
 
1710
    userdescrs = realloc(userdescrs,
 
1711
                         (NPY_NUMUSERTYPES+1)*sizeof(void *));
 
1712
    if (userdescrs == NULL) {
 
1713
        PyErr_SetString(PyExc_MemoryError, "RegisterDataType");
 
1714
        return -1;
 
1715
    }
 
1716
    userdescrs[NPY_NUMUSERTYPES++] = descr;
 
1717
    return typenum;
1601
1718
}
1602
1719
 
1603
1720
/*MULTIARRAY_API
1608
1725
PyArray_RegisterCastFunc(PyArray_Descr *descr, int totype,
1609
1726
                         PyArray_VectorUnaryFunc *castfunc)
1610
1727
{
1611
 
        PyObject *cobj, *key;
1612
 
        int ret;
1613
 
        if (totype < PyArray_NTYPES) {
1614
 
                descr->f->cast[totype] = castfunc;
1615
 
                return 0;
1616
 
        }
1617
 
        if (!PyTypeNum_ISUSERDEF(totype)) {
1618
 
                PyErr_SetString(PyExc_TypeError, "invalid type number.");
1619
 
                return -1;
1620
 
        }
1621
 
        if (descr->f->castdict == NULL) {
1622
 
                descr->f->castdict = PyDict_New();
1623
 
                if (descr->f->castdict == NULL) return -1;
1624
 
        }
1625
 
        key = PyInt_FromLong(totype);
1626
 
        if (PyErr_Occurred()) return -1;
1627
 
        cobj = PyCObject_FromVoidPtr((void *)castfunc, NULL);
1628
 
        if (cobj == NULL) {Py_DECREF(key); return -1;}
1629
 
        ret = PyDict_SetItem(descr->f->castdict, key, cobj);
1630
 
        Py_DECREF(key);
1631
 
        Py_DECREF(cobj);
1632
 
        return ret;
 
1728
    PyObject *cobj, *key;
 
1729
    int ret;
 
1730
    if (totype < PyArray_NTYPES) {
 
1731
        descr->f->cast[totype] = castfunc;
 
1732
        return 0;
 
1733
    }
 
1734
    if (!PyTypeNum_ISUSERDEF(totype)) {
 
1735
        PyErr_SetString(PyExc_TypeError, "invalid type number.");
 
1736
        return -1;
 
1737
    }
 
1738
    if (descr->f->castdict == NULL) {
 
1739
        descr->f->castdict = PyDict_New();
 
1740
        if (descr->f->castdict == NULL) return -1;
 
1741
    }
 
1742
    key = PyInt_FromLong(totype);
 
1743
    if (PyErr_Occurred()) return -1;
 
1744
    cobj = PyCObject_FromVoidPtr((void *)castfunc, NULL);
 
1745
    if (cobj == NULL) {Py_DECREF(key); return -1;}
 
1746
    ret = PyDict_SetItem(descr->f->castdict, key, cobj);
 
1747
    Py_DECREF(key);
 
1748
    Py_DECREF(cobj);
 
1749
    return ret;
1633
1750
}
1634
1751
 
1635
1752
static int *
1636
1753
_append_new(int *types, int insert)
1637
1754
{
1638
 
        int n=0;
1639
 
        int *newtypes;
 
1755
    int n=0;
 
1756
    int *newtypes;
1640
1757
 
1641
 
        while (types[n] != PyArray_NOTYPE) n++;
1642
 
        newtypes = (int *)realloc(types, (n+2)*sizeof(int));
1643
 
        newtypes[n] = insert;
1644
 
        newtypes[n+1] = PyArray_NOTYPE;
1645
 
        return newtypes;
 
1758
    while (types[n] != PyArray_NOTYPE) n++;
 
1759
    newtypes = (int *)realloc(types, (n+2)*sizeof(int));
 
1760
    newtypes[n] = insert;
 
1761
    newtypes[n+1] = PyArray_NOTYPE;
 
1762
    return newtypes;
1646
1763
}
1647
1764
 
1648
1765
/*MULTIARRAY_API
1653
1770
PyArray_RegisterCanCast(PyArray_Descr *descr, int totype,
1654
1771
                        NPY_SCALARKIND scalar)
1655
1772
{
1656
 
        if (scalar == PyArray_NOSCALAR) {
1657
 
                /* register with cancastto */
1658
 
                /* These lists won't be freed once created
1659
 
                   -- they become part of the data-type */
1660
 
                if (descr->f->cancastto == NULL) {
1661
 
                        descr->f->cancastto = (int *)malloc(1*sizeof(int));
1662
 
                        descr->f->cancastto[0] = PyArray_NOTYPE;
1663
 
                }
1664
 
                descr->f->cancastto = _append_new(descr->f->cancastto,
1665
 
                                                  totype);
1666
 
        }
1667
 
        else {
1668
 
                /* register with cancastscalarkindto */
1669
 
                if (descr->f->cancastscalarkindto == NULL) {
1670
 
                        int i;
1671
 
                        descr->f->cancastscalarkindto =                 \
1672
 
                                (int **)malloc(PyArray_NSCALARKINDS*    \
1673
 
                                               sizeof(int*));
1674
 
                        for (i=0; i<PyArray_NSCALARKINDS; i++) {
1675
 
                                descr->f->cancastscalarkindto[i] = NULL;
1676
 
                        }
1677
 
                }
1678
 
                if (descr->f->cancastscalarkindto[scalar] == NULL) {
1679
 
                        descr->f->cancastscalarkindto[scalar] = \
1680
 
                                (int *)malloc(1*sizeof(int));
1681
 
                        descr->f->cancastscalarkindto[scalar][0] =      \
1682
 
                                PyArray_NOTYPE;
1683
 
                }
1684
 
                descr->f->cancastscalarkindto[scalar] =                 \
1685
 
                        _append_new(descr->f->cancastscalarkindto[scalar],
1686
 
                                    totype);
1687
 
        }
1688
 
        return 0;
 
1773
    if (scalar == PyArray_NOSCALAR) {
 
1774
        /* register with cancastto */
 
1775
        /* These lists won't be freed once created
 
1776
           -- they become part of the data-type */
 
1777
        if (descr->f->cancastto == NULL) {
 
1778
            descr->f->cancastto = (int *)malloc(1*sizeof(int));
 
1779
            descr->f->cancastto[0] = PyArray_NOTYPE;
 
1780
        }
 
1781
        descr->f->cancastto = _append_new(descr->f->cancastto,
 
1782
                                          totype);
 
1783
    }
 
1784
    else {
 
1785
        /* register with cancastscalarkindto */
 
1786
        if (descr->f->cancastscalarkindto == NULL) {
 
1787
            int i;
 
1788
            descr->f->cancastscalarkindto =                 \
 
1789
                (int **)malloc(PyArray_NSCALARKINDS*    \
 
1790
                               sizeof(int*));
 
1791
            for(i=0; i<PyArray_NSCALARKINDS; i++) {
 
1792
                descr->f->cancastscalarkindto[i] = NULL;
 
1793
            }
 
1794
        }
 
1795
        if (descr->f->cancastscalarkindto[scalar] == NULL) {
 
1796
            descr->f->cancastscalarkindto[scalar] = \
 
1797
                (int *)malloc(1*sizeof(int));
 
1798
            descr->f->cancastscalarkindto[scalar][0] =      \
 
1799
                PyArray_NOTYPE;
 
1800
        }
 
1801
        descr->f->cancastscalarkindto[scalar] =                 \
 
1802
            _append_new(descr->f->cancastscalarkindto[scalar],
 
1803
                        totype);
 
1804
    }
 
1805
    return 0;
1689
1806
}
1690
1807
 
 
1808
 
 
1809
/* XXX: FIXME --- add ordering argument to
 
1810
   Allow Fortran ordering on write
 
1811
   This will need the addition of a Fortran-order iterator.
 
1812
 */
 
1813
 
1691
1814
/*OBJECT_API
1692
 
 To File
 
1815
  To File
1693
1816
*/
1694
1817
static int
1695
1818
PyArray_ToFile(PyArrayObject *self, FILE *fp, char *sep, char *format)
1696
1819
{
1697
 
        intp size;
1698
 
        intp n, n2;
1699
 
        size_t n3, n4;
1700
 
        PyArrayIterObject *it;
1701
 
        PyObject *obj, *strobj, *tupobj;
1702
 
 
1703
 
        n3 = (sep ? strlen((const char *)sep) : 0);
1704
 
        if (n3 == 0) { /* binary data */
1705
 
                if (PyDataType_FLAGCHK(self->descr, NPY_LIST_PICKLE)) {
1706
 
                        PyErr_SetString(PyExc_ValueError, "cannot write " \
1707
 
                                        "object arrays to a file in "   \
1708
 
                                        "binary mode");
1709
 
                        return -1;
1710
 
                }
1711
 
 
1712
 
                if (PyArray_ISCONTIGUOUS(self)) {
1713
 
                        size = PyArray_SIZE(self);
1714
 
                        NPY_BEGIN_ALLOW_THREADS
1715
 
                        n=fwrite((const void *)self->data,
1716
 
                                 (size_t) self->descr->elsize,
1717
 
                                 (size_t) size, fp);
1718
 
                        NPY_END_ALLOW_THREADS
1719
 
                        if (n < size) {
1720
 
                                PyErr_Format(PyExc_ValueError,
1721
 
                                             "%ld requested and %ld written",
1722
 
                                             (long) size, (long) n);
1723
 
                                return -1;
1724
 
                        }
1725
 
                }
1726
 
                else {
1727
 
                        NPY_BEGIN_THREADS_DEF
1728
 
 
1729
 
                        it=(PyArrayIterObject *)                        \
1730
 
                                PyArray_IterNew((PyObject *)self);
1731
 
                        NPY_BEGIN_THREADS
1732
 
                        while(it->index < it->size) {
1733
 
                                if (fwrite((const void *)it->dataptr,
1734
 
                                           (size_t) self->descr->elsize,
1735
 
                                           1, fp) < 1) {
1736
 
                                        NPY_END_THREADS
1737
 
                                        PyErr_Format(PyExc_IOError,
1738
 
                                                     "problem writing element"\
1739
 
                                                     " %d to file",
1740
 
                                                     (int)it->index);
1741
 
                                        Py_DECREF(it);
1742
 
                                        return -1;
1743
 
                                }
1744
 
                                PyArray_ITER_NEXT(it);
1745
 
                        }
1746
 
                        NPY_END_THREADS
1747
 
                        Py_DECREF(it);
1748
 
                }
1749
 
        }
1750
 
        else {  /* text data */
1751
 
 
1752
 
                it=(PyArrayIterObject *)                                \
1753
 
                        PyArray_IterNew((PyObject *)self);
1754
 
                n4 = (format ? strlen((const char *)format) : 0);
1755
 
                while(it->index < it->size) {
1756
 
                        obj = self->descr->f->getitem(it->dataptr, self);
1757
 
                        if (obj == NULL) {Py_DECREF(it); return -1;}
1758
 
                        if (n4 == 0) { /* standard writing */
1759
 
                                strobj = PyObject_Str(obj);
1760
 
                                Py_DECREF(obj);
1761
 
                                if (strobj == NULL) {Py_DECREF(it); return -1;}
1762
 
                        }
1763
 
                        else { /* use format string */
1764
 
                                tupobj = PyTuple_New(1);
1765
 
                                if (tupobj == NULL) {Py_DECREF(it); return -1;}
1766
 
                                PyTuple_SET_ITEM(tupobj,0,obj);
1767
 
                                obj = PyString_FromString((const char *)format);
1768
 
                                if (obj == NULL) {Py_DECREF(tupobj);
1769
 
                                        Py_DECREF(it); return -1;}
1770
 
                                strobj = PyString_Format(obj, tupobj);
1771
 
                                Py_DECREF(obj);
1772
 
                                Py_DECREF(tupobj);
1773
 
                                if (strobj == NULL) {Py_DECREF(it); return -1;}
1774
 
                        }
1775
 
                        NPY_BEGIN_ALLOW_THREADS
1776
 
                        n=fwrite(PyString_AS_STRING(strobj), 1,
1777
 
                                 n2=PyString_GET_SIZE(strobj), fp);
1778
 
                        NPY_END_ALLOW_THREADS
1779
 
                        if (n < n2) {
1780
 
                                PyErr_Format(PyExc_IOError,
1781
 
                                             "problem writing element %d"\
1782
 
                                             " to file",
1783
 
                                             (int) it->index);
1784
 
                                Py_DECREF(strobj);
1785
 
                                Py_DECREF(it);
1786
 
                                return -1;
1787
 
                        }
1788
 
                        /* write separator for all but last one */
1789
 
                        if (it->index != it->size-1)
1790
 
                                if (fwrite(sep, 1, n3, fp) < n3) {
1791
 
                                        PyErr_Format(PyExc_IOError,
1792
 
                                                     "problem writing "\
1793
 
                                                     "separator to file");
1794
 
                                        Py_DECREF(strobj);
1795
 
                                        Py_DECREF(it);
1796
 
                                        return -1;
1797
 
                                }
1798
 
                        Py_DECREF(strobj);
1799
 
                        PyArray_ITER_NEXT(it);
1800
 
                }
1801
 
                Py_DECREF(it);
1802
 
        }
1803
 
        return 0;
 
1820
    intp size;
 
1821
    intp n, n2;
 
1822
    size_t n3, n4;
 
1823
    PyArrayIterObject *it;
 
1824
    PyObject *obj, *strobj, *tupobj;
 
1825
 
 
1826
    n3 = (sep ? strlen((const char *)sep) : 0);
 
1827
    if (n3 == 0) {
 
1828
        /* binary data */
 
1829
        if (PyDataType_FLAGCHK(self->descr, NPY_LIST_PICKLE)) {
 
1830
            PyErr_SetString(PyExc_ValueError, "cannot write " \
 
1831
                    "object arrays to a file in "   \
 
1832
                    "binary mode");
 
1833
            return -1;
 
1834
        }
 
1835
 
 
1836
        if (PyArray_ISCONTIGUOUS(self)) {
 
1837
            size = PyArray_SIZE(self);
 
1838
            NPY_BEGIN_ALLOW_THREADS;
 
1839
            n = fwrite((const void *)self->data,
 
1840
                    (size_t) self->descr->elsize,
 
1841
                    (size_t) size, fp);
 
1842
            NPY_END_ALLOW_THREADS;
 
1843
            if (n < size) {
 
1844
                PyErr_Format(PyExc_ValueError,
 
1845
                        "%ld requested and %ld written",
 
1846
                        (long) size, (long) n);
 
1847
                return -1;
 
1848
            }
 
1849
        }
 
1850
        else {
 
1851
            NPY_BEGIN_THREADS_DEF;
 
1852
 
 
1853
            it = (PyArrayIterObject *)
 
1854
                PyArray_IterNew((PyObject *)self);
 
1855
            NPY_BEGIN_THREADS;
 
1856
            while(it->index < it->size) {
 
1857
                if (fwrite((const void *)it->dataptr,
 
1858
                            (size_t) self->descr->elsize,
 
1859
                            1, fp) < 1) {
 
1860
                    NPY_END_THREADS;
 
1861
                    PyErr_Format(PyExc_IOError,
 
1862
                            "problem writing element"\
 
1863
                            " %d to file",
 
1864
                            (int)it->index);
 
1865
                    Py_DECREF(it);
 
1866
                    return -1;
 
1867
                }
 
1868
                PyArray_ITER_NEXT(it);
 
1869
            }
 
1870
            NPY_END_THREADS;
 
1871
            Py_DECREF(it);
 
1872
        }
 
1873
    }
 
1874
    else {
 
1875
        /*
 
1876
         * text data
 
1877
         */
 
1878
 
 
1879
        it = (PyArrayIterObject *)
 
1880
            PyArray_IterNew((PyObject *)self);
 
1881
        n4 = (format ? strlen((const char *)format) : 0);
 
1882
        while(it->index < it->size) {
 
1883
            obj = self->descr->f->getitem(it->dataptr, self);
 
1884
            if (obj == NULL) {
 
1885
                Py_DECREF(it);
 
1886
                return -1;
 
1887
            }
 
1888
            if (n4 == 0) {
 
1889
                /*
 
1890
                 * standard writing
 
1891
                 */
 
1892
                strobj = PyObject_Str(obj);
 
1893
                Py_DECREF(obj);
 
1894
                if (strobj == NULL) {
 
1895
                    Py_DECREF(it);
 
1896
                    return -1;
 
1897
                }
 
1898
            }
 
1899
            else {
 
1900
                /*
 
1901
                 * use format string
 
1902
                 */
 
1903
                tupobj = PyTuple_New(1);
 
1904
                if (tupobj == NULL) {
 
1905
                    Py_DECREF(it);
 
1906
                    return -1;
 
1907
                }
 
1908
                PyTuple_SET_ITEM(tupobj,0,obj);
 
1909
                obj = PyString_FromString((const char *)format);
 
1910
                if (obj == NULL) {
 
1911
                    Py_DECREF(tupobj);
 
1912
                    Py_DECREF(it);
 
1913
                    return -1;
 
1914
                }
 
1915
                strobj = PyString_Format(obj, tupobj);
 
1916
                Py_DECREF(obj);
 
1917
                Py_DECREF(tupobj);
 
1918
                if (strobj == NULL) {
 
1919
                    Py_DECREF(it);
 
1920
                    return -1;
 
1921
                }
 
1922
            }
 
1923
            NPY_BEGIN_ALLOW_THREADS;
 
1924
            n = fwrite(PyString_AS_STRING(strobj), 1,
 
1925
                    n2=PyString_GET_SIZE(strobj), fp);
 
1926
            NPY_END_ALLOW_THREADS;
 
1927
            if (n < n2) {
 
1928
                PyErr_Format(PyExc_IOError,
 
1929
                        "problem writing element %d"\
 
1930
                        " to file",
 
1931
                        (int) it->index);
 
1932
                Py_DECREF(strobj);
 
1933
                Py_DECREF(it);
 
1934
                return -1;
 
1935
            }
 
1936
            /* write separator for all but last one */
 
1937
            if (it->index != it->size-1) {
 
1938
                if (fwrite(sep, 1, n3, fp) < n3) {
 
1939
                    PyErr_Format(PyExc_IOError,
 
1940
                            "problem writing "\
 
1941
                            "separator to file");
 
1942
                    Py_DECREF(strobj);
 
1943
                    Py_DECREF(it);
 
1944
                    return -1;
 
1945
                }
 
1946
            }
 
1947
            Py_DECREF(strobj);
 
1948
            PyArray_ITER_NEXT(it);
 
1949
        }
 
1950
        Py_DECREF(it);
 
1951
    }
 
1952
    return 0;
1804
1953
}
1805
1954
 
1806
1955
/*OBJECT_API
1807
 
 To List
1808
 
*/
 
1956
 * To List
 
1957
 */
1809
1958
static PyObject *
1810
1959
PyArray_ToList(PyArrayObject *self)
1811
1960
{
1812
 
        PyObject *lp;
1813
 
        PyArrayObject *v;
1814
 
        intp sz, i;
1815
 
 
1816
 
        if (!PyArray_Check(self)) return (PyObject *)self;
1817
 
 
1818
 
        if (self->nd == 0)
1819
 
                return self->descr->f->getitem(self->data,self);
1820
 
 
1821
 
        sz = self->dimensions[0];
1822
 
        lp = PyList_New(sz);
1823
 
 
1824
 
        for (i=0; i<sz; i++) {
1825
 
                v=(PyArrayObject *)array_big_item(self, i);
1826
 
                if (v->nd >= self->nd) {
1827
 
                        PyErr_SetString(PyExc_RuntimeError,
1828
 
                                        "array_item not returning smaller-" \
1829
 
                                        "dimensional array");
1830
 
                        Py_DECREF(v);
1831
 
                        Py_DECREF(lp);
1832
 
                        return NULL;
1833
 
                }
1834
 
                PyList_SetItem(lp, i, PyArray_ToList(v));
1835
 
                Py_DECREF(v);
1836
 
        }
1837
 
 
1838
 
        return lp;
 
1961
    PyObject *lp;
 
1962
    PyArrayObject *v;
 
1963
    intp sz, i;
 
1964
 
 
1965
    if (!PyArray_Check(self)) {
 
1966
        return (PyObject *)self;
 
1967
    }
 
1968
    if (self->nd == 0) {
 
1969
        return self->descr->f->getitem(self->data,self);
 
1970
    }
 
1971
 
 
1972
    sz = self->dimensions[0];
 
1973
    lp = PyList_New(sz);
 
1974
    for(i = 0; i < sz; i++) {
 
1975
        v = (PyArrayObject *)array_big_item(self, i);
 
1976
        if (PyArray_Check(v) && (v->nd >= self->nd)) {
 
1977
            PyErr_SetString(PyExc_RuntimeError,
 
1978
                            "array_item not returning smaller-" \
 
1979
                            "dimensional array");
 
1980
            Py_DECREF(v);
 
1981
            Py_DECREF(lp);
 
1982
            return NULL;
 
1983
        }
 
1984
        PyList_SetItem(lp, i, PyArray_ToList(v));
 
1985
        Py_DECREF(v);
 
1986
    }
 
1987
    return lp;
1839
1988
}
1840
1989
 
1841
1990
/*OBJECT_API*/
1842
1991
static PyObject *
1843
1992
PyArray_ToString(PyArrayObject *self, NPY_ORDER order)
1844
1993
{
1845
 
        intp numbytes;
1846
 
        intp index;
1847
 
        char *dptr;
1848
 
        int elsize;
1849
 
        PyObject *ret;
1850
 
        PyArrayIterObject *it;
1851
 
 
1852
 
        if (order == NPY_ANYORDER)
1853
 
                order = PyArray_ISFORTRAN(self);
1854
 
 
1855
 
        /*        if (PyArray_TYPE(self) == PyArray_OBJECT) {
1856
 
                  PyErr_SetString(PyExc_ValueError, "a string for the data" \
1857
 
                  "in an object array is not appropriate");
1858
 
                  return NULL;
1859
 
                  }
1860
 
        */
1861
 
 
1862
 
        numbytes = PyArray_NBYTES(self);
1863
 
        if ((PyArray_ISCONTIGUOUS(self) && (order == NPY_CORDER)) ||    \
1864
 
            (PyArray_ISFORTRAN(self) && (order == NPY_FORTRANORDER))) {
1865
 
                ret = PyString_FromStringAndSize(self->data, (int) numbytes);
 
1994
    intp numbytes;
 
1995
    intp index;
 
1996
    char *dptr;
 
1997
    int elsize;
 
1998
    PyObject *ret;
 
1999
    PyArrayIterObject *it;
 
2000
 
 
2001
    if (order == NPY_ANYORDER)
 
2002
        order = PyArray_ISFORTRAN(self);
 
2003
 
 
2004
    /*        if (PyArray_TYPE(self) == PyArray_OBJECT) {
 
2005
              PyErr_SetString(PyExc_ValueError, "a string for the data" \
 
2006
              "in an object array is not appropriate");
 
2007
              return NULL;
 
2008
              }
 
2009
    */
 
2010
 
 
2011
    numbytes = PyArray_NBYTES(self);
 
2012
    if ((PyArray_ISCONTIGUOUS(self) && (order == NPY_CORDER)) ||    \
 
2013
        (PyArray_ISFORTRAN(self) && (order == NPY_FORTRANORDER))) {
 
2014
        ret = PyString_FromStringAndSize(self->data, (int) numbytes);
 
2015
    }
 
2016
    else {
 
2017
        PyObject *new;
 
2018
        if (order == NPY_FORTRANORDER) {
 
2019
            /* iterators are always in C-order */
 
2020
            new = PyArray_Transpose(self, NULL);
 
2021
            if (new == NULL) return NULL;
1866
2022
        }
1867
2023
        else {
1868
 
                PyObject *new;
1869
 
                if (order == NPY_FORTRANORDER) {
1870
 
                        /* iterators are always in C-order */
1871
 
                        new = PyArray_Transpose(self, NULL);
1872
 
                        if (new == NULL) return NULL;
1873
 
                }
1874
 
                else {
1875
 
                        Py_INCREF(self);
1876
 
                        new = (PyObject *)self;
1877
 
                }
1878
 
                it = (PyArrayIterObject *)PyArray_IterNew(new);
1879
 
                Py_DECREF(new);
1880
 
                if (it==NULL) return NULL;
1881
 
                ret = PyString_FromStringAndSize(NULL, (int) numbytes);
1882
 
                if (ret == NULL) {Py_DECREF(it); return NULL;}
1883
 
                dptr = PyString_AS_STRING(ret);
1884
 
                index = it->size;
1885
 
                elsize = self->descr->elsize;
1886
 
                while(index--) {
1887
 
                        memcpy(dptr, it->dataptr, elsize);
1888
 
                        dptr += elsize;
1889
 
                        PyArray_ITER_NEXT(it);
1890
 
                }
1891
 
                Py_DECREF(it);
1892
 
        }
1893
 
        return ret;
 
2024
            Py_INCREF(self);
 
2025
            new = (PyObject *)self;
 
2026
        }
 
2027
        it = (PyArrayIterObject *)PyArray_IterNew(new);
 
2028
        Py_DECREF(new);
 
2029
        if (it==NULL) return NULL;
 
2030
        ret = PyString_FromStringAndSize(NULL, (int) numbytes);
 
2031
        if (ret == NULL) {Py_DECREF(it); return NULL;}
 
2032
        dptr = PyString_AS_STRING(ret);
 
2033
        index = it->size;
 
2034
        elsize = self->descr->elsize;
 
2035
        while(index--) {
 
2036
            memcpy(dptr, it->dataptr, elsize);
 
2037
            dptr += elsize;
 
2038
            PyArray_ITER_NEXT(it);
 
2039
        }
 
2040
        Py_DECREF(it);
 
2041
    }
 
2042
    return ret;
1894
2043
}
1895
2044
 
1896
2045
 
1902
2051
static void
1903
2052
array_dealloc(PyArrayObject *self) {
1904
2053
 
1905
 
        if (self->weakreflist != NULL)
1906
 
                PyObject_ClearWeakRefs((PyObject *)self);
1907
 
 
1908
 
        if(self->base) {
1909
 
                /* UPDATEIFCOPY means that base points to an
1910
 
                   array that should be updated with the contents
1911
 
                   of this array upon destruction.
1912
 
                   self->base->flags must have been WRITEABLE
1913
 
                   (checked previously) and it was locked here
1914
 
                   thus, unlock it.
1915
 
                */
1916
 
                if (self->flags & UPDATEIFCOPY) {
1917
 
                        ((PyArrayObject *)self->base)->flags |= WRITEABLE;
1918
 
                        Py_INCREF(self); /* hold on to self in next call */
1919
 
                        if (PyArray_CopyAnyInto((PyArrayObject *)self->base,
1920
 
                                                self) < 0) {
1921
 
                                PyErr_Print();
1922
 
                                PyErr_Clear();
1923
 
                        }
1924
 
                        /* Don't need to DECREF -- because we are deleting
1925
 
                           self already... */
1926
 
                }
1927
 
                /* In any case base is pointing to something that we need
1928
 
                   to DECREF -- either a view or a buffer object */
1929
 
                Py_DECREF(self->base);
1930
 
        }
1931
 
 
1932
 
        if ((self->flags & OWNDATA) && self->data) {
1933
 
                /* Free internal references if an Object array */
1934
 
                if (PyDataType_FLAGCHK(self->descr, NPY_ITEM_REFCOUNT)) {
1935
 
                        Py_INCREF(self); /*hold on to self */
1936
 
                        PyArray_XDECREF(self);
1937
 
                        /* Don't need to DECREF -- because we are deleting
1938
 
                           self already... */
1939
 
                }
1940
 
                PyDataMem_FREE(self->data);
1941
 
        }
1942
 
 
1943
 
        PyDimMem_FREE(self->dimensions);
1944
 
 
1945
 
        Py_DECREF(self->descr);
1946
 
 
1947
 
        self->ob_type->tp_free((PyObject *)self);
 
2054
    if (self->weakreflist != NULL)
 
2055
        PyObject_ClearWeakRefs((PyObject *)self);
 
2056
 
 
2057
    if(self->base) {
 
2058
        /* UPDATEIFCOPY means that base points to an
 
2059
           array that should be updated with the contents
 
2060
           of this array upon destruction.
 
2061
           self->base->flags must have been WRITEABLE
 
2062
           (checked previously) and it was locked here
 
2063
           thus, unlock it.
 
2064
        */
 
2065
        if (self->flags & UPDATEIFCOPY) {
 
2066
            ((PyArrayObject *)self->base)->flags |= WRITEABLE;
 
2067
            Py_INCREF(self); /* hold on to self in next call */
 
2068
            if (PyArray_CopyAnyInto((PyArrayObject *)self->base,
 
2069
                                    self) < 0) {
 
2070
                PyErr_Print();
 
2071
                PyErr_Clear();
 
2072
            }
 
2073
            /* Don't need to DECREF -- because we are deleting
 
2074
               self already... */
 
2075
        }
 
2076
        /* In any case base is pointing to something that we need
 
2077
           to DECREF -- either a view or a buffer object */
 
2078
        Py_DECREF(self->base);
 
2079
    }
 
2080
 
 
2081
    if ((self->flags & OWNDATA) && self->data) {
 
2082
        /* Free internal references if an Object array */
 
2083
        if (PyDataType_FLAGCHK(self->descr, NPY_ITEM_REFCOUNT)) {
 
2084
            Py_INCREF(self); /*hold on to self */
 
2085
            PyArray_XDECREF(self);
 
2086
            /* Don't need to DECREF -- because we are deleting
 
2087
               self already... */
 
2088
        }
 
2089
        PyDataMem_FREE(self->data);
 
2090
    }
 
2091
 
 
2092
    PyDimMem_FREE(self->dimensions);
 
2093
 
 
2094
    Py_DECREF(self->descr);
 
2095
 
 
2096
    self->ob_type->tp_free((PyObject *)self);
1948
2097
}
1949
2098
 
1950
2099
/*************************************************************************
1954
2103
static Py_ssize_t
1955
2104
array_length(PyArrayObject *self)
1956
2105
{
1957
 
        if (self->nd != 0) {
1958
 
                return self->dimensions[0];
1959
 
        } else {
1960
 
                PyErr_SetString(PyExc_TypeError, "len() of unsized object");
1961
 
                return -1;
1962
 
        }
 
2106
    if (self->nd != 0) {
 
2107
        return self->dimensions[0];
 
2108
    } else {
 
2109
        PyErr_SetString(PyExc_TypeError, "len() of unsized object");
 
2110
        return -1;
 
2111
    }
1963
2112
}
1964
2113
 
1965
2114
static PyObject *
1966
2115
array_big_item(PyArrayObject *self, intp i)
1967
2116
{
1968
 
        char *item;
1969
 
        PyArrayObject *r;
1970
 
 
1971
 
        if(self->nd == 0) {
1972
 
                PyErr_SetString(PyExc_IndexError,
1973
 
                                "0-d arrays can't be indexed");
1974
 
                return NULL;
1975
 
        }
1976
 
        if ((item = index2ptr(self, i)) == NULL) return NULL;
1977
 
 
1978
 
        Py_INCREF(self->descr);
1979
 
        r = (PyArrayObject *)PyArray_NewFromDescr(self->ob_type,
1980
 
                                                  self->descr,
1981
 
                                                  self->nd-1,
1982
 
                                                  self->dimensions+1,
1983
 
                                                  self->strides+1, item,
1984
 
                                                  self->flags,
1985
 
                                                  (PyObject *)self);
1986
 
        if (r == NULL) return NULL;
1987
 
        Py_INCREF(self);
1988
 
        r->base = (PyObject *)self;
1989
 
        PyArray_UpdateFlags(r, CONTIGUOUS | FORTRAN);
1990
 
        return (PyObject *)r;
 
2117
    char *item;
 
2118
    PyArrayObject *r;
 
2119
 
 
2120
    if(self->nd == 0) {
 
2121
        PyErr_SetString(PyExc_IndexError,
 
2122
                        "0-d arrays can't be indexed");
 
2123
        return NULL;
 
2124
    }
 
2125
    if ((item = index2ptr(self, i)) == NULL) return NULL;
 
2126
 
 
2127
    Py_INCREF(self->descr);
 
2128
    r = (PyArrayObject *)PyArray_NewFromDescr(self->ob_type,
 
2129
                                              self->descr,
 
2130
                                              self->nd-1,
 
2131
                                              self->dimensions+1,
 
2132
                                              self->strides+1, item,
 
2133
                                              self->flags,
 
2134
                                              (PyObject *)self);
 
2135
    if (r == NULL) return NULL;
 
2136
    Py_INCREF(self);
 
2137
    r->base = (PyObject *)self;
 
2138
    PyArray_UpdateFlags(r, CONTIGUOUS | FORTRAN);
 
2139
    return (PyObject *)r;
1991
2140
}
1992
2141
 
1993
2142
/* contains optimization for 1-d arrays */
1994
2143
static PyObject *
1995
2144
array_item_nice(PyArrayObject *self, Py_ssize_t i)
1996
2145
{
1997
 
        if (self->nd == 1) {
1998
 
                char *item;
1999
 
                if ((item = index2ptr(self, i)) == NULL) return NULL;
2000
 
                return PyArray_Scalar(item, self->descr, (PyObject *)self);
2001
 
        }
2002
 
        else {
2003
 
                return PyArray_Return((PyArrayObject *)\
2004
 
                                      array_big_item(self, (intp) i));
2005
 
        }
 
2146
    if (self->nd == 1) {
 
2147
        char *item;
 
2148
        if ((item = index2ptr(self, i)) == NULL) return NULL;
 
2149
        return PyArray_Scalar(item, self->descr, (PyObject *)self);
 
2150
    }
 
2151
    else {
 
2152
        return PyArray_Return((PyArrayObject *)\
 
2153
                              array_big_item(self, (intp) i));
 
2154
    }
2006
2155
}
2007
2156
 
2008
2157
static int
2009
2158
array_ass_big_item(PyArrayObject *self, intp i, PyObject *v)
2010
2159
{
2011
 
        PyArrayObject *tmp;
2012
 
        char *item;
2013
 
        int ret;
2014
 
 
2015
 
        if (v == NULL) {
2016
 
                PyErr_SetString(PyExc_ValueError,
2017
 
                                "can't delete array elements");
2018
 
                return -1;
2019
 
        }
2020
 
        if (!PyArray_ISWRITEABLE(self)) {
2021
 
                PyErr_SetString(PyExc_RuntimeError,
2022
 
                                "array is not writeable");
2023
 
                return -1;
2024
 
        }
2025
 
        if (self->nd == 0) {
2026
 
                PyErr_SetString(PyExc_IndexError,
2027
 
                                "0-d arrays can't be indexed.");
2028
 
                return -1;
2029
 
        }
2030
 
 
2031
 
 
2032
 
        if (self->nd > 1) {
2033
 
                if((tmp = (PyArrayObject *)array_big_item(self, i)) == NULL)
2034
 
                        return -1;
2035
 
                ret = PyArray_CopyObject(tmp, v);
2036
 
                Py_DECREF(tmp);
2037
 
                return ret;
2038
 
        }
2039
 
 
2040
 
        if ((item = index2ptr(self, i)) == NULL) return -1;
2041
 
        if (self->descr->f->setitem(v, item, self) == -1) return -1;
2042
 
        return 0;
 
2160
    PyArrayObject *tmp;
 
2161
    char *item;
 
2162
    int ret;
 
2163
 
 
2164
    if (v == NULL) {
 
2165
        PyErr_SetString(PyExc_ValueError,
 
2166
                        "can't delete array elements");
 
2167
        return -1;
 
2168
    }
 
2169
    if (!PyArray_ISWRITEABLE(self)) {
 
2170
        PyErr_SetString(PyExc_RuntimeError,
 
2171
                        "array is not writeable");
 
2172
        return -1;
 
2173
    }
 
2174
    if (self->nd == 0) {
 
2175
        PyErr_SetString(PyExc_IndexError,
 
2176
                        "0-d arrays can't be indexed.");
 
2177
        return -1;
 
2178
    }
 
2179
 
 
2180
 
 
2181
    if (self->nd > 1) {
 
2182
        if((tmp = (PyArrayObject *)array_big_item(self, i)) == NULL)
 
2183
            return -1;
 
2184
        ret = PyArray_CopyObject(tmp, v);
 
2185
        Py_DECREF(tmp);
 
2186
        return ret;
 
2187
    }
 
2188
 
 
2189
    if ((item = index2ptr(self, i)) == NULL) return -1;
 
2190
    if (self->descr->f->setitem(v, item, self) == -1) return -1;
 
2191
    return 0;
2043
2192
}
2044
2193
 
2045
2194
#if PY_VERSION_HEX < 0x02050000
2046
 
 #if SIZEOF_INT == SIZEOF_INTP
2047
 
 #define array_ass_item array_ass_big_item
2048
 
 #endif
 
2195
#if SIZEOF_INT == SIZEOF_INTP
 
2196
#define array_ass_item array_ass_big_item
 
2197
#endif
2049
2198
#else
2050
 
 #if SIZEOF_SIZE_T == SIZEOF_INTP
2051
 
 #define array_ass_item array_ass_big_item
2052
 
 #endif
 
2199
#if SIZEOF_SIZE_T == SIZEOF_INTP
 
2200
#define array_ass_item array_ass_big_item
 
2201
#endif
2053
2202
#endif
2054
2203
#ifndef array_ass_item
2055
2204
static int
2056
2205
array_ass_item(PyArrayObject *self, Py_ssize_t i, PyObject *v)
2057
2206
{
2058
 
        return array_ass_big_item(self, (intp) i, v);
 
2207
    return array_ass_big_item(self, (intp) i, v);
2059
2208
}
2060
2209
#endif
2061
2210
 
2064
2213
static int
2065
2214
slice_coerce_index(PyObject *o, intp *v)
2066
2215
{
2067
 
        *v = PyArray_PyIntAsIntp(o);
2068
 
        if (error_converting(*v)) {
2069
 
                PyErr_Clear();
2070
 
                return 0;
2071
 
        }
2072
 
        return 1;
 
2216
    *v = PyArray_PyIntAsIntp(o);
 
2217
    if (error_converting(*v)) {
 
2218
        PyErr_Clear();
 
2219
        return 0;
 
2220
    }
 
2221
    return 1;
2073
2222
}
2074
2223
 
2075
2224
 
2080
2229
                 intp *start, intp *stop, intp *step,
2081
2230
                 intp *slicelength)
2082
2231
{
2083
 
        intp defstop;
2084
 
 
2085
 
        if (r->step == Py_None) {
2086
 
                *step = 1;
2087
 
        } else {
2088
 
                if (!slice_coerce_index(r->step, step)) return -1;
2089
 
                if (*step == 0) {
2090
 
                        PyErr_SetString(PyExc_ValueError,
2091
 
                                        "slice step cannot be zero");
2092
 
                        return -1;
2093
 
                }
2094
 
        }
2095
 
        /* defstart = *step < 0 ? length - 1 : 0; */
2096
 
 
2097
 
        defstop = *step < 0 ? -1 : length;
2098
 
 
2099
 
        if (r->start == Py_None) {
2100
 
                *start = *step < 0 ? length-1 : 0;
2101
 
        } else {
2102
 
                if (!slice_coerce_index(r->start, start)) return -1;
2103
 
                if (*start < 0) *start += length;
2104
 
                if (*start < 0) *start = (*step < 0) ? -1 : 0;
2105
 
                if (*start >= length) {
2106
 
                        *start = (*step < 0) ? length - 1 : length;
2107
 
                }
2108
 
        }
2109
 
 
2110
 
        if (r->stop == Py_None) {
2111
 
                *stop = defstop;
2112
 
        } else {
2113
 
                if (!slice_coerce_index(r->stop, stop)) return -1;
2114
 
                if (*stop < 0) *stop += length;
 
2232
    intp defstop;
 
2233
 
 
2234
    if (r->step == Py_None) {
 
2235
        *step = 1;
 
2236
    } else {
 
2237
        if (!slice_coerce_index(r->step, step)) return -1;
 
2238
        if (*step == 0) {
 
2239
            PyErr_SetString(PyExc_ValueError,
 
2240
                            "slice step cannot be zero");
 
2241
            return -1;
 
2242
        }
 
2243
    }
 
2244
    /* defstart = *step < 0 ? length - 1 : 0; */
 
2245
 
 
2246
    defstop = *step < 0 ? -1 : length;
 
2247
 
 
2248
    if (r->start == Py_None) {
 
2249
        *start = *step < 0 ? length-1 : 0;
 
2250
    } else {
 
2251
        if (!slice_coerce_index(r->start, start)) return -1;
 
2252
        if (*start < 0) *start += length;
 
2253
        if (*start < 0) *start = (*step < 0) ? -1 : 0;
 
2254
        if (*start >= length) {
 
2255
            *start = (*step < 0) ? length - 1 : length;
 
2256
        }
 
2257
    }
 
2258
 
 
2259
    if (r->stop == Py_None) {
 
2260
        *stop = defstop;
 
2261
    } else {
 
2262
        if (!slice_coerce_index(r->stop, stop)) return -1;
 
2263
        if (*stop < 0) *stop += length;
2115
2264
        if (*stop < 0) *stop = -1;
2116
2265
        if (*stop > length) *stop = length;
2117
 
        }
2118
 
 
2119
 
        if ((*step < 0 && *stop >= *start) || \
2120
 
            (*step > 0 && *start >= *stop)) {
2121
 
                *slicelength = 0;
2122
 
        } else if (*step < 0) {
2123
 
                *slicelength = (*stop - *start + 1) / (*step) + 1;
2124
 
        } else {
2125
 
                *slicelength = (*stop - *start - 1) / (*step) + 1;
2126
 
        }
2127
 
 
2128
 
        return 0;
 
2266
    }
 
2267
 
 
2268
    if ((*step < 0 && *stop >= *start) || \
 
2269
        (*step > 0 && *start >= *stop)) {
 
2270
        *slicelength = 0;
 
2271
    } else if (*step < 0) {
 
2272
        *slicelength = (*stop - *start + 1) / (*step) + 1;
 
2273
    } else {
 
2274
        *slicelength = (*stop - *start - 1) / (*step) + 1;
 
2275
    }
 
2276
 
 
2277
    return 0;
2129
2278
}
2130
2279
 
2131
2280
#define PseudoIndex -1
2135
2284
static intp
2136
2285
parse_subindex(PyObject *op, intp *step_size, intp *n_steps, intp max)
2137
2286
{
2138
 
        intp index;
 
2287
    intp index;
2139
2288
 
2140
 
        if (op == Py_None) {
2141
 
                *n_steps = PseudoIndex;
2142
 
                index = 0;
2143
 
        } else if (op == Py_Ellipsis) {
2144
 
                *n_steps = RubberIndex;
2145
 
                index = 0;
2146
 
        } else if (PySlice_Check(op)) {
2147
 
                intp stop;
2148
 
                if (slice_GetIndices((PySliceObject *)op, max,
2149
 
                                     &index, &stop, step_size, n_steps) < 0) {
2150
 
                        if (!PyErr_Occurred()) {
2151
 
                                PyErr_SetString(PyExc_IndexError,
2152
 
                                                "invalid slice");
2153
 
                        }
2154
 
                        goto fail;
2155
 
                }
2156
 
                if (*n_steps <= 0) {
2157
 
                        *n_steps = 0;
2158
 
                        *step_size = 1;
2159
 
                        index = 0;
2160
 
                }
2161
 
        } else {
2162
 
                index = PyArray_PyIntAsIntp(op);
2163
 
                if (error_converting(index)) {
2164
 
                        PyErr_SetString(PyExc_IndexError,
2165
 
                                        "each subindex must be either a "\
2166
 
                                        "slice, an integer, Ellipsis, or "\
2167
 
                                        "newaxis");
2168
 
                        goto fail;
2169
 
                }
2170
 
                *n_steps = SingleIndex;
2171
 
                *step_size = 0;
2172
 
                if (index < 0) index += max;
2173
 
                if (index >= max || index < 0) {
2174
 
                        PyErr_SetString(PyExc_IndexError, "invalid index");
2175
 
                        goto fail;
2176
 
                }
2177
 
        }
2178
 
        return index;
 
2289
    if (op == Py_None) {
 
2290
        *n_steps = PseudoIndex;
 
2291
        index = 0;
 
2292
    } else if (op == Py_Ellipsis) {
 
2293
        *n_steps = RubberIndex;
 
2294
        index = 0;
 
2295
    } else if (PySlice_Check(op)) {
 
2296
        intp stop;
 
2297
        if (slice_GetIndices((PySliceObject *)op, max,
 
2298
                             &index, &stop, step_size, n_steps) < 0) {
 
2299
            if (!PyErr_Occurred()) {
 
2300
                PyErr_SetString(PyExc_IndexError,
 
2301
                                "invalid slice");
 
2302
            }
 
2303
            goto fail;
 
2304
        }
 
2305
        if (*n_steps <= 0) {
 
2306
            *n_steps = 0;
 
2307
            *step_size = 1;
 
2308
            index = 0;
 
2309
        }
 
2310
    } else {
 
2311
        index = PyArray_PyIntAsIntp(op);
 
2312
        if (error_converting(index)) {
 
2313
            PyErr_SetString(PyExc_IndexError,
 
2314
                            "each subindex must be either a "\
 
2315
                            "slice, an integer, Ellipsis, or "\
 
2316
                            "newaxis");
 
2317
            goto fail;
 
2318
        }
 
2319
        *n_steps = SingleIndex;
 
2320
        *step_size = 0;
 
2321
        if (index < 0) index += max;
 
2322
        if (index >= max || index < 0) {
 
2323
            PyErr_SetString(PyExc_IndexError, "invalid index");
 
2324
            goto fail;
 
2325
        }
 
2326
    }
 
2327
    return index;
2179
2328
 fail:
2180
 
        return -1;
 
2329
    return -1;
2181
2330
}
2182
2331
 
2183
2332
 
2185
2334
parse_index(PyArrayObject *self, PyObject *op,
2186
2335
            intp *dimensions, intp *strides, intp *offset_ptr)
2187
2336
{
2188
 
        int i, j, n;
2189
 
        int nd_old, nd_new, n_add, n_pseudo;
2190
 
        intp n_steps, start, offset, step_size;
2191
 
        PyObject *op1=NULL;
2192
 
        int is_slice;
2193
 
 
2194
 
        if (PySlice_Check(op) || op == Py_Ellipsis || op == Py_None) {
2195
 
                n = 1;
2196
 
                op1 = op;
2197
 
                Py_INCREF(op);
2198
 
                /* this relies on the fact that n==1 for loop below */
2199
 
                is_slice = 1;
2200
 
        }
2201
 
        else {
2202
 
                if (!PySequence_Check(op)) {
2203
 
                        PyErr_SetString(PyExc_IndexError,
2204
 
                                        "index must be either an int "\
2205
 
                                        "or a sequence");
2206
 
                        return -1;
2207
 
                }
2208
 
                n = PySequence_Length(op);
2209
 
                is_slice = 0;
2210
 
        }
2211
 
 
2212
 
        nd_old = nd_new = 0;
2213
 
 
2214
 
        offset = 0;
2215
 
        for(i=0; i<n; i++) {
2216
 
                if (!is_slice) {
2217
 
                        if (!(op1=PySequence_GetItem(op, i))) {
2218
 
                                PyErr_SetString(PyExc_IndexError,
2219
 
                                                "invalid index");
2220
 
                                return -1;
2221
 
                        }
2222
 
                }
2223
 
 
2224
 
                start = parse_subindex(op1, &step_size, &n_steps,
2225
 
                                       nd_old < self->nd ? \
2226
 
                                       self->dimensions[nd_old] : 0);
2227
 
                Py_DECREF(op1);
2228
 
                if (start == -1) break;
2229
 
 
2230
 
                if (n_steps == PseudoIndex) {
2231
 
                        dimensions[nd_new] = 1; strides[nd_new] = 0;
2232
 
                        nd_new++;
2233
 
                } else {
2234
 
                        if (n_steps == RubberIndex) {
2235
 
                                for(j=i+1, n_pseudo=0; j<n; j++) {
2236
 
                                        op1 = PySequence_GetItem(op, j);
2237
 
                                        if (op1 == Py_None) n_pseudo++;
2238
 
                                        Py_DECREF(op1);
2239
 
                                }
2240
 
                                n_add = self->nd-(n-i-n_pseudo-1+nd_old);
2241
 
                                if (n_add < 0) {
2242
 
                                        PyErr_SetString(PyExc_IndexError,
2243
 
                                                        "too many indices");
2244
 
                                        return -1;
2245
 
                                }
2246
 
                                for(j=0; j<n_add; j++) {
2247
 
                                        dimensions[nd_new] = \
2248
 
                                                self->dimensions[nd_old];
2249
 
                                        strides[nd_new] = \
2250
 
                                                self->strides[nd_old];
2251
 
                                        nd_new++; nd_old++;
2252
 
                                }
2253
 
                        } else {
2254
 
                                if (nd_old >= self->nd) {
2255
 
                                        PyErr_SetString(PyExc_IndexError,
2256
 
                                                        "too many indices");
2257
 
                                        return -1;
2258
 
                                }
2259
 
                                offset += self->strides[nd_old]*start;
2260
 
                                nd_old++;
2261
 
                                if (n_steps != SingleIndex) {
2262
 
                                        dimensions[nd_new] = n_steps;
2263
 
                                        strides[nd_new] = step_size * \
2264
 
                                                self->strides[nd_old-1];
2265
 
                                        nd_new++;
2266
 
                                }
2267
 
                        }
2268
 
                }
2269
 
        }
2270
 
        if (i < n) return -1;
2271
 
        n_add = self->nd-nd_old;
2272
 
        for(j=0; j<n_add; j++) {
2273
 
                dimensions[nd_new] = self->dimensions[nd_old];
2274
 
                strides[nd_new] = self->strides[nd_old];
2275
 
                nd_new++; nd_old++;
2276
 
        }
2277
 
        *offset_ptr = offset;
2278
 
        return nd_new;
 
2337
    int i, j, n;
 
2338
    int nd_old, nd_new, n_add, n_pseudo;
 
2339
    intp n_steps, start, offset, step_size;
 
2340
    PyObject *op1=NULL;
 
2341
    int is_slice;
 
2342
 
 
2343
    if (PySlice_Check(op) || op == Py_Ellipsis || op == Py_None) {
 
2344
        n = 1;
 
2345
        op1 = op;
 
2346
        Py_INCREF(op);
 
2347
        /* this relies on the fact that n==1 for loop below */
 
2348
        is_slice = 1;
 
2349
    }
 
2350
    else {
 
2351
        if (!PySequence_Check(op)) {
 
2352
            PyErr_SetString(PyExc_IndexError,
 
2353
                            "index must be either an int "\
 
2354
                            "or a sequence");
 
2355
            return -1;
 
2356
        }
 
2357
        n = PySequence_Length(op);
 
2358
        is_slice = 0;
 
2359
    }
 
2360
 
 
2361
    nd_old = nd_new = 0;
 
2362
 
 
2363
    offset = 0;
 
2364
    for(i=0; i<n; i++) {
 
2365
        if (!is_slice) {
 
2366
            if (!(op1=PySequence_GetItem(op, i))) {
 
2367
                PyErr_SetString(PyExc_IndexError,
 
2368
                                "invalid index");
 
2369
                return -1;
 
2370
            }
 
2371
        }
 
2372
 
 
2373
        start = parse_subindex(op1, &step_size, &n_steps,
 
2374
                               nd_old < self->nd ? \
 
2375
                               self->dimensions[nd_old] : 0);
 
2376
        Py_DECREF(op1);
 
2377
        if (start == -1) break;
 
2378
 
 
2379
        if (n_steps == PseudoIndex) {
 
2380
            dimensions[nd_new] = 1; strides[nd_new] = 0;
 
2381
            nd_new++;
 
2382
        } else {
 
2383
            if (n_steps == RubberIndex) {
 
2384
                for(j=i+1, n_pseudo=0; j<n; j++) {
 
2385
                    op1 = PySequence_GetItem(op, j);
 
2386
                    if (op1 == Py_None) n_pseudo++;
 
2387
                    Py_DECREF(op1);
 
2388
                }
 
2389
                n_add = self->nd-(n-i-n_pseudo-1+nd_old);
 
2390
                if (n_add < 0) {
 
2391
                    PyErr_SetString(PyExc_IndexError,
 
2392
                                    "too many indices");
 
2393
                    return -1;
 
2394
                }
 
2395
                for(j=0; j<n_add; j++) {
 
2396
                    dimensions[nd_new] = \
 
2397
                        self->dimensions[nd_old];
 
2398
                    strides[nd_new] = \
 
2399
                        self->strides[nd_old];
 
2400
                    nd_new++; nd_old++;
 
2401
                }
 
2402
            } else {
 
2403
                if (nd_old >= self->nd) {
 
2404
                    PyErr_SetString(PyExc_IndexError,
 
2405
                                    "too many indices");
 
2406
                    return -1;
 
2407
                }
 
2408
                offset += self->strides[nd_old]*start;
 
2409
                nd_old++;
 
2410
                if (n_steps != SingleIndex) {
 
2411
                    dimensions[nd_new] = n_steps;
 
2412
                    strides[nd_new] = step_size * \
 
2413
                        self->strides[nd_old-1];
 
2414
                    nd_new++;
 
2415
                }
 
2416
            }
 
2417
        }
 
2418
    }
 
2419
    if (i < n) return -1;
 
2420
    n_add = self->nd-nd_old;
 
2421
    for(j=0; j<n_add; j++) {
 
2422
        dimensions[nd_new] = self->dimensions[nd_old];
 
2423
        strides[nd_new] = self->strides[nd_old];
 
2424
        nd_new++; nd_old++;
 
2425
    }
 
2426
    *offset_ptr = offset;
 
2427
    return nd_new;
2279
2428
}
2280
2429
 
2281
2430
static void
2282
2431
_swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getmap)
2283
2432
{
2284
 
        PyObject *new;
2285
 
        int n1, n2, n3, val, bnd;
2286
 
        int i;
2287
 
        PyArray_Dims permute;
2288
 
        intp d[MAX_DIMS];
2289
 
        PyArrayObject *arr;
2290
 
 
2291
 
        permute.ptr = d;
2292
 
        permute.len = mit->nd;
2293
 
 
2294
 
        /* arr might not have the right number of dimensions
2295
 
           and need to be reshaped first by pre-pending ones */
2296
 
        arr = *ret;
2297
 
        if (arr->nd != mit->nd) {
2298
 
                for (i=1; i<=arr->nd; i++) {
2299
 
                        permute.ptr[mit->nd-i] = arr->dimensions[arr->nd-i];
2300
 
                }
2301
 
                for (i=0; i<mit->nd-arr->nd; i++) {
2302
 
                        permute.ptr[i] = 1;
2303
 
                }
2304
 
                new = PyArray_Newshape(arr, &permute, PyArray_ANYORDER);
2305
 
                Py_DECREF(arr);
2306
 
                *ret = (PyArrayObject *)new;
2307
 
                if (new == NULL) return;
2308
 
        }
2309
 
 
2310
 
        /* Setting and getting need to have different permutations.
2311
 
           On the get we are permuting the returned object, but on
2312
 
           setting we are permuting the object-to-be-set. 
2313
 
           The set permutation is the inverse of the get permutation.
2314
 
        */
2315
 
 
2316
 
        /* For getting the array the tuple for transpose is
2317
 
           (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1)
2318
 
           n1 is the number of dimensions of
2319
 
              the broadcasted index array
2320
 
           n2 is the number of dimensions skipped at the
2321
 
              start 
2322
 
           n3 is the number of dimensions of the
2323
 
              result
2324
 
        */
2325
 
 
2326
 
        /* For setting the array the tuple for transpose is
2327
 
           (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1)
2328
 
        */
2329
 
        n1 = mit->iters[0]->nd_m1 + 1;
2330
 
        n2 = mit->iteraxes[0];
2331
 
        n3 = mit->nd;
2332
 
 
2333
 
        bnd = (getmap ? n1 : n2); /* use n1 as the boundary if getting
2334
 
                                      but n2 if setting */
2335
 
        
2336
 
        val = bnd;
2337
 
        i = 0;
2338
 
        while(val < n1+n2)
2339
 
                permute.ptr[i++] = val++;
2340
 
        val = 0;
2341
 
        while(val < bnd)
2342
 
                permute.ptr[i++] = val++;
2343
 
        val = n1+n2;
2344
 
        while(val < n3)
2345
 
                permute.ptr[i++] = val++;
2346
 
 
2347
 
        new = PyArray_Transpose(*ret, &permute);
2348
 
        Py_DECREF(*ret);
 
2433
    PyObject *new;
 
2434
    int n1, n2, n3, val, bnd;
 
2435
    int i;
 
2436
    PyArray_Dims permute;
 
2437
    intp d[MAX_DIMS];
 
2438
    PyArrayObject *arr;
 
2439
 
 
2440
    permute.ptr = d;
 
2441
    permute.len = mit->nd;
 
2442
 
 
2443
    /* arr might not have the right number of dimensions
 
2444
       and need to be reshaped first by pre-pending ones */
 
2445
    arr = *ret;
 
2446
    if (arr->nd != mit->nd) {
 
2447
        for(i=1; i<=arr->nd; i++) {
 
2448
            permute.ptr[mit->nd-i] = arr->dimensions[arr->nd-i];
 
2449
        }
 
2450
        for(i=0; i<mit->nd-arr->nd; i++) {
 
2451
            permute.ptr[i] = 1;
 
2452
        }
 
2453
        new = PyArray_Newshape(arr, &permute, PyArray_ANYORDER);
 
2454
        Py_DECREF(arr);
2349
2455
        *ret = (PyArrayObject *)new;
 
2456
        if (new == NULL) return;
 
2457
    }
 
2458
 
 
2459
    /* Setting and getting need to have different permutations.
 
2460
       On the get we are permuting the returned object, but on
 
2461
       setting we are permuting the object-to-be-set.
 
2462
       The set permutation is the inverse of the get permutation.
 
2463
    */
 
2464
 
 
2465
    /* For getting the array the tuple for transpose is
 
2466
       (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1)
 
2467
       n1 is the number of dimensions of
 
2468
       the broadcasted index array
 
2469
       n2 is the number of dimensions skipped at the
 
2470
       start
 
2471
       n3 is the number of dimensions of the
 
2472
       result
 
2473
    */
 
2474
 
 
2475
    /* For setting the array the tuple for transpose is
 
2476
       (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1)
 
2477
    */
 
2478
    n1 = mit->iters[0]->nd_m1 + 1;
 
2479
    n2 = mit->iteraxes[0];
 
2480
    n3 = mit->nd;
 
2481
 
 
2482
    bnd = (getmap ? n1 : n2); /* use n1 as the boundary if getting
 
2483
                                 but n2 if setting */
 
2484
 
 
2485
    val = bnd;
 
2486
    i = 0;
 
2487
    while(val < n1+n2)
 
2488
        permute.ptr[i++] = val++;
 
2489
    val = 0;
 
2490
    while(val < bnd)
 
2491
        permute.ptr[i++] = val++;
 
2492
    val = n1+n2;
 
2493
    while(val < n3)
 
2494
        permute.ptr[i++] = val++;
 
2495
 
 
2496
    new = PyArray_Transpose(*ret, &permute);
 
2497
    Py_DECREF(*ret);
 
2498
    *ret = (PyArrayObject *)new;
2350
2499
}
2351
2500
 
2352
2501
/* Prototypes for Mapping calls --- not part of the C-API
2362
2511
PyArray_GetMap(PyArrayMapIterObject *mit)
2363
2512
{
2364
2513
 
2365
 
        PyArrayObject *ret, *temp;
2366
 
        PyArrayIterObject *it;
2367
 
        int index;
2368
 
        int swap;
2369
 
        PyArray_CopySwapFunc *copyswap;
2370
 
 
2371
 
        /* Unbound map iterator --- Bind should have been called */
2372
 
        if (mit->ait == NULL) return NULL;
2373
 
 
2374
 
        /* This relies on the map iterator object telling us the shape
2375
 
           of the new array in nd and dimensions.
2376
 
        */
2377
 
        temp = mit->ait->ao;
2378
 
        Py_INCREF(temp->descr);
2379
 
        ret = (PyArrayObject *)\
2380
 
                PyArray_NewFromDescr(temp->ob_type,
2381
 
                                     temp->descr,
2382
 
                                     mit->nd, mit->dimensions,
2383
 
                                     NULL, NULL,
2384
 
                                     PyArray_ISFORTRAN(temp),
2385
 
                                     (PyObject *)temp);
2386
 
        if (ret == NULL) return NULL;
2387
 
 
2388
 
        /* Now just iterate through the new array filling it in
2389
 
           with the next object from the original array as
2390
 
           defined by the mapping iterator */
2391
 
 
2392
 
        if ((it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ret))
2393
 
            == NULL) {
2394
 
                Py_DECREF(ret);
2395
 
                return NULL;
2396
 
        }
2397
 
        index = it->size;
2398
 
        swap = (PyArray_ISNOTSWAPPED(temp) != PyArray_ISNOTSWAPPED(ret));
2399
 
        copyswap = ret->descr->f->copyswap;
2400
 
        PyArray_MapIterReset(mit);
 
2514
    PyArrayObject *ret, *temp;
 
2515
    PyArrayIterObject *it;
 
2516
    int index;
 
2517
    int swap;
 
2518
    PyArray_CopySwapFunc *copyswap;
 
2519
 
 
2520
    /* Unbound map iterator --- Bind should have been called */
 
2521
    if (mit->ait == NULL) return NULL;
 
2522
 
 
2523
    /* This relies on the map iterator object telling us the shape
 
2524
       of the new array in nd and dimensions.
 
2525
    */
 
2526
    temp = mit->ait->ao;
 
2527
    Py_INCREF(temp->descr);
 
2528
    ret = (PyArrayObject *)\
 
2529
        PyArray_NewFromDescr(temp->ob_type,
 
2530
                             temp->descr,
 
2531
                             mit->nd, mit->dimensions,
 
2532
                             NULL, NULL,
 
2533
                             PyArray_ISFORTRAN(temp),
 
2534
                             (PyObject *)temp);
 
2535
    if (ret == NULL) return NULL;
 
2536
 
 
2537
    /* Now just iterate through the new array filling it in
 
2538
       with the next object from the original array as
 
2539
       defined by the mapping iterator */
 
2540
 
 
2541
    if ((it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ret))
 
2542
        == NULL) {
 
2543
        Py_DECREF(ret);
 
2544
        return NULL;
 
2545
    }
 
2546
    index = it->size;
 
2547
    swap = (PyArray_ISNOTSWAPPED(temp) != PyArray_ISNOTSWAPPED(ret));
 
2548
    copyswap = ret->descr->f->copyswap;
 
2549
    PyArray_MapIterReset(mit);
 
2550
    while (index--) {
 
2551
        copyswap(it->dataptr, mit->dataptr, swap, ret);
 
2552
        PyArray_MapIterNext(mit);
 
2553
        PyArray_ITER_NEXT(it);
 
2554
    }
 
2555
    Py_DECREF(it);
 
2556
 
 
2557
    /* check for consecutive axes */
 
2558
    if ((mit->subspace != NULL) && (mit->consec)) {
 
2559
        if (mit->iteraxes[0] > 0) {  /* then we need to swap */
 
2560
            _swap_axes(mit, &ret, 1);
 
2561
        }
 
2562
    }
 
2563
    return (PyObject *)ret;
 
2564
}
 
2565
 
 
2566
static int
 
2567
PyArray_SetMap(PyArrayMapIterObject *mit, PyObject *op)
 
2568
{
 
2569
    PyObject *arr=NULL;
 
2570
    PyArrayIterObject *it;
 
2571
    int index;
 
2572
    int swap;
 
2573
    PyArray_CopySwapFunc *copyswap;
 
2574
    PyArray_Descr *descr;
 
2575
 
 
2576
    /* Unbound Map Iterator */
 
2577
    if (mit->ait == NULL) return -1;
 
2578
 
 
2579
    descr = mit->ait->ao->descr;
 
2580
    Py_INCREF(descr);
 
2581
    arr = PyArray_FromAny(op, descr, 0, 0, FORCECAST, NULL);
 
2582
    if (arr == NULL) return -1;
 
2583
 
 
2584
    if ((mit->subspace != NULL) && (mit->consec)) {
 
2585
        if (mit->iteraxes[0] > 0) {  /* then we need to swap */
 
2586
            _swap_axes(mit, (PyArrayObject **)&arr, 0);
 
2587
            if (arr == NULL) return -1;
 
2588
        }
 
2589
    }
 
2590
 
 
2591
    /* Be sure values array is "broadcastable"
 
2592
       to shape of mit->dimensions, mit->nd */
 
2593
 
 
2594
    if ((it = (PyArrayIterObject *)\
 
2595
         PyArray_BroadcastToShape(arr, mit->dimensions, mit->nd))==NULL) {
 
2596
        Py_DECREF(arr);
 
2597
        return -1;
 
2598
    }
 
2599
 
 
2600
    index = mit->size;
 
2601
    swap = (PyArray_ISNOTSWAPPED(mit->ait->ao) != \
 
2602
            (PyArray_ISNOTSWAPPED(arr)));
 
2603
    copyswap = PyArray_DESCR(arr)->f->copyswap;
 
2604
    PyArray_MapIterReset(mit);
 
2605
    /* Need to decref hasobject arrays */
 
2606
    if (PyDataType_FLAGCHK(descr, NPY_ITEM_REFCOUNT)) {
2401
2607
        while (index--) {
2402
 
                copyswap(it->dataptr, mit->dataptr, swap, ret);
2403
 
                PyArray_MapIterNext(mit);
2404
 
                PyArray_ITER_NEXT(it);
2405
 
        }
2406
 
        Py_DECREF(it);
2407
 
 
2408
 
        /* check for consecutive axes */
2409
 
        if ((mit->subspace != NULL) && (mit->consec)) {
2410
 
                if (mit->iteraxes[0] > 0) {  /* then we need to swap */
2411
 
                        _swap_axes(mit, &ret, 1);
2412
 
                }
2413
 
        }
2414
 
        return (PyObject *)ret;
2415
 
}
2416
 
 
2417
 
static int
2418
 
PyArray_SetMap(PyArrayMapIterObject *mit, PyObject *op)
2419
 
{
2420
 
        PyObject *arr=NULL;
2421
 
        PyArrayIterObject *it;
2422
 
        int index;
2423
 
        int swap;
2424
 
        PyArray_CopySwapFunc *copyswap;
2425
 
        PyArray_Descr *descr;
2426
 
 
2427
 
        /* Unbound Map Iterator */
2428
 
        if (mit->ait == NULL) return -1;
2429
 
 
2430
 
        descr = mit->ait->ao->descr;
2431
 
        Py_INCREF(descr);
2432
 
        arr = PyArray_FromAny(op, descr, 0, 0, FORCECAST, NULL);
2433
 
        if (arr == NULL) return -1;
2434
 
 
2435
 
        if ((mit->subspace != NULL) && (mit->consec)) {
2436
 
                if (mit->iteraxes[0] > 0) {  /* then we need to swap */
2437
 
                        _swap_axes(mit, (PyArrayObject **)&arr, 0);
2438
 
                        if (arr == NULL) return -1;
2439
 
                }
2440
 
        }
2441
 
 
2442
 
        /* Be sure values array is "broadcastable"
2443
 
           to shape of mit->dimensions, mit->nd */
2444
 
 
2445
 
        if ((it = (PyArrayIterObject *)\
2446
 
             PyArray_BroadcastToShape(arr, mit->dimensions, mit->nd))==NULL) {
2447
 
                Py_DECREF(arr);
2448
 
                return -1;
2449
 
        }
2450
 
 
2451
 
        index = mit->size;
2452
 
        swap = (PyArray_ISNOTSWAPPED(mit->ait->ao) != \
2453
 
                (PyArray_ISNOTSWAPPED(arr)));
2454
 
        copyswap = PyArray_DESCR(arr)->f->copyswap;
2455
 
        PyArray_MapIterReset(mit);
2456
 
        /* Need to decref hasobject arrays */
2457
 
        if (PyDataType_FLAGCHK(descr, NPY_ITEM_REFCOUNT)) {
2458
 
                while (index--) {
2459
 
                        PyArray_Item_XDECREF(mit->dataptr, PyArray_DESCR(arr));
2460
 
                        PyArray_Item_INCREF(it->dataptr, PyArray_DESCR(arr));
2461
 
                        memmove(mit->dataptr, it->dataptr, sizeof(PyObject *));
2462
 
                        /* ignored unless VOID array with object's */
2463
 
                        if (swap)
2464
 
                                copyswap(mit->dataptr, NULL, swap, arr);
2465
 
                        PyArray_MapIterNext(mit);
2466
 
                        PyArray_ITER_NEXT(it);
2467
 
                }
2468
 
                Py_DECREF(arr);
2469
 
                Py_DECREF(it);
2470
 
                return 0;
2471
 
        }
2472
 
        while(index--) {
2473
 
                memmove(mit->dataptr, it->dataptr, PyArray_ITEMSIZE(arr));
2474
 
                if (swap)
2475
 
                        copyswap(mit->dataptr, NULL, swap, arr);
2476
 
                PyArray_MapIterNext(mit);
2477
 
                PyArray_ITER_NEXT(it);
 
2608
            PyArray_Item_XDECREF(mit->dataptr, PyArray_DESCR(arr));
 
2609
            PyArray_Item_INCREF(it->dataptr, PyArray_DESCR(arr));
 
2610
            memmove(mit->dataptr, it->dataptr, sizeof(PyObject *));
 
2611
            /* ignored unless VOID array with object's */
 
2612
            if (swap)
 
2613
                copyswap(mit->dataptr, NULL, swap, arr);
 
2614
            PyArray_MapIterNext(mit);
 
2615
            PyArray_ITER_NEXT(it);
2478
2616
        }
2479
2617
        Py_DECREF(arr);
2480
2618
        Py_DECREF(it);
2481
2619
        return 0;
 
2620
    }
 
2621
    while(index--) {
 
2622
        memmove(mit->dataptr, it->dataptr, PyArray_ITEMSIZE(arr));
 
2623
        if (swap)
 
2624
            copyswap(mit->dataptr, NULL, swap, arr);
 
2625
        PyArray_MapIterNext(mit);
 
2626
        PyArray_ITER_NEXT(it);
 
2627
    }
 
2628
    Py_DECREF(arr);
 
2629
    Py_DECREF(it);
 
2630
    return 0;
2482
2631
}
2483
2632
 
2484
 
int
 
2633
static int
2485
2634
count_new_axes_0d(PyObject *tuple)
2486
2635
{
2487
 
        int i, argument_count;
2488
 
        int ellipsis_count = 0;
2489
 
        int newaxis_count = 0;
2490
 
 
2491
 
        argument_count = PyTuple_GET_SIZE(tuple);
2492
 
 
2493
 
        for (i = 0; i < argument_count; ++i) {
2494
 
                PyObject *arg = PyTuple_GET_ITEM(tuple, i);
2495
 
                if (arg == Py_Ellipsis && !ellipsis_count) ellipsis_count++;
2496
 
                else if (arg == Py_None) newaxis_count++;
2497
 
                else break;
2498
 
        }
2499
 
        if (i < argument_count) {
2500
 
                PyErr_SetString(PyExc_IndexError,
2501
 
                                "0-d arrays can only use a single ()"
2502
 
                                " or a list of newaxes (and a single ...)"
2503
 
                                " as an index");
2504
 
                return -1;
2505
 
        }
2506
 
        if (newaxis_count > MAX_DIMS) {
2507
 
                PyErr_SetString(PyExc_IndexError,
2508
 
                                "too many dimensions");
2509
 
                return -1;
2510
 
        }
2511
 
        return newaxis_count;
 
2636
    int i, argument_count;
 
2637
    int ellipsis_count = 0;
 
2638
    int newaxis_count = 0;
 
2639
 
 
2640
    argument_count = PyTuple_GET_SIZE(tuple);
 
2641
 
 
2642
    for(i = 0; i < argument_count; ++i) {
 
2643
        PyObject *arg = PyTuple_GET_ITEM(tuple, i);
 
2644
        if (arg == Py_Ellipsis && !ellipsis_count) ellipsis_count++;
 
2645
        else if (arg == Py_None) newaxis_count++;
 
2646
        else break;
 
2647
    }
 
2648
    if (i < argument_count) {
 
2649
        PyErr_SetString(PyExc_IndexError,
 
2650
                        "0-d arrays can only use a single ()"
 
2651
                        " or a list of newaxes (and a single ...)"
 
2652
                        " as an index");
 
2653
        return -1;
 
2654
    }
 
2655
    if (newaxis_count > MAX_DIMS) {
 
2656
        PyErr_SetString(PyExc_IndexError,
 
2657
                        "too many dimensions");
 
2658
        return -1;
 
2659
    }
 
2660
    return newaxis_count;
2512
2661
}
2513
2662
 
2514
2663
static PyObject *
2515
2664
add_new_axes_0d(PyArrayObject *arr,  int newaxis_count)
2516
2665
{
2517
 
        PyArrayObject *other;
2518
 
        intp dimensions[MAX_DIMS];
2519
 
        int i;
2520
 
        for (i = 0; i < newaxis_count; ++i) {
2521
 
                dimensions[i]  = 1;
2522
 
        }
2523
 
        Py_INCREF(arr->descr);
2524
 
        if ((other = (PyArrayObject *)
2525
 
             PyArray_NewFromDescr(arr->ob_type, arr->descr,
2526
 
                                  newaxis_count, dimensions,
2527
 
                                  NULL, arr->data,
2528
 
                                  arr->flags,
2529
 
                                  (PyObject *)arr)) == NULL)
2530
 
                return NULL;
2531
 
        other->base = (PyObject *)arr;
2532
 
        Py_INCREF(arr);
2533
 
        return (PyObject *)other;
 
2666
    PyArrayObject *other;
 
2667
    intp dimensions[MAX_DIMS];
 
2668
    int i;
 
2669
    for(i = 0; i < newaxis_count; ++i) {
 
2670
        dimensions[i]  = 1;
 
2671
    }
 
2672
    Py_INCREF(arr->descr);
 
2673
    if ((other = (PyArrayObject *)
 
2674
         PyArray_NewFromDescr(arr->ob_type, arr->descr,
 
2675
                              newaxis_count, dimensions,
 
2676
                              NULL, arr->data,
 
2677
                              arr->flags,
 
2678
                              (PyObject *)arr)) == NULL)
 
2679
        return NULL;
 
2680
    other->base = (PyObject *)arr;
 
2681
    Py_INCREF(arr);
 
2682
    return (PyObject *)other;
2534
2683
}
2535
2684
 
2536
2685
 
2545
2694
static int
2546
2695
fancy_indexing_check(PyObject *args)
2547
2696
{
2548
 
        int i, n;
2549
 
        PyObject *obj;
2550
 
        int retval = SOBJ_NOTFANCY;
 
2697
    int i, n;
 
2698
    PyObject *obj;
 
2699
    int retval = SOBJ_NOTFANCY;
2551
2700
 
2552
 
        if (PyTuple_Check(args)) {
2553
 
                n = PyTuple_GET_SIZE(args);
2554
 
                if (n >= MAX_DIMS) return SOBJ_TOOMANY;
2555
 
                for (i=0; i<n; i++) {
2556
 
                        obj = PyTuple_GET_ITEM(args,i);
2557
 
                        if (PyArray_Check(obj)) {
2558
 
                                if (PyArray_ISINTEGER(obj) || 
2559
 
                                    PyArray_ISBOOL(obj))
2560
 
                                        retval = SOBJ_ISFANCY;
2561
 
                                else {
2562
 
                                        retval = SOBJ_BADARRAY;
2563
 
                                        break;
2564
 
                                }
2565
 
                        }
2566
 
                        else if (PySequence_Check(obj)) {
2567
 
                                retval = SOBJ_ISFANCY;
2568
 
                        }
 
2701
    if (PyTuple_Check(args)) {
 
2702
        n = PyTuple_GET_SIZE(args);
 
2703
        if (n >= MAX_DIMS) return SOBJ_TOOMANY;
 
2704
        for(i=0; i<n; i++) {
 
2705
            obj = PyTuple_GET_ITEM(args,i);
 
2706
            if (PyArray_Check(obj)) {
 
2707
                if (PyArray_ISINTEGER(obj) ||
 
2708
                    PyArray_ISBOOL(obj))
 
2709
                    retval = SOBJ_ISFANCY;
 
2710
                else {
 
2711
                    retval = SOBJ_BADARRAY;
 
2712
                    break;
2569
2713
                }
2570
 
        }
2571
 
        else if (PyArray_Check(args)) {
2572
 
                if ((PyArray_TYPE(args)==PyArray_BOOL) ||
2573
 
                    (PyArray_ISINTEGER(args)))
2574
 
                        return SOBJ_ISFANCY;
2575
 
                else
2576
 
                        return SOBJ_BADARRAY;
2577
 
        }
2578
 
        else if (PySequence_Check(args)) {
2579
 
                /* Sequences < MAX_DIMS with any slice objects
2580
 
                   or newaxis, or Ellipsis is considered standard
2581
 
                   as long as there are also no Arrays and or additional
2582
 
                   sequences embedded.
2583
 
                */
 
2714
            }
 
2715
            else if (PySequence_Check(obj)) {
2584
2716
                retval = SOBJ_ISFANCY;
2585
 
                n = PySequence_Size(args);
2586
 
                if (n<0 || n>=MAX_DIMS) return SOBJ_ISFANCY;
2587
 
                for (i=0; i<n; i++) {
2588
 
                        obj = PySequence_GetItem(args, i);
2589
 
                        if (obj == NULL) return SOBJ_ISFANCY;
2590
 
                        if (PyArray_Check(obj)) {
2591
 
                                if (PyArray_ISINTEGER(obj) ||
2592
 
                                    PyArray_ISBOOL(obj))
2593
 
                                        retval = SOBJ_LISTTUP;
2594
 
                                else
2595
 
                                        retval = SOBJ_BADARRAY;
2596
 
                        }
2597
 
                        else if (PySequence_Check(obj)) {
2598
 
                                retval = SOBJ_LISTTUP;
2599
 
                        }
2600
 
                        else if (PySlice_Check(obj) || obj == Py_Ellipsis || 
2601
 
                                 obj == Py_None) {
2602
 
                                retval = SOBJ_NOTFANCY;
2603
 
                        }
2604
 
                        Py_DECREF(obj);
2605
 
                        if (retval > SOBJ_ISFANCY) return retval;
2606
 
                }
2607
 
        }
2608
 
        return retval;
 
2717
            }
 
2718
        }
 
2719
    }
 
2720
    else if (PyArray_Check(args)) {
 
2721
        if ((PyArray_TYPE(args)==PyArray_BOOL) ||
 
2722
            (PyArray_ISINTEGER(args)))
 
2723
            return SOBJ_ISFANCY;
 
2724
        else
 
2725
            return SOBJ_BADARRAY;
 
2726
    }
 
2727
    else if (PySequence_Check(args)) {
 
2728
        /* Sequences < MAX_DIMS with any slice objects
 
2729
           or newaxis, or Ellipsis is considered standard
 
2730
           as long as there are also no Arrays and or additional
 
2731
           sequences embedded.
 
2732
        */
 
2733
        retval = SOBJ_ISFANCY;
 
2734
        n = PySequence_Size(args);
 
2735
        if (n<0 || n>=MAX_DIMS) return SOBJ_ISFANCY;
 
2736
        for(i=0; i<n; i++) {
 
2737
            obj = PySequence_GetItem(args, i);
 
2738
            if (obj == NULL) return SOBJ_ISFANCY;
 
2739
            if (PyArray_Check(obj)) {
 
2740
                if (PyArray_ISINTEGER(obj) ||
 
2741
                    PyArray_ISBOOL(obj))
 
2742
                    retval = SOBJ_LISTTUP;
 
2743
                else
 
2744
                    retval = SOBJ_BADARRAY;
 
2745
            }
 
2746
            else if (PySequence_Check(obj)) {
 
2747
                retval = SOBJ_LISTTUP;
 
2748
            }
 
2749
            else if (PySlice_Check(obj) || obj == Py_Ellipsis ||
 
2750
                     obj == Py_None) {
 
2751
                retval = SOBJ_NOTFANCY;
 
2752
            }
 
2753
            Py_DECREF(obj);
 
2754
            if (retval > SOBJ_ISFANCY) return retval;
 
2755
        }
 
2756
    }
 
2757
    return retval;
2609
2758
}
2610
2759
 
2611
2760
/* Called when treating array object like a mapping -- called first from
2616
2765
 
2617
2766
/* There are two situations:
2618
2767
 
2619
 
     1 - the subscript is a standard view and a reference to the
2620
 
         array can be returned
 
2768
   1 - the subscript is a standard view and a reference to the
 
2769
   array can be returned
2621
2770
 
2622
 
     2 - the subscript uses Boolean masks or integer indexing and
2623
 
         therefore a new array is created and returned.
 
2771
   2 - the subscript uses Boolean masks or integer indexing and
 
2772
   therefore a new array is created and returned.
2624
2773
 
2625
2774
*/
2626
2775
 
2632
2781
static PyObject *
2633
2782
array_subscript_simple(PyArrayObject *self, PyObject *op)
2634
2783
{
2635
 
        intp dimensions[MAX_DIMS], strides[MAX_DIMS];
2636
 
        intp offset;
2637
 
        int nd;
2638
 
        PyArrayObject *other;
2639
 
        intp value;
2640
 
 
2641
 
        value = PyArray_PyIntAsIntp(op);
2642
 
        if (!PyErr_Occurred()) {
2643
 
                return array_big_item(self, value);
2644
 
        }
2645
 
        PyErr_Clear();
2646
 
 
2647
 
        /* Standard (view-based) Indexing */
2648
 
        if ((nd = parse_index(self, op, dimensions, strides, &offset))
2649
 
            == -1) return NULL;
2650
 
 
2651
 
        /* This will only work if new array will be a view */
2652
 
        Py_INCREF(self->descr);
2653
 
        if ((other = (PyArrayObject *)                                  \
2654
 
             PyArray_NewFromDescr(self->ob_type, self->descr,
2655
 
                                  nd, dimensions,
2656
 
                                  strides, self->data+offset,
2657
 
                                  self->flags,
2658
 
                                  (PyObject *)self)) == NULL)
2659
 
                return NULL;
2660
 
 
2661
 
        other->base = (PyObject *)self;
2662
 
        Py_INCREF(self);
2663
 
 
2664
 
        PyArray_UpdateFlags(other, UPDATE_ALL);
2665
 
 
2666
 
        return (PyObject *)other;
 
2784
    intp dimensions[MAX_DIMS], strides[MAX_DIMS];
 
2785
    intp offset;
 
2786
    int nd;
 
2787
    PyArrayObject *other;
 
2788
    intp value;
 
2789
 
 
2790
    value = PyArray_PyIntAsIntp(op);
 
2791
    if (!PyErr_Occurred()) {
 
2792
        return array_big_item(self, value);
 
2793
    }
 
2794
    PyErr_Clear();
 
2795
 
 
2796
    /* Standard (view-based) Indexing */
 
2797
    if ((nd = parse_index(self, op, dimensions, strides, &offset))
 
2798
        == -1) return NULL;
 
2799
 
 
2800
    /* This will only work if new array will be a view */
 
2801
    Py_INCREF(self->descr);
 
2802
    if ((other = (PyArrayObject *)                                  \
 
2803
         PyArray_NewFromDescr(self->ob_type, self->descr,
 
2804
                              nd, dimensions,
 
2805
                              strides, self->data+offset,
 
2806
                              self->flags,
 
2807
                              (PyObject *)self)) == NULL)
 
2808
        return NULL;
 
2809
 
 
2810
    other->base = (PyObject *)self;
 
2811
    Py_INCREF(self);
 
2812
 
 
2813
    PyArray_UpdateFlags(other, UPDATE_ALL);
 
2814
 
 
2815
    return (PyObject *)other;
2667
2816
}
2668
2817
 
2669
2818
static PyObject *
2670
2819
array_subscript(PyArrayObject *self, PyObject *op)
2671
2820
{
2672
 
        int nd, oned, fancy;
2673
 
        PyArrayObject *other;
2674
 
        PyArrayMapIterObject *mit;
2675
 
 
2676
 
        if (PyString_Check(op) || PyUnicode_Check(op)) {
2677
 
                if (self->descr->names) {
2678
 
                        PyObject *obj;
2679
 
                        obj = PyDict_GetItem(self->descr->fields, op);
2680
 
                        if (obj != NULL) {
2681
 
                                PyArray_Descr *descr;
2682
 
                                int offset;
2683
 
                                PyObject *title;
2684
 
 
2685
 
                                if (PyArg_ParseTuple(obj, "Oi|O",
2686
 
                                                     &descr, &offset, &title)) {
2687
 
                                        Py_INCREF(descr);
2688
 
                                        return PyArray_GetField(self, descr,
2689
 
                                                                offset);
2690
 
                                }
2691
 
                        }
2692
 
                }
2693
 
 
2694
 
                PyErr_Format(PyExc_ValueError,
2695
 
                             "field named %s not found.",
2696
 
                             PyString_AsString(op));
2697
 
                return NULL;
2698
 
        }
2699
 
 
2700
 
        if (self->nd == 0) {
2701
 
                if (op == Py_Ellipsis) {
2702
 
                        /* XXX: This leads to a small inconsistency
2703
 
                           XXX: with the nd>0 case where (x[...] is x)
2704
 
                           XXX: is false for nd>0 case. */
2705
 
                        Py_INCREF(self);
2706
 
                        return (PyObject *)self;
2707
 
                }
2708
 
                if (op == Py_None)
2709
 
                        return add_new_axes_0d(self, 1);
2710
 
                if (PyTuple_Check(op)) {
2711
 
                        if (0 == PyTuple_GET_SIZE(op))  {
2712
 
                                Py_INCREF(self);
2713
 
                                return (PyObject *)self;
2714
 
                        }
2715
 
                        if ((nd = count_new_axes_0d(op)) == -1)
2716
 
                                return NULL;
2717
 
                        return add_new_axes_0d(self, nd);
2718
 
                }
2719
 
                PyErr_SetString(PyExc_IndexError,
2720
 
                                "0-d arrays can't be indexed.");
2721
 
                return NULL;
2722
 
        }
2723
 
 
2724
 
        fancy = fancy_indexing_check(op);
2725
 
 
2726
 
        if (fancy != SOBJ_NOTFANCY) {
2727
 
                oned = ((self->nd == 1) &&
2728
 
                        !(PyTuple_Check(op) && PyTuple_GET_SIZE(op) > 1));
2729
 
 
2730
 
                /* wrap arguments into a mapiter object */
2731
 
                mit = (PyArrayMapIterObject *)\
2732
 
                        PyArray_MapIterNew(op, oned, fancy);
2733
 
                if (mit == NULL) return NULL;
2734
 
                if (oned) {
2735
 
                        PyArrayIterObject *it;
2736
 
                        PyObject *rval;
2737
 
                        it = (PyArrayIterObject *)\
2738
 
                                PyArray_IterNew((PyObject *)self);
2739
 
                        if (it == NULL) {Py_DECREF(mit); return NULL;}
2740
 
                        rval = iter_subscript(it, mit->indexobj);
2741
 
                        Py_DECREF(it);
2742
 
                        Py_DECREF(mit);
2743
 
                        return rval;
2744
 
                }
2745
 
                PyArray_MapIterBind(mit, self);
2746
 
                other = (PyArrayObject *)PyArray_GetMap(mit);
2747
 
                Py_DECREF(mit);
2748
 
                return (PyObject *)other;
2749
 
        }
2750
 
 
2751
 
        return array_subscript_simple(self, op);
 
2821
    int nd, fancy;
 
2822
    PyArrayObject *other;
 
2823
    PyArrayMapIterObject *mit;
 
2824
 
 
2825
    if (PyString_Check(op) || PyUnicode_Check(op)) {
 
2826
        if (self->descr->names) {
 
2827
            PyObject *obj;
 
2828
            obj = PyDict_GetItem(self->descr->fields, op);
 
2829
            if (obj != NULL) {
 
2830
                PyArray_Descr *descr;
 
2831
                int offset;
 
2832
                PyObject *title;
 
2833
 
 
2834
                if (PyArg_ParseTuple(obj, "Oi|O",
 
2835
                                     &descr, &offset, &title)) {
 
2836
                    Py_INCREF(descr);
 
2837
                    return PyArray_GetField(self, descr,
 
2838
                                            offset);
 
2839
                }
 
2840
            }
 
2841
        }
 
2842
 
 
2843
        PyErr_Format(PyExc_ValueError,
 
2844
                     "field named %s not found.",
 
2845
                     PyString_AsString(op));
 
2846
        return NULL;
 
2847
    }
 
2848
 
 
2849
    if (op == Py_Ellipsis) {
 
2850
        Py_INCREF(self);
 
2851
        return (PyObject *)self;
 
2852
    }
 
2853
 
 
2854
    if (self->nd == 0) {
 
2855
        if (op == Py_None)
 
2856
            return add_new_axes_0d(self, 1);
 
2857
        if (PyTuple_Check(op)) {
 
2858
            if (0 == PyTuple_GET_SIZE(op))  {
 
2859
                Py_INCREF(self);
 
2860
                return (PyObject *)self;
 
2861
            }
 
2862
            if ((nd = count_new_axes_0d(op)) == -1)
 
2863
                return NULL;
 
2864
            return add_new_axes_0d(self, nd);
 
2865
        }
 
2866
        /* Allow Boolean mask selection also */
 
2867
        if ((PyArray_Check(op) && (PyArray_DIMS(op)==0) &&
 
2868
             PyArray_ISBOOL(op))) {
 
2869
            if (PyObject_IsTrue(op)) {
 
2870
                Py_INCREF(self);
 
2871
                return (PyObject *)self;
 
2872
            }
 
2873
            else {
 
2874
                intp oned = 0;
 
2875
                Py_INCREF(self->descr);
 
2876
                return PyArray_NewFromDescr(self->ob_type,
 
2877
                                            self->descr,
 
2878
                                            1, &oned,
 
2879
                                            NULL, NULL,
 
2880
                                            NPY_DEFAULT,
 
2881
                                            NULL);
 
2882
            }
 
2883
        }
 
2884
        PyErr_SetString(PyExc_IndexError,
 
2885
                        "0-d arrays can't be indexed.");
 
2886
        return NULL;
 
2887
    }
 
2888
 
 
2889
    fancy = fancy_indexing_check(op);
 
2890
 
 
2891
    if (fancy != SOBJ_NOTFANCY) {
 
2892
        int oned;
 
2893
        oned = ((self->nd == 1) &&
 
2894
                !(PyTuple_Check(op) && PyTuple_GET_SIZE(op) > 1));
 
2895
 
 
2896
        /* wrap arguments into a mapiter object */
 
2897
        mit = (PyArrayMapIterObject *)\
 
2898
            PyArray_MapIterNew(op, oned, fancy);
 
2899
        if (mit == NULL) return NULL;
 
2900
        if (oned) {
 
2901
            PyArrayIterObject *it;
 
2902
            PyObject *rval;
 
2903
            it = (PyArrayIterObject *)\
 
2904
                PyArray_IterNew((PyObject *)self);
 
2905
            if (it == NULL) {Py_DECREF(mit); return NULL;}
 
2906
            rval = iter_subscript(it, mit->indexobj);
 
2907
            Py_DECREF(it);
 
2908
            Py_DECREF(mit);
 
2909
            return rval;
 
2910
        }
 
2911
        PyArray_MapIterBind(mit, self);
 
2912
        other = (PyArrayObject *)PyArray_GetMap(mit);
 
2913
        Py_DECREF(mit);
 
2914
        return (PyObject *)other;
 
2915
    }
 
2916
 
 
2917
    return array_subscript_simple(self, op);
2752
2918
}
2753
2919
 
2754
2920
 
2766
2932
static int
2767
2933
array_ass_sub_simple(PyArrayObject *self, PyObject *index, PyObject *op)
2768
2934
{
2769
 
        int ret;
2770
 
        PyArrayObject *tmp;
2771
 
        intp value;
2772
 
 
2773
 
        value = PyArray_PyIntAsIntp(index);
2774
 
        if (!error_converting(value)) {
2775
 
                return array_ass_big_item(self, value, op);
2776
 
        }
2777
 
        PyErr_Clear();
2778
 
 
2779
 
        /* Rest of standard (view-based) indexing */
2780
 
 
2781
 
        if (PyArray_CheckExact(self)) {
2782
 
                tmp = (PyArrayObject *)array_subscript_simple(self, index);
2783
 
                if (tmp == NULL) return -1;
2784
 
        }
2785
 
        else {
2786
 
                PyObject *tmp0;
2787
 
                tmp0 = PyObject_GetItem((PyObject *)self, index);
2788
 
                if (tmp0 == NULL) return -1;
2789
 
                if (!PyArray_Check(tmp0)) {
2790
 
                        PyErr_SetString(PyExc_RuntimeError,
2791
 
                                        "Getitem not returning array.");
2792
 
                        Py_DECREF(tmp0);
2793
 
                        return -1;
2794
 
                }
2795
 
                tmp = (PyArrayObject *)tmp0;
2796
 
        }
2797
 
 
2798
 
        if (PyArray_ISOBJECT(self) && (tmp->nd == 0)) {
2799
 
                ret = tmp->descr->f->setitem(op, tmp->data, tmp);
2800
 
        }
2801
 
        else {
2802
 
                ret = PyArray_CopyObject(tmp, op);
2803
 
        }
2804
 
        Py_DECREF(tmp);
2805
 
        return ret;
 
2935
    int ret;
 
2936
    PyArrayObject *tmp;
 
2937
    intp value;
 
2938
 
 
2939
    value = PyArray_PyIntAsIntp(index);
 
2940
    if (!error_converting(value)) {
 
2941
        return array_ass_big_item(self, value, op);
 
2942
    }
 
2943
    PyErr_Clear();
 
2944
 
 
2945
    /* Rest of standard (view-based) indexing */
 
2946
 
 
2947
    if (PyArray_CheckExact(self)) {
 
2948
        tmp = (PyArrayObject *)array_subscript_simple(self, index);
 
2949
        if (tmp == NULL) return -1;
 
2950
    }
 
2951
    else {
 
2952
        PyObject *tmp0;
 
2953
        tmp0 = PyObject_GetItem((PyObject *)self, index);
 
2954
        if (tmp0 == NULL) return -1;
 
2955
        if (!PyArray_Check(tmp0)) {
 
2956
            PyErr_SetString(PyExc_RuntimeError,
 
2957
                            "Getitem not returning array.");
 
2958
            Py_DECREF(tmp0);
 
2959
            return -1;
 
2960
        }
 
2961
        tmp = (PyArrayObject *)tmp0;
 
2962
    }
 
2963
 
 
2964
    if (PyArray_ISOBJECT(self) && (tmp->nd == 0)) {
 
2965
        ret = tmp->descr->f->setitem(op, tmp->data, tmp);
 
2966
    }
 
2967
    else {
 
2968
        ret = PyArray_CopyObject(tmp, op);
 
2969
    }
 
2970
    Py_DECREF(tmp);
 
2971
    return ret;
2806
2972
}
2807
2973
 
2808
2974
 
2812
2978
static int
2813
2979
_tuple_of_integers(PyObject *seq, intp *vals, int maxvals)
2814
2980
{
2815
 
        int i;
2816
 
        PyObject *obj;
2817
 
        intp temp;
 
2981
    int i;
 
2982
    PyObject *obj;
 
2983
    intp temp;
2818
2984
 
2819
 
        for (i=0; i<maxvals; i++) {
2820
 
                obj = PyTuple_GET_ITEM(seq, i);
2821
 
                if ((PyArray_Check(obj) && PyArray_NDIM(obj) > 0) ||
2822
 
                    PyList_Check(obj)) return -1;
2823
 
                temp = PyArray_PyIntAsIntp(obj);
2824
 
                if (error_converting(temp)) return -1;
2825
 
                vals[i] = temp;
2826
 
        }
2827
 
        return 0;
 
2985
    for(i=0; i<maxvals; i++) {
 
2986
        obj = PyTuple_GET_ITEM(seq, i);
 
2987
        if ((PyArray_Check(obj) && PyArray_NDIM(obj) > 0) ||
 
2988
            PyList_Check(obj)) return -1;
 
2989
        temp = PyArray_PyIntAsIntp(obj);
 
2990
        if (error_converting(temp)) return -1;
 
2991
        vals[i] = temp;
 
2992
    }
 
2993
    return 0;
2828
2994
}
2829
2995
 
2830
2996
 
2831
2997
static int
2832
2998
array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op)
2833
2999
{
2834
 
        int ret, oned, fancy;
2835
 
        PyArrayMapIterObject *mit;
2836
 
        intp vals[MAX_DIMS];
2837
 
 
2838
 
        if (op == NULL) {
2839
 
                PyErr_SetString(PyExc_ValueError,
2840
 
                                "cannot delete array elements");
2841
 
                return -1;
2842
 
        }
2843
 
        if (!PyArray_ISWRITEABLE(self)) {
2844
 
                PyErr_SetString(PyExc_RuntimeError,
2845
 
                                "array is not writeable");
2846
 
                return -1;
2847
 
        }
2848
 
 
2849
 
        if (PyInt_Check(index) || PyArray_IsScalar(index, Integer) ||
2850
 
            PyLong_Check(index) || (PyIndex_Check(index) && 
2851
 
                                    !PySequence_Check(index))) {
2852
 
                intp value;
2853
 
                value = PyArray_PyIntAsIntp(index);
2854
 
                if (PyErr_Occurred())
2855
 
                        PyErr_Clear();
2856
 
                else
2857
 
                        return array_ass_big_item(self, value, op);
2858
 
        }
2859
 
 
2860
 
        if (PyString_Check(index) || PyUnicode_Check(index)) {
2861
 
                if (self->descr->names) {
2862
 
                        PyObject *obj;
2863
 
                        obj = PyDict_GetItem(self->descr->fields, index);
2864
 
                        if (obj != NULL) {
2865
 
                                PyArray_Descr *descr;
2866
 
                                int offset;
2867
 
                                PyObject *title;
2868
 
 
2869
 
                                if (PyArg_ParseTuple(obj, "Oi|O",
2870
 
                                                     &descr, &offset, &title)) {
2871
 
                                        Py_INCREF(descr);
2872
 
                                        return PyArray_SetField(self, descr,
2873
 
                                                                offset, op);
2874
 
                                }
2875
 
                        }
2876
 
                }
2877
 
 
2878
 
                PyErr_Format(PyExc_ValueError,
2879
 
                             "field named %s not found.",
2880
 
                             PyString_AsString(index));
2881
 
                return -1;
2882
 
        }
2883
 
 
2884
 
        if (self->nd == 0) {
2885
 
                if (index == Py_Ellipsis || index == Py_None ||         \
2886
 
                    (PyTuple_Check(index) && (0 == PyTuple_GET_SIZE(index) || \
2887
 
                                              count_new_axes_0d(index) > 0)))
2888
 
                        return self->descr->f->setitem(op, self->data, self);
2889
 
                PyErr_SetString(PyExc_IndexError,
2890
 
                                "0-d arrays can't be indexed.");
2891
 
                return -1;
2892
 
        }
2893
 
        
2894
 
        /* optimization for integer-tuple */
2895
 
        if (self->nd > 1 &&
2896
 
            (PyTuple_Check(index) && (PyTuple_GET_SIZE(index) == self->nd)) 
2897
 
            && (_tuple_of_integers(index, vals, self->nd) >= 0)) {
2898
 
                int i;
2899
 
                char *item;
2900
 
                for (i=0; i<self->nd; i++) {
2901
 
                        if (vals[i] < 0) vals[i] += self->dimensions[i];
2902
 
                        if ((vals[i] < 0) || (vals[i] >= self->dimensions[i])) {
2903
 
                                PyErr_Format(PyExc_IndexError,
2904
 
                                             "index (%"INTP_FMT") out of range "\
2905
 
                                             "(0<=index<%"INTP_FMT") in dimension %d",
2906
 
                                             vals[i], self->dimensions[i], i);
2907
 
                                return -1;
2908
 
                        }
2909
 
                }
2910
 
                item = PyArray_GetPtr(self, vals);
2911
 
                /* fprintf(stderr, "Here I am...\n");*/
2912
 
                return self->descr->f->setitem(op, item, self);
2913
 
        }
2914
 
        PyErr_Clear();
2915
 
 
2916
 
        fancy = fancy_indexing_check(index);
2917
 
 
2918
 
        if (fancy != SOBJ_NOTFANCY) {
2919
 
                oned = ((self->nd == 1) &&
2920
 
                        !(PyTuple_Check(index) && PyTuple_GET_SIZE(index) > 1));
2921
 
 
2922
 
                mit = (PyArrayMapIterObject *)                  \
2923
 
                        PyArray_MapIterNew(index, oned, fancy);
2924
 
                if (mit == NULL) return -1;
2925
 
                if (oned) {
2926
 
                        PyArrayIterObject *it;
2927
 
                        int rval;
2928
 
                        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
2929
 
                        if (it == NULL) {Py_DECREF(mit); return -1;}
2930
 
                        rval = iter_ass_subscript(it, mit->indexobj, op);
2931
 
                        Py_DECREF(it);
2932
 
                        Py_DECREF(mit);
2933
 
                        return rval;
2934
 
                }
2935
 
                PyArray_MapIterBind(mit, self);
2936
 
                ret = PyArray_SetMap(mit, op);
2937
 
                Py_DECREF(mit);
2938
 
                return ret;
2939
 
        }
2940
 
 
2941
 
        return array_ass_sub_simple(self, index, op);
 
3000
    int ret, oned, fancy;
 
3001
    PyArrayMapIterObject *mit;
 
3002
    intp vals[MAX_DIMS];
 
3003
 
 
3004
    if (op == NULL) {
 
3005
        PyErr_SetString(PyExc_ValueError,
 
3006
                        "cannot delete array elements");
 
3007
        return -1;
 
3008
    }
 
3009
    if (!PyArray_ISWRITEABLE(self)) {
 
3010
        PyErr_SetString(PyExc_RuntimeError,
 
3011
                        "array is not writeable");
 
3012
        return -1;
 
3013
    }
 
3014
 
 
3015
    if (PyInt_Check(index) || PyArray_IsScalar(index, Integer) ||
 
3016
        PyLong_Check(index) || (PyIndex_Check(index) &&
 
3017
                                !PySequence_Check(index))) {
 
3018
        intp value;
 
3019
        value = PyArray_PyIntAsIntp(index);
 
3020
        if (PyErr_Occurred())
 
3021
            PyErr_Clear();
 
3022
        else
 
3023
            return array_ass_big_item(self, value, op);
 
3024
    }
 
3025
 
 
3026
    if (PyString_Check(index) || PyUnicode_Check(index)) {
 
3027
        if (self->descr->names) {
 
3028
            PyObject *obj;
 
3029
            obj = PyDict_GetItem(self->descr->fields, index);
 
3030
            if (obj != NULL) {
 
3031
                PyArray_Descr *descr;
 
3032
                int offset;
 
3033
                PyObject *title;
 
3034
 
 
3035
                if (PyArg_ParseTuple(obj, "Oi|O",
 
3036
                                     &descr, &offset, &title)) {
 
3037
                    Py_INCREF(descr);
 
3038
                    return PyArray_SetField(self, descr,
 
3039
                                            offset, op);
 
3040
                }
 
3041
            }
 
3042
        }
 
3043
 
 
3044
        PyErr_Format(PyExc_ValueError,
 
3045
                     "field named %s not found.",
 
3046
                     PyString_AsString(index));
 
3047
        return -1;
 
3048
    }
 
3049
 
 
3050
    if (self->nd == 0) {
 
3051
        /* Several different exceptions to the 0-d no-indexing rule
 
3052
 
 
3053
           1) ellipses
 
3054
           2) empty tuple
 
3055
           3) Using newaxis (None)
 
3056
           4) Boolean mask indexing
 
3057
        */
 
3058
        if (index == Py_Ellipsis || index == Py_None ||         \
 
3059
            (PyTuple_Check(index) && (0 == PyTuple_GET_SIZE(index) || \
 
3060
                                      count_new_axes_0d(index) > 0)))
 
3061
            return self->descr->f->setitem(op, self->data, self);
 
3062
        if (PyBool_Check(index) || PyArray_IsScalar(index, Bool) ||
 
3063
            (PyArray_Check(index) && (PyArray_DIMS(index)==0) &&
 
3064
             PyArray_ISBOOL(index))) {
 
3065
            if (PyObject_IsTrue(index)) {
 
3066
                return self->descr->f->setitem(op, self->data, self);
 
3067
            }
 
3068
            else { /* don't do anything */
 
3069
                return 0;
 
3070
            }
 
3071
        }
 
3072
        PyErr_SetString(PyExc_IndexError,
 
3073
                        "0-d arrays can't be indexed.");
 
3074
        return -1;
 
3075
    }
 
3076
 
 
3077
    /* optimization for integer-tuple */
 
3078
    if (self->nd > 1 &&
 
3079
        (PyTuple_Check(index) && (PyTuple_GET_SIZE(index) == self->nd))
 
3080
        && (_tuple_of_integers(index, vals, self->nd) >= 0)) {
 
3081
        int i;
 
3082
        char *item;
 
3083
        for(i=0; i<self->nd; i++) {
 
3084
            if (vals[i] < 0) vals[i] += self->dimensions[i];
 
3085
            if ((vals[i] < 0) || (vals[i] >= self->dimensions[i])) {
 
3086
                PyErr_Format(PyExc_IndexError,
 
3087
                             "index (%"INTP_FMT") out of range "\
 
3088
                             "(0<=index<%"INTP_FMT") in dimension %d",
 
3089
                             vals[i], self->dimensions[i], i);
 
3090
                return -1;
 
3091
            }
 
3092
        }
 
3093
        item = PyArray_GetPtr(self, vals);
 
3094
        /* fprintf(stderr, "Here I am...\n");*/
 
3095
        return self->descr->f->setitem(op, item, self);
 
3096
    }
 
3097
    PyErr_Clear();
 
3098
 
 
3099
    fancy = fancy_indexing_check(index);
 
3100
 
 
3101
    if (fancy != SOBJ_NOTFANCY) {
 
3102
        oned = ((self->nd == 1) &&
 
3103
                !(PyTuple_Check(index) && PyTuple_GET_SIZE(index) > 1));
 
3104
 
 
3105
        mit = (PyArrayMapIterObject *)                  \
 
3106
            PyArray_MapIterNew(index, oned, fancy);
 
3107
        if (mit == NULL) return -1;
 
3108
        if (oned) {
 
3109
            PyArrayIterObject *it;
 
3110
            int rval;
 
3111
            it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
 
3112
            if (it == NULL) {Py_DECREF(mit); return -1;}
 
3113
            rval = iter_ass_subscript(it, mit->indexobj, op);
 
3114
            Py_DECREF(it);
 
3115
            Py_DECREF(mit);
 
3116
            return rval;
 
3117
        }
 
3118
        PyArray_MapIterBind(mit, self);
 
3119
        ret = PyArray_SetMap(mit, op);
 
3120
        Py_DECREF(mit);
 
3121
        return ret;
 
3122
    }
 
3123
 
 
3124
    return array_ass_sub_simple(self, index, op);
2942
3125
}
2943
3126
 
2944
3127
 
2952
3135
array_subscript_nice(PyArrayObject *self, PyObject *op)
2953
3136
{
2954
3137
 
2955
 
        PyArrayObject *mp;
2956
 
        intp vals[MAX_DIMS];
2957
 
 
2958
 
        if (PyInt_Check(op) || PyArray_IsScalar(op, Integer) || \
2959
 
            PyLong_Check(op) || (PyIndex_Check(op) && 
2960
 
                                 !PySequence_Check(op))) {
2961
 
                intp value;
2962
 
                value = PyArray_PyIntAsIntp(op);
2963
 
                if (PyErr_Occurred())
2964
 
                        PyErr_Clear();
2965
 
                else {
2966
 
                        return array_item_nice(self, (Py_ssize_t) value);
2967
 
                }
2968
 
        }
2969
 
        /* optimization for a tuple of integers */
2970
 
        if (self->nd > 1 && PyTuple_Check(op) &&
2971
 
            (PyTuple_GET_SIZE(op) == self->nd)
2972
 
            && (_tuple_of_integers(op, vals, self->nd) >= 0)) {
2973
 
                int i;
2974
 
                char *item;
2975
 
                for (i=0; i<self->nd; i++) {
2976
 
                        if (vals[i] < 0) vals[i] += self->dimensions[i];
2977
 
                        if ((vals[i] < 0) || (vals[i] >= self->dimensions[i])) {
2978
 
                                PyErr_Format(PyExc_IndexError,
2979
 
                                             "index (%"INTP_FMT") out of range "\
2980
 
                                             "(0<=index<=%"INTP_FMT") in dimension %d",
2981
 
                                             vals[i], self->dimensions[i], i);
2982
 
                                return NULL;
2983
 
                        }
2984
 
                }
2985
 
                item = PyArray_GetPtr(self, vals);
2986
 
                return PyArray_Scalar(item, self->descr, (PyObject *)self);
2987
 
        }
2988
 
        PyErr_Clear();
2989
 
 
2990
 
        mp = (PyArrayObject *)array_subscript(self, op);
2991
 
 
2992
 
        /* The following is just a copy of PyArray_Return with an
2993
 
           additional logic in the nd == 0 case.
2994
 
        */
2995
 
 
2996
 
        if (mp == NULL) return NULL;
2997
 
 
2998
 
        if (PyErr_Occurred()) {
2999
 
                Py_XDECREF(mp);
 
3138
    PyArrayObject *mp;
 
3139
    intp vals[MAX_DIMS];
 
3140
 
 
3141
    if (PyInt_Check(op) || PyArray_IsScalar(op, Integer) || \
 
3142
        PyLong_Check(op) || (PyIndex_Check(op) &&
 
3143
                             !PySequence_Check(op))) {
 
3144
        intp value;
 
3145
        value = PyArray_PyIntAsIntp(op);
 
3146
        if (PyErr_Occurred())
 
3147
            PyErr_Clear();
 
3148
        else {
 
3149
            return array_item_nice(self, (Py_ssize_t) value);
 
3150
        }
 
3151
    }
 
3152
    /* optimization for a tuple of integers */
 
3153
    if (self->nd > 1 && PyTuple_Check(op) &&
 
3154
        (PyTuple_GET_SIZE(op) == self->nd)
 
3155
        && (_tuple_of_integers(op, vals, self->nd) >= 0)) {
 
3156
        int i;
 
3157
        char *item;
 
3158
        for(i=0; i<self->nd; i++) {
 
3159
            if (vals[i] < 0) vals[i] += self->dimensions[i];
 
3160
            if ((vals[i] < 0) || (vals[i] >= self->dimensions[i])) {
 
3161
                PyErr_Format(PyExc_IndexError,
 
3162
                             "index (%"INTP_FMT") out of range "\
 
3163
                             "(0<=index<%"INTP_FMT") in dimension %d",
 
3164
                             vals[i], self->dimensions[i], i);
3000
3165
                return NULL;
3001
 
        }
3002
 
 
3003
 
        if (mp->nd == 0) {
3004
 
                Bool noellipses = TRUE;
3005
 
                if (op == Py_Ellipsis)
3006
 
                        noellipses = FALSE;
3007
 
                else if (PySequence_Check(op)) {
3008
 
                        int n, i;
3009
 
                        PyObject *temp;
3010
 
                        n = PySequence_Size(op);
3011
 
                        i=0;
3012
 
                        while (i<n && noellipses) {
3013
 
                                temp = PySequence_GetItem(op, i);
3014
 
                                if (temp == Py_Ellipsis)
3015
 
                                        noellipses = FALSE;
3016
 
                                Py_DECREF(temp);
3017
 
                                i++;
3018
 
                        }
3019
 
                }
3020
 
                if (noellipses) {
3021
 
                        PyObject *ret;
3022
 
                        ret = PyArray_ToScalar(mp->data, mp);
3023
 
                        Py_DECREF(mp);
3024
 
                        return ret;
3025
 
                }
3026
 
        }
3027
 
        return (PyObject *)mp;
 
3166
            }
 
3167
        }
 
3168
        item = PyArray_GetPtr(self, vals);
 
3169
        return PyArray_Scalar(item, self->descr, (PyObject *)self);
 
3170
    }
 
3171
    PyErr_Clear();
 
3172
 
 
3173
    mp = (PyArrayObject *)array_subscript(self, op);
 
3174
 
 
3175
    /* mp could be a scalar if op is not an Int, Scalar, Long or other Index
 
3176
       object and still convertable to an integer (so that the code goes to
 
3177
       array_subscript_simple).  So, this cast is a bit dangerous..
 
3178
    */
 
3179
 
 
3180
    /* The following is just a copy of PyArray_Return with an
 
3181
       additional logic in the nd == 0 case.
 
3182
    */
 
3183
 
 
3184
    if (mp == NULL) return NULL;
 
3185
 
 
3186
    if (PyErr_Occurred()) {
 
3187
        Py_XDECREF(mp);
 
3188
        return NULL;
 
3189
    }
 
3190
 
 
3191
    if (PyArray_Check(mp) && mp->nd == 0) {
 
3192
        Bool noellipses = TRUE;
 
3193
        if ((op == Py_Ellipsis) || PyString_Check(op) || PyUnicode_Check(op))
 
3194
            noellipses = FALSE;
 
3195
        else if (PyBool_Check(op) || PyArray_IsScalar(op, Bool) ||
 
3196
                 (PyArray_Check(op) && (PyArray_DIMS(op)==0) &&
 
3197
                  PyArray_ISBOOL(op))) {
 
3198
            noellipses = FALSE;
 
3199
        }
 
3200
        else if (PySequence_Check(op)) {
 
3201
            int n, i;
 
3202
            PyObject *temp;
 
3203
            n = PySequence_Size(op);
 
3204
            i=0;
 
3205
            while (i<n && noellipses) {
 
3206
                temp = PySequence_GetItem(op, i);
 
3207
                if (temp == Py_Ellipsis)
 
3208
                    noellipses = FALSE;
 
3209
                Py_DECREF(temp);
 
3210
                i++;
 
3211
            }
 
3212
        }
 
3213
        if (noellipses) {
 
3214
            PyObject *ret;
 
3215
            ret = PyArray_ToScalar(mp->data, mp);
 
3216
            Py_DECREF(mp);
 
3217
            return ret;
 
3218
        }
 
3219
    }
 
3220
    return (PyObject *)mp;
3028
3221
}
3029
3222
 
3030
3223
 
3031
3224
static PyMappingMethods array_as_mapping = {
3032
3225
#if PY_VERSION_HEX >= 0x02050000
3033
 
        (lenfunc)array_length,              /*mp_length*/
 
3226
    (lenfunc)array_length,              /*mp_length*/
3034
3227
#else
3035
 
        (inquiry)array_length,              /*mp_length*/
 
3228
    (inquiry)array_length,              /*mp_length*/
3036
3229
#endif
3037
 
        (binaryfunc)array_subscript_nice,       /*mp_subscript*/
3038
 
        (objobjargproc)array_ass_sub,       /*mp_ass_subscript*/
 
3230
    (binaryfunc)array_subscript_nice,       /*mp_subscript*/
 
3231
    (objobjargproc)array_ass_sub,       /*mp_ass_subscript*/
3039
3232
};
3040
3233
 
3041
3234
/****************** End of Mapping Protocol ******************************/
3050
3243
static Py_ssize_t
3051
3244
array_getsegcount(PyArrayObject *self, Py_ssize_t *lenp)
3052
3245
{
3053
 
        if (lenp)
3054
 
                *lenp = PyArray_NBYTES(self);
3055
 
 
3056
 
        if (PyArray_ISONESEGMENT(self)) {
3057
 
                return 1;
3058
 
        }
3059
 
 
3060
 
        if (lenp)
3061
 
                *lenp = 0;
3062
 
        return 0;
 
3246
    if (lenp)
 
3247
        *lenp = PyArray_NBYTES(self);
 
3248
 
 
3249
    if (PyArray_ISONESEGMENT(self)) {
 
3250
        return 1;
 
3251
    }
 
3252
 
 
3253
    if (lenp)
 
3254
        *lenp = 0;
 
3255
    return 0;
3063
3256
}
3064
3257
 
3065
3258
static Py_ssize_t
3066
3259
array_getreadbuf(PyArrayObject *self, Py_ssize_t segment, void **ptrptr)
3067
3260
{
3068
 
        if (segment != 0) {
3069
 
                PyErr_SetString(PyExc_ValueError,
3070
 
                                "accessing non-existing array segment");
3071
 
                return -1;
3072
 
        }
3073
 
 
3074
 
        if (PyArray_ISONESEGMENT(self)) {
3075
 
                *ptrptr = self->data;
3076
 
                return PyArray_NBYTES(self);
3077
 
        }
3078
 
        PyErr_SetString(PyExc_ValueError, "array is not a single segment");
3079
 
        *ptrptr = NULL;
 
3261
    if (segment != 0) {
 
3262
        PyErr_SetString(PyExc_ValueError,
 
3263
                        "accessing non-existing array segment");
3080
3264
        return -1;
 
3265
    }
 
3266
 
 
3267
    if (PyArray_ISONESEGMENT(self)) {
 
3268
        *ptrptr = self->data;
 
3269
        return PyArray_NBYTES(self);
 
3270
    }
 
3271
    PyErr_SetString(PyExc_ValueError, "array is not a single segment");
 
3272
    *ptrptr = NULL;
 
3273
    return -1;
3081
3274
}
3082
3275
 
3083
3276
 
3084
3277
static Py_ssize_t
3085
3278
array_getwritebuf(PyArrayObject *self, Py_ssize_t segment, void **ptrptr)
3086
3279
{
3087
 
        if (PyArray_CHKFLAGS(self, WRITEABLE))
3088
 
                return array_getreadbuf(self, segment, (void **) ptrptr);
3089
 
        else {
3090
 
                PyErr_SetString(PyExc_ValueError, "array cannot be "\
3091
 
                                "accessed as a writeable buffer");
3092
 
                return -1;
3093
 
        }
 
3280
    if (PyArray_CHKFLAGS(self, WRITEABLE))
 
3281
        return array_getreadbuf(self, segment, (void **) ptrptr);
 
3282
    else {
 
3283
        PyErr_SetString(PyExc_ValueError, "array cannot be "\
 
3284
                        "accessed as a writeable buffer");
 
3285
        return -1;
 
3286
    }
3094
3287
}
3095
3288
 
3096
3289
static Py_ssize_t
3097
3290
array_getcharbuf(PyArrayObject *self, Py_ssize_t segment, constchar **ptrptr)
3098
3291
{
3099
 
        if (self->descr->type_num == PyArray_STRING || \
3100
 
            self->descr->type_num == PyArray_UNICODE || \
3101
 
            self->descr->elsize == 1)
3102
 
                return array_getreadbuf(self, segment, (void **) ptrptr);
3103
 
        else {
3104
 
                PyErr_SetString(PyExc_TypeError,
3105
 
                                "non-character (or 8-bit) array cannot be "\
3106
 
                                "interpreted as character buffer");
3107
 
                return -1;
3108
 
        }
 
3292
    return array_getreadbuf(self, segment, (void **) ptrptr);
3109
3293
}
3110
3294
 
3111
3295
static PyBufferProcs array_as_buffer = {
3112
3296
#if PY_VERSION_HEX >= 0x02050000
3113
 
        (readbufferproc)array_getreadbuf,    /*bf_getreadbuffer*/
3114
 
        (writebufferproc)array_getwritebuf,  /*bf_getwritebuffer*/
3115
 
        (segcountproc)array_getsegcount,            /*bf_getsegcount*/
3116
 
        (charbufferproc)array_getcharbuf,    /*bf_getcharbuffer*/
 
3297
    (readbufferproc)array_getreadbuf,    /*bf_getreadbuffer*/
 
3298
    (writebufferproc)array_getwritebuf,  /*bf_getwritebuffer*/
 
3299
    (segcountproc)array_getsegcount,            /*bf_getsegcount*/
 
3300
    (charbufferproc)array_getcharbuf,    /*bf_getcharbuffer*/
3117
3301
#else
3118
 
        (getreadbufferproc)array_getreadbuf,    /*bf_getreadbuffer*/
3119
 
        (getwritebufferproc)array_getwritebuf,  /*bf_getwritebuffer*/
3120
 
        (getsegcountproc)array_getsegcount,         /*bf_getsegcount*/
3121
 
        (getcharbufferproc)array_getcharbuf,    /*bf_getcharbuffer*/
 
3302
    (getreadbufferproc)array_getreadbuf,    /*bf_getreadbuffer*/
 
3303
    (getwritebufferproc)array_getwritebuf,  /*bf_getwritebuffer*/
 
3304
    (getsegcountproc)array_getsegcount,         /*bf_getsegcount*/
 
3305
    (getcharbufferproc)array_getcharbuf,    /*bf_getcharbuffer*/
3122
3306
#endif
3123
3307
};
3124
3308
 
3131
3315
 
3132
3316
 
3133
3317
typedef struct {
3134
 
        PyObject *add,
3135
 
                *subtract,
3136
 
                *multiply,
3137
 
                *divide,
3138
 
                *remainder,
3139
 
                *power,
3140
 
                *square,
3141
 
                *reciprocal,
3142
 
                *ones_like,
3143
 
                *sqrt,
3144
 
                *negative,
3145
 
                *absolute,
3146
 
                *invert,
3147
 
                *left_shift,
3148
 
                *right_shift,
3149
 
                *bitwise_and,
3150
 
                *bitwise_xor,
3151
 
                *bitwise_or,
3152
 
                *less,
3153
 
                *less_equal,
3154
 
                *equal,
3155
 
                *not_equal,
3156
 
                *greater,
3157
 
                *greater_equal,
3158
 
                *floor_divide,
3159
 
                *true_divide,
3160
 
                *logical_or,
3161
 
                *logical_and,
3162
 
                *floor,
3163
 
                *ceil,
3164
 
                *maximum,
3165
 
                *minimum,
3166
 
                *rint;
 
3318
    PyObject *add,
 
3319
        *subtract,
 
3320
        *multiply,
 
3321
        *divide,
 
3322
        *remainder,
 
3323
        *power,
 
3324
        *square,
 
3325
        *reciprocal,
 
3326
        *ones_like,
 
3327
        *sqrt,
 
3328
        *negative,
 
3329
        *absolute,
 
3330
        *invert,
 
3331
        *left_shift,
 
3332
        *right_shift,
 
3333
        *bitwise_and,
 
3334
        *bitwise_xor,
 
3335
        *bitwise_or,
 
3336
        *less,
 
3337
        *less_equal,
 
3338
        *equal,
 
3339
        *not_equal,
 
3340
        *greater,
 
3341
        *greater_equal,
 
3342
        *floor_divide,
 
3343
        *true_divide,
 
3344
        *logical_or,
 
3345
        *logical_and,
 
3346
        *floor,
 
3347
        *ceil,
 
3348
        *maximum,
 
3349
        *minimum,
 
3350
        *rint,
 
3351
        *conjugate;
3167
3352
} NumericOps;
3168
3353
 
3169
 
static NumericOps n_ops; /* NB: static objects inlitialized to zero */
 
3354
static NumericOps n_ops; /* NB: static objects initialized to zero */
3170
3355
 
3171
3356
/* Dictionary can contain any of the numeric operations, by name.
3172
 
  Those not present will not be changed
3173
 
 */
 
3357
   Those not present will not be changed
 
3358
*/
3174
3359
 
3175
3360
#define SET(op)   temp=PyDict_GetItemString(dict, #op); \
3176
 
        if (temp != NULL) {                             \
3177
 
                if (!(PyCallable_Check(temp))) return -1; \
3178
 
                Py_XDECREF(n_ops.op); \
3179
 
                n_ops.op = temp; \
3180
 
        }
 
3361
    if (temp != NULL) {                                 \
 
3362
        if (!(PyCallable_Check(temp))) return -1;       \
 
3363
        Py_XDECREF(n_ops.op);                           \
 
3364
        n_ops.op = temp;                                \
 
3365
    }
3181
3366
 
3182
3367
 
3183
3368
/*OBJECT_API
3184
 
 Set internal structure with number functions that all arrays will use
 
3369
  Set internal structure with number functions that all arrays will use
3185
3370
*/
3186
3371
int
3187
3372
PyArray_SetNumericOps(PyObject *dict)
3188
3373
{
3189
 
        PyObject *temp = NULL;
3190
 
        SET(add);
3191
 
        SET(subtract);
3192
 
        SET(multiply);
3193
 
        SET(divide);
3194
 
        SET(remainder);
3195
 
        SET(power);
3196
 
        SET(square);
3197
 
        SET(reciprocal);
3198
 
        SET(ones_like);
3199
 
        SET(sqrt);
3200
 
        SET(negative);
3201
 
        SET(absolute);
3202
 
        SET(invert);
3203
 
        SET(left_shift);
3204
 
        SET(right_shift);
3205
 
        SET(bitwise_and);
3206
 
        SET(bitwise_or);
3207
 
        SET(bitwise_xor);
3208
 
        SET(less);
3209
 
        SET(less_equal);
3210
 
        SET(equal);
3211
 
        SET(not_equal);
3212
 
        SET(greater);
3213
 
        SET(greater_equal);
3214
 
        SET(floor_divide);
3215
 
        SET(true_divide);
3216
 
        SET(logical_or);
3217
 
        SET(logical_and);
3218
 
        SET(floor);
3219
 
        SET(ceil);
3220
 
        SET(maximum);
3221
 
        SET(minimum);
3222
 
        SET(rint);
3223
 
        return 0;
 
3374
    PyObject *temp = NULL;
 
3375
    SET(add);
 
3376
    SET(subtract);
 
3377
    SET(multiply);
 
3378
    SET(divide);
 
3379
    SET(remainder);
 
3380
    SET(power);
 
3381
    SET(square);
 
3382
    SET(reciprocal);
 
3383
    SET(ones_like);
 
3384
    SET(sqrt);
 
3385
    SET(negative);
 
3386
    SET(absolute);
 
3387
    SET(invert);
 
3388
    SET(left_shift);
 
3389
    SET(right_shift);
 
3390
    SET(bitwise_and);
 
3391
    SET(bitwise_or);
 
3392
    SET(bitwise_xor);
 
3393
    SET(less);
 
3394
    SET(less_equal);
 
3395
    SET(equal);
 
3396
    SET(not_equal);
 
3397
    SET(greater);
 
3398
    SET(greater_equal);
 
3399
    SET(floor_divide);
 
3400
    SET(true_divide);
 
3401
    SET(logical_or);
 
3402
    SET(logical_and);
 
3403
    SET(floor);
 
3404
    SET(ceil);
 
3405
    SET(maximum);
 
3406
    SET(minimum);
 
3407
    SET(rint);
 
3408
    SET(conjugate);
 
3409
    return 0;
3224
3410
}
3225
3411
 
3226
3412
#define GET(op) if (n_ops.op &&                                         \
3227
3413
                    (PyDict_SetItemString(dict, #op, n_ops.op)==-1))    \
3228
 
                goto fail;
 
3414
        goto fail;
3229
3415
 
3230
3416
/*OBJECT_API
3231
 
 Get dictionary showing number functions that all arrays will use
 
3417
  Get dictionary showing number functions that all arrays will use
3232
3418
*/
3233
3419
static PyObject *
3234
3420
PyArray_GetNumericOps(void)
3235
3421
{
3236
 
        PyObject *dict;
3237
 
        if ((dict = PyDict_New())==NULL)
3238
 
                return NULL;
3239
 
        GET(add);
3240
 
        GET(subtract);
3241
 
        GET(multiply);
3242
 
        GET(divide);
3243
 
        GET(remainder);
3244
 
        GET(power);
3245
 
        GET(square);
3246
 
        GET(reciprocal);
3247
 
        GET(ones_like);
3248
 
        GET(sqrt);
3249
 
        GET(negative);
3250
 
        GET(absolute);
3251
 
        GET(invert);
3252
 
        GET(left_shift);
3253
 
        GET(right_shift);
3254
 
        GET(bitwise_and);
3255
 
        GET(bitwise_or);
3256
 
        GET(bitwise_xor);
3257
 
        GET(less);
3258
 
        GET(less_equal);
3259
 
        GET(equal);
3260
 
        GET(not_equal);
3261
 
        GET(greater);
3262
 
        GET(greater_equal);
3263
 
        GET(floor_divide);
3264
 
        GET(true_divide);
3265
 
        GET(logical_or);
3266
 
        GET(logical_and);
3267
 
        GET(floor);
3268
 
        GET(ceil);
3269
 
        GET(maximum);
3270
 
        GET(minimum);
3271
 
        GET(rint);
3272
 
        return dict;
 
3422
    PyObject *dict;
 
3423
    if ((dict = PyDict_New())==NULL)
 
3424
        return NULL;
 
3425
    GET(add);
 
3426
    GET(subtract);
 
3427
    GET(multiply);
 
3428
    GET(divide);
 
3429
    GET(remainder);
 
3430
    GET(power);
 
3431
    GET(square);
 
3432
    GET(reciprocal);
 
3433
    GET(ones_like);
 
3434
    GET(sqrt);
 
3435
    GET(negative);
 
3436
    GET(absolute);
 
3437
    GET(invert);
 
3438
    GET(left_shift);
 
3439
    GET(right_shift);
 
3440
    GET(bitwise_and);
 
3441
    GET(bitwise_or);
 
3442
    GET(bitwise_xor);
 
3443
    GET(less);
 
3444
    GET(less_equal);
 
3445
    GET(equal);
 
3446
    GET(not_equal);
 
3447
    GET(greater);
 
3448
    GET(greater_equal);
 
3449
    GET(floor_divide);
 
3450
    GET(true_divide);
 
3451
    GET(logical_or);
 
3452
    GET(logical_and);
 
3453
    GET(floor);
 
3454
    GET(ceil);
 
3455
    GET(maximum);
 
3456
    GET(minimum);
 
3457
    GET(rint);
 
3458
    GET(conjugate);
 
3459
    return dict;
3273
3460
 
3274
3461
 fail:
3275
 
        Py_DECREF(dict);
3276
 
        return NULL;
 
3462
    Py_DECREF(dict);
 
3463
    return NULL;
3277
3464
}
3278
3465
 
3279
3466
static PyObject *
3280
3467
_get_keywords(int rtype, PyArrayObject *out)
3281
3468
{
3282
 
        PyObject *kwds=NULL;
3283
 
        if (rtype != PyArray_NOTYPE || out != NULL) {
3284
 
                kwds = PyDict_New();
3285
 
                if (rtype != PyArray_NOTYPE) {
3286
 
                        PyArray_Descr *descr;
3287
 
                        descr = PyArray_DescrFromType(rtype);
3288
 
                        if (descr) {
3289
 
                                PyDict_SetItemString(kwds, "dtype",
3290
 
                                                     (PyObject *)descr);
3291
 
                                Py_DECREF(descr);
3292
 
                        }
3293
 
                }
3294
 
                if (out != NULL) {
3295
 
                        PyDict_SetItemString(kwds, "out",
3296
 
                                             (PyObject *)out);
3297
 
                }
3298
 
        }
3299
 
        return kwds;
 
3469
    PyObject *kwds=NULL;
 
3470
    if (rtype != PyArray_NOTYPE || out != NULL) {
 
3471
        kwds = PyDict_New();
 
3472
        if (rtype != PyArray_NOTYPE) {
 
3473
            PyArray_Descr *descr;
 
3474
            descr = PyArray_DescrFromType(rtype);
 
3475
            if (descr) {
 
3476
                PyDict_SetItemString(kwds, "dtype",
 
3477
                                     (PyObject *)descr);
 
3478
                Py_DECREF(descr);
 
3479
            }
 
3480
        }
 
3481
        if (out != NULL) {
 
3482
            PyDict_SetItemString(kwds, "out",
 
3483
                                 (PyObject *)out);
 
3484
        }
 
3485
    }
 
3486
    return kwds;
3300
3487
}
3301
3488
 
3302
3489
static PyObject *
3303
3490
PyArray_GenericReduceFunction(PyArrayObject *m1, PyObject *op, int axis,
3304
3491
                              int rtype, PyArrayObject *out)
3305
3492
{
3306
 
        PyObject *args, *ret=NULL, *meth;
3307
 
        PyObject *kwds;
3308
 
        if (op == NULL) {
3309
 
                Py_INCREF(Py_NotImplemented);
3310
 
                return Py_NotImplemented;
3311
 
        }
3312
 
        args = Py_BuildValue("(Oi)", m1, axis);
3313
 
        kwds = _get_keywords(rtype, out);
3314
 
        meth = PyObject_GetAttrString(op, "reduce");
3315
 
        if (meth && PyCallable_Check(meth)) {
3316
 
                ret = PyObject_Call(meth, args, kwds);
3317
 
        }
3318
 
        Py_DECREF(args);
3319
 
        Py_DECREF(meth);
3320
 
        Py_XDECREF(kwds);
3321
 
        return ret;
 
3493
    PyObject *args, *ret=NULL, *meth;
 
3494
    PyObject *kwds;
 
3495
    if (op == NULL) {
 
3496
        Py_INCREF(Py_NotImplemented);
 
3497
        return Py_NotImplemented;
 
3498
    }
 
3499
    args = Py_BuildValue("(Oi)", m1, axis);
 
3500
    kwds = _get_keywords(rtype, out);
 
3501
    meth = PyObject_GetAttrString(op, "reduce");
 
3502
    if (meth && PyCallable_Check(meth)) {
 
3503
        ret = PyObject_Call(meth, args, kwds);
 
3504
    }
 
3505
    Py_DECREF(args);
 
3506
    Py_DECREF(meth);
 
3507
    Py_XDECREF(kwds);
 
3508
    return ret;
3322
3509
}
3323
3510
 
3324
3511
 
3326
3513
PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis,
3327
3514
                                  int rtype, PyArrayObject *out)
3328
3515
{
3329
 
        PyObject *args, *ret=NULL, *meth;
3330
 
        PyObject *kwds;
3331
 
        if (op == NULL) {
3332
 
                Py_INCREF(Py_NotImplemented);
3333
 
                return Py_NotImplemented;
3334
 
        }
3335
 
        args = Py_BuildValue("(Oi)", m1, axis);
3336
 
        kwds = _get_keywords(rtype, out);
3337
 
        meth = PyObject_GetAttrString(op, "accumulate");
3338
 
        if (meth && PyCallable_Check(meth)) {
3339
 
                ret = PyObject_Call(meth, args, kwds);
3340
 
        }
3341
 
        Py_DECREF(args);
3342
 
        Py_DECREF(meth);
3343
 
        Py_XDECREF(kwds);
3344
 
        return ret;
 
3516
    PyObject *args, *ret=NULL, *meth;
 
3517
    PyObject *kwds;
 
3518
    if (op == NULL) {
 
3519
        Py_INCREF(Py_NotImplemented);
 
3520
        return Py_NotImplemented;
 
3521
    }
 
3522
    args = Py_BuildValue("(Oi)", m1, axis);
 
3523
    kwds = _get_keywords(rtype, out);
 
3524
    meth = PyObject_GetAttrString(op, "accumulate");
 
3525
    if (meth && PyCallable_Check(meth)) {
 
3526
        ret = PyObject_Call(meth, args, kwds);
 
3527
    }
 
3528
    Py_DECREF(args);
 
3529
    Py_DECREF(meth);
 
3530
    Py_XDECREF(kwds);
 
3531
    return ret;
3345
3532
}
3346
3533
 
3347
3534
 
3348
3535
static PyObject *
3349
3536
PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op)
3350
3537
{
3351
 
        if (op == NULL) {
3352
 
                Py_INCREF(Py_NotImplemented);
3353
 
                return Py_NotImplemented;
3354
 
        }
3355
 
        return PyObject_CallFunction(op, "OO", m1, m2);
 
3538
    if (op == NULL) {
 
3539
        Py_INCREF(Py_NotImplemented);
 
3540
        return Py_NotImplemented;
 
3541
    }
 
3542
    return PyObject_CallFunction(op, "OO", m1, m2);
3356
3543
}
3357
3544
 
3358
3545
static PyObject *
3359
3546
PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op)
3360
3547
{
3361
 
        if (op == NULL) {
3362
 
                Py_INCREF(Py_NotImplemented);
3363
 
                return Py_NotImplemented;
3364
 
        }
3365
 
        return PyObject_CallFunction(op, "(O)", m1);
 
3548
    if (op == NULL) {
 
3549
        Py_INCREF(Py_NotImplemented);
 
3550
        return Py_NotImplemented;
 
3551
    }
 
3552
    return PyObject_CallFunction(op, "(O)", m1);
3366
3553
}
3367
3554
 
3368
3555
static PyObject *
3369
3556
PyArray_GenericInplaceBinaryFunction(PyArrayObject *m1,
3370
3557
                                     PyObject *m2, PyObject *op)
3371
3558
{
3372
 
        if (op == NULL) {
3373
 
                Py_INCREF(Py_NotImplemented);
3374
 
                return Py_NotImplemented;
3375
 
        }
3376
 
        return PyObject_CallFunction(op, "OOO", m1, m2, m1);
 
3559
    if (op == NULL) {
 
3560
        Py_INCREF(Py_NotImplemented);
 
3561
        return Py_NotImplemented;
 
3562
    }
 
3563
    return PyObject_CallFunction(op, "OOO", m1, m2, m1);
3377
3564
}
3378
3565
 
3379
3566
static PyObject *
3380
3567
PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op)
3381
3568
{
3382
 
        if (op == NULL) {
3383
 
                Py_INCREF(Py_NotImplemented);
3384
 
                return Py_NotImplemented;
3385
 
        }
3386
 
        return PyObject_CallFunction(op, "OO", m1, m1);
 
3569
    if (op == NULL) {
 
3570
        Py_INCREF(Py_NotImplemented);
 
3571
        return Py_NotImplemented;
 
3572
    }
 
3573
    return PyObject_CallFunction(op, "OO", m1, m1);
3387
3574
}
3388
3575
 
3389
3576
static PyObject *
3390
3577
array_add(PyArrayObject *m1, PyObject *m2)
3391
3578
{
3392
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.add);
 
3579
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.add);
3393
3580
}
3394
3581
 
3395
3582
static PyObject *
3396
3583
array_subtract(PyArrayObject *m1, PyObject *m2)
3397
3584
{
3398
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.subtract);
 
3585
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.subtract);
3399
3586
}
3400
3587
 
3401
3588
static PyObject *
3402
3589
array_multiply(PyArrayObject *m1, PyObject *m2)
3403
3590
{
3404
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.multiply);
 
3591
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.multiply);
3405
3592
}
3406
3593
 
3407
3594
static PyObject *
3408
3595
array_divide(PyArrayObject *m1, PyObject *m2)
3409
3596
{
3410
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.divide);
 
3597
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.divide);
3411
3598
}
3412
3599
 
3413
3600
static PyObject *
3414
3601
array_remainder(PyArrayObject *m1, PyObject *m2)
3415
3602
{
3416
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder);
 
3603
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder);
3417
3604
}
3418
3605
 
3419
3606
static int
3423
3610
    const int optimize_fpexps = 1;
3424
3611
 
3425
3612
    if (PyInt_Check(o2)) {
3426
 
            *exp = (double)PyInt_AsLong(o2);
3427
 
            return 1;
 
3613
        *exp = (double)PyInt_AsLong(o2);
 
3614
        return 1;
3428
3615
    }
3429
3616
    if (optimize_fpexps && PyFloat_Check(o2)) {
3430
 
            *exp = PyFloat_AsDouble(o2);
3431
 
            return 1;
 
3617
        *exp = PyFloat_AsDouble(o2);
 
3618
        return 1;
3432
3619
    }
3433
3620
    if ((PyArray_IsZeroDim(o2) &&
3434
3621
         ((PyArray_ISINTEGER(o2) ||
3435
3622
           (optimize_fpexps && PyArray_ISFLOAT(o2))))) ||
3436
3623
        PyArray_IsScalar(o2, Integer) ||
3437
3624
        (optimize_fpexps && PyArray_IsScalar(o2, Floating))) {
3438
 
            temp = o2->ob_type->tp_as_number->nb_float(o2);
3439
 
            if (temp != NULL) {
3440
 
                    *exp = PyFloat_AsDouble(o2);
3441
 
                    Py_DECREF(temp);
3442
 
                    return 1;
3443
 
            }
 
3625
        temp = o2->ob_type->tp_as_number->nb_float(o2);
 
3626
        if (temp != NULL) {
 
3627
            *exp = PyFloat_AsDouble(o2);
 
3628
            Py_DECREF(temp);
 
3629
            return 1;
 
3630
        }
3444
3631
    }
3445
3632
#if (PY_VERSION_HEX >= 0x02050000)
3446
3633
    if (PyIndex_Check(o2)) {
3447
 
            PyObject* value = PyNumber_Index(o2);
3448
 
            Py_ssize_t val;
3449
 
            if (value==NULL) {
3450
 
              if (PyErr_Occurred())
3451
 
                PyErr_Clear();
3452
 
              return 0;
3453
 
            }
3454
 
            val = PyInt_AsSsize_t(value);
3455
 
            if (val == -1 && PyErr_Occurred()) {
3456
 
                    PyErr_Clear();
3457
 
                    return 0;
3458
 
            }
3459
 
            *exp = (double) val;
3460
 
            return 1;
 
3634
        PyObject* value = PyNumber_Index(o2);
 
3635
        Py_ssize_t val;
 
3636
        if (value==NULL) {
 
3637
            if (PyErr_Occurred())
 
3638
                PyErr_Clear();
 
3639
            return 0;
 
3640
        }
 
3641
        val = PyInt_AsSsize_t(value);
 
3642
        if (val == -1 && PyErr_Occurred()) {
 
3643
            PyErr_Clear();
 
3644
            return 0;
 
3645
        }
 
3646
        *exp = (double) val;
 
3647
        return 1;
3461
3648
    }
3462
3649
#endif
3463
3650
    return 0;
3466
3653
/* optimize float array or complex array to a scalar power */
3467
3654
static PyObject *
3468
3655
fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace) {
3469
 
        double exp;
3470
 
        if (PyArray_Check(a1) && array_power_is_scalar(o2, &exp)) {
3471
 
                PyObject *fastop = NULL;
3472
 
                if (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) {
3473
 
                        if (exp == 1.0) {
3474
 
                                /* we have to do this one special, as the
3475
 
                                   "copy" method of array objects isn't set
3476
 
                                   up early enough to be added
3477
 
                                   by PyArray_SetNumericOps.
3478
 
                                */
3479
 
                                if (inplace) {
3480
 
                                        Py_INCREF(a1);
3481
 
                                        return (PyObject *)a1;
3482
 
                                } else {
3483
 
                                        return PyArray_Copy(a1);
3484
 
                                }
3485
 
                        } else if (exp == -1.0) {
3486
 
                                fastop = n_ops.reciprocal;
3487
 
                        } else if (exp ==  0.0) {
3488
 
                                fastop = n_ops.ones_like;
3489
 
                        } else if (exp ==  0.5) {
3490
 
                                fastop = n_ops.sqrt;
3491
 
                        } else if (exp ==  2.0) {
3492
 
                                fastop = n_ops.square;
3493
 
                        } else {
3494
 
                                return NULL;
3495
 
                        }
3496
 
                        if (inplace) {
3497
 
                                return PyArray_GenericInplaceUnaryFunction(a1,
3498
 
                                                                    fastop);
3499
 
                        } else {
3500
 
                                return PyArray_GenericUnaryFunction(a1,
3501
 
                                                                    fastop);
3502
 
                        }
3503
 
                }
3504
 
                else if (exp==2.0) {
3505
 
                        fastop = n_ops.multiply;
3506
 
                        if (inplace) {
3507
 
                                return PyArray_GenericInplaceBinaryFunction \
3508
 
                                        (a1, (PyObject *)a1, fastop);
3509
 
                        }
3510
 
                        else {
3511
 
                                return PyArray_GenericBinaryFunction \
3512
 
                                        (a1, (PyObject *)a1, fastop);
3513
 
                        }
3514
 
                }
3515
 
        }
3516
 
        return NULL;
 
3656
    double exp;
 
3657
    if (PyArray_Check(a1) && array_power_is_scalar(o2, &exp)) {
 
3658
        PyObject *fastop = NULL;
 
3659
        if (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) {
 
3660
            if (exp == 1.0) {
 
3661
                /* we have to do this one special, as the
 
3662
                   "copy" method of array objects isn't set
 
3663
                   up early enough to be added
 
3664
                   by PyArray_SetNumericOps.
 
3665
                */
 
3666
                if (inplace) {
 
3667
                    Py_INCREF(a1);
 
3668
                    return (PyObject *)a1;
 
3669
                } else {
 
3670
                    return PyArray_Copy(a1);
 
3671
                }
 
3672
            } else if (exp == -1.0) {
 
3673
                fastop = n_ops.reciprocal;
 
3674
            } else if (exp ==  0.0) {
 
3675
                fastop = n_ops.ones_like;
 
3676
            } else if (exp ==  0.5) {
 
3677
                fastop = n_ops.sqrt;
 
3678
            } else if (exp ==  2.0) {
 
3679
                fastop = n_ops.square;
 
3680
            } else {
 
3681
                return NULL;
 
3682
            }
 
3683
            if (inplace) {
 
3684
                return PyArray_GenericInplaceUnaryFunction(a1,
 
3685
                                                           fastop);
 
3686
            } else {
 
3687
                return PyArray_GenericUnaryFunction(a1,
 
3688
                                                    fastop);
 
3689
            }
 
3690
        }
 
3691
        else if (exp==2.0) {
 
3692
            fastop = n_ops.multiply;
 
3693
            if (inplace) {
 
3694
                return PyArray_GenericInplaceBinaryFunction \
 
3695
                    (a1, (PyObject *)a1, fastop);
 
3696
            }
 
3697
            else {
 
3698
                return PyArray_GenericBinaryFunction \
 
3699
                    (a1, (PyObject *)a1, fastop);
 
3700
            }
 
3701
        }
 
3702
    }
 
3703
    return NULL;
3517
3704
}
3518
3705
 
3519
3706
static PyObject *
3520
3707
array_power(PyArrayObject *a1, PyObject *o2, PyObject *modulo)
3521
3708
{
3522
 
        /* modulo is ignored! */
3523
 
        PyObject *value;
3524
 
        value = fast_scalar_power(a1, o2, 0);
3525
 
        if (!value) {
3526
 
                value = PyArray_GenericBinaryFunction(a1, o2, n_ops.power);
3527
 
        }
3528
 
        return value;
 
3709
    /* modulo is ignored! */
 
3710
    PyObject *value;
 
3711
    value = fast_scalar_power(a1, o2, 0);
 
3712
    if (!value) {
 
3713
        value = PyArray_GenericBinaryFunction(a1, o2, n_ops.power);
 
3714
    }
 
3715
    return value;
3529
3716
}
3530
3717
 
3531
3718
 
3532
3719
static PyObject *
3533
3720
array_negative(PyArrayObject *m1)
3534
3721
{
3535
 
        return PyArray_GenericUnaryFunction(m1, n_ops.negative);
 
3722
    return PyArray_GenericUnaryFunction(m1, n_ops.negative);
3536
3723
}
3537
3724
 
3538
3725
static PyObject *
3539
3726
array_absolute(PyArrayObject *m1)
3540
3727
{
3541
 
        return PyArray_GenericUnaryFunction(m1, n_ops.absolute);
 
3728
    return PyArray_GenericUnaryFunction(m1, n_ops.absolute);
3542
3729
}
3543
3730
 
3544
3731
static PyObject *
3545
3732
array_invert(PyArrayObject *m1)
3546
3733
{
3547
 
        return PyArray_GenericUnaryFunction(m1, n_ops.invert);
 
3734
    return PyArray_GenericUnaryFunction(m1, n_ops.invert);
3548
3735
}
3549
3736
 
3550
3737
static PyObject *
3551
3738
array_left_shift(PyArrayObject *m1, PyObject *m2)
3552
3739
{
3553
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.left_shift);
 
3740
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.left_shift);
3554
3741
}
3555
3742
 
3556
3743
static PyObject *
3557
3744
array_right_shift(PyArrayObject *m1, PyObject *m2)
3558
3745
{
3559
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.right_shift);
 
3746
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.right_shift);
3560
3747
}
3561
3748
 
3562
3749
static PyObject *
3563
3750
array_bitwise_and(PyArrayObject *m1, PyObject *m2)
3564
3751
{
3565
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_and);
 
3752
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_and);
3566
3753
}
3567
3754
 
3568
3755
static PyObject *
3569
3756
array_bitwise_or(PyArrayObject *m1, PyObject *m2)
3570
3757
{
3571
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_or);
 
3758
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_or);
3572
3759
}
3573
3760
 
3574
3761
static PyObject *
3575
3762
array_bitwise_xor(PyArrayObject *m1, PyObject *m2)
3576
3763
{
3577
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_xor);
 
3764
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.bitwise_xor);
3578
3765
}
3579
3766
 
3580
3767
static PyObject *
3581
3768
array_inplace_add(PyArrayObject *m1, PyObject *m2)
3582
3769
{
3583
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.add);
 
3770
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.add);
3584
3771
}
3585
3772
 
3586
3773
static PyObject *
3587
3774
array_inplace_subtract(PyArrayObject *m1, PyObject *m2)
3588
3775
{
3589
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.subtract);
 
3776
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.subtract);
3590
3777
}
3591
3778
 
3592
3779
static PyObject *
3593
3780
array_inplace_multiply(PyArrayObject *m1, PyObject *m2)
3594
3781
{
3595
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.multiply);
 
3782
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.multiply);
3596
3783
}
3597
3784
 
3598
3785
static PyObject *
3599
3786
array_inplace_divide(PyArrayObject *m1, PyObject *m2)
3600
3787
{
3601
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.divide);
 
3788
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.divide);
3602
3789
}
3603
3790
 
3604
3791
static PyObject *
3605
3792
array_inplace_remainder(PyArrayObject *m1, PyObject *m2)
3606
3793
{
3607
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.remainder);
 
3794
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.remainder);
3608
3795
}
3609
3796
 
3610
3797
static PyObject *
3622
3809
static PyObject *
3623
3810
array_inplace_left_shift(PyArrayObject *m1, PyObject *m2)
3624
3811
{
3625
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.left_shift);
 
3812
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.left_shift);
3626
3813
}
3627
3814
 
3628
3815
static PyObject *
3629
3816
array_inplace_right_shift(PyArrayObject *m1, PyObject *m2)
3630
3817
{
3631
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.right_shift);
 
3818
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.right_shift);
3632
3819
}
3633
3820
 
3634
3821
static PyObject *
3635
3822
array_inplace_bitwise_and(PyArrayObject *m1, PyObject *m2)
3636
3823
{
3637
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_and);
 
3824
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_and);
3638
3825
}
3639
3826
 
3640
3827
static PyObject *
3641
3828
array_inplace_bitwise_or(PyArrayObject *m1, PyObject *m2)
3642
3829
{
3643
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_or);
 
3830
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_or);
3644
3831
}
3645
3832
 
3646
3833
static PyObject *
3647
3834
array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2)
3648
3835
{
3649
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_xor);
 
3836
    return PyArray_GenericInplaceBinaryFunction(m1, m2, n_ops.bitwise_xor);
3650
3837
}
3651
3838
 
3652
3839
static PyObject *
3653
3840
array_floor_divide(PyArrayObject *m1, PyObject *m2)
3654
3841
{
3655
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.floor_divide);
 
3842
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.floor_divide);
3656
3843
}
3657
3844
 
3658
3845
static PyObject *
3659
3846
array_true_divide(PyArrayObject *m1, PyObject *m2)
3660
3847
{
3661
 
        return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide);
 
3848
    return PyArray_GenericBinaryFunction(m1, m2, n_ops.true_divide);
3662
3849
}
3663
3850
 
3664
3851
static PyObject *
3665
3852
array_inplace_floor_divide(PyArrayObject *m1, PyObject *m2)
3666
3853
{
3667
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2,
3668
 
                                                    n_ops.floor_divide);
 
3854
    return PyArray_GenericInplaceBinaryFunction(m1, m2,
 
3855
                                                n_ops.floor_divide);
3669
3856
}
3670
3857
 
3671
3858
static PyObject *
3672
3859
array_inplace_true_divide(PyArrayObject *m1, PyObject *m2)
3673
3860
{
3674
 
        return PyArray_GenericInplaceBinaryFunction(m1, m2,
3675
 
                                                    n_ops.true_divide);
 
3861
    return PyArray_GenericInplaceBinaryFunction(m1, m2,
 
3862
                                                n_ops.true_divide);
3676
3863
}
3677
3864
 
3678
3865
/* Array evaluates as "TRUE" if any of the elements are non-zero*/
3679
3866
static int
3680
3867
array_any_nonzero(PyArrayObject *mp)
3681
3868
{
3682
 
        intp index;
3683
 
        PyArrayIterObject *it;
3684
 
        Bool anyTRUE = FALSE;
 
3869
    intp index;
 
3870
    PyArrayIterObject *it;
 
3871
    Bool anyTRUE = FALSE;
3685
3872
 
3686
 
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
3687
 
        if (it==NULL) return anyTRUE;
3688
 
        index = it->size;
3689
 
        while(index--) {
3690
 
                if (mp->descr->f->nonzero(it->dataptr, mp)) {
3691
 
                        anyTRUE = TRUE;
3692
 
                        break;
3693
 
                }
3694
 
                PyArray_ITER_NEXT(it);
 
3873
    it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
3874
    if (it==NULL) return anyTRUE;
 
3875
    index = it->size;
 
3876
    while(index--) {
 
3877
        if (mp->descr->f->nonzero(it->dataptr, mp)) {
 
3878
            anyTRUE = TRUE;
 
3879
            break;
3695
3880
        }
3696
 
        Py_DECREF(it);
3697
 
        return anyTRUE;
 
3881
        PyArray_ITER_NEXT(it);
 
3882
    }
 
3883
    Py_DECREF(it);
 
3884
    return anyTRUE;
3698
3885
}
3699
3886
 
3700
3887
static int
3701
3888
_array_nonzero(PyArrayObject *mp)
3702
3889
{
3703
 
        intp n;
3704
 
        n = PyArray_SIZE(mp);
3705
 
        if (n == 1) {
3706
 
                return mp->descr->f->nonzero(mp->data, mp);
3707
 
        }
3708
 
        else if (n == 0) {
3709
 
                return 0;
3710
 
        }
3711
 
        else {
3712
 
                PyErr_SetString(PyExc_ValueError,
3713
 
                                "The truth value of an array " \
3714
 
                                "with more than one element is ambiguous. " \
3715
 
                                "Use a.any() or a.all()");
3716
 
                return -1;
3717
 
        }
 
3890
    intp n;
 
3891
    n = PyArray_SIZE(mp);
 
3892
    if (n == 1) {
 
3893
        return mp->descr->f->nonzero(mp->data, mp);
 
3894
    }
 
3895
    else if (n == 0) {
 
3896
        return 0;
 
3897
    }
 
3898
    else {
 
3899
        PyErr_SetString(PyExc_ValueError,
 
3900
                        "The truth value of an array " \
 
3901
                        "with more than one element is ambiguous. " \
 
3902
                        "Use a.any() or a.all()");
 
3903
        return -1;
 
3904
    }
3718
3905
}
3719
3906
 
3720
3907
 
3722
3909
static PyObject *
3723
3910
array_divmod(PyArrayObject *op1, PyObject *op2)
3724
3911
{
3725
 
        PyObject *divp, *modp, *result;
 
3912
    PyObject *divp, *modp, *result;
3726
3913
 
3727
 
        divp = array_floor_divide(op1, op2);
3728
 
        if (divp == NULL) return NULL;
3729
 
        modp = array_remainder(op1, op2);
3730
 
        if (modp == NULL) {
3731
 
                Py_DECREF(divp);
3732
 
                return NULL;
3733
 
        }
3734
 
        result = Py_BuildValue("OO", divp, modp);
 
3914
    divp = array_floor_divide(op1, op2);
 
3915
    if (divp == NULL) return NULL;
 
3916
    modp = array_remainder(op1, op2);
 
3917
    if (modp == NULL) {
3735
3918
        Py_DECREF(divp);
3736
 
        Py_DECREF(modp);
3737
 
        return result;
 
3919
        return NULL;
 
3920
    }
 
3921
    result = Py_BuildValue("OO", divp, modp);
 
3922
    Py_DECREF(divp);
 
3923
    Py_DECREF(modp);
 
3924
    return result;
3738
3925
}
3739
3926
 
3740
3927
 
3741
3928
static PyObject *
3742
3929
array_int(PyArrayObject *v)
3743
3930
{
3744
 
        PyObject *pv, *pv2;
3745
 
        if (PyArray_SIZE(v) != 1) {
3746
 
                PyErr_SetString(PyExc_TypeError, "only length-1 arrays can be"\
3747
 
                                " converted to Python scalars");
3748
 
                return NULL;
3749
 
        }
3750
 
        pv = v->descr->f->getitem(v->data, v);
3751
 
        if (pv == NULL) return NULL;
3752
 
        if (pv->ob_type->tp_as_number == 0) {
3753
 
                PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
3754
 
                                "scalar object is not a number");
3755
 
                Py_DECREF(pv);
3756
 
                return NULL;
3757
 
        }
3758
 
        if (pv->ob_type->tp_as_number->nb_int == 0) {
3759
 
                PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
3760
 
                                "scalar number to int");
3761
 
                Py_DECREF(pv);
3762
 
                return NULL;
3763
 
        }
 
3931
    PyObject *pv, *pv2;
 
3932
    if (PyArray_SIZE(v) != 1) {
 
3933
        PyErr_SetString(PyExc_TypeError, "only length-1 arrays can be"\
 
3934
                        " converted to Python scalars");
 
3935
        return NULL;
 
3936
    }
 
3937
    pv = v->descr->f->getitem(v->data, v);
 
3938
    if (pv == NULL) return NULL;
 
3939
    if (pv->ob_type->tp_as_number == 0) {
 
3940
        PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
 
3941
                        "scalar object is not a number");
 
3942
        Py_DECREF(pv);
 
3943
        return NULL;
 
3944
    }
 
3945
    if (pv->ob_type->tp_as_number->nb_int == 0) {
 
3946
        PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
 
3947
                        "scalar number to int");
 
3948
        Py_DECREF(pv);
 
3949
        return NULL;
 
3950
    }
3764
3951
 
3765
 
        pv2 = pv->ob_type->tp_as_number->nb_int(pv);
3766
 
        Py_DECREF(pv);
3767
 
        return pv2;
 
3952
    pv2 = pv->ob_type->tp_as_number->nb_int(pv);
 
3953
    Py_DECREF(pv);
 
3954
    return pv2;
3768
3955
}
3769
3956
 
3770
3957
static PyObject *
3771
3958
array_float(PyArrayObject *v)
3772
3959
{
3773
 
        PyObject *pv, *pv2;
3774
 
        if (PyArray_SIZE(v) != 1) {
3775
 
                PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
3776
 
                                "be converted to Python scalars");
3777
 
                return NULL;
3778
 
        }
3779
 
        pv = v->descr->f->getitem(v->data, v);
3780
 
        if (pv == NULL) return NULL;
3781
 
        if (pv->ob_type->tp_as_number == 0) {
3782
 
                PyErr_SetString(PyExc_TypeError, "cannot convert to a "\
3783
 
                                "float; scalar object is not a number");
3784
 
                Py_DECREF(pv);
3785
 
                return NULL;
3786
 
        }
3787
 
        if (pv->ob_type->tp_as_number->nb_float == 0) {
3788
 
                PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
3789
 
                                "scalar number to float");
3790
 
                Py_DECREF(pv);
3791
 
                return NULL;
3792
 
        }
3793
 
        pv2 = pv->ob_type->tp_as_number->nb_float(pv);
3794
 
        Py_DECREF(pv);
3795
 
        return pv2;
 
3960
    PyObject *pv, *pv2;
 
3961
    if (PyArray_SIZE(v) != 1) {
 
3962
        PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
 
3963
                        "be converted to Python scalars");
 
3964
        return NULL;
 
3965
    }
 
3966
    pv = v->descr->f->getitem(v->data, v);
 
3967
    if (pv == NULL) return NULL;
 
3968
    if (pv->ob_type->tp_as_number == 0) {
 
3969
        PyErr_SetString(PyExc_TypeError, "cannot convert to a "\
 
3970
                        "float; scalar object is not a number");
 
3971
        Py_DECREF(pv);
 
3972
        return NULL;
 
3973
    }
 
3974
    if (pv->ob_type->tp_as_number->nb_float == 0) {
 
3975
        PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
 
3976
                        "scalar number to float");
 
3977
        Py_DECREF(pv);
 
3978
        return NULL;
 
3979
    }
 
3980
    pv2 = pv->ob_type->tp_as_number->nb_float(pv);
 
3981
    Py_DECREF(pv);
 
3982
    return pv2;
3796
3983
}
3797
3984
 
3798
3985
static PyObject *
3799
3986
array_long(PyArrayObject *v)
3800
3987
{
3801
 
        PyObject *pv, *pv2;
3802
 
        if (PyArray_SIZE(v) != 1) {
3803
 
                PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
3804
 
                                "be converted to Python scalars");
3805
 
                return NULL;
3806
 
        }
3807
 
        pv = v->descr->f->getitem(v->data, v);
3808
 
        if (pv->ob_type->tp_as_number == 0) {
3809
 
                PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
3810
 
                                "scalar object is not a number");
3811
 
                return NULL;
3812
 
        }
3813
 
        if (pv->ob_type->tp_as_number->nb_long == 0) {
3814
 
                PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
3815
 
                                "scalar number to long");
3816
 
                return NULL;
3817
 
        }
3818
 
        pv2 = pv->ob_type->tp_as_number->nb_long(pv);
3819
 
        Py_DECREF(pv);
3820
 
        return pv2;
 
3988
    PyObject *pv, *pv2;
 
3989
    if (PyArray_SIZE(v) != 1) {
 
3990
        PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
 
3991
                        "be converted to Python scalars");
 
3992
        return NULL;
 
3993
    }
 
3994
    pv = v->descr->f->getitem(v->data, v);
 
3995
    if (pv->ob_type->tp_as_number == 0) {
 
3996
        PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
 
3997
                        "scalar object is not a number");
 
3998
        return NULL;
 
3999
    }
 
4000
    if (pv->ob_type->tp_as_number->nb_long == 0) {
 
4001
        PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
 
4002
                        "scalar number to long");
 
4003
        return NULL;
 
4004
    }
 
4005
    pv2 = pv->ob_type->tp_as_number->nb_long(pv);
 
4006
    Py_DECREF(pv);
 
4007
    return pv2;
3821
4008
}
3822
4009
 
3823
4010
static PyObject *
3824
4011
array_oct(PyArrayObject *v)
3825
4012
{
3826
 
        PyObject *pv, *pv2;
3827
 
        if (PyArray_SIZE(v) != 1) {
3828
 
                PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
3829
 
                                "be converted to Python scalars");
3830
 
                return NULL;
3831
 
        }
3832
 
        pv = v->descr->f->getitem(v->data, v);
3833
 
        if (pv->ob_type->tp_as_number == 0) {
3834
 
                PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
3835
 
                                "scalar object is not a number");
3836
 
                return NULL;
3837
 
        }
3838
 
        if (pv->ob_type->tp_as_number->nb_oct == 0) {
3839
 
                PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
3840
 
                                "scalar number to oct");
3841
 
                return NULL;
3842
 
        }
3843
 
        pv2 = pv->ob_type->tp_as_number->nb_oct(pv);
3844
 
        Py_DECREF(pv);
3845
 
        return pv2;
 
4013
    PyObject *pv, *pv2;
 
4014
    if (PyArray_SIZE(v) != 1) {
 
4015
        PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
 
4016
                        "be converted to Python scalars");
 
4017
        return NULL;
 
4018
    }
 
4019
    pv = v->descr->f->getitem(v->data, v);
 
4020
    if (pv->ob_type->tp_as_number == 0) {
 
4021
        PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
 
4022
                        "scalar object is not a number");
 
4023
        return NULL;
 
4024
    }
 
4025
    if (pv->ob_type->tp_as_number->nb_oct == 0) {
 
4026
        PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
 
4027
                        "scalar number to oct");
 
4028
        return NULL;
 
4029
    }
 
4030
    pv2 = pv->ob_type->tp_as_number->nb_oct(pv);
 
4031
    Py_DECREF(pv);
 
4032
    return pv2;
3846
4033
}
3847
4034
 
3848
4035
static PyObject *
3849
4036
array_hex(PyArrayObject *v)
3850
4037
{
3851
 
        PyObject *pv, *pv2;
3852
 
        if (PyArray_SIZE(v) != 1) {
3853
 
                PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
3854
 
                                "be converted to Python scalars");
3855
 
                return NULL;
3856
 
        }
3857
 
        pv = v->descr->f->getitem(v->data, v);
3858
 
        if (pv->ob_type->tp_as_number == 0) {
3859
 
                PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
3860
 
                                "scalar object is not a number");
3861
 
                return NULL;
3862
 
        }
3863
 
        if (pv->ob_type->tp_as_number->nb_hex == 0) {
3864
 
                PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
3865
 
                                "scalar number to hex");
3866
 
                return NULL;
3867
 
        }
3868
 
        pv2 = pv->ob_type->tp_as_number->nb_hex(pv);
3869
 
        Py_DECREF(pv);
3870
 
        return pv2;
 
4038
    PyObject *pv, *pv2;
 
4039
    if (PyArray_SIZE(v) != 1) {
 
4040
        PyErr_SetString(PyExc_TypeError, "only length-1 arrays can "\
 
4041
                        "be converted to Python scalars");
 
4042
        return NULL;
 
4043
    }
 
4044
    pv = v->descr->f->getitem(v->data, v);
 
4045
    if (pv->ob_type->tp_as_number == 0) {
 
4046
        PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\
 
4047
                        "scalar object is not a number");
 
4048
        return NULL;
 
4049
    }
 
4050
    if (pv->ob_type->tp_as_number->nb_hex == 0) {
 
4051
        PyErr_SetString(PyExc_TypeError, "don't know how to convert "\
 
4052
                        "scalar number to hex");
 
4053
        return NULL;
 
4054
    }
 
4055
    pv2 = pv->ob_type->tp_as_number->nb_hex(pv);
 
4056
    Py_DECREF(pv);
 
4057
    return pv2;
3871
4058
}
3872
4059
 
3873
4060
static PyObject *
3874
4061
_array_copy_nice(PyArrayObject *self)
3875
4062
{
3876
 
        return PyArray_Return((PyArrayObject *)         \
3877
 
                              PyArray_Copy(self));
 
4063
    return PyArray_Return((PyArrayObject *)         \
 
4064
                          PyArray_Copy(self));
3878
4065
}
3879
4066
 
3880
4067
#if PY_VERSION_HEX >= 0x02050000
3881
4068
static PyObject *
3882
4069
array_index(PyArrayObject *v)
3883
4070
{
3884
 
        if (!PyArray_ISINTEGER(v) || PyArray_SIZE(v) != 1) {
3885
 
                PyErr_SetString(PyExc_TypeError, "only integer arrays with "     \
3886
 
                                "one element can be converted to an index");
3887
 
                return NULL;
3888
 
        }
3889
 
        return v->descr->f->getitem(v->data, v);
 
4071
    if (!PyArray_ISINTEGER(v) || PyArray_SIZE(v) != 1) {
 
4072
        PyErr_SetString(PyExc_TypeError, "only integer arrays with "     \
 
4073
                        "one element can be converted to an index");
 
4074
        return NULL;
 
4075
    }
 
4076
    return v->descr->f->getitem(v->data, v);
3890
4077
}
3891
4078
#endif
3892
4079
 
3893
4080
 
3894
4081
static PyNumberMethods array_as_number = {
3895
 
        (binaryfunc)array_add,              /*nb_add*/
3896
 
        (binaryfunc)array_subtract,                 /*nb_subtract*/
3897
 
        (binaryfunc)array_multiply,                 /*nb_multiply*/
3898
 
        (binaryfunc)array_divide,                   /*nb_divide*/
3899
 
        (binaryfunc)array_remainder,               /*nb_remainder*/
3900
 
        (binaryfunc)array_divmod,                   /*nb_divmod*/
3901
 
        (ternaryfunc)array_power,                   /*nb_power*/
3902
 
        (unaryfunc)array_negative,                  /*nb_neg*/
3903
 
        (unaryfunc)_array_copy_nice,                /*nb_pos*/
3904
 
        (unaryfunc)array_absolute,                  /*(unaryfunc)array_abs,*/
3905
 
        (inquiry)_array_nonzero,                    /*nb_nonzero*/
3906
 
        (unaryfunc)array_invert,                    /*nb_invert*/
3907
 
        (binaryfunc)array_left_shift,       /*nb_lshift*/
3908
 
        (binaryfunc)array_right_shift,      /*nb_rshift*/
3909
 
        (binaryfunc)array_bitwise_and,      /*nb_and*/
3910
 
        (binaryfunc)array_bitwise_xor,      /*nb_xor*/
3911
 
        (binaryfunc)array_bitwise_or,       /*nb_or*/
3912
 
        0,                                  /*nb_coerce*/
3913
 
        (unaryfunc)array_int,               /*nb_int*/
3914
 
        (unaryfunc)array_long,              /*nb_long*/
3915
 
        (unaryfunc)array_float,             /*nb_float*/
3916
 
        (unaryfunc)array_oct,               /*nb_oct*/
3917
 
        (unaryfunc)array_hex,               /*nb_hex*/
3918
 
 
3919
 
        /*This code adds augmented assignment functionality*/
3920
 
        /*that was made available in Python 2.0*/
3921
 
        (binaryfunc)array_inplace_add,      /*inplace_add*/
3922
 
        (binaryfunc)array_inplace_subtract,         /*inplace_subtract*/
3923
 
        (binaryfunc)array_inplace_multiply,         /*inplace_multiply*/
3924
 
        (binaryfunc)array_inplace_divide,           /*inplace_divide*/
3925
 
        (binaryfunc)array_inplace_remainder,    /*inplace_remainder*/
3926
 
        (ternaryfunc)array_inplace_power,           /*inplace_power*/
3927
 
        (binaryfunc)array_inplace_left_shift,   /*inplace_lshift*/
3928
 
        (binaryfunc)array_inplace_right_shift,  /*inplace_rshift*/
3929
 
        (binaryfunc)array_inplace_bitwise_and,  /*inplace_and*/
3930
 
        (binaryfunc)array_inplace_bitwise_xor,  /*inplace_xor*/
3931
 
        (binaryfunc)array_inplace_bitwise_or,   /*inplace_or*/
3932
 
 
3933
 
        (binaryfunc)array_floor_divide,      /*nb_floor_divide*/
3934
 
        (binaryfunc)array_true_divide,       /*nb_true_divide*/
3935
 
        (binaryfunc)array_inplace_floor_divide,  /*nb_inplace_floor_divide*/
3936
 
        (binaryfunc)array_inplace_true_divide,   /*nb_inplace_true_divide*/
 
4082
    (binaryfunc)array_add,                      /*nb_add*/
 
4083
    (binaryfunc)array_subtract,                 /*nb_subtract*/
 
4084
    (binaryfunc)array_multiply,                 /*nb_multiply*/
 
4085
    (binaryfunc)array_divide,                   /*nb_divide*/
 
4086
    (binaryfunc)array_remainder,                /*nb_remainder*/
 
4087
    (binaryfunc)array_divmod,                   /*nb_divmod*/
 
4088
    (ternaryfunc)array_power,                   /*nb_power*/
 
4089
    (unaryfunc)array_negative,                  /*nb_neg*/
 
4090
    (unaryfunc)_array_copy_nice,                /*nb_pos*/
 
4091
    (unaryfunc)array_absolute,                  /*(unaryfunc)array_abs,*/
 
4092
    (inquiry)_array_nonzero,                    /*nb_nonzero*/
 
4093
    (unaryfunc)array_invert,                    /*nb_invert*/
 
4094
    (binaryfunc)array_left_shift,               /*nb_lshift*/
 
4095
    (binaryfunc)array_right_shift,              /*nb_rshift*/
 
4096
    (binaryfunc)array_bitwise_and,              /*nb_and*/
 
4097
    (binaryfunc)array_bitwise_xor,              /*nb_xor*/
 
4098
    (binaryfunc)array_bitwise_or,               /*nb_or*/
 
4099
    0,                                          /*nb_coerce*/
 
4100
    (unaryfunc)array_int,                       /*nb_int*/
 
4101
    (unaryfunc)array_long,                      /*nb_long*/
 
4102
    (unaryfunc)array_float,                     /*nb_float*/
 
4103
    (unaryfunc)array_oct,                       /*nb_oct*/
 
4104
    (unaryfunc)array_hex,                       /*nb_hex*/
 
4105
 
 
4106
    /*This code adds augmented assignment functionality*/
 
4107
    /*that was made available in Python 2.0*/
 
4108
    (binaryfunc)array_inplace_add,              /*inplace_add*/
 
4109
    (binaryfunc)array_inplace_subtract,         /*inplace_subtract*/
 
4110
    (binaryfunc)array_inplace_multiply,         /*inplace_multiply*/
 
4111
    (binaryfunc)array_inplace_divide,           /*inplace_divide*/
 
4112
    (binaryfunc)array_inplace_remainder,        /*inplace_remainder*/
 
4113
    (ternaryfunc)array_inplace_power,           /*inplace_power*/
 
4114
    (binaryfunc)array_inplace_left_shift,       /*inplace_lshift*/
 
4115
    (binaryfunc)array_inplace_right_shift,      /*inplace_rshift*/
 
4116
    (binaryfunc)array_inplace_bitwise_and,      /*inplace_and*/
 
4117
    (binaryfunc)array_inplace_bitwise_xor,      /*inplace_xor*/
 
4118
    (binaryfunc)array_inplace_bitwise_or,       /*inplace_or*/
 
4119
 
 
4120
    (binaryfunc)array_floor_divide,             /*nb_floor_divide*/
 
4121
    (binaryfunc)array_true_divide,              /*nb_true_divide*/
 
4122
    (binaryfunc)array_inplace_floor_divide,     /*nb_inplace_floor_divide*/
 
4123
    (binaryfunc)array_inplace_true_divide,      /*nb_inplace_true_divide*/
3937
4124
 
3938
4125
#if PY_VERSION_HEX >= 0x02050000
3939
 
        (unaryfunc)array_index,                /* nb_index */
 
4126
    (unaryfunc)array_index,                     /* nb_index */
3940
4127
#endif
3941
4128
 
3942
4129
};
3957
4144
array_slice(PyArrayObject *self, Py_ssize_t ilow,
3958
4145
            Py_ssize_t ihigh)
3959
4146
{
3960
 
        PyArrayObject *r;
3961
 
        Py_ssize_t l;
3962
 
        char *data;
3963
 
 
3964
 
        if (self->nd == 0) {
3965
 
                PyErr_SetString(PyExc_ValueError, "cannot slice a 0-d array");
3966
 
                return NULL;
3967
 
        }
3968
 
 
3969
 
        l=self->dimensions[0];
3970
 
        if (ilow < 0) ilow = 0;
3971
 
        else if (ilow > l) ilow = l;
3972
 
        if (ihigh < ilow) ihigh = ilow;
3973
 
        else if (ihigh > l) ihigh = l;
3974
 
 
3975
 
        if (ihigh != ilow) {
3976
 
                data = index2ptr(self, ilow);
3977
 
                if (data == NULL) return NULL;
3978
 
        } else {
3979
 
                data = self->data;
3980
 
        }
3981
 
 
3982
 
        self->dimensions[0] = ihigh-ilow;
3983
 
        Py_INCREF(self->descr);
3984
 
        r = (PyArrayObject *)                                           \
3985
 
                PyArray_NewFromDescr(self->ob_type, self->descr,
3986
 
                                     self->nd, self->dimensions,
3987
 
                                     self->strides, data,
3988
 
                                     self->flags, (PyObject *)self);
3989
 
        self->dimensions[0] = l;
3990
 
        if (r == NULL) return NULL;
3991
 
        r->base = (PyObject *)self;
3992
 
        Py_INCREF(self);
3993
 
        PyArray_UpdateFlags(r, UPDATE_ALL);
3994
 
        return (PyObject *)r;
 
4147
    PyArrayObject *r;
 
4148
    Py_ssize_t l;
 
4149
    char *data;
 
4150
 
 
4151
    if (self->nd == 0) {
 
4152
        PyErr_SetString(PyExc_ValueError, "cannot slice a 0-d array");
 
4153
        return NULL;
 
4154
    }
 
4155
 
 
4156
    l=self->dimensions[0];
 
4157
    if (ilow < 0) ilow = 0;
 
4158
    else if (ilow > l) ilow = l;
 
4159
    if (ihigh < ilow) ihigh = ilow;
 
4160
    else if (ihigh > l) ihigh = l;
 
4161
 
 
4162
    if (ihigh != ilow) {
 
4163
        data = index2ptr(self, ilow);
 
4164
        if (data == NULL) return NULL;
 
4165
    } else {
 
4166
        data = self->data;
 
4167
    }
 
4168
 
 
4169
    self->dimensions[0] = ihigh-ilow;
 
4170
    Py_INCREF(self->descr);
 
4171
    r = (PyArrayObject *)                                           \
 
4172
        PyArray_NewFromDescr(self->ob_type, self->descr,
 
4173
                             self->nd, self->dimensions,
 
4174
                             self->strides, data,
 
4175
                             self->flags, (PyObject *)self);
 
4176
    self->dimensions[0] = l;
 
4177
    if (r == NULL) return NULL;
 
4178
    r->base = (PyObject *)self;
 
4179
    Py_INCREF(self);
 
4180
    PyArray_UpdateFlags(r, UPDATE_ALL);
 
4181
    return (PyObject *)r;
3995
4182
}
3996
4183
 
3997
4184
 
3998
4185
static int
3999
4186
array_ass_slice(PyArrayObject *self, Py_ssize_t ilow,
4000
4187
                Py_ssize_t ihigh, PyObject *v) {
4001
 
        int ret;
4002
 
        PyArrayObject *tmp;
4003
 
 
4004
 
        if (v == NULL) {
4005
 
                PyErr_SetString(PyExc_ValueError,
4006
 
                                "cannot delete array elements");
4007
 
                return -1;
4008
 
        }
4009
 
        if (!PyArray_ISWRITEABLE(self)) {
4010
 
                PyErr_SetString(PyExc_RuntimeError,
4011
 
                                "array is not writeable");
4012
 
                return -1;
4013
 
        }
4014
 
        if ((tmp = (PyArrayObject *)array_slice(self, ilow, ihigh)) \
4015
 
            == NULL)
4016
 
                return -1;
4017
 
        ret = PyArray_CopyObject(tmp, v);
4018
 
        Py_DECREF(tmp);
4019
 
 
4020
 
        return ret;
 
4188
    int ret;
 
4189
    PyArrayObject *tmp;
 
4190
 
 
4191
    if (v == NULL) {
 
4192
        PyErr_SetString(PyExc_ValueError,
 
4193
                        "cannot delete array elements");
 
4194
        return -1;
 
4195
    }
 
4196
    if (!PyArray_ISWRITEABLE(self)) {
 
4197
        PyErr_SetString(PyExc_RuntimeError,
 
4198
                        "array is not writeable");
 
4199
        return -1;
 
4200
    }
 
4201
    if ((tmp = (PyArrayObject *)array_slice(self, ilow, ihigh)) \
 
4202
        == NULL)
 
4203
        return -1;
 
4204
    ret = PyArray_CopyObject(tmp, v);
 
4205
    Py_DECREF(tmp);
 
4206
 
 
4207
    return ret;
4021
4208
}
4022
4209
 
4023
4210
static int
4024
4211
array_contains(PyArrayObject *self, PyObject *el)
4025
4212
{
4026
 
        /* equivalent to (self == el).any() */
4027
 
 
4028
 
        PyObject *res;
4029
 
        int ret;
4030
 
 
4031
 
        res = PyArray_EnsureAnyArray(PyObject_RichCompare((PyObject *)self,
4032
 
                                                          el, Py_EQ));
4033
 
        if (res == NULL) return -1;
4034
 
        ret = array_any_nonzero((PyArrayObject *)res);
4035
 
        Py_DECREF(res);
4036
 
        return ret;
 
4213
    /* equivalent to (self == el).any() */
 
4214
 
 
4215
    PyObject *res;
 
4216
    int ret;
 
4217
 
 
4218
    res = PyArray_EnsureAnyArray(PyObject_RichCompare((PyObject *)self,
 
4219
                                                      el, Py_EQ));
 
4220
    if (res == NULL) return -1;
 
4221
    ret = array_any_nonzero((PyArrayObject *)res);
 
4222
    Py_DECREF(res);
 
4223
    return ret;
4037
4224
}
4038
4225
 
4039
4226
static PySequenceMethods array_as_sequence = {
4040
4227
#if PY_VERSION_HEX >= 0x02050000
4041
 
        (lenfunc)array_length,          /*sq_length*/
4042
 
        (binaryfunc)NULL,               /* sq_concat is handled by nb_add*/
4043
 
        (ssizeargfunc)NULL,             
4044
 
        (ssizeargfunc)array_item_nice,
4045
 
        (ssizessizeargfunc)array_slice,
4046
 
        (ssizeobjargproc)array_ass_item,               /*sq_ass_item*/
4047
 
        (ssizessizeobjargproc)array_ass_slice,  /*sq_ass_slice*/
4048
 
        (objobjproc) array_contains,           /* sq_contains */
4049
 
        (binaryfunc) NULL,                  /* sg_inplace_concat */
4050
 
        (ssizeargfunc)NULL,
 
4228
    (lenfunc)array_length,                  /*sq_length*/
 
4229
    (binaryfunc)NULL,                       /*sq_concat is handled by nb_add*/
 
4230
    (ssizeargfunc)NULL,
 
4231
    (ssizeargfunc)array_item_nice,
 
4232
    (ssizessizeargfunc)array_slice,
 
4233
    (ssizeobjargproc)array_ass_item,        /*sq_ass_item*/
 
4234
    (ssizessizeobjargproc)array_ass_slice,  /*sq_ass_slice*/
 
4235
    (objobjproc) array_contains,            /*sq_contains */
 
4236
    (binaryfunc) NULL,                      /*sg_inplace_concat */
 
4237
    (ssizeargfunc)NULL,
4051
4238
#else
4052
 
        (inquiry)array_length,          /*sq_length*/
4053
 
        (binaryfunc)NULL, /* sq_concat is handled by nb_add*/
4054
 
        (intargfunc)NULL, /* sq_repeat is handled nb_multiply*/
4055
 
        (intargfunc)array_item_nice,            /*sq_item*/
4056
 
        (intintargfunc)array_slice,             /*sq_slice*/
4057
 
        (intobjargproc)array_ass_item,         /*sq_ass_item*/
4058
 
        (intintobjargproc)array_ass_slice,      /*sq_ass_slice*/
4059
 
        (objobjproc) array_contains,           /* sq_contains */
4060
 
        (binaryfunc) NULL,                  /* sg_inplace_concat */
4061
 
        (intargfunc) NULL         /* sg_inplace_repeat */
 
4239
    (inquiry)array_length,                  /*sq_length*/
 
4240
    (binaryfunc)NULL,                       /*sq_concat is handled by nb_add*/
 
4241
    (intargfunc)NULL,                       /*sq_repeat is handled nb_multiply*/
 
4242
    (intargfunc)array_item_nice,            /*sq_item*/
 
4243
    (intintargfunc)array_slice,             /*sq_slice*/
 
4244
    (intobjargproc)array_ass_item,          /*sq_ass_item*/
 
4245
    (intintobjargproc)array_ass_slice,      /*sq_ass_slice*/
 
4246
    (objobjproc) array_contains,            /*sq_contains */
 
4247
    (binaryfunc) NULL,                      /*sg_inplace_concat */
 
4248
    (intargfunc) NULL                       /*sg_inplace_repeat */
4062
4249
#endif
4063
4250
};
4064
4251
 
4070
4257
dump_data(char **string, int *n, int *max_n, char *data, int nd,
4071
4258
          intp *dimensions, intp *strides, PyArrayObject* self)
4072
4259
{
4073
 
        PyArray_Descr *descr=self->descr;
4074
 
        PyObject *op, *sp;
4075
 
        char *ostring;
4076
 
        int i, N;
4077
 
 
4078
 
#define CHECK_MEMORY if (*n >= *max_n-16) { *max_n *= 2; \
4079
 
                *string = (char *)_pya_realloc(*string, *max_n); }
4080
 
 
4081
 
        if (nd == 0) {
4082
 
 
4083
 
                if ((op = descr->f->getitem(data, self)) == NULL) return -1;
4084
 
                sp = PyObject_Repr(op);
4085
 
                if (sp == NULL) {Py_DECREF(op); return -1;}
4086
 
                ostring = PyString_AsString(sp);
4087
 
                N = PyString_Size(sp)*sizeof(char);
4088
 
                *n += N;
4089
 
                CHECK_MEMORY
4090
 
                        memmove(*string+(*n-N), ostring, N);
4091
 
                Py_DECREF(sp);
4092
 
                Py_DECREF(op);
4093
 
                return 0;
4094
 
        } else {
4095
 
                CHECK_MEMORY
4096
 
                        (*string)[*n] = '[';
4097
 
                *n += 1;
4098
 
                for(i=0; i<dimensions[0]; i++) {
4099
 
                        if (dump_data(string, n, max_n,
4100
 
                                      data+(*strides)*i,
4101
 
                                      nd-1, dimensions+1,
4102
 
                                      strides+1, self) < 0)
4103
 
                                return -1;
4104
 
                                CHECK_MEMORY
4105
 
                                        if (i<dimensions[0]-1) {
4106
 
                                                (*string)[*n] = ',';
4107
 
                                                (*string)[*n+1] = ' ';
4108
 
                                                *n += 2;
4109
 
                                        }
 
4260
    PyArray_Descr *descr=self->descr;
 
4261
    PyObject *op, *sp;
 
4262
    char *ostring;
 
4263
    int i, N;
 
4264
 
 
4265
#define CHECK_MEMORY if (*n >= *max_n-16) { *max_n *= 2;        \
 
4266
        *string = (char *)_pya_realloc(*string, *max_n); }
 
4267
 
 
4268
    if (nd == 0) {
 
4269
 
 
4270
        if ((op = descr->f->getitem(data, self)) == NULL) {
 
4271
            return -1;
 
4272
        }
 
4273
        sp = PyObject_Repr(op);
 
4274
        if (sp == NULL) {
 
4275
            Py_DECREF(op);
 
4276
            return -1;
 
4277
        }
 
4278
        ostring = PyString_AsString(sp);
 
4279
        N = PyString_Size(sp)*sizeof(char);
 
4280
        *n += N;
 
4281
        CHECK_MEMORY
 
4282
            memmove(*string + (*n - N), ostring, N);
 
4283
        Py_DECREF(sp);
 
4284
        Py_DECREF(op);
 
4285
        return 0;
 
4286
    }
 
4287
    else {
 
4288
        CHECK_MEMORY
 
4289
            (*string)[*n] = '[';
 
4290
        *n += 1;
 
4291
        for(i = 0; i < dimensions[0]; i++) {
 
4292
            if (dump_data(string, n, max_n,
 
4293
                          data + (*strides)*i,
 
4294
                          nd - 1, dimensions + 1,
 
4295
                          strides + 1, self) < 0) {
 
4296
                return -1;
 
4297
            }
 
4298
            CHECK_MEMORY
 
4299
                if (i < dimensions[0] - 1) {
 
4300
                    (*string)[*n] = ',';
 
4301
                    (*string)[*n+1] = ' ';
 
4302
                    *n += 2;
4110
4303
                }
4111
 
                CHECK_MEMORY
4112
 
                        (*string)[*n] = ']'; *n += 1;
4113
 
                return 0;
4114
4304
        }
 
4305
        CHECK_MEMORY
 
4306
            (*string)[*n] = ']';
 
4307
            *n += 1;
 
4308
        return 0;
 
4309
    }
4115
4310
 
4116
4311
#undef CHECK_MEMORY
4117
4312
}
4119
4314
static PyObject *
4120
4315
array_repr_builtin(PyArrayObject *self, int repr)
4121
4316
{
4122
 
        PyObject *ret;
4123
 
        char *string;
4124
 
        int n, max_n;
4125
 
 
4126
 
        max_n = PyArray_NBYTES(self)*4*sizeof(char) + 7;
4127
 
 
4128
 
        if ((string = (char *)_pya_malloc(max_n)) == NULL) {
4129
 
                PyErr_SetString(PyExc_MemoryError, "out of memory");
4130
 
                return NULL;
4131
 
        }
4132
 
 
4133
 
        if (repr) {
4134
 
                n = 6;
4135
 
                sprintf(string, "array(");
4136
 
        }
4137
 
        else {
4138
 
                n = 0;
4139
 
        }
4140
 
        if (dump_data(&string, &n, &max_n, self->data,
4141
 
                      self->nd, self->dimensions,
4142
 
                      self->strides, self) < 0) {
4143
 
                _pya_free(string); return NULL;
4144
 
        }
4145
 
 
4146
 
        if (repr) {
4147
 
                if (PyArray_ISEXTENDED(self)) {
4148
 
                        char buf[100];
4149
 
                        snprintf(buf, sizeof(buf), "%d", self->descr->elsize);
4150
 
                        sprintf(string+n, ", '%c%s')", self->descr->type, buf);
4151
 
                        ret = PyString_FromStringAndSize(string, n+6+strlen(buf));
4152
 
                }
4153
 
                else {
4154
 
                        sprintf(string+n, ", '%c')", self->descr->type);
4155
 
                        ret = PyString_FromStringAndSize(string, n+6);
4156
 
                }
4157
 
        }
4158
 
        else {
4159
 
                ret = PyString_FromStringAndSize(string, n);
4160
 
        }
4161
 
 
 
4317
    PyObject *ret;
 
4318
    char *string;
 
4319
    int n, max_n;
 
4320
 
 
4321
    max_n = PyArray_NBYTES(self)*4*sizeof(char) + 7;
 
4322
 
 
4323
    if ((string = (char *)_pya_malloc(max_n)) == NULL) {
 
4324
        PyErr_SetString(PyExc_MemoryError, "out of memory");
 
4325
        return NULL;
 
4326
    }
 
4327
 
 
4328
    if (repr) {
 
4329
        n = 6;
 
4330
        sprintf(string, "array(");
 
4331
    }
 
4332
    else {
 
4333
        n = 0;
 
4334
    }
 
4335
    if (dump_data(&string, &n, &max_n, self->data,
 
4336
                  self->nd, self->dimensions,
 
4337
                  self->strides, self) < 0) {
4162
4338
        _pya_free(string);
4163
 
        return ret;
 
4339
        return NULL;
 
4340
    }
 
4341
 
 
4342
    if (repr) {
 
4343
        if (PyArray_ISEXTENDED(self)) {
 
4344
            char buf[100];
 
4345
            snprintf(buf, sizeof(buf), "%d", self->descr->elsize);
 
4346
            sprintf(string+n, ", '%c%s')", self->descr->type, buf);
 
4347
            ret = PyString_FromStringAndSize(string, n+6+strlen(buf));
 
4348
        }
 
4349
        else {
 
4350
            sprintf(string+n, ", '%c')", self->descr->type);
 
4351
            ret = PyString_FromStringAndSize(string, n+6);
 
4352
        }
 
4353
    }
 
4354
    else {
 
4355
        ret = PyString_FromStringAndSize(string, n);
 
4356
    }
 
4357
 
 
4358
    _pya_free(string);
 
4359
    return ret;
4164
4360
}
4165
4361
 
4166
4362
static PyObject *PyArray_StrFunction=NULL;
4167
4363
static PyObject *PyArray_ReprFunction=NULL;
4168
4364
 
4169
4365
/*OBJECT_API
4170
 
 Set the array print function to be a Python function.
 
4366
  Set the array print function to be a Python function.
4171
4367
*/
4172
4368
static void
4173
4369
PyArray_SetStringFunction(PyObject *op, int repr)
4174
4370
{
4175
 
        if (repr) {
4176
 
                /* Dispose of previous callback */
4177
 
                Py_XDECREF(PyArray_ReprFunction);
4178
 
                /* Add a reference to new callback */
4179
 
                Py_XINCREF(op);
4180
 
                /* Remember new callback */
4181
 
                PyArray_ReprFunction = op;
4182
 
        } else {
4183
 
                /* Dispose of previous callback */
4184
 
                Py_XDECREF(PyArray_StrFunction);
4185
 
                /* Add a reference to new callback */
4186
 
                Py_XINCREF(op);
4187
 
                /* Remember new callback */
4188
 
                PyArray_StrFunction = op;
4189
 
        }
 
4371
    if (repr) {
 
4372
        /* Dispose of previous callback */
 
4373
        Py_XDECREF(PyArray_ReprFunction);
 
4374
        /* Add a reference to new callback */
 
4375
        Py_XINCREF(op);
 
4376
        /* Remember new callback */
 
4377
        PyArray_ReprFunction = op;
 
4378
    } else {
 
4379
        /* Dispose of previous callback */
 
4380
        Py_XDECREF(PyArray_StrFunction);
 
4381
        /* Add a reference to new callback */
 
4382
        Py_XINCREF(op);
 
4383
        /* Remember new callback */
 
4384
        PyArray_StrFunction = op;
 
4385
    }
4190
4386
}
4191
4387
 
4192
4388
static PyObject *
4193
4389
array_repr(PyArrayObject *self)
4194
4390
{
4195
 
        PyObject *s, *arglist;
 
4391
    PyObject *s, *arglist;
4196
4392
 
4197
 
        if (PyArray_ReprFunction == NULL) {
4198
 
                s = array_repr_builtin(self, 1);
4199
 
        } else {
4200
 
                arglist = Py_BuildValue("(O)", self);
4201
 
                s = PyEval_CallObject(PyArray_ReprFunction, arglist);
4202
 
                Py_DECREF(arglist);
4203
 
        }
4204
 
        return s;
 
4393
    if (PyArray_ReprFunction == NULL) {
 
4394
        s = array_repr_builtin(self, 1);
 
4395
    } else {
 
4396
        arglist = Py_BuildValue("(O)", self);
 
4397
        s = PyEval_CallObject(PyArray_ReprFunction, arglist);
 
4398
        Py_DECREF(arglist);
 
4399
    }
 
4400
    return s;
4205
4401
}
4206
4402
 
4207
4403
static PyObject *
4208
4404
array_str(PyArrayObject *self)
4209
4405
{
4210
 
        PyObject *s, *arglist;
 
4406
    PyObject *s, *arglist;
4211
4407
 
4212
 
        if (PyArray_StrFunction == NULL) {
4213
 
                s = array_repr_builtin(self, 0);
4214
 
        } else {
4215
 
                arglist = Py_BuildValue("(O)", self);
4216
 
                s = PyEval_CallObject(PyArray_StrFunction, arglist);
4217
 
                Py_DECREF(arglist);
4218
 
        }
4219
 
        return s;
 
4408
    if (PyArray_StrFunction == NULL) {
 
4409
        s = array_repr_builtin(self, 0);
 
4410
    } else {
 
4411
        arglist = Py_BuildValue("(O)", self);
 
4412
        s = PyEval_CallObject(PyArray_StrFunction, arglist);
 
4413
        Py_DECREF(arglist);
 
4414
    }
 
4415
    return s;
4220
4416
}
4221
4417
 
4222
4418
 
4226
4422
static int
4227
4423
PyArray_CompareUCS4(npy_ucs4 *s1, npy_ucs4 *s2, register size_t len)
4228
4424
{
4229
 
        register PyArray_UCS4 c1, c2;
4230
 
        while(len-- > 0) {
4231
 
                c1 = *s1++;
4232
 
                c2 = *s2++;
4233
 
                if (c1 != c2) {
4234
 
                        return (c1 < c2) ? -1 : 1;
4235
 
                }
4236
 
        }
4237
 
        return 0;
4238
 
}
 
4425
    register PyArray_UCS4 c1, c2;
 
4426
    while(len-- > 0) {
 
4427
        c1 = *s1++;
 
4428
        c2 = *s2++;
 
4429
        if (c1 != c2) {
 
4430
            return (c1 < c2) ? -1 : 1;
 
4431
        }
 
4432
    }
 
4433
    return 0;
 
4434
}
 
4435
 
 
4436
/*MULTIARRAY_API
 
4437
 */
 
4438
static int
 
4439
PyArray_CompareString(char *s1, char *s2, size_t len)
 
4440
{
 
4441
    const unsigned char *c1 = (unsigned char *)s1;
 
4442
    const unsigned char *c2 = (unsigned char *)s2;
 
4443
    size_t i;
 
4444
 
 
4445
    for(i = 0; i < len; ++i) {
 
4446
        if (c1[i] != c2[i]) {
 
4447
            return (c1[i] > c2[i]) ? 1 : -1;
 
4448
        }
 
4449
    }
 
4450
    return 0;
 
4451
}
 
4452
 
4239
4453
 
4240
4454
/* This also handles possibly mis-aligned data */
4241
4455
/* Compare s1 and s2 which are not necessarily NULL-terminated.
4246
4460
static int
4247
4461
_myunincmp(PyArray_UCS4 *s1, PyArray_UCS4 *s2, int len1, int len2)
4248
4462
{
4249
 
        PyArray_UCS4 *sptr;
4250
 
        PyArray_UCS4 *s1t=s1, *s2t=s2;
4251
 
        int val;
4252
 
        intp size;
 
4463
    PyArray_UCS4 *sptr;
 
4464
    PyArray_UCS4 *s1t=s1, *s2t=s2;
 
4465
    int val;
 
4466
    intp size;
 
4467
    int diff;
4253
4468
 
4254
 
        if ((intp)s1 % sizeof(PyArray_UCS4) != 0) {
4255
 
                size = len1*sizeof(PyArray_UCS4);
4256
 
                s1t = malloc(size);
4257
 
                memcpy(s1t, s1, size);
4258
 
        }
4259
 
        if ((intp)s2 % sizeof(PyArray_UCS4) != 0) {
4260
 
                size = len2*sizeof(PyArray_UCS4);
4261
 
                s2t = malloc(size);
4262
 
                memcpy(s2t, s2, size);
4263
 
        }
4264
 
        val = PyArray_CompareUCS4(s1t, s2t, MIN(len1,len2));
4265
 
        if ((val != 0) || (len1 == len2)) goto finish;
4266
 
        if (len2 > len1) {sptr = s2t+len1; val = -1;}
4267
 
        else {sptr = s1t+len2; val = 1;}
 
4469
    if ((intp)s1 % sizeof(PyArray_UCS4) != 0) {
 
4470
        size = len1*sizeof(PyArray_UCS4);
 
4471
        s1t = malloc(size);
 
4472
        memcpy(s1t, s1, size);
 
4473
    }
 
4474
    if ((intp)s2 % sizeof(PyArray_UCS4) != 0) {
 
4475
        size = len2*sizeof(PyArray_UCS4);
 
4476
        s2t = malloc(size);
 
4477
        memcpy(s2t, s2, size);
 
4478
    }
 
4479
    val = PyArray_CompareUCS4(s1t, s2t, MIN(len1,len2));
 
4480
    if ((val != 0) || (len1 == len2)) goto finish;
 
4481
    if (len2 > len1) {sptr = s2t+len1; val = -1; diff=len2-len1;}
 
4482
    else {sptr = s1t+len2; val = 1; diff=len1-len2;}
 
4483
    while (diff--) {
4268
4484
        if (*sptr != 0) goto finish;
4269
 
        val = 0;
 
4485
        sptr++;
 
4486
    }
 
4487
    val = 0;
4270
4488
 
4271
4489
 finish:
4272
 
        if (s1t != s1) free(s1t);
4273
 
        if (s2t != s2) free(s2t);
4274
 
        return val;
 
4490
    if (s1t != s1) free(s1t);
 
4491
    if (s2t != s2) free(s2t);
 
4492
    return val;
4275
4493
}
4276
4494
 
4277
4495
 
4285
4503
static int
4286
4504
_mystrncmp(char *s1, char *s2, int len1, int len2)
4287
4505
{
4288
 
        char *sptr;
4289
 
        int val;
 
4506
    char *sptr;
 
4507
    int val;
 
4508
    int diff;
4290
4509
 
4291
 
        val = strncmp(s1, s2, MIN(len1, len2));
4292
 
        if ((val != 0) || (len1 == len2)) return val;
4293
 
        if (len2 > len1) {sptr = s2+len1; val = -1;}
4294
 
        else {sptr = s1+len2; val = 1;}
 
4510
    val = memcmp(s1, s2, MIN(len1, len2));
 
4511
    if ((val != 0) || (len1 == len2)) return val;
 
4512
    if (len2 > len1) {sptr = s2+len1; val = -1; diff=len2-len1;}
 
4513
    else {sptr = s1+len2; val = 1; diff=len1-len2;}
 
4514
    while (diff--) {
4295
4515
        if (*sptr != 0) return val;
4296
 
        return 0;
 
4516
        sptr++;
 
4517
    }
 
4518
    return 0; /* Only happens if NULLs are everywhere */
4297
4519
}
4298
4520
 
4299
4521
/* Borrowed from Numarray */
4307
4529
 
4308
4530
static void _rstripw(char *s, int n)
4309
4531
{
4310
 
        int i;
4311
 
        for(i=n-1; i>=1; i--)  /* Never strip to length 0. */
 
4532
    int i;
 
4533
    for(i=n-1; i>=1; i--)  /* Never strip to length 0. */
4312
4534
        {
4313
 
                int c = s[i];
4314
 
                if (!c || isspace(c))
4315
 
                        s[i] = 0;
4316
 
                else
4317
 
                        break;
 
4535
            int c = s[i];
 
4536
            if (!c || isspace(c))
 
4537
                s[i] = 0;
 
4538
            else
 
4539
                break;
4318
4540
        }
4319
4541
}
4320
4542
 
4321
4543
static void _unistripw(PyArray_UCS4 *s, int n)
4322
4544
{
4323
 
        int i;
4324
 
        for(i=n-1; i>=1; i--)  /* Never strip to length 0. */
 
4545
    int i;
 
4546
    for(i=n-1; i>=1; i--)  /* Never strip to length 0. */
4325
4547
        {
4326
 
                PyArray_UCS4 c = s[i];
4327
 
                if (!c || isspace(c))
4328
 
                        s[i] = 0;
4329
 
                else
4330
 
                        break;
 
4548
            PyArray_UCS4 c = s[i];
 
4549
            if (!c || isspace(c))
 
4550
                s[i] = 0;
 
4551
            else
 
4552
                break;
4331
4553
        }
4332
4554
}
4333
4555
 
4335
4557
static char *
4336
4558
_char_copy_n_strip(char *original, char *temp, int nc)
4337
4559
{
4338
 
        if (nc > SMALL_STRING) {
4339
 
                temp = malloc(nc);
4340
 
                if (!temp) {
4341
 
                        PyErr_NoMemory();
4342
 
                        return NULL;
4343
 
                }
 
4560
    if (nc > SMALL_STRING) {
 
4561
        temp = malloc(nc);
 
4562
        if (!temp) {
 
4563
            PyErr_NoMemory();
 
4564
            return NULL;
4344
4565
        }
4345
 
        memcpy(temp, original, nc);
4346
 
        _rstripw(temp, nc);
4347
 
        return temp;
 
4566
    }
 
4567
    memcpy(temp, original, nc);
 
4568
    _rstripw(temp, nc);
 
4569
    return temp;
4348
4570
}
4349
4571
 
4350
4572
static void
4351
4573
_char_release(char *ptr, int nc)
4352
4574
{
4353
 
        if (nc > SMALL_STRING) {
4354
 
                free(ptr);
4355
 
        }
 
4575
    if (nc > SMALL_STRING) {
 
4576
        free(ptr);
 
4577
    }
4356
4578
}
4357
4579
 
4358
4580
static char *
4359
4581
_uni_copy_n_strip(char *original, char *temp, int nc)
4360
4582
{
4361
 
        if (nc*sizeof(PyArray_UCS4) > SMALL_STRING) {
4362
 
                temp = malloc(nc*sizeof(PyArray_UCS4));
4363
 
                if (!temp) {
4364
 
                        PyErr_NoMemory();
4365
 
                        return NULL;
4366
 
                }
 
4583
    if (nc*sizeof(PyArray_UCS4) > SMALL_STRING) {
 
4584
        temp = malloc(nc*sizeof(PyArray_UCS4));
 
4585
        if (!temp) {
 
4586
            PyErr_NoMemory();
 
4587
            return NULL;
4367
4588
        }
4368
 
        memcpy(temp, original, nc*sizeof(PyArray_UCS4));
4369
 
        _unistripw((PyArray_UCS4 *)temp, nc);
4370
 
        return temp;
 
4589
    }
 
4590
    memcpy(temp, original, nc*sizeof(PyArray_UCS4));
 
4591
    _unistripw((PyArray_UCS4 *)temp, nc);
 
4592
    return temp;
4371
4593
}
4372
4594
 
4373
4595
static void
4374
4596
_uni_release(char *ptr, int nc)
4375
4597
{
4376
 
        if (nc*sizeof(PyArray_UCS4) > SMALL_STRING) {
4377
 
                free(ptr);
4378
 
        }
 
4598
    if (nc*sizeof(PyArray_UCS4) > SMALL_STRING) {
 
4599
        free(ptr);
 
4600
    }
4379
4601
}
4380
4602
 
4381
4603
 
4382
4604
/* End borrowed from numarray */
4383
4605
 
4384
 
#define _rstrip_loop(CMP) {                     \
4385
 
                void *aptr, *bptr; \
4386
 
                char atemp[SMALL_STRING], btemp[SMALL_STRING]; \
4387
 
                while(size--) { \
4388
 
                        aptr = stripfunc(iself->dataptr, atemp, N1); \
4389
 
                        if (!aptr) return -1; \
4390
 
                        bptr = stripfunc(iother->dataptr, btemp, N2); \
4391
 
                        if (!bptr) { \
4392
 
                                relfunc(aptr, N1); \
4393
 
                                return -1; \
4394
 
                        } \
4395
 
                        val = cmpfunc(aptr, bptr, N1, N2); \
4396
 
                        *dptr = (val CMP 0); \
4397
 
                        PyArray_ITER_NEXT(iself); \
4398
 
                        PyArray_ITER_NEXT(iother); \
4399
 
                        dptr += 1; \
4400
 
                        relfunc(aptr, N1); \
4401
 
                        relfunc(bptr, N2); \
4402
 
                } \
4403
 
        }
4404
 
 
4405
 
#define _reg_loop(CMP) { \
4406
 
                while(size--) {                                 \
4407
 
                        val = cmpfunc((void *)iself->dataptr,   \
4408
 
                                      (void *)iother->dataptr,  \
4409
 
                                      N1, N2);                  \
4410
 
                        *dptr = (val CMP 0);                    \
4411
 
                        PyArray_ITER_NEXT(iself);               \
4412
 
                        PyArray_ITER_NEXT(iother);              \
4413
 
                        dptr += 1;                              \
4414
 
                } \
4415
 
        }
4416
 
 
4417
 
#define _loop(CMP) if (rstrip) _rstrip_loop(CMP) \
 
4606
#define _rstrip_loop(CMP) {                                     \
 
4607
        void *aptr, *bptr;                                      \
 
4608
        char atemp[SMALL_STRING], btemp[SMALL_STRING];          \
 
4609
        while(size--) {                                         \
 
4610
            aptr = stripfunc(iself->dataptr, atemp, N1);        \
 
4611
            if (!aptr) return -1;                               \
 
4612
            bptr = stripfunc(iother->dataptr, btemp, N2);       \
 
4613
            if (!bptr) {                                        \
 
4614
                relfunc(aptr, N1);                              \
 
4615
                return -1;                                      \
 
4616
            }                                                   \
 
4617
            val = cmpfunc(aptr, bptr, N1, N2);                  \
 
4618
            *dptr = (val CMP 0);                                \
 
4619
            PyArray_ITER_NEXT(iself);                           \
 
4620
            PyArray_ITER_NEXT(iother);                          \
 
4621
            dptr += 1;                                          \
 
4622
            relfunc(aptr, N1);                                  \
 
4623
            relfunc(bptr, N2);                                  \
 
4624
        }                                                       \
 
4625
    }
 
4626
 
 
4627
#define _reg_loop(CMP) {                                \
 
4628
        while(size--) {                                 \
 
4629
            val = cmpfunc((void *)iself->dataptr,       \
 
4630
                          (void *)iother->dataptr,      \
 
4631
                          N1, N2);                      \
 
4632
            *dptr = (val CMP 0);                        \
 
4633
            PyArray_ITER_NEXT(iself);                   \
 
4634
            PyArray_ITER_NEXT(iother);                  \
 
4635
            dptr += 1;                                  \
 
4636
        }                                               \
 
4637
    }
 
4638
 
 
4639
#define _loop(CMP) if (rstrip) _rstrip_loop(CMP)        \
4418
4640
        else _reg_loop(CMP)
4419
4641
 
4420
4642
static int
4421
4643
_compare_strings(PyObject *result, PyArrayMultiIterObject *multi,
4422
4644
                 int cmp_op, void *func, int rstrip)
4423
4645
{
4424
 
        PyArrayIterObject *iself, *iother;
4425
 
        Bool *dptr;
4426
 
        intp size;
4427
 
        int val;
4428
 
        int N1, N2;
4429
 
        int (*cmpfunc)(void *, void *, int, int);
4430
 
        void (*relfunc)(char *, int);
4431
 
        char* (*stripfunc)(char *, char *, int);
 
4646
    PyArrayIterObject *iself, *iother;
 
4647
    Bool *dptr;
 
4648
    intp size;
 
4649
    int val;
 
4650
    int N1, N2;
 
4651
    int (*cmpfunc)(void *, void *, int, int);
 
4652
    void (*relfunc)(char *, int);
 
4653
    char* (*stripfunc)(char *, char *, int);
4432
4654
 
4433
 
        cmpfunc = func;
4434
 
        dptr = (Bool *)PyArray_DATA(result);
4435
 
        iself = multi->iters[0];
4436
 
        iother = multi->iters[1];
4437
 
        size = multi->size;
4438
 
        N1 = iself->ao->descr->elsize;
4439
 
        N2 = iother->ao->descr->elsize;
4440
 
        if ((void *)cmpfunc == (void *)_myunincmp) {
4441
 
                N1 >>= 2;
4442
 
                N2 >>= 2;
4443
 
                stripfunc = _uni_copy_n_strip;
4444
 
                relfunc = _uni_release;
4445
 
        }
4446
 
        else {
4447
 
                stripfunc = _char_copy_n_strip;
4448
 
                relfunc = _char_release;
4449
 
        }
4450
 
        switch (cmp_op) {
4451
 
        case Py_EQ:
4452
 
                _loop(==)
4453
 
                break;
4454
 
        case Py_NE:
4455
 
                _loop(!=)
4456
 
                break;
4457
 
        case Py_LT:
4458
 
                _loop(<)
4459
 
                break;
4460
 
        case Py_LE:
4461
 
                _loop(<=)
4462
 
                break;
4463
 
        case Py_GT:
4464
 
                _loop(>)
4465
 
                break;
4466
 
        case Py_GE:
4467
 
                _loop(>=)
4468
 
                break;
4469
 
        default:
4470
 
                PyErr_SetString(PyExc_RuntimeError,
4471
 
                                "bad comparison operator");
4472
 
                return -1;
4473
 
        }
4474
 
        return 0;
 
4655
    cmpfunc = func;
 
4656
    dptr = (Bool *)PyArray_DATA(result);
 
4657
    iself = multi->iters[0];
 
4658
    iother = multi->iters[1];
 
4659
    size = multi->size;
 
4660
    N1 = iself->ao->descr->elsize;
 
4661
    N2 = iother->ao->descr->elsize;
 
4662
    if ((void *)cmpfunc == (void *)_myunincmp) {
 
4663
        N1 >>= 2;
 
4664
        N2 >>= 2;
 
4665
        stripfunc = _uni_copy_n_strip;
 
4666
        relfunc = _uni_release;
 
4667
    }
 
4668
    else {
 
4669
        stripfunc = _char_copy_n_strip;
 
4670
        relfunc = _char_release;
 
4671
    }
 
4672
    switch (cmp_op) {
 
4673
    case Py_EQ:
 
4674
        _loop(==)
 
4675
            break;
 
4676
    case Py_NE:
 
4677
        _loop(!=)
 
4678
            break;
 
4679
    case Py_LT:
 
4680
        _loop(<)
 
4681
            break;
 
4682
    case Py_LE:
 
4683
        _loop(<=)
 
4684
            break;
 
4685
    case Py_GT:
 
4686
        _loop(>)
 
4687
            break;
 
4688
    case Py_GE:
 
4689
        _loop(>=)
 
4690
            break;
 
4691
    default:
 
4692
        PyErr_SetString(PyExc_RuntimeError,
 
4693
                        "bad comparison operator");
 
4694
        return -1;
 
4695
    }
 
4696
    return 0;
4475
4697
}
4476
4698
 
4477
4699
#undef _loop
4483
4705
_strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op,
4484
4706
                     int rstrip)
4485
4707
{
4486
 
        PyObject *result;
4487
 
        PyArrayMultiIterObject *mit;
4488
 
        int val;
4489
 
 
4490
 
        /* Cast arrays to a common type */
4491
 
        if (self->descr->type_num != other->descr->type_num) {
4492
 
                PyObject *new;
4493
 
                if (self->descr->type_num == PyArray_STRING && \
4494
 
                    other->descr->type_num == PyArray_UNICODE) {
4495
 
                        Py_INCREF(other);
4496
 
                        Py_INCREF(other->descr);
4497
 
                        new = PyArray_FromAny((PyObject *)self, other->descr,
4498
 
                                              0, 0, 0, NULL);
4499
 
                        if (new == NULL) return NULL;
4500
 
                        self = (PyArrayObject *)new;
4501
 
                }
4502
 
                else if (self->descr->type_num == PyArray_UNICODE &&    \
4503
 
                         other->descr->type_num == PyArray_STRING) {
4504
 
                        Py_INCREF(self);
4505
 
                        Py_INCREF(self->descr);
4506
 
                        new = PyArray_FromAny((PyObject *)other, self->descr,
4507
 
                                              0, 0, 0, NULL);
4508
 
                        if (new == NULL) return NULL;
4509
 
                        other = (PyArrayObject *)new;
4510
 
                }
4511
 
                else {
4512
 
                        PyErr_SetString(PyExc_TypeError,
4513
 
                                        "invalid string data-types "
4514
 
                                        "in comparison");
4515
 
                        return NULL;
4516
 
                }
4517
 
        }
4518
 
        else {
4519
 
                Py_INCREF(self);
4520
 
                Py_INCREF(other);
4521
 
        }
4522
 
 
4523
 
        /* Broad-cast the arrays to a common shape */
4524
 
        mit = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, self, other);
4525
 
        Py_DECREF(self);
4526
 
        Py_DECREF(other);
4527
 
        if (mit == NULL) return NULL;
4528
 
 
4529
 
        result = PyArray_NewFromDescr(&PyArray_Type,
4530
 
                                      PyArray_DescrFromType(PyArray_BOOL),
4531
 
                                      mit->nd,
4532
 
                                      mit->dimensions,
4533
 
                                      NULL, NULL, 0,
4534
 
                                      NULL);
4535
 
        if (result == NULL) goto finish;
4536
 
 
4537
 
        if (self->descr->type_num == PyArray_UNICODE) {
4538
 
                val = _compare_strings(result, mit, cmp_op, _myunincmp,
4539
 
                                       rstrip);
4540
 
        }
4541
 
        else {
4542
 
                val = _compare_strings(result, mit, cmp_op, _mystrncmp,
4543
 
                                       rstrip);
4544
 
        }
4545
 
 
4546
 
        if (val < 0) {Py_DECREF(result); result = NULL;}
 
4708
    PyObject *result;
 
4709
    PyArrayMultiIterObject *mit;
 
4710
    int val;
 
4711
 
 
4712
    /* Cast arrays to a common type */
 
4713
    if (self->descr->type_num != other->descr->type_num) {
 
4714
        PyObject *new;
 
4715
        if (self->descr->type_num == PyArray_STRING && \
 
4716
            other->descr->type_num == PyArray_UNICODE) {
 
4717
            Py_INCREF(other);
 
4718
            Py_INCREF(other->descr);
 
4719
            new = PyArray_FromAny((PyObject *)self, other->descr,
 
4720
                                  0, 0, 0, NULL);
 
4721
            if (new == NULL) {
 
4722
                return NULL;
 
4723
            }
 
4724
            self = (PyArrayObject *)new;
 
4725
        }
 
4726
        else if (self->descr->type_num == PyArray_UNICODE &&    \
 
4727
                 other->descr->type_num == PyArray_STRING) {
 
4728
            Py_INCREF(self);
 
4729
            Py_INCREF(self->descr);
 
4730
            new = PyArray_FromAny((PyObject *)other, self->descr,
 
4731
                                  0, 0, 0, NULL);
 
4732
            if (new == NULL) {
 
4733
                return NULL;
 
4734
            }
 
4735
            other = (PyArrayObject *)new;
 
4736
        }
 
4737
        else {
 
4738
            PyErr_SetString(PyExc_TypeError,
 
4739
                            "invalid string data-types "
 
4740
                            "in comparison");
 
4741
            return NULL;
 
4742
        }
 
4743
    }
 
4744
    else {
 
4745
        Py_INCREF(self);
 
4746
        Py_INCREF(other);
 
4747
    }
 
4748
 
 
4749
    /* Broad-cast the arrays to a common shape */
 
4750
    mit = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, self, other);
 
4751
    Py_DECREF(self);
 
4752
    Py_DECREF(other);
 
4753
    if (mit == NULL) {
 
4754
        return NULL;
 
4755
    }
 
4756
 
 
4757
    result = PyArray_NewFromDescr(&PyArray_Type,
 
4758
                                  PyArray_DescrFromType(PyArray_BOOL),
 
4759
                                  mit->nd,
 
4760
                                  mit->dimensions,
 
4761
                                  NULL, NULL, 0,
 
4762
                                  NULL);
 
4763
    if (result == NULL) {
 
4764
        goto finish;
 
4765
    }
 
4766
 
 
4767
    if (self->descr->type_num == PyArray_UNICODE) {
 
4768
        val = _compare_strings(result, mit, cmp_op, _myunincmp,
 
4769
                               rstrip);
 
4770
    }
 
4771
    else {
 
4772
        val = _compare_strings(result, mit, cmp_op, _mystrncmp,
 
4773
                               rstrip);
 
4774
    }
 
4775
 
 
4776
    if (val < 0) {
 
4777
        Py_DECREF(result); result = NULL;
 
4778
    }
4547
4779
 
4548
4780
 finish:
4549
 
        Py_DECREF(mit);
4550
 
        return result;
 
4781
    Py_DECREF(mit);
 
4782
    return result;
4551
4783
}
4552
4784
 
4553
4785
/* VOID-type arrays can only be compared equal and not-equal
4554
 
    in which case the fields are all compared by extracting the fields
4555
 
    and testing one at a time...
4556
 
    equality testing is performed using logical_ands on all the fields.
4557
 
    in-equality testing is performed using logical_ors on all the fields.
 
4786
   in which case the fields are all compared by extracting the fields
 
4787
   and testing one at a time...
 
4788
   equality testing is performed using logical_ands on all the fields.
 
4789
   in-equality testing is performed using logical_ors on all the fields.
4558
4790
 
4559
 
    VOID-type arrays without fields are compared for equality by comparing their
4560
 
    memory at each location directly (using string-code).
4561
 
 */
 
4791
   VOID-type arrays without fields are compared for equality by comparing their
 
4792
   memory at each location directly (using string-code).
 
4793
*/
4562
4794
 
4563
4795
static PyObject *array_richcompare(PyArrayObject *, PyObject *, int);
4564
4796
 
4566
4798
static PyObject *
4567
4799
_void_compare(PyArrayObject *self, PyArrayObject *other, int cmp_op)
4568
4800
{
4569
 
        if (!(cmp_op == Py_EQ || cmp_op == Py_NE)) {
4570
 
                PyErr_SetString(PyExc_ValueError, "Void-arrays can only" \
4571
 
                                "be compared for equality.");
4572
 
                return NULL;
4573
 
        }
4574
 
        if (PyArray_HASFIELDS(self)) {
4575
 
                PyObject *res=NULL, *temp, *a, *b;
4576
 
                PyObject *key, *value, *temp2;
4577
 
                PyObject *op;
4578
 
                Py_ssize_t pos=0;
4579
 
                op = (cmp_op == Py_EQ ? n_ops.logical_and : n_ops.logical_or);
4580
 
                while (PyDict_Next(self->descr->fields, &pos, &key, &value)) {
4581
 
                        a = PyArray_EnsureAnyArray(array_subscript(self, key));
4582
 
                        if (a==NULL) {Py_XDECREF(res); return NULL;}
4583
 
                        b = array_subscript(other, key);
4584
 
                        if (b==NULL) {Py_XDECREF(res); Py_DECREF(a); return NULL;}
4585
 
                        temp = array_richcompare((PyArrayObject *)a,b,cmp_op);
4586
 
                        Py_DECREF(a);
4587
 
                        Py_DECREF(b);
4588
 
                        if (temp == NULL) {Py_XDECREF(res); return NULL;}
4589
 
                        if (res == NULL) {
4590
 
                                res = temp;
4591
 
                        }
4592
 
                        else {
4593
 
                                temp2 = PyObject_CallFunction(op, "OO", res, temp);
4594
 
                                Py_DECREF(temp);
4595
 
                                Py_DECREF(res);
4596
 
                                if (temp2 == NULL) return NULL;
4597
 
                                res = temp2;
4598
 
                        }
4599
 
                }
4600
 
                if (res == NULL && !PyErr_Occurred()) {
4601
 
                        PyErr_SetString(PyExc_ValueError, "No fields found.");
4602
 
                }
4603
 
                return res;
4604
 
        }
4605
 
        else { /* compare as a string */
4606
 
                /* assumes self and other have same descr->type */
4607
 
                return _strings_richcompare(self, other, cmp_op, 0);
4608
 
        }
 
4801
    if (!(cmp_op == Py_EQ || cmp_op == Py_NE)) {
 
4802
        PyErr_SetString(PyExc_ValueError,
 
4803
                "Void-arrays can only be compared for equality.");
 
4804
        return NULL;
 
4805
    }
 
4806
    if (PyArray_HASFIELDS(self)) {
 
4807
        PyObject *res=NULL, *temp, *a, *b;
 
4808
        PyObject *key, *value, *temp2;
 
4809
        PyObject *op;
 
4810
        Py_ssize_t pos=0;
 
4811
 
 
4812
        op = (cmp_op == Py_EQ ? n_ops.logical_and : n_ops.logical_or);
 
4813
        while (PyDict_Next(self->descr->fields, &pos, &key, &value)) {
 
4814
            a = PyArray_EnsureAnyArray(array_subscript(self, key));
 
4815
            if (a==NULL) {
 
4816
                Py_XDECREF(res);
 
4817
                return NULL;
 
4818
            }
 
4819
            b = array_subscript(other, key);
 
4820
            if (b==NULL) {
 
4821
                Py_XDECREF(res);
 
4822
                Py_DECREF(a);
 
4823
                return NULL;
 
4824
            }
 
4825
            temp = array_richcompare((PyArrayObject *)a,b,cmp_op);
 
4826
            Py_DECREF(a);
 
4827
            Py_DECREF(b);
 
4828
            if (temp == NULL) {
 
4829
                Py_XDECREF(res);
 
4830
                return NULL;
 
4831
            }
 
4832
            if (res == NULL) {
 
4833
                res = temp;
 
4834
            }
 
4835
            else {
 
4836
                temp2 = PyObject_CallFunction(op, "OO", res, temp);
 
4837
                Py_DECREF(temp);
 
4838
                Py_DECREF(res);
 
4839
                if (temp2 == NULL) {
 
4840
                    return NULL;
 
4841
                }
 
4842
                res = temp2;
 
4843
            }
 
4844
        }
 
4845
        if (res == NULL && !PyErr_Occurred()) {
 
4846
            PyErr_SetString(PyExc_ValueError, "No fields found.");
 
4847
        }
 
4848
        return res;
 
4849
    }
 
4850
    else {
 
4851
        /* compare as a string */
 
4852
        /* assumes self and other have same descr->type */
 
4853
        return _strings_richcompare(self, other, cmp_op, 0);
 
4854
    }
4609
4855
}
4610
4856
 
4611
4857
static PyObject *
4612
4858
array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
4613
4859
{
4614
 
        PyObject *array_other, *result = NULL;
4615
 
        int typenum;
4616
 
 
4617
 
        switch (cmp_op)
4618
 
                {
4619
 
                case Py_LT:
4620
 
                        result = PyArray_GenericBinaryFunction(self, other,
4621
 
                                                               n_ops.less);
4622
 
                        break;
4623
 
                case Py_LE:
4624
 
                        result = PyArray_GenericBinaryFunction(self, other,
4625
 
                                                               n_ops.less_equal);
4626
 
                        break;
4627
 
                case Py_EQ:
4628
 
                        if (other == Py_None) {
4629
 
                                Py_INCREF(Py_False);
4630
 
                                return Py_False;
4631
 
                        }
4632
 
                        /* Try to convert other to an array */
4633
 
                        if (!PyArray_Check(other)) {
4634
 
                                typenum = self->descr->type_num;
4635
 
                                if (typenum != PyArray_OBJECT) {
4636
 
                                        typenum = PyArray_NOTYPE;
4637
 
                                }
4638
 
                                array_other = PyArray_FromObject(other,
4639
 
                                                                 typenum, 0, 0);
4640
 
                                /* If not successful, then return False
4641
 
                                   This fixes code that used to
4642
 
                                   allow equality comparisons between arrays
4643
 
                                   and other objects which would give a result
4644
 
                                   of False
4645
 
                                */
4646
 
                                if ((array_other == NULL) ||    \
4647
 
                                    (array_other == Py_None)) {
4648
 
                                        Py_XDECREF(array_other);
4649
 
                                        PyErr_Clear();
4650
 
                                        Py_INCREF(Py_False);
4651
 
                                        return Py_False;
4652
 
                                }
4653
 
                        }
4654
 
                        else {
4655
 
                                Py_INCREF(other);
4656
 
                                array_other = other;
4657
 
                        }
4658
 
                        result = PyArray_GenericBinaryFunction(self,
4659
 
                                                               array_other,
4660
 
                                                               n_ops.equal);
4661
 
                        if ((result == Py_NotImplemented) &&
4662
 
                            (self->descr->type_num == PyArray_VOID)) {
4663
 
                                int _res;
4664
 
                                _res = PyObject_RichCompareBool \
4665
 
                                        ((PyObject *)self->descr,
4666
 
                                         (PyObject *)\
4667
 
                                         PyArray_DESCR(array_other),
4668
 
                                         Py_EQ);
4669
 
                                if (_res < 0) {
4670
 
                                        Py_DECREF(result);
4671
 
                                        Py_DECREF(array_other);
4672
 
                                        return NULL;
4673
 
                                }
4674
 
                                if (_res) {
4675
 
                                        Py_DECREF(result);
4676
 
                                        result = _void_compare\
4677
 
                                                (self,
4678
 
                                                 (PyArrayObject *)array_other,
4679
 
                                                 cmp_op);
4680
 
                                        Py_DECREF(array_other);
4681
 
                                }
4682
 
                                return result;
4683
 
                        }
4684
 
                        /* If the comparison results in NULL, then the
4685
 
                           two array objects can not be compared together so
4686
 
                           return zero
4687
 
                        */
4688
 
                        Py_DECREF(array_other);
4689
 
                        if (result == NULL) {
4690
 
                                PyErr_Clear();
4691
 
                                Py_INCREF(Py_False);
4692
 
                                return Py_False;
4693
 
                        }
4694
 
                        break;
4695
 
                case Py_NE:
4696
 
                        if (other == Py_None) {
4697
 
                                Py_INCREF(Py_True);
4698
 
                                return Py_True;
4699
 
                        }
4700
 
                        /* Try to convert other to an array */
4701
 
                        if (!PyArray_Check(other)) {
4702
 
                                typenum = self->descr->type_num;
4703
 
                                if (typenum != PyArray_OBJECT) {
4704
 
                                        typenum = PyArray_NOTYPE;
4705
 
                                }
4706
 
                                array_other = PyArray_FromObject(other,
4707
 
                                                                 typenum, 0, 0);
4708
 
                                /* If not successful, then objects cannot be
4709
 
                                   compared and cannot be equal, therefore,
4710
 
                                   return True;
4711
 
                                */
4712
 
                                if ((array_other == NULL) ||    \
4713
 
                                    (array_other == Py_None)) {
4714
 
                                        Py_XDECREF(array_other);
4715
 
                                        PyErr_Clear();
4716
 
                                        Py_INCREF(Py_True);
4717
 
                                        return Py_True;
4718
 
                                }
4719
 
                        }
4720
 
                        else {
4721
 
                                Py_INCREF(other);
4722
 
                                array_other = other;
4723
 
                        }
4724
 
                        result = PyArray_GenericBinaryFunction(self,
4725
 
                                                               array_other,
4726
 
                                                               n_ops.not_equal);
4727
 
                        if ((result == Py_NotImplemented) &&
4728
 
                            (self->descr->type_num == PyArray_VOID)) {
4729
 
                                int _res;
4730
 
                                _res = PyObject_RichCompareBool\
4731
 
                                        ((PyObject *)self->descr,
4732
 
                                         (PyObject *)\
4733
 
                                         PyArray_DESCR(array_other),
4734
 
                                         Py_EQ);
4735
 
                                if (_res < 0) {
4736
 
                                        Py_DECREF(result);
4737
 
                                        Py_DECREF(array_other);
4738
 
                                        return NULL;
4739
 
                                }
4740
 
                                if (_res) {
4741
 
                                        Py_DECREF(result);
4742
 
                                        result = _void_compare\
4743
 
                                                (self,
4744
 
                                                 (PyArrayObject *)array_other,
4745
 
                                                 cmp_op);
4746
 
                                        Py_DECREF(array_other);
4747
 
                                }
4748
 
                                return result;
4749
 
                        }
4750
 
 
4751
 
                        Py_DECREF(array_other);
4752
 
                        if (result == NULL) {
4753
 
                                PyErr_Clear();
4754
 
                                Py_INCREF(Py_True);
4755
 
                                return Py_True;
4756
 
                        }
4757
 
                        break;
4758
 
                case Py_GT:
4759
 
                        result = PyArray_GenericBinaryFunction(self, other,
4760
 
                                                               n_ops.greater);
4761
 
                        break;
4762
 
                case Py_GE:
4763
 
                        result = PyArray_GenericBinaryFunction(self, other,
4764
 
                                                               n_ops.greater_equal);
4765
 
                        break;
4766
 
                default:
4767
 
                        result = Py_NotImplemented;
4768
 
                        Py_INCREF(result);
4769
 
                }
4770
 
        if (result == Py_NotImplemented) {
4771
 
                /* Try to handle string comparisons */
4772
 
                if (self->descr->type_num == PyArray_OBJECT) return result;
4773
 
                array_other = PyArray_FromObject(other,PyArray_NOTYPE, 0, 0);
4774
 
                if (PyArray_ISSTRING(self) && PyArray_ISSTRING(array_other)) {
4775
 
                        Py_DECREF(result);
4776
 
                        result = _strings_richcompare(self, (PyArrayObject *)
4777
 
                                                      array_other, cmp_op, 0);
4778
 
                }
4779
 
                Py_DECREF(array_other);
4780
 
        }
4781
 
        return result;
 
4860
    PyObject *array_other, *result = NULL;
 
4861
    int typenum;
 
4862
 
 
4863
    switch (cmp_op)
 
4864
        {
 
4865
        case Py_LT:
 
4866
            result = PyArray_GenericBinaryFunction(self, other,
 
4867
                                                   n_ops.less);
 
4868
            break;
 
4869
        case Py_LE:
 
4870
            result = PyArray_GenericBinaryFunction(self, other,
 
4871
                                                   n_ops.less_equal);
 
4872
            break;
 
4873
        case Py_EQ:
 
4874
            if (other == Py_None) {
 
4875
                Py_INCREF(Py_False);
 
4876
                return Py_False;
 
4877
            }
 
4878
            /* Try to convert other to an array */
 
4879
            if (!PyArray_Check(other)) {
 
4880
                typenum = self->descr->type_num;
 
4881
                if (typenum != PyArray_OBJECT) {
 
4882
                    typenum = PyArray_NOTYPE;
 
4883
                }
 
4884
                array_other = PyArray_FromObject(other,
 
4885
                                                 typenum, 0, 0);
 
4886
                /* If not successful, then return False
 
4887
                   This fixes code that used to
 
4888
                   allow equality comparisons between arrays
 
4889
                   and other objects which would give a result
 
4890
                   of False
 
4891
                */
 
4892
                if ((array_other == NULL) ||    \
 
4893
                    (array_other == Py_None)) {
 
4894
                    Py_XDECREF(array_other);
 
4895
                    PyErr_Clear();
 
4896
                    Py_INCREF(Py_False);
 
4897
                    return Py_False;
 
4898
                }
 
4899
            }
 
4900
            else {
 
4901
                Py_INCREF(other);
 
4902
                array_other = other;
 
4903
            }
 
4904
            result = PyArray_GenericBinaryFunction(self,
 
4905
                                                   array_other,
 
4906
                                                   n_ops.equal);
 
4907
            if ((result == Py_NotImplemented) &&
 
4908
                (self->descr->type_num == PyArray_VOID)) {
 
4909
                int _res;
 
4910
                _res = PyObject_RichCompareBool \
 
4911
                    ((PyObject *)self->descr,
 
4912
                     (PyObject *)\
 
4913
                     PyArray_DESCR(array_other),
 
4914
                     Py_EQ);
 
4915
                if (_res < 0) {
 
4916
                    Py_DECREF(result);
 
4917
                    Py_DECREF(array_other);
 
4918
                    return NULL;
 
4919
                }
 
4920
                if (_res) {
 
4921
                    Py_DECREF(result);
 
4922
                    result = _void_compare\
 
4923
                        (self,
 
4924
                         (PyArrayObject *)array_other,
 
4925
                         cmp_op);
 
4926
                    Py_DECREF(array_other);
 
4927
                }
 
4928
                return result;
 
4929
            }
 
4930
            /* If the comparison results in NULL, then the
 
4931
               two array objects can not be compared together so
 
4932
               return zero
 
4933
            */
 
4934
            Py_DECREF(array_other);
 
4935
            if (result == NULL) {
 
4936
                PyErr_Clear();
 
4937
                Py_INCREF(Py_False);
 
4938
                return Py_False;
 
4939
            }
 
4940
            break;
 
4941
        case Py_NE:
 
4942
            if (other == Py_None) {
 
4943
                Py_INCREF(Py_True);
 
4944
                return Py_True;
 
4945
            }
 
4946
            /* Try to convert other to an array */
 
4947
            if (!PyArray_Check(other)) {
 
4948
                typenum = self->descr->type_num;
 
4949
                if (typenum != PyArray_OBJECT) {
 
4950
                    typenum = PyArray_NOTYPE;
 
4951
                }
 
4952
                array_other = PyArray_FromObject(other,
 
4953
                                                 typenum, 0, 0);
 
4954
                /* If not successful, then objects cannot be
 
4955
                   compared and cannot be equal, therefore,
 
4956
                   return True;
 
4957
                */
 
4958
                if ((array_other == NULL) ||    \
 
4959
                    (array_other == Py_None)) {
 
4960
                    Py_XDECREF(array_other);
 
4961
                    PyErr_Clear();
 
4962
                    Py_INCREF(Py_True);
 
4963
                    return Py_True;
 
4964
                }
 
4965
            }
 
4966
            else {
 
4967
                Py_INCREF(other);
 
4968
                array_other = other;
 
4969
            }
 
4970
            result = PyArray_GenericBinaryFunction(self,
 
4971
                                                   array_other,
 
4972
                                                   n_ops.not_equal);
 
4973
            if ((result == Py_NotImplemented) &&
 
4974
                (self->descr->type_num == PyArray_VOID)) {
 
4975
                int _res;
 
4976
                _res = PyObject_RichCompareBool\
 
4977
                    ((PyObject *)self->descr,
 
4978
                     (PyObject *)\
 
4979
                     PyArray_DESCR(array_other),
 
4980
                     Py_EQ);
 
4981
                if (_res < 0) {
 
4982
                    Py_DECREF(result);
 
4983
                    Py_DECREF(array_other);
 
4984
                    return NULL;
 
4985
                }
 
4986
                if (_res) {
 
4987
                    Py_DECREF(result);
 
4988
                    result = _void_compare\
 
4989
                        (self,
 
4990
                         (PyArrayObject *)array_other,
 
4991
                         cmp_op);
 
4992
                    Py_DECREF(array_other);
 
4993
                }
 
4994
                return result;
 
4995
            }
 
4996
 
 
4997
            Py_DECREF(array_other);
 
4998
            if (result == NULL) {
 
4999
                PyErr_Clear();
 
5000
                Py_INCREF(Py_True);
 
5001
                return Py_True;
 
5002
            }
 
5003
            break;
 
5004
        case Py_GT:
 
5005
            result = PyArray_GenericBinaryFunction(self, other,
 
5006
                                                   n_ops.greater);
 
5007
            break;
 
5008
        case Py_GE:
 
5009
            result = PyArray_GenericBinaryFunction(self, other,
 
5010
                                                   n_ops.greater_equal);
 
5011
            break;
 
5012
        default:
 
5013
            result = Py_NotImplemented;
 
5014
            Py_INCREF(result);
 
5015
        }
 
5016
    if (result == Py_NotImplemented) {
 
5017
        /* Try to handle string comparisons */
 
5018
        if (self->descr->type_num == PyArray_OBJECT) return result;
 
5019
        array_other = PyArray_FromObject(other,PyArray_NOTYPE, 0, 0);
 
5020
        if (PyArray_ISSTRING(self) && PyArray_ISSTRING(array_other)) {
 
5021
            Py_DECREF(result);
 
5022
            result = _strings_richcompare(self, (PyArrayObject *)
 
5023
                                          array_other, cmp_op, 0);
 
5024
        }
 
5025
        Py_DECREF(array_other);
 
5026
    }
 
5027
    return result;
4782
5028
}
4783
5029
 
 
5030
 
 
5031
/*MULTIARRAY_API
 
5032
  PyArray_CheckAxis
 
5033
*/
4784
5034
static PyObject *
4785
 
_check_axis(PyArrayObject *arr, int *axis, int flags)
 
5035
PyArray_CheckAxis(PyArrayObject *arr, int *axis, int flags)
4786
5036
{
4787
 
        PyObject *temp1, *temp2;
4788
 
        int n = arr->nd;
 
5037
    PyObject *temp1, *temp2;
 
5038
    int n = arr->nd;
4789
5039
 
4790
 
        if ((*axis >= MAX_DIMS) || (n==0)) {
4791
 
                if (n != 1) {
4792
 
                        temp1 = PyArray_Ravel(arr,0);
4793
 
                        if (temp1 == NULL) {*axis=0; return NULL;}
4794
 
                        *axis = PyArray_NDIM(temp1)-1;
4795
 
                }
4796
 
                else {
4797
 
                        temp1 = (PyObject *)arr;
4798
 
                        Py_INCREF(temp1);
4799
 
                        *axis = 0;
4800
 
                }
4801
 
                if (!flags) return temp1;
4802
 
        }
4803
 
        else {
4804
 
                temp1 = (PyObject *)arr;
4805
 
                Py_INCREF(temp1);
4806
 
        }
4807
 
        if (flags) {
4808
 
                temp2 = PyArray_CheckFromAny((PyObject *)temp1, NULL,
4809
 
                                             0, 0, flags, NULL);
4810
 
                Py_DECREF(temp1);
4811
 
                if (temp2 == NULL) return NULL;
4812
 
        }
4813
 
        else {
4814
 
                temp2 = (PyObject *)temp1;
4815
 
        }
4816
 
        n = PyArray_NDIM(temp2);
4817
 
        if (*axis < 0) *axis += n;
4818
 
        if ((*axis < 0) || (*axis >= n)) {
4819
 
                PyErr_Format(PyExc_ValueError,
4820
 
                             "axis(=%d) out of bounds", *axis);
4821
 
                Py_DECREF(temp2);
4822
 
                return NULL;
4823
 
        }
4824
 
        return temp2;
 
5040
    if ((*axis >= MAX_DIMS) || (n==0)) {
 
5041
        if (n != 1) {
 
5042
            temp1 = PyArray_Ravel(arr,0);
 
5043
            if (temp1 == NULL) {*axis=0; return NULL;}
 
5044
            *axis = PyArray_NDIM(temp1)-1;
 
5045
        }
 
5046
        else {
 
5047
            temp1 = (PyObject *)arr;
 
5048
            Py_INCREF(temp1);
 
5049
            *axis = 0;
 
5050
        }
 
5051
        if (!flags) return temp1;
 
5052
    }
 
5053
    else {
 
5054
        temp1 = (PyObject *)arr;
 
5055
        Py_INCREF(temp1);
 
5056
    }
 
5057
    if (flags) {
 
5058
        temp2 = PyArray_CheckFromAny((PyObject *)temp1, NULL,
 
5059
                                     0, 0, flags, NULL);
 
5060
        Py_DECREF(temp1);
 
5061
        if (temp2 == NULL) return NULL;
 
5062
    }
 
5063
    else {
 
5064
        temp2 = (PyObject *)temp1;
 
5065
    }
 
5066
    n = PyArray_NDIM(temp2);
 
5067
    if (*axis < 0) *axis += n;
 
5068
    if ((*axis < 0) || (*axis >= n)) {
 
5069
        PyErr_Format(PyExc_ValueError,
 
5070
                     "axis(=%d) out of bounds", *axis);
 
5071
        Py_DECREF(temp2);
 
5072
        return NULL;
 
5073
    }
 
5074
    return temp2;
4825
5075
}
4826
5076
 
 
5077
#define _check_axis PyArray_CheckAxis
 
5078
 
4827
5079
#include "arraymethods.c"
4828
5080
 
4829
5081
/* Lifted from numarray */
4830
5082
/*MULTIARRAY_API
4831
 
 PyArray_IntTupleFromIntp
 
5083
  PyArray_IntTupleFromIntp
4832
5084
*/
4833
5085
static PyObject *
4834
5086
PyArray_IntTupleFromIntp(int len, intp *vals)
4835
5087
{
4836
 
        int i;
4837
 
        PyObject *intTuple = PyTuple_New(len);
4838
 
        if (!intTuple) goto fail;
4839
 
        for(i=0; i<len; i++) {
 
5088
    int i;
 
5089
    PyObject *intTuple = PyTuple_New(len);
 
5090
    if (!intTuple) goto fail;
 
5091
    for(i=0; i<len; i++) {
4840
5092
#if SIZEOF_INTP <= SIZEOF_LONG
4841
 
                PyObject *o = PyInt_FromLong((long) vals[i]);
 
5093
        PyObject *o = PyInt_FromLong((long) vals[i]);
4842
5094
#else
4843
 
                PyObject *o = PyLong_FromLongLong((longlong) vals[i]);
 
5095
        PyObject *o = PyLong_FromLongLong((longlong) vals[i]);
4844
5096
#endif
4845
 
                if (!o) {
4846
 
                        Py_DECREF(intTuple);
4847
 
                        intTuple = NULL;
4848
 
                        goto fail;
4849
 
                }
4850
 
                PyTuple_SET_ITEM(intTuple, i, o);
 
5097
        if (!o) {
 
5098
            Py_DECREF(intTuple);
 
5099
            intTuple = NULL;
 
5100
            goto fail;
4851
5101
        }
4852
 
  fail:
4853
 
        return intTuple;
 
5102
        PyTuple_SET_ITEM(intTuple, i, o);
 
5103
    }
 
5104
 fail:
 
5105
    return intTuple;
4854
5106
}
4855
5107
 
4856
5108
/* Returns the number of dimensions or -1 if an error occurred */
4857
5109
/*  vals must be large enough to hold maxvals */
4858
5110
/*MULTIARRAY_API
4859
 
 PyArray_IntpFromSequence
 
5111
  PyArray_IntpFromSequence
4860
5112
*/
4861
5113
static int
4862
5114
PyArray_IntpFromSequence(PyObject *seq, intp *vals, int maxvals)
4863
5115
{
4864
 
        int nd, i;
4865
 
        PyObject *op;
 
5116
    int nd, i;
 
5117
    PyObject *op;
4866
5118
 
4867
 
        /* Check to see if sequence is a single integer first.
4868
 
             or, can be made into one */
4869
 
        if ((nd=PySequence_Length(seq)) == -1) {
4870
 
                if (PyErr_Occurred()) PyErr_Clear();
4871
 
#if SIZEOF_LONG >= SIZEOF_INTP
4872
 
                if (!(op = PyNumber_Int(seq))) return -1;
4873
 
#else
4874
 
                if (!(op = PyNumber_Long(seq))) return -1;
4875
 
#endif
4876
 
                nd = 1;
4877
 
#if SIZEOF_LONG >= SIZEOF_INTP
4878
 
                vals[0] = (intp ) PyInt_AsLong(op);
4879
 
#else
4880
 
                vals[0] = (intp ) PyLong_AsLongLong(op);
4881
 
#endif
4882
 
                Py_DECREF(op);
4883
 
        } else {
4884
 
                for(i=0; i < MIN(nd,maxvals); i++) {
4885
 
                        op = PySequence_GetItem(seq, i);
4886
 
                        if (op == NULL) return -1;
4887
 
#if SIZEOF_LONG >= SIZEOF_INTP
4888
 
                        vals[i]=(intp )PyInt_AsLong(op);
4889
 
#else
4890
 
                        vals[i]=(intp )PyLong_AsLongLong(op);
4891
 
#endif
4892
 
                        Py_DECREF(op);
4893
 
                        if(PyErr_Occurred()) return -1;
4894
 
                }
 
5119
    /* Check to see if sequence is a single integer first.
 
5120
       or, can be made into one */
 
5121
    if ((nd=PySequence_Length(seq)) == -1) {
 
5122
        if (PyErr_Occurred()) PyErr_Clear();
 
5123
#if SIZEOF_LONG >= SIZEOF_INTP
 
5124
        if (!(op = PyNumber_Int(seq))) return -1;
 
5125
#else
 
5126
        if (!(op = PyNumber_Long(seq))) return -1;
 
5127
#endif
 
5128
        nd = 1;
 
5129
#if SIZEOF_LONG >= SIZEOF_INTP
 
5130
        vals[0] = (intp ) PyInt_AsLong(op);
 
5131
#else
 
5132
        vals[0] = (intp ) PyLong_AsLongLong(op);
 
5133
#endif
 
5134
        Py_DECREF(op);
 
5135
    } else {
 
5136
        for(i=0; i < MIN(nd,maxvals); i++) {
 
5137
            op = PySequence_GetItem(seq, i);
 
5138
            if (op == NULL) return -1;
 
5139
#if SIZEOF_LONG >= SIZEOF_INTP
 
5140
            vals[i]=(intp )PyInt_AsLong(op);
 
5141
#else
 
5142
            vals[i]=(intp )PyLong_AsLongLong(op);
 
5143
#endif
 
5144
            Py_DECREF(op);
 
5145
            if(PyErr_Occurred()) return -1;
4895
5146
        }
4896
 
        return nd;
 
5147
    }
 
5148
    return nd;
4897
5149
}
4898
5150
 
4899
5151
 
4905
5157
static int
4906
5158
_IsContiguous(PyArrayObject *ap)
4907
5159
{
4908
 
        register intp sd;
4909
 
        register intp dim;
4910
 
        register int i;
 
5160
    register intp sd;
 
5161
    register intp dim;
 
5162
    register int i;
4911
5163
 
4912
 
        if (ap->nd == 0) return 1;
4913
 
        sd = ap->descr->elsize;
4914
 
        if (ap->nd == 1) return (ap->dimensions[0] == 1 || \
4915
 
                                 sd == ap->strides[0]);
4916
 
        for (i = ap->nd-1; i >= 0; --i) {
4917
 
                dim = ap->dimensions[i];
4918
 
                /* contiguous by definition */
4919
 
                if (dim == 0) return 1;
4920
 
                if (ap->strides[i] != sd) return 0;
4921
 
                sd *= dim;
4922
 
        }
4923
 
        return 1;
 
5164
    if (ap->nd == 0) return 1;
 
5165
    sd = ap->descr->elsize;
 
5166
    if (ap->nd == 1) return (ap->dimensions[0] == 1 || \
 
5167
                             sd == ap->strides[0]);
 
5168
    for(i = ap->nd-1; i >= 0; --i) {
 
5169
        dim = ap->dimensions[i];
 
5170
        /* contiguous by definition */
 
5171
        if (dim == 0) return 1;
 
5172
        if (ap->strides[i] != sd) return 0;
 
5173
        sd *= dim;
 
5174
    }
 
5175
    return 1;
4924
5176
}
4925
5177
 
4926
5178
 
4928
5180
static int
4929
5181
_IsFortranContiguous(PyArrayObject *ap)
4930
5182
{
4931
 
        register intp sd;
4932
 
        register intp dim;
4933
 
        register int i;
 
5183
    register intp sd;
 
5184
    register intp dim;
 
5185
    register int i;
4934
5186
 
4935
 
        if (ap->nd == 0) return 1;
4936
 
        sd = ap->descr->elsize;
4937
 
        if (ap->nd == 1) return (ap->dimensions[0] == 1 || \
4938
 
                                 sd == ap->strides[0]);
4939
 
        for (i=0; i< ap->nd; ++i) {
4940
 
                dim = ap->dimensions[i];
4941
 
                /* fortran contiguous by definition */
4942
 
                if (dim == 0) return 1;
4943
 
                if (ap->strides[i] != sd) return 0;
4944
 
                sd *= dim;
4945
 
        }
4946
 
        return 1;
 
5187
    if (ap->nd == 0) return 1;
 
5188
    sd = ap->descr->elsize;
 
5189
    if (ap->nd == 1) return (ap->dimensions[0] == 1 || \
 
5190
                             sd == ap->strides[0]);
 
5191
    for(i=0; i< ap->nd; ++i) {
 
5192
        dim = ap->dimensions[i];
 
5193
        /* fortran contiguous by definition */
 
5194
        if (dim == 0) return 1;
 
5195
        if (ap->strides[i] != sd) return 0;
 
5196
        sd *= dim;
 
5197
    }
 
5198
    return 1;
4947
5199
}
4948
5200
 
4949
5201
static int
4950
5202
_IsAligned(PyArrayObject *ap)
4951
5203
{
4952
 
        int i, alignment, aligned=1;
4953
 
        intp ptr;
4954
 
        int type = ap->descr->type_num;
4955
 
 
4956
 
        if ((type == PyArray_STRING) || (type == PyArray_VOID))
4957
 
                return 1;
4958
 
 
4959
 
        alignment = ap->descr->alignment;
4960
 
        if (alignment == 1) return 1;
4961
 
 
4962
 
        ptr = (intp) ap->data;
4963
 
        aligned = (ptr % alignment) == 0;
4964
 
        for (i=0; i <ap->nd; i++)
4965
 
                aligned &= ((ap->strides[i] % alignment) == 0);
4966
 
        return aligned != 0;
 
5204
    int i, alignment, aligned=1;
 
5205
    intp ptr;
 
5206
    int type = ap->descr->type_num;
 
5207
 
 
5208
    if ((type == PyArray_STRING) || (type == PyArray_VOID))
 
5209
        return 1;
 
5210
 
 
5211
    alignment = ap->descr->alignment;
 
5212
    if (alignment == 1) return 1;
 
5213
 
 
5214
    ptr = (intp) ap->data;
 
5215
    aligned = (ptr % alignment) == 0;
 
5216
    for(i=0; i <ap->nd; i++)
 
5217
        aligned &= ((ap->strides[i] % alignment) == 0);
 
5218
    return aligned != 0;
4967
5219
}
4968
5220
 
4969
5221
static Bool
4970
5222
_IsWriteable(PyArrayObject *ap)
4971
5223
{
4972
 
        PyObject *base=ap->base;
4973
 
        void *dummy;
4974
 
        Py_ssize_t n;
4975
 
 
4976
 
        /* If we own our own data, then no-problem */
4977
 
        if ((base == NULL) || (ap->flags & OWNDATA)) return TRUE;
4978
 
 
4979
 
        /* Get to the final base object
4980
 
           If it is a writeable array, then return TRUE
4981
 
           If we can find an array object
4982
 
           or a writeable buffer object as the final base object
4983
 
           or a string object (for pickling support memory savings).
4984
 
             - this last could be removed if a proper pickleable
4985
 
               buffer was added to Python.
4986
 
        */
4987
 
 
4988
 
        while(PyArray_Check(base)) {
4989
 
                if (PyArray_CHKFLAGS(base, OWNDATA))
4990
 
                        return (Bool) (PyArray_ISWRITEABLE(base));
4991
 
                base = PyArray_BASE(base);
4992
 
        }
4993
 
 
4994
 
        /* here so pickle support works seamlessly
4995
 
           and unpickled array can be set and reset writeable
4996
 
           -- could be abused -- */
4997
 
        if PyString_Check(base) return TRUE;
4998
 
 
4999
 
        if (PyObject_AsWriteBuffer(base, &dummy, &n) < 0)
5000
 
                return FALSE;
5001
 
 
5002
 
        return TRUE;
 
5224
    PyObject *base=ap->base;
 
5225
    void *dummy;
 
5226
    Py_ssize_t n;
 
5227
 
 
5228
    /* If we own our own data, then no-problem */
 
5229
    if ((base == NULL) || (ap->flags & OWNDATA)) return TRUE;
 
5230
 
 
5231
    /* Get to the final base object
 
5232
       If it is a writeable array, then return TRUE
 
5233
       If we can find an array object
 
5234
       or a writeable buffer object as the final base object
 
5235
       or a string object (for pickling support memory savings).
 
5236
       - this last could be removed if a proper pickleable
 
5237
       buffer was added to Python.
 
5238
    */
 
5239
 
 
5240
    while(PyArray_Check(base)) {
 
5241
        if (PyArray_CHKFLAGS(base, OWNDATA))
 
5242
            return (Bool) (PyArray_ISWRITEABLE(base));
 
5243
        base = PyArray_BASE(base);
 
5244
    }
 
5245
 
 
5246
    /* here so pickle support works seamlessly
 
5247
       and unpickled array can be set and reset writeable
 
5248
       -- could be abused -- */
 
5249
    if PyString_Check(base) return TRUE;
 
5250
 
 
5251
    if (PyObject_AsWriteBuffer(base, &dummy, &n) < 0)
 
5252
        return FALSE;
 
5253
 
 
5254
    return TRUE;
5003
5255
}
5004
5256
 
5005
5257
 
5008
5260
static int
5009
5261
PyArray_ElementStrides(PyObject *arr)
5010
5262
{
5011
 
        register int itemsize = PyArray_ITEMSIZE(arr);
5012
 
        register int i, N=PyArray_NDIM(arr);
5013
 
        register intp *strides = PyArray_STRIDES(arr);
5014
 
 
5015
 
        for (i=0; i<N; i++) {
5016
 
                if ((strides[i] % itemsize) != 0) return 0;
5017
 
        }
5018
 
 
5019
 
        return 1;
 
5263
    register int itemsize = PyArray_ITEMSIZE(arr);
 
5264
    register int i, N=PyArray_NDIM(arr);
 
5265
    register intp *strides = PyArray_STRIDES(arr);
 
5266
 
 
5267
    for(i=0; i<N; i++) {
 
5268
        if ((strides[i] % itemsize) != 0) return 0;
 
5269
    }
 
5270
 
 
5271
    return 1;
5020
5272
}
5021
5273
 
5022
5274
/*OBJECT_API
5023
 
 Update Several Flags at once.
 
5275
  Update Several Flags at once.
5024
5276
*/
5025
5277
static void
5026
5278
PyArray_UpdateFlags(PyArrayObject *ret, int flagmask)
5027
5279
{
5028
5280
 
5029
 
        if (flagmask & FORTRAN) {
5030
 
                if (_IsFortranContiguous(ret)) {
5031
 
                        ret->flags |= FORTRAN;
5032
 
                        if (ret->nd > 1) ret->flags &= ~CONTIGUOUS;
5033
 
                }
5034
 
                else ret->flags &= ~FORTRAN;
5035
 
        }
5036
 
        if (flagmask & CONTIGUOUS) {
5037
 
                if (_IsContiguous(ret)) {
5038
 
                        ret->flags |= CONTIGUOUS;
5039
 
                        if (ret->nd > 1) ret->flags &= ~FORTRAN;
5040
 
                }
5041
 
                else ret->flags &= ~CONTIGUOUS;
5042
 
        }
5043
 
        if (flagmask & ALIGNED) {
5044
 
                if (_IsAligned(ret)) ret->flags |= ALIGNED;
5045
 
                else ret->flags &= ~ALIGNED;
5046
 
        }
5047
 
        /* This is not checked by default WRITEABLE is not
5048
 
           part of UPDATE_ALL */
5049
 
        if (flagmask & WRITEABLE) {
5050
 
                if (_IsWriteable(ret)) ret->flags |= WRITEABLE;
5051
 
                else ret->flags &= ~WRITEABLE;
5052
 
        }
5053
 
        return;
 
5281
    if (flagmask & FORTRAN) {
 
5282
        if (_IsFortranContiguous(ret)) {
 
5283
            ret->flags |= FORTRAN;
 
5284
            if (ret->nd > 1) ret->flags &= ~CONTIGUOUS;
 
5285
        }
 
5286
        else ret->flags &= ~FORTRAN;
 
5287
    }
 
5288
    if (flagmask & CONTIGUOUS) {
 
5289
        if (_IsContiguous(ret)) {
 
5290
            ret->flags |= CONTIGUOUS;
 
5291
            if (ret->nd > 1) ret->flags &= ~FORTRAN;
 
5292
        }
 
5293
        else ret->flags &= ~CONTIGUOUS;
 
5294
    }
 
5295
    if (flagmask & ALIGNED) {
 
5296
        if (_IsAligned(ret)) ret->flags |= ALIGNED;
 
5297
        else ret->flags &= ~ALIGNED;
 
5298
    }
 
5299
    /* This is not checked by default WRITEABLE is not
 
5300
       part of UPDATE_ALL */
 
5301
    if (flagmask & WRITEABLE) {
 
5302
        if (_IsWriteable(ret)) ret->flags |= WRITEABLE;
 
5303
        else ret->flags &= ~WRITEABLE;
 
5304
    }
 
5305
    return;
5054
5306
}
5055
5307
 
5056
5308
/* This routine checks to see if newstrides (of length nd) will not
5074
5326
PyArray_CheckStrides(int elsize, int nd, intp numbytes, intp offset,
5075
5327
                     intp *dims, intp *newstrides)
5076
5328
{
5077
 
        int i;
5078
 
        intp byte_begin;
5079
 
        intp begin;
5080
 
        intp end;
5081
 
 
5082
 
        if (numbytes == 0)
5083
 
                numbytes = PyArray_MultiplyList(dims, nd) * elsize;
5084
 
 
5085
 
        begin = -offset;
5086
 
        end = numbytes - offset - elsize;
5087
 
        for (i=0; i<nd; i++) {
5088
 
                byte_begin = newstrides[i]*(dims[i]-1);
5089
 
                if ((byte_begin < begin) || (byte_begin > end))
5090
 
                        return FALSE;
5091
 
        }
5092
 
        return TRUE;
 
5329
    int i;
 
5330
    intp byte_begin;
 
5331
    intp begin;
 
5332
    intp end;
 
5333
 
 
5334
    if (numbytes == 0)
 
5335
        numbytes = PyArray_MultiplyList(dims, nd) * elsize;
 
5336
 
 
5337
    begin = -offset;
 
5338
    end = numbytes - offset - elsize;
 
5339
    for(i=0; i<nd; i++) {
 
5340
        byte_begin = newstrides[i]*(dims[i]-1);
 
5341
        if ((byte_begin < begin) || (byte_begin > end))
 
5342
            return FALSE;
 
5343
    }
 
5344
    return TRUE;
5093
5345
 
5094
5346
}
5095
5347
 
5114
5366
_array_fill_strides(intp *strides, intp *dims, int nd, size_t itemsize,
5115
5367
                    int inflag, int *objflags)
5116
5368
{
5117
 
        int i;
5118
 
        /* Only make Fortran strides if not contiguous as well */
5119
 
        if ((inflag & FORTRAN) && !(inflag & CONTIGUOUS)) {
5120
 
                for (i=0; i<nd; i++) {
5121
 
                        strides[i] = itemsize;
5122
 
                        itemsize *= dims[i] ? dims[i] : 1;
5123
 
                }
5124
 
                *objflags |= FORTRAN;
5125
 
                if (nd > 1) *objflags &= ~CONTIGUOUS;
5126
 
                else *objflags |= CONTIGUOUS;
5127
 
        }
5128
 
        else {
5129
 
                for (i=nd-1;i>=0;i--) {
5130
 
                        strides[i] = itemsize;
5131
 
                        itemsize *= dims[i] ? dims[i] : 1;
5132
 
                }
5133
 
                *objflags |= CONTIGUOUS;
5134
 
                if (nd > 1) *objflags &= ~FORTRAN;
5135
 
                else *objflags |= FORTRAN;
5136
 
        }
5137
 
        return itemsize;
 
5369
    int i;
 
5370
    /* Only make Fortran strides if not contiguous as well */
 
5371
    if ((inflag & FORTRAN) && !(inflag & CONTIGUOUS)) {
 
5372
        for(i=0; i<nd; i++) {
 
5373
            strides[i] = itemsize;
 
5374
            itemsize *= dims[i] ? dims[i] : 1;
 
5375
        }
 
5376
        *objflags |= FORTRAN;
 
5377
        if (nd > 1) *objflags &= ~CONTIGUOUS;
 
5378
        else *objflags |= CONTIGUOUS;
 
5379
    }
 
5380
    else {
 
5381
        for(i=nd-1;i>=0;i--) {
 
5382
            strides[i] = itemsize;
 
5383
            itemsize *= dims[i] ? dims[i] : 1;
 
5384
        }
 
5385
        *objflags |= CONTIGUOUS;
 
5386
        if (nd > 1) *objflags &= ~FORTRAN;
 
5387
        else *objflags |= FORTRAN;
 
5388
    }
 
5389
    return itemsize;
5138
5390
}
5139
5391
 
5140
5392
/*OBJECT_API
5141
 
 Generic new array creation routine.
 
5393
  Generic new array creation routine.
5142
5394
*/
5143
5395
static PyObject *
5144
5396
PyArray_New(PyTypeObject *subtype, int nd, intp *dims, int type_num,
5145
5397
            intp *strides, void *data, int itemsize, int flags,
5146
5398
            PyObject *obj)
5147
5399
{
5148
 
        PyArray_Descr *descr;
5149
 
        PyObject *new;
 
5400
    PyArray_Descr *descr;
 
5401
    PyObject *new;
5150
5402
 
5151
 
        descr = PyArray_DescrFromType(type_num);
5152
 
        if (descr == NULL) return NULL;
5153
 
        if (descr->elsize == 0) {
5154
 
                if (itemsize < 1) {
5155
 
                        PyErr_SetString(PyExc_ValueError,
5156
 
                                        "data type must provide an itemsize");
5157
 
                        Py_DECREF(descr);
5158
 
                        return NULL;
5159
 
                }
5160
 
                PyArray_DESCR_REPLACE(descr);
5161
 
                descr->elsize = itemsize;
 
5403
    descr = PyArray_DescrFromType(type_num);
 
5404
    if (descr == NULL) return NULL;
 
5405
    if (descr->elsize == 0) {
 
5406
        if (itemsize < 1) {
 
5407
            PyErr_SetString(PyExc_ValueError,
 
5408
                            "data type must provide an itemsize");
 
5409
            Py_DECREF(descr);
 
5410
            return NULL;
5162
5411
        }
5163
 
        new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides,
5164
 
                                   data, flags, obj);
5165
 
        return new;
 
5412
        PyArray_DESCR_REPLACE(descr);
 
5413
        descr->elsize = itemsize;
 
5414
    }
 
5415
    new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides,
 
5416
                               data, flags, obj);
 
5417
    return new;
5166
5418
}
5167
5419
 
5168
5420
/* Change a sub-array field to the base descriptor */
5177
5429
_update_descr_and_dimensions(PyArray_Descr **des, intp *newdims,
5178
5430
                             intp *newstrides, int oldnd, int isfortran)
5179
5431
{
5180
 
        PyArray_Descr *old;
5181
 
        int newnd;
5182
 
        int numnew;
5183
 
        intp *mydim;
5184
 
        int i;
5185
 
        int tuple;
5186
 
 
5187
 
        old = *des;
5188
 
        *des = old->subarray->base;
5189
 
 
5190
 
 
5191
 
        mydim = newdims + oldnd;
5192
 
        tuple = PyTuple_Check(old->subarray->shape);
5193
 
        if (tuple) {
5194
 
                numnew = PyTuple_GET_SIZE(old->subarray->shape);
5195
 
        }
5196
 
        else {
5197
 
                numnew = 1;
5198
 
        }
5199
 
 
5200
 
 
5201
 
        newnd = oldnd + numnew;
5202
 
        if (newnd > MAX_DIMS) goto finish;
 
5432
    PyArray_Descr *old;
 
5433
    int newnd;
 
5434
    int numnew;
 
5435
    intp *mydim;
 
5436
    int i;
 
5437
    int tuple;
 
5438
 
 
5439
    old = *des;
 
5440
    *des = old->subarray->base;
 
5441
 
 
5442
 
 
5443
    mydim = newdims + oldnd;
 
5444
    tuple = PyTuple_Check(old->subarray->shape);
 
5445
    if (tuple) {
 
5446
        numnew = PyTuple_GET_SIZE(old->subarray->shape);
 
5447
    }
 
5448
    else {
 
5449
        numnew = 1;
 
5450
    }
 
5451
 
 
5452
 
 
5453
    newnd = oldnd + numnew;
 
5454
    if (newnd > MAX_DIMS) goto finish;
 
5455
    if (isfortran) {
 
5456
        memmove(newdims+numnew, newdims, oldnd*sizeof(intp));
 
5457
        mydim = newdims;
 
5458
    }
 
5459
 
 
5460
    if (tuple) {
 
5461
        for(i=0; i<numnew; i++) {
 
5462
            mydim[i] = (intp) PyInt_AsLong                  \
 
5463
                (PyTuple_GET_ITEM(old->subarray->shape, i));
 
5464
        }
 
5465
    }
 
5466
    else {
 
5467
        mydim[0] = (intp) PyInt_AsLong(old->subarray->shape);
 
5468
    }
 
5469
 
 
5470
    if (newstrides) {
 
5471
        intp tempsize;
 
5472
        intp *mystrides;
 
5473
        mystrides = newstrides + oldnd;
5203
5474
        if (isfortran) {
5204
 
                memmove(newdims+numnew, newdims, oldnd*sizeof(intp));
5205
 
                mydim = newdims;
5206
 
        }
5207
 
 
5208
 
        if (tuple) {
5209
 
                for (i=0; i<numnew; i++) {
5210
 
                        mydim[i] = (intp) PyInt_AsLong                  \
5211
 
                                (PyTuple_GET_ITEM(old->subarray->shape, i));
5212
 
                }
5213
 
        }
5214
 
        else {
5215
 
                mydim[0] = (intp) PyInt_AsLong(old->subarray->shape);
5216
 
        }
5217
 
 
5218
 
        if (newstrides) {
5219
 
                intp tempsize;
5220
 
                intp *mystrides;
5221
 
                mystrides = newstrides + oldnd;
5222
 
                if (isfortran) {
5223
 
                        memmove(newstrides+numnew, newstrides,
5224
 
                                oldnd*sizeof(intp));
5225
 
                        mystrides = newstrides;
5226
 
                }
5227
 
                /* Make new strides -- alwasy C-contiguous */
5228
 
                tempsize = (*des)->elsize;
5229
 
                for (i=numnew-1; i>=0; i--) {
5230
 
                        mystrides[i] = tempsize;
5231
 
                        tempsize *= mydim[i] ? mydim[i] : 1;
5232
 
                }
5233
 
        }
 
5475
            memmove(newstrides+numnew, newstrides,
 
5476
                    oldnd*sizeof(intp));
 
5477
            mystrides = newstrides;
 
5478
        }
 
5479
        /* Make new strides -- alwasy C-contiguous */
 
5480
        tempsize = (*des)->elsize;
 
5481
        for(i=numnew-1; i>=0; i--) {
 
5482
            mystrides[i] = tempsize;
 
5483
            tempsize *= mydim[i] ? mydim[i] : 1;
 
5484
        }
 
5485
    }
5234
5486
 
5235
5487
 finish:
5236
 
        Py_INCREF(*des);
5237
 
        Py_DECREF(old);
5238
 
        return newnd;
 
5488
    Py_INCREF(*des);
 
5489
    Py_DECREF(old);
 
5490
    return newnd;
5239
5491
}
5240
5492
 
5241
5493
 
5242
5494
/* steals a reference to descr (even on failure) */
5243
5495
/*OBJECT_API
5244
 
 Generic new array creation routine.
 
5496
  Generic new array creation routine.
5245
5497
*/
5246
5498
static PyObject *
5247
5499
PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
5248
5500
                     intp *dims, intp *strides, void *data,
5249
5501
                     int flags, PyObject *obj)
5250
5502
{
5251
 
        PyArrayObject *self;
5252
 
        register int i;
5253
 
        size_t sd;
5254
 
        intp largest;
5255
 
        intp size;
5256
 
 
5257
 
        if (descr->subarray) {
5258
 
                PyObject *ret;
5259
 
                intp newdims[2*MAX_DIMS];
5260
 
                intp *newstrides=NULL;
5261
 
                int isfortran=0;
5262
 
                isfortran = (data && (flags & FORTRAN) && !(flags & CONTIGUOUS)) || \
5263
 
                        (!data && flags);
5264
 
                memcpy(newdims, dims, nd*sizeof(intp));
5265
 
                if (strides) {
5266
 
                        newstrides = newdims + MAX_DIMS;
5267
 
                        memcpy(newstrides, strides, nd*sizeof(intp));
5268
 
                }
5269
 
                nd =_update_descr_and_dimensions(&descr, newdims,
5270
 
                                                 newstrides, nd, isfortran);
5271
 
                ret = PyArray_NewFromDescr(subtype, descr, nd, newdims,
5272
 
                                           newstrides,
5273
 
                                           data, flags, obj);
5274
 
                return ret;
5275
 
        }
5276
 
 
5277
 
        if (nd < 0) {
5278
 
                PyErr_SetString(PyExc_ValueError,
5279
 
                                "number of dimensions must be >=0");
5280
 
                Py_DECREF(descr);
5281
 
                return NULL;
5282
 
        }
5283
 
        if (nd > MAX_DIMS) {
5284
 
                PyErr_Format(PyExc_ValueError,
5285
 
                             "maximum number of dimensions is %d", MAX_DIMS);
5286
 
                Py_DECREF(descr);
5287
 
                return NULL;
5288
 
        }
5289
 
 
5290
 
        /* Check dimensions */
5291
 
        size = 1;
 
5503
    PyArrayObject *self;
 
5504
    register int i;
 
5505
    size_t sd;
 
5506
    intp largest;
 
5507
    intp size;
 
5508
 
 
5509
    if (descr->subarray) {
 
5510
        PyObject *ret;
 
5511
        intp newdims[2*MAX_DIMS];
 
5512
        intp *newstrides=NULL;
 
5513
        int isfortran=0;
 
5514
        isfortran = (data && (flags & FORTRAN) && !(flags & CONTIGUOUS)) || \
 
5515
            (!data && flags);
 
5516
        memcpy(newdims, dims, nd*sizeof(intp));
 
5517
        if (strides) {
 
5518
            newstrides = newdims + MAX_DIMS;
 
5519
            memcpy(newstrides, strides, nd*sizeof(intp));
 
5520
        }
 
5521
        nd =_update_descr_and_dimensions(&descr, newdims,
 
5522
                                         newstrides, nd, isfortran);
 
5523
        ret = PyArray_NewFromDescr(subtype, descr, nd, newdims,
 
5524
                                   newstrides,
 
5525
                                   data, flags, obj);
 
5526
        return ret;
 
5527
    }
 
5528
 
 
5529
    if (nd < 0) {
 
5530
        PyErr_SetString(PyExc_ValueError,
 
5531
                        "number of dimensions must be >=0");
 
5532
        Py_DECREF(descr);
 
5533
        return NULL;
 
5534
    }
 
5535
    if (nd > MAX_DIMS) {
 
5536
        PyErr_Format(PyExc_ValueError,
 
5537
                     "maximum number of dimensions is %d", MAX_DIMS);
 
5538
        Py_DECREF(descr);
 
5539
        return NULL;
 
5540
    }
 
5541
 
 
5542
    /* Check dimensions */
 
5543
    size = 1;
 
5544
    sd = (size_t) descr->elsize;
 
5545
    if (sd == 0) {
 
5546
        if (!PyDataType_ISSTRING(descr)) {
 
5547
            PyErr_SetString(PyExc_ValueError, "Empty data-type");
 
5548
            Py_DECREF(descr);
 
5549
            return NULL;
 
5550
        }
 
5551
        PyArray_DESCR_REPLACE(descr);
 
5552
        if (descr->type_num == NPY_STRING) descr->elsize = 1;
 
5553
        else descr->elsize = sizeof(PyArray_UCS4);
5292
5554
        sd = (size_t) descr->elsize;
5293
 
        if (sd == 0) {
5294
 
                if (!PyDataType_ISSTRING(descr)) {
5295
 
                        PyErr_SetString(PyExc_ValueError, "Empty data-type");
5296
 
                        Py_DECREF(descr);
5297
 
                        return NULL;
5298
 
                }
5299
 
                PyArray_DESCR_REPLACE(descr);
5300
 
                if (descr->type_num == NPY_STRING) descr->elsize = 1;
5301
 
                else descr->elsize = sizeof(PyArray_UCS4);
5302
 
                sd = (size_t) descr->elsize;  
5303
 
        }
5304
 
        largest = MAX_INTP / sd;
5305
 
        for (i=0;i<nd;i++) {
5306
 
                if (dims[i] == 0) continue;
5307
 
                if (dims[i] < 0) {
5308
 
                        PyErr_SetString(PyExc_ValueError,
5309
 
                                        "negative dimensions "  \
5310
 
                                        "are not allowed");
5311
 
                        Py_DECREF(descr);
5312
 
                        return NULL;
5313
 
                }
5314
 
                size *= dims[i];
5315
 
                if (size <=0 || size > largest) {
5316
 
                        PyErr_SetString(PyExc_ValueError,
5317
 
                                        "dimensions too large.");
5318
 
                        Py_DECREF(descr);
5319
 
                        return NULL;
5320
 
                }
5321
 
        }
5322
 
 
5323
 
        self = (PyArrayObject *) subtype->tp_alloc(subtype, 0);
5324
 
        if (self == NULL) {
5325
 
                Py_DECREF(descr);
5326
 
                return NULL;
5327
 
        }
5328
 
        self->nd = nd;
5329
 
        self->dimensions = NULL;
5330
 
        self->data = NULL;
5331
 
        if (data == NULL) {
5332
 
                self->flags = DEFAULT;
5333
 
                if (flags) {
5334
 
                        self->flags |= FORTRAN;
5335
 
                        if (nd > 1) self->flags &= ~CONTIGUOUS;
5336
 
                        flags = FORTRAN;
5337
 
                }
5338
 
        }
5339
 
        else self->flags = (flags & ~UPDATEIFCOPY);
5340
 
 
5341
 
        self->descr = descr;
5342
 
        self->base = (PyObject *)NULL;
5343
 
        self->weakreflist = (PyObject *)NULL;
5344
 
 
5345
 
        if (nd > 0) {
5346
 
                self->dimensions = PyDimMem_NEW(2*nd);
5347
 
                if (self->dimensions == NULL) {
5348
 
                        PyErr_NoMemory();
5349
 
                        goto fail;
5350
 
                }
5351
 
                self->strides = self->dimensions + nd;
5352
 
                memcpy(self->dimensions, dims, sizeof(intp)*nd);
5353
 
                if (strides == NULL) { /* fill it in */
5354
 
                        sd = _array_fill_strides(self->strides, dims, nd, sd,
5355
 
                                                 flags, &(self->flags));
5356
 
                }
5357
 
                else { /* we allow strides even when we create
5358
 
                          the memory, but be careful with this...
5359
 
                       */
5360
 
                        memcpy(self->strides, strides, sizeof(intp)*nd);
5361
 
                        sd *= size;
5362
 
                }
5363
 
        }
5364
 
        else { self->dimensions = self->strides = NULL; }
5365
 
 
5366
 
        if (data == NULL) {
5367
 
 
5368
 
                /* Allocate something even for zero-space arrays
5369
 
                 e.g. shape=(0,) -- otherwise buffer exposure
5370
 
                 (a.data) doesn't work as it should. */
5371
 
 
5372
 
                if (sd==0) sd = descr->elsize;
5373
 
 
5374
 
                if ((data = PyDataMem_NEW(sd))==NULL) {
5375
 
                        PyErr_NoMemory();
5376
 
                        goto fail;
5377
 
                }
5378
 
                self->flags |= OWNDATA;
5379
 
 
5380
 
                /* It is bad to have unitialized OBJECT pointers */
5381
 
                /* which could also be sub-fields of a VOID array */
5382
 
                if (PyDataType_FLAGCHK(descr, NPY_NEEDS_INIT)) {
5383
 
                        memset(data, 0, sd);
5384
 
                }
5385
 
        }
5386
 
        else {
5387
 
                self->flags &= ~OWNDATA;  /* If data is passed in,
5388
 
                                           this object won't own it
5389
 
                                           by default.
5390
 
                                           Caller must arrange for
5391
 
                                           this to be reset if truly
5392
 
                                           desired */
5393
 
        }
5394
 
        self->data = data;
5395
 
 
5396
 
        /* call the __array_finalize__
5397
 
           method if a subtype.
5398
 
           If obj is NULL, then call method with Py_None
5399
 
        */
5400
 
        if ((subtype != &PyArray_Type)) {
5401
 
                PyObject *res, *func, *args;
5402
 
                static PyObject *str=NULL;
5403
 
 
5404
 
                if (str == NULL) {
5405
 
                        str = PyString_InternFromString("__array_finalize__");
5406
 
                }
5407
 
                func = PyObject_GetAttr((PyObject *)self, str);
5408
 
                if (func && func != Py_None) {
5409
 
                        if (strides != NULL) { /* did not allocate own data
5410
 
                                                  or funny strides */
5411
 
                                /* update flags before finalize function */
5412
 
                                PyArray_UpdateFlags(self, UPDATE_ALL);
5413
 
                        }
5414
 
                        if PyCObject_Check(func) { /* A C-function is stored here */
5415
 
                                PyArray_FinalizeFunc *cfunc;
5416
 
                                cfunc = PyCObject_AsVoidPtr(func);
5417
 
                                Py_DECREF(func);
5418
 
                                if (cfunc(self, obj) < 0) goto fail;
5419
 
                        }
5420
 
                        else {
5421
 
                                args = PyTuple_New(1);
5422
 
                                if (obj == NULL) obj=Py_None;
5423
 
                                Py_INCREF(obj);
5424
 
                                PyTuple_SET_ITEM(args, 0, obj);
5425
 
                                res = PyObject_Call(func, args, NULL);
5426
 
                                Py_DECREF(args);
5427
 
                                Py_DECREF(func);
5428
 
                                if (res == NULL) goto fail;
5429
 
                                else Py_DECREF(res);
5430
 
                        }
5431
 
                }
5432
 
                else Py_XDECREF(func);
5433
 
        }
5434
 
 
5435
 
        return (PyObject *)self;
 
5555
    }
 
5556
    largest = MAX_INTP / sd;
 
5557
    for(i=0;i<nd;i++) {
 
5558
        if (dims[i] == 0) continue;
 
5559
        if (dims[i] < 0) {
 
5560
            PyErr_SetString(PyExc_ValueError,
 
5561
                            "negative dimensions "  \
 
5562
                            "are not allowed");
 
5563
            Py_DECREF(descr);
 
5564
            return NULL;
 
5565
        }
 
5566
        size *= dims[i];
 
5567
        if (size > largest || size < 0) {
 
5568
            PyErr_SetString(PyExc_ValueError,
 
5569
                            "dimensions too large.");
 
5570
            Py_DECREF(descr);
 
5571
            return NULL;
 
5572
        }
 
5573
    }
 
5574
 
 
5575
    self = (PyArrayObject *) subtype->tp_alloc(subtype, 0);
 
5576
    if (self == NULL) {
 
5577
        Py_DECREF(descr);
 
5578
        return NULL;
 
5579
    }
 
5580
    self->nd = nd;
 
5581
    self->dimensions = NULL;
 
5582
    self->data = NULL;
 
5583
    if (data == NULL) {
 
5584
        self->flags = DEFAULT;
 
5585
        if (flags) {
 
5586
            self->flags |= FORTRAN;
 
5587
            if (nd > 1) self->flags &= ~CONTIGUOUS;
 
5588
            flags = FORTRAN;
 
5589
        }
 
5590
    }
 
5591
    else self->flags = (flags & ~UPDATEIFCOPY);
 
5592
 
 
5593
    self->descr = descr;
 
5594
    self->base = (PyObject *)NULL;
 
5595
    self->weakreflist = (PyObject *)NULL;
 
5596
 
 
5597
    if (nd > 0) {
 
5598
        self->dimensions = PyDimMem_NEW(2*nd);
 
5599
        if (self->dimensions == NULL) {
 
5600
            PyErr_NoMemory();
 
5601
            goto fail;
 
5602
        }
 
5603
        self->strides = self->dimensions + nd;
 
5604
        memcpy(self->dimensions, dims, sizeof(intp)*nd);
 
5605
        if (strides == NULL) { /* fill it in */
 
5606
            sd = _array_fill_strides(self->strides, dims, nd, sd,
 
5607
                                     flags, &(self->flags));
 
5608
        }
 
5609
        else { /* we allow strides even when we create
 
5610
                  the memory, but be careful with this...
 
5611
               */
 
5612
            memcpy(self->strides, strides, sizeof(intp)*nd);
 
5613
            sd *= size;
 
5614
        }
 
5615
    }
 
5616
    else { self->dimensions = self->strides = NULL; }
 
5617
 
 
5618
    if (data == NULL) {
 
5619
 
 
5620
        /* Allocate something even for zero-space arrays
 
5621
           e.g. shape=(0,) -- otherwise buffer exposure
 
5622
           (a.data) doesn't work as it should. */
 
5623
 
 
5624
        if (sd==0) sd = descr->elsize;
 
5625
 
 
5626
        if ((data = PyDataMem_NEW(sd))==NULL) {
 
5627
            PyErr_NoMemory();
 
5628
            goto fail;
 
5629
        }
 
5630
        self->flags |= OWNDATA;
 
5631
 
 
5632
        /* It is bad to have unitialized OBJECT pointers */
 
5633
        /* which could also be sub-fields of a VOID array */
 
5634
        if (PyDataType_FLAGCHK(descr, NPY_NEEDS_INIT)) {
 
5635
            memset(data, 0, sd);
 
5636
        }
 
5637
    }
 
5638
    else {
 
5639
        self->flags &= ~OWNDATA;  /* If data is passed in,
 
5640
                                     this object won't own it
 
5641
                                     by default.
 
5642
                                     Caller must arrange for
 
5643
                                     this to be reset if truly
 
5644
                                     desired */
 
5645
    }
 
5646
    self->data = data;
 
5647
 
 
5648
    /* call the __array_finalize__
 
5649
       method if a subtype.
 
5650
       If obj is NULL, then call method with Py_None
 
5651
    */
 
5652
    if ((subtype != &PyArray_Type)) {
 
5653
        PyObject *res, *func, *args;
 
5654
        static PyObject *str=NULL;
 
5655
 
 
5656
        if (str == NULL) {
 
5657
            str = PyString_InternFromString("__array_finalize__");
 
5658
        }
 
5659
        func = PyObject_GetAttr((PyObject *)self, str);
 
5660
        if (func && func != Py_None) {
 
5661
            if (strides != NULL) { /* did not allocate own data
 
5662
                                      or funny strides */
 
5663
                /* update flags before finalize function */
 
5664
                PyArray_UpdateFlags(self, UPDATE_ALL);
 
5665
            }
 
5666
            if PyCObject_Check(func) { /* A C-function is stored here */
 
5667
                    PyArray_FinalizeFunc *cfunc;
 
5668
                    cfunc = PyCObject_AsVoidPtr(func);
 
5669
                    Py_DECREF(func);
 
5670
                    if (cfunc(self, obj) < 0) goto fail;
 
5671
                }
 
5672
            else {
 
5673
                args = PyTuple_New(1);
 
5674
                if (obj == NULL) obj=Py_None;
 
5675
                Py_INCREF(obj);
 
5676
                PyTuple_SET_ITEM(args, 0, obj);
 
5677
                res = PyObject_Call(func, args, NULL);
 
5678
                Py_DECREF(args);
 
5679
                Py_DECREF(func);
 
5680
                if (res == NULL) goto fail;
 
5681
                else Py_DECREF(res);
 
5682
            }
 
5683
        }
 
5684
        else Py_XDECREF(func);
 
5685
    }
 
5686
 
 
5687
    return (PyObject *)self;
5436
5688
 
5437
5689
 fail:
5438
 
        Py_DECREF(self);
5439
 
        return NULL;
 
5690
    Py_DECREF(self);
 
5691
    return NULL;
5440
5692
}
5441
5693
 
5442
5694
static void
5443
5695
_putzero(char *optr, PyObject *zero, PyArray_Descr *dtype)
5444
5696
{
5445
 
        if (!PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)) {
5446
 
                memset(optr, 0, dtype->elsize);
5447
 
        }
5448
 
        else if (PyDescr_HASFIELDS(dtype)) {
5449
 
                PyObject *key, *value, *title=NULL;
5450
 
                PyArray_Descr *new;
5451
 
                int offset;
5452
 
                Py_ssize_t pos=0;
5453
 
                while (PyDict_Next(dtype->fields, &pos, &key, &value)) {
5454
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
5455
 
                                              &title)) return;
5456
 
                        _putzero(optr + offset, zero, new);
5457
 
                }
5458
 
        }
5459
 
        else {
5460
 
                PyObject **temp;
5461
 
                Py_INCREF(zero);
5462
 
                temp = (PyObject **)optr;
5463
 
                *temp = zero;
5464
 
        }
5465
 
        return;
 
5697
    if (!PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)) {
 
5698
        memset(optr, 0, dtype->elsize);
 
5699
    }
 
5700
    else if (PyDescr_HASFIELDS(dtype)) {
 
5701
        PyObject *key, *value, *title=NULL;
 
5702
        PyArray_Descr *new;
 
5703
        int offset;
 
5704
        Py_ssize_t pos=0;
 
5705
        while (PyDict_Next(dtype->fields, &pos, &key, &value)) {
 
5706
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
5707
                                  &title)) return;
 
5708
            _putzero(optr + offset, zero, new);
 
5709
        }
 
5710
    }
 
5711
    else {
 
5712
        PyObject **temp;
 
5713
        Py_INCREF(zero);
 
5714
        temp = (PyObject **)optr;
 
5715
        *temp = zero;
 
5716
    }
 
5717
    return;
5466
5718
}
5467
5719
 
5468
5720
 
5469
5721
/*OBJECT_API
5470
 
 Resize (reallocate data).  Only works if nothing else is referencing
5471
 
 this array and it is contiguous.
5472
 
 If refcheck is 0, then the reference count is not checked
5473
 
 and assumed to be 1.
5474
 
 You still must own this data and have no weak-references and no base
5475
 
 object.
 
5722
  Resize (reallocate data).  Only works if nothing else is referencing
 
5723
  this array and it is contiguous.
 
5724
  If refcheck is 0, then the reference count is not checked
 
5725
  and assumed to be 1.
 
5726
  You still must own this data and have no weak-references and no base
 
5727
  object.
5476
5728
*/
5477
5729
static PyObject *
5478
5730
PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck,
5479
5731
               NPY_ORDER fortran)
5480
5732
{
5481
 
        intp oldsize, newsize;
5482
 
        int new_nd=newshape->len, k, n, elsize;
5483
 
        int refcnt;
5484
 
        intp* new_dimensions=newshape->ptr;
5485
 
        intp new_strides[MAX_DIMS];
5486
 
        size_t sd;
5487
 
        intp *dimptr;
5488
 
        char *new_data;
5489
 
        intp largest;
5490
 
 
5491
 
        if (!PyArray_ISONESEGMENT(self)) {
5492
 
                PyErr_SetString(PyExc_ValueError,
5493
 
                                "resize only works on single-segment arrays");
5494
 
                return NULL;
5495
 
        }
5496
 
 
5497
 
        if (fortran == PyArray_ANYORDER)
5498
 
                fortran = PyArray_CORDER;
5499
 
 
5500
 
        if (self->descr->elsize == 0) {
5501
 
                PyErr_SetString(PyExc_ValueError, "Bad data-type size.");
5502
 
                return NULL;
5503
 
        }
5504
 
        newsize = 1;
5505
 
        largest = MAX_INTP / self->descr->elsize;
5506
 
        for (k=0; k<new_nd; k++) {
5507
 
                if (new_dimensions[k]==0) break;
5508
 
                if (new_dimensions[k] < 0) {
5509
 
                        PyErr_SetString(PyExc_ValueError,
5510
 
                                        "negative dimensions not allowed");
5511
 
                        return NULL;
5512
 
                }
5513
 
                newsize *= new_dimensions[k];
5514
 
                if (newsize <=0 || newsize > largest) {
5515
 
                        return PyErr_NoMemory();
5516
 
                }
5517
 
        }
5518
 
        oldsize = PyArray_SIZE(self);
5519
 
 
5520
 
        if (oldsize != newsize) {
5521
 
                if (!(self->flags & OWNDATA)) {
5522
 
                        PyErr_SetString(PyExc_ValueError,
5523
 
                                        "cannot resize this array:  "   \
5524
 
                                        "it does not own its data");
5525
 
                        return NULL;
5526
 
                }
5527
 
 
5528
 
                if (refcheck) refcnt = REFCOUNT(self);
5529
 
                else refcnt = 1;
5530
 
                if ((refcnt > 2) || (self->base != NULL) ||     \
5531
 
                    (self->weakreflist != NULL)) {
5532
 
                        PyErr_SetString(PyExc_ValueError,
5533
 
                                        "cannot resize an array that has "\
5534
 
                                        "been referenced or is referencing\n"\
5535
 
                                        "another array in this way.  Use the "\
5536
 
                                        "resize function");
5537
 
                        return NULL;
5538
 
                }
5539
 
 
5540
 
                if (newsize == 0) sd = self->descr->elsize;
5541
 
                else sd = newsize * self->descr->elsize;
5542
 
                /* Reallocate space if needed */
5543
 
                new_data = PyDataMem_RENEW(self->data, sd);
5544
 
                if (new_data == NULL) {
5545
 
                        PyErr_SetString(PyExc_MemoryError,
5546
 
                                        "cannot allocate memory for array");
5547
 
                        return NULL;
5548
 
                }
5549
 
                self->data = new_data;
5550
 
        }
5551
 
 
5552
 
        if ((newsize > oldsize) && PyArray_ISWRITEABLE(self)) {
5553
 
                /* Fill new memory with zeros */
5554
 
                elsize = self->descr->elsize;
5555
 
                if (PyDataType_FLAGCHK(self->descr, NPY_ITEM_REFCOUNT)) {
5556
 
                        PyObject *zero = PyInt_FromLong(0);
5557
 
                        char *optr;
5558
 
                        optr = self->data + oldsize*elsize;
5559
 
                        n = newsize - oldsize;
5560
 
                        for (k=0; k<n; k++) {
5561
 
                                _putzero((char *)optr, zero, self->descr);
5562
 
                                optr += elsize;
5563
 
                        }
5564
 
                        Py_DECREF(zero);
5565
 
                }
5566
 
                else{
5567
 
                        memset(self->data+oldsize*elsize, 0,
5568
 
                               (newsize-oldsize)*elsize);
5569
 
                }
5570
 
        }
5571
 
 
5572
 
        if (self->nd != new_nd) {  /* Different number of dimensions. */
5573
 
                self->nd = new_nd;
5574
 
 
5575
 
                /* Need new dimensions and strides arrays */
5576
 
                dimptr = PyDimMem_RENEW(self->dimensions, 2*new_nd);
5577
 
                if (dimptr == NULL) {
5578
 
                        PyErr_SetString(PyExc_MemoryError,
5579
 
                                        "cannot allocate memory for array " \
5580
 
                                        "(array may be corrupted)");
5581
 
                        return NULL;
5582
 
                }
5583
 
                self->dimensions = dimptr;
5584
 
                self->strides = dimptr + new_nd;
5585
 
        }
5586
 
 
5587
 
        /* make new_strides variable */
5588
 
        sd = (size_t) self->descr->elsize;
5589
 
        sd = (size_t) _array_fill_strides(new_strides, new_dimensions, new_nd, sd,
5590
 
                                          self->flags, &(self->flags));
5591
 
 
5592
 
        memmove(self->dimensions, new_dimensions, new_nd*sizeof(intp));
5593
 
        memmove(self->strides, new_strides, new_nd*sizeof(intp));
5594
 
 
5595
 
        Py_INCREF(Py_None);
5596
 
        return Py_None;
 
5733
    intp oldsize, newsize;
 
5734
    int new_nd=newshape->len, k, n, elsize;
 
5735
    int refcnt;
 
5736
    intp* new_dimensions=newshape->ptr;
 
5737
    intp new_strides[MAX_DIMS];
 
5738
    size_t sd;
 
5739
    intp *dimptr;
 
5740
    char *new_data;
 
5741
    intp largest;
 
5742
 
 
5743
    if (!PyArray_ISONESEGMENT(self)) {
 
5744
        PyErr_SetString(PyExc_ValueError,
 
5745
                        "resize only works on single-segment arrays");
 
5746
        return NULL;
 
5747
    }
 
5748
 
 
5749
    if (fortran == PyArray_ANYORDER)
 
5750
        fortran = PyArray_CORDER;
 
5751
 
 
5752
    if (self->descr->elsize == 0) {
 
5753
        PyErr_SetString(PyExc_ValueError, "Bad data-type size.");
 
5754
        return NULL;
 
5755
    }
 
5756
    newsize = 1;
 
5757
    largest = MAX_INTP / self->descr->elsize;
 
5758
    for(k=0; k<new_nd; k++) {
 
5759
        if (new_dimensions[k]==0) break;
 
5760
        if (new_dimensions[k] < 0) {
 
5761
            PyErr_SetString(PyExc_ValueError,
 
5762
                            "negative dimensions not allowed");
 
5763
            return NULL;
 
5764
        }
 
5765
        newsize *= new_dimensions[k];
 
5766
        if (newsize <=0 || newsize > largest) {
 
5767
            return PyErr_NoMemory();
 
5768
        }
 
5769
    }
 
5770
    oldsize = PyArray_SIZE(self);
 
5771
 
 
5772
    if (oldsize != newsize) {
 
5773
        if (!(self->flags & OWNDATA)) {
 
5774
            PyErr_SetString(PyExc_ValueError,
 
5775
                            "cannot resize this array:  "   \
 
5776
                            "it does not own its data");
 
5777
            return NULL;
 
5778
        }
 
5779
 
 
5780
        if (refcheck) refcnt = REFCOUNT(self);
 
5781
        else refcnt = 1;
 
5782
        if ((refcnt > 2) || (self->base != NULL) ||     \
 
5783
            (self->weakreflist != NULL)) {
 
5784
            PyErr_SetString(PyExc_ValueError,
 
5785
                            "cannot resize an array that has "\
 
5786
                            "been referenced or is referencing\n"\
 
5787
                            "another array in this way.  Use the "\
 
5788
                            "resize function");
 
5789
            return NULL;
 
5790
        }
 
5791
 
 
5792
        if (newsize == 0) sd = self->descr->elsize;
 
5793
        else sd = newsize * self->descr->elsize;
 
5794
        /* Reallocate space if needed */
 
5795
        new_data = PyDataMem_RENEW(self->data, sd);
 
5796
        if (new_data == NULL) {
 
5797
            PyErr_SetString(PyExc_MemoryError,
 
5798
                            "cannot allocate memory for array");
 
5799
            return NULL;
 
5800
        }
 
5801
        self->data = new_data;
 
5802
    }
 
5803
 
 
5804
    if ((newsize > oldsize) && PyArray_ISWRITEABLE(self)) {
 
5805
        /* Fill new memory with zeros */
 
5806
        elsize = self->descr->elsize;
 
5807
        if (PyDataType_FLAGCHK(self->descr, NPY_ITEM_REFCOUNT)) {
 
5808
            PyObject *zero = PyInt_FromLong(0);
 
5809
            char *optr;
 
5810
            optr = self->data + oldsize*elsize;
 
5811
            n = newsize - oldsize;
 
5812
            for(k=0; k<n; k++) {
 
5813
                _putzero((char *)optr, zero, self->descr);
 
5814
                optr += elsize;
 
5815
            }
 
5816
            Py_DECREF(zero);
 
5817
        }
 
5818
        else{
 
5819
            memset(self->data+oldsize*elsize, 0,
 
5820
                   (newsize-oldsize)*elsize);
 
5821
        }
 
5822
    }
 
5823
 
 
5824
    if (self->nd != new_nd) {  /* Different number of dimensions. */
 
5825
        self->nd = new_nd;
 
5826
 
 
5827
        /* Need new dimensions and strides arrays */
 
5828
        dimptr = PyDimMem_RENEW(self->dimensions, 2*new_nd);
 
5829
        if (dimptr == NULL) {
 
5830
            PyErr_SetString(PyExc_MemoryError,
 
5831
                            "cannot allocate memory for array " \
 
5832
                            "(array may be corrupted)");
 
5833
            return NULL;
 
5834
        }
 
5835
        self->dimensions = dimptr;
 
5836
        self->strides = dimptr + new_nd;
 
5837
    }
 
5838
 
 
5839
    /* make new_strides variable */
 
5840
    sd = (size_t) self->descr->elsize;
 
5841
    sd = (size_t) _array_fill_strides(new_strides, new_dimensions, new_nd, sd,
 
5842
                                      self->flags, &(self->flags));
 
5843
 
 
5844
    memmove(self->dimensions, new_dimensions, new_nd*sizeof(intp));
 
5845
    memmove(self->strides, new_strides, new_nd*sizeof(intp));
 
5846
 
 
5847
    Py_INCREF(Py_None);
 
5848
    return Py_None;
5597
5849
 
5598
5850
}
5599
5851
 
5600
5852
static void
5601
5853
_fillobject(char *optr, PyObject *obj, PyArray_Descr *dtype)
5602
5854
{
5603
 
        if (!PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)) {
5604
 
                if ((obj == Py_None) ||
5605
 
                    (PyInt_Check(obj) && PyInt_AsLong(obj)==0))
5606
 
                        return;
5607
 
                else {
5608
 
                        PyObject *arr;
5609
 
                        Py_INCREF(dtype);
5610
 
                        arr = PyArray_NewFromDescr(&PyArray_Type, dtype,
5611
 
                                                   0, NULL, NULL, NULL,
5612
 
                                                   0, NULL);
5613
 
                        if (arr!=NULL)
5614
 
                                dtype->f->setitem(obj, optr, arr);
5615
 
                        Py_XDECREF(arr);
5616
 
                }
5617
 
        }
5618
 
        else if (PyDescr_HASFIELDS(dtype)) {
5619
 
                PyObject *key, *value, *title=NULL;
5620
 
                PyArray_Descr *new;
5621
 
                int offset;
5622
 
                Py_ssize_t pos=0;
5623
 
                while (PyDict_Next(dtype->fields, &pos, &key, &value)) {
5624
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
5625
 
                                              &title)) return;
5626
 
                        _fillobject(optr + offset, obj, new);
5627
 
                }
5628
 
        }
 
5855
    if (!PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)) {
 
5856
        if ((obj == Py_None) ||
 
5857
            (PyInt_Check(obj) && PyInt_AsLong(obj)==0))
 
5858
            return;
5629
5859
        else {
5630
 
                PyObject **temp;
5631
 
                Py_XINCREF(obj);
5632
 
                temp = (PyObject **)optr;
5633
 
                *temp = obj;
5634
 
                return;
5635
 
        }
 
5860
            PyObject *arr;
 
5861
            Py_INCREF(dtype);
 
5862
            arr = PyArray_NewFromDescr(&PyArray_Type, dtype,
 
5863
                                       0, NULL, NULL, NULL,
 
5864
                                       0, NULL);
 
5865
            if (arr!=NULL)
 
5866
                dtype->f->setitem(obj, optr, arr);
 
5867
            Py_XDECREF(arr);
 
5868
        }
 
5869
    }
 
5870
    else if (PyDescr_HASFIELDS(dtype)) {
 
5871
        PyObject *key, *value, *title=NULL;
 
5872
        PyArray_Descr *new;
 
5873
        int offset;
 
5874
        Py_ssize_t pos=0;
 
5875
        while (PyDict_Next(dtype->fields, &pos, &key, &value)) {
 
5876
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
5877
                                  &title)) return;
 
5878
            _fillobject(optr + offset, obj, new);
 
5879
        }
 
5880
    }
 
5881
    else {
 
5882
        PyObject **temp;
 
5883
        Py_XINCREF(obj);
 
5884
        temp = (PyObject **)optr;
 
5885
        *temp = obj;
 
5886
        return;
 
5887
    }
5636
5888
}
5637
5889
 
5638
5890
/* Assumes contiguous */
5640
5892
static void
5641
5893
PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
5642
5894
{
5643
 
        intp i,n;
 
5895
    intp i,n;
 
5896
    n = PyArray_SIZE(arr);
 
5897
    if (arr->descr->type_num == PyArray_OBJECT) {
 
5898
        PyObject **optr;
 
5899
        optr = (PyObject **)(arr->data);
5644
5900
        n = PyArray_SIZE(arr);
5645
 
        if (arr->descr->type_num == PyArray_OBJECT) {
5646
 
                PyObject **optr;
5647
 
                optr = (PyObject **)(arr->data);
5648
 
                n = PyArray_SIZE(arr);
5649
 
                if (obj == NULL) {
5650
 
                        for (i=0; i<n; i++) {
5651
 
                                *optr++ = NULL;
5652
 
                        }
5653
 
                }
5654
 
                else {
5655
 
                        for (i=0; i<n; i++) {
5656
 
                                Py_INCREF(obj);
5657
 
                                *optr++ = obj;
5658
 
                        }
5659
 
                }
 
5901
        if (obj == NULL) {
 
5902
            for(i=0; i<n; i++) {
 
5903
                *optr++ = NULL;
 
5904
            }
5660
5905
        }
5661
5906
        else {
5662
 
                char *optr;
5663
 
                optr = arr->data;
5664
 
                for (i=0; i<n; i++) {
5665
 
                        _fillobject(optr, obj, arr->descr);
5666
 
                        optr += arr->descr->elsize;
5667
 
                }
5668
 
        }
 
5907
            for(i=0; i<n; i++) {
 
5908
                Py_INCREF(obj);
 
5909
                *optr++ = obj;
 
5910
            }
 
5911
        }
 
5912
    }
 
5913
    else {
 
5914
        char *optr;
 
5915
        optr = arr->data;
 
5916
        for(i=0; i<n; i++) {
 
5917
            _fillobject(optr, obj, arr->descr);
 
5918
            optr += arr->descr->elsize;
 
5919
        }
 
5920
    }
5669
5921
}
5670
5922
 
5671
5923
/*OBJECT_API*/
5672
5924
static int
5673
5925
PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj)
5674
5926
{
5675
 
        PyObject *newarr;
5676
 
        int itemsize, swap;
5677
 
        void *fromptr;
5678
 
        PyArray_Descr *descr;
5679
 
        intp size;
5680
 
        PyArray_CopySwapFunc *copyswap;
5681
 
 
5682
 
        itemsize = arr->descr->elsize;
5683
 
        if (PyArray_ISOBJECT(arr)) {
5684
 
                fromptr = &obj;
5685
 
                swap = 0;
5686
 
                newarr = NULL;
5687
 
        }
5688
 
        else {
5689
 
                descr = PyArray_DESCR(arr);
5690
 
                Py_INCREF(descr);
5691
 
                newarr = PyArray_FromAny(obj, descr, 0,0, ALIGNED, NULL);
5692
 
                if (newarr == NULL) return -1;
5693
 
                fromptr = PyArray_DATA(newarr);
5694
 
                swap=!PyArray_ISNOTSWAPPED(arr);
5695
 
        }
5696
 
        size=PyArray_SIZE(arr);
5697
 
        copyswap = arr->descr->f->copyswap;
5698
 
        if (PyArray_ISONESEGMENT(arr)) {
5699
 
                char *toptr=PyArray_DATA(arr);
5700
 
                PyArray_FillWithScalarFunc* fillwithscalar =
5701
 
                        arr->descr->f->fillwithscalar;
5702
 
                if (fillwithscalar && PyArray_ISALIGNED(arr)) {
5703
 
                        copyswap(fromptr, NULL, swap, newarr);
5704
 
                        fillwithscalar(toptr, size, fromptr, arr);
5705
 
                }
5706
 
                else {
5707
 
                        while (size--) {
5708
 
                                copyswap(toptr, fromptr, swap, arr);
5709
 
                                toptr += itemsize;
5710
 
                        }
5711
 
                }
5712
 
        }
5713
 
        else {
5714
 
                PyArrayIterObject *iter;
5715
 
 
5716
 
                iter = (PyArrayIterObject *)\
5717
 
                        PyArray_IterNew((PyObject *)arr);
5718
 
                if (iter == NULL) {
5719
 
                        Py_XDECREF(newarr);
5720
 
                        return -1;
5721
 
                }
5722
 
                while(size--) {
5723
 
                        copyswap(iter->dataptr, fromptr, swap, arr);
5724
 
                        PyArray_ITER_NEXT(iter);
5725
 
                }
5726
 
                Py_DECREF(iter);
5727
 
        }
5728
 
        Py_XDECREF(newarr);
5729
 
        return 0;
 
5927
    PyObject *newarr;
 
5928
    int itemsize, swap;
 
5929
    void *fromptr;
 
5930
    PyArray_Descr *descr;
 
5931
    intp size;
 
5932
    PyArray_CopySwapFunc *copyswap;
 
5933
 
 
5934
    itemsize = arr->descr->elsize;
 
5935
    if (PyArray_ISOBJECT(arr)) {
 
5936
        fromptr = &obj;
 
5937
        swap = 0;
 
5938
        newarr = NULL;
 
5939
    }
 
5940
    else {
 
5941
        descr = PyArray_DESCR(arr);
 
5942
        Py_INCREF(descr);
 
5943
        newarr = PyArray_FromAny(obj, descr, 0,0, ALIGNED, NULL);
 
5944
        if (newarr == NULL) return -1;
 
5945
        fromptr = PyArray_DATA(newarr);
 
5946
        swap = (PyArray_ISNOTSWAPPED(arr) != PyArray_ISNOTSWAPPED(newarr));
 
5947
    }
 
5948
    size=PyArray_SIZE(arr);
 
5949
    copyswap = arr->descr->f->copyswap;
 
5950
    if (PyArray_ISONESEGMENT(arr)) {
 
5951
        char *toptr=PyArray_DATA(arr);
 
5952
        PyArray_FillWithScalarFunc* fillwithscalar =
 
5953
            arr->descr->f->fillwithscalar;
 
5954
        if (fillwithscalar && PyArray_ISALIGNED(arr)) {
 
5955
            copyswap(fromptr, NULL, swap, newarr);
 
5956
            fillwithscalar(toptr, size, fromptr, arr);
 
5957
        }
 
5958
        else {
 
5959
            while (size--) {
 
5960
                copyswap(toptr, fromptr, swap, arr);
 
5961
                toptr += itemsize;
 
5962
            }
 
5963
        }
 
5964
    }
 
5965
    else {
 
5966
        PyArrayIterObject *iter;
 
5967
 
 
5968
        iter = (PyArrayIterObject *)\
 
5969
            PyArray_IterNew((PyObject *)arr);
 
5970
        if (iter == NULL) {
 
5971
            Py_XDECREF(newarr);
 
5972
            return -1;
 
5973
        }
 
5974
        while(size--) {
 
5975
            copyswap(iter->dataptr, fromptr, swap, arr);
 
5976
            PyArray_ITER_NEXT(iter);
 
5977
        }
 
5978
        Py_DECREF(iter);
 
5979
    }
 
5980
    Py_XDECREF(newarr);
 
5981
    return 0;
5730
5982
}
5731
5983
 
5732
5984
static PyObject *
5733
5985
array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
5734
5986
{
5735
 
        static char *kwlist[] = {"shape", "dtype", "buffer",
5736
 
                                 "offset", "strides",
5737
 
                                 "order", NULL};
5738
 
        PyArray_Descr *descr=NULL;
5739
 
        int itemsize;
5740
 
        PyArray_Dims dims = {NULL, 0};
5741
 
        PyArray_Dims strides = {NULL, 0};
5742
 
        PyArray_Chunk buffer;
5743
 
        longlong offset=0;
5744
 
        NPY_ORDER order=PyArray_CORDER;
5745
 
        int fortran = 0;
5746
 
        PyArrayObject *ret;
5747
 
 
5748
 
        buffer.ptr = NULL;
5749
 
        /* Usually called with shape and type
5750
 
           but can also be called with buffer, strides, and swapped info
5751
 
        */
5752
 
 
5753
 
        /* For now, let's just use this to create an empty, contiguous
5754
 
           array of a specific type and shape.
5755
 
        */
5756
 
 
5757
 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&LO&O&",
5758
 
                                         kwlist, PyArray_IntpConverter,
5759
 
                                         &dims,
5760
 
                                         PyArray_DescrConverter,
5761
 
                                         &descr,
5762
 
                                         PyArray_BufferConverter,
5763
 
                                         &buffer,
5764
 
                                         &offset,
5765
 
                                         &PyArray_IntpConverter,
5766
 
                                         &strides,
5767
 
                                         &PyArray_OrderConverter,
5768
 
                                         &order))
5769
 
                goto fail;
5770
 
 
5771
 
        if (order == PyArray_FORTRANORDER) fortran = 1;
5772
 
 
5773
 
        if (descr == NULL)
5774
 
                descr = PyArray_DescrFromType(PyArray_DEFAULT);
5775
 
 
5776
 
        itemsize = descr->elsize;
5777
 
 
5778
 
        if (itemsize == 0) {
5779
 
                PyErr_SetString(PyExc_ValueError,
5780
 
                                "data-type with unspecified variable length");
5781
 
                goto fail;
5782
 
        }
5783
 
 
5784
 
        if (strides.ptr != NULL) {
5785
 
                intp nb, off;
5786
 
                if (strides.len != dims.len) {
5787
 
                        PyErr_SetString(PyExc_ValueError,
5788
 
                                        "strides, if given, must be "   \
5789
 
                                        "the same length as shape");
5790
 
                        goto fail;
5791
 
                }
5792
 
 
5793
 
                if (buffer.ptr == NULL) {
5794
 
                        nb = 0;
5795
 
                        off = 0;
5796
 
                }
5797
 
                else {
5798
 
                        nb = buffer.len;
5799
 
                        off = (intp) offset;
5800
 
                }
5801
 
 
5802
 
 
5803
 
                if (!PyArray_CheckStrides(itemsize, dims.len,
5804
 
                                          nb, off,
5805
 
                                          dims.ptr, strides.ptr)) {
5806
 
                        PyErr_SetString(PyExc_ValueError,
5807
 
                                        "strides is incompatible "      \
5808
 
                                        "with shape of requested "      \
5809
 
                                        "array and size of buffer");
5810
 
                        goto fail;
5811
 
                }
 
5987
    static char *kwlist[] = {"shape", "dtype", "buffer",
 
5988
                             "offset", "strides",
 
5989
                             "order", NULL};
 
5990
    PyArray_Descr *descr=NULL;
 
5991
    int itemsize;
 
5992
    PyArray_Dims dims = {NULL, 0};
 
5993
    PyArray_Dims strides = {NULL, 0};
 
5994
    PyArray_Chunk buffer;
 
5995
    longlong offset=0;
 
5996
    NPY_ORDER order=PyArray_CORDER;
 
5997
    int fortran = 0;
 
5998
    PyArrayObject *ret;
 
5999
 
 
6000
    buffer.ptr = NULL;
 
6001
    /* Usually called with shape and type
 
6002
       but can also be called with buffer, strides, and swapped info
 
6003
    */
 
6004
 
 
6005
    /* For now, let's just use this to create an empty, contiguous
 
6006
       array of a specific type and shape.
 
6007
    */
 
6008
 
 
6009
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&LO&O&",
 
6010
                                     kwlist, PyArray_IntpConverter,
 
6011
                                     &dims,
 
6012
                                     PyArray_DescrConverter,
 
6013
                                     &descr,
 
6014
                                     PyArray_BufferConverter,
 
6015
                                     &buffer,
 
6016
                                     &offset,
 
6017
                                     &PyArray_IntpConverter,
 
6018
                                     &strides,
 
6019
                                     &PyArray_OrderConverter,
 
6020
                                     &order))
 
6021
        goto fail;
 
6022
 
 
6023
    if (order == PyArray_FORTRANORDER) fortran = 1;
 
6024
 
 
6025
    if (descr == NULL)
 
6026
        descr = PyArray_DescrFromType(PyArray_DEFAULT);
 
6027
 
 
6028
    itemsize = descr->elsize;
 
6029
 
 
6030
    if (itemsize == 0) {
 
6031
        PyErr_SetString(PyExc_ValueError,
 
6032
                        "data-type with unspecified variable length");
 
6033
        goto fail;
 
6034
    }
 
6035
 
 
6036
    if (strides.ptr != NULL) {
 
6037
        intp nb, off;
 
6038
        if (strides.len != dims.len) {
 
6039
            PyErr_SetString(PyExc_ValueError,
 
6040
                            "strides, if given, must be "   \
 
6041
                            "the same length as shape");
 
6042
            goto fail;
5812
6043
        }
5813
6044
 
5814
6045
        if (buffer.ptr == NULL) {
5815
 
                ret = (PyArrayObject *)                         \
5816
 
                        PyArray_NewFromDescr(subtype, descr,
5817
 
                                             (int)dims.len,
5818
 
                                             dims.ptr,
5819
 
                                             strides.ptr, NULL, fortran, NULL);
5820
 
                if (ret == NULL) {descr=NULL;goto fail;}
5821
 
                if (PyDataType_FLAGCHK(descr, NPY_ITEM_HASOBJECT)) { 
5822
 
                        /* place Py_None in object positions */
5823
 
                        PyArray_FillObjectArray(ret, Py_None);
5824
 
                        if (PyErr_Occurred()) {
5825
 
                                descr=NULL;
5826
 
                                goto fail;
5827
 
                        }
5828
 
                }
5829
 
        }
5830
 
        else {  /* buffer given -- use it */
5831
 
                if (dims.len == 1 && dims.ptr[0] == -1) {
5832
 
                        dims.ptr[0] = (buffer.len-(intp)offset) / itemsize;
5833
 
                }
5834
 
                else if ((strides.ptr == NULL) && \
5835
 
                         (buffer.len < ((intp)itemsize)*                \
5836
 
                          PyArray_MultiplyList(dims.ptr, dims.len))) {
5837
 
                        PyErr_SetString(PyExc_TypeError,
5838
 
                                        "buffer is too small for "      \
5839
 
                                        "requested array");
5840
 
                        goto fail;
5841
 
                }
5842
 
                /* get writeable and aligned */
5843
 
                if (fortran) buffer.flags |= FORTRAN;
5844
 
                ret = (PyArrayObject *)\
5845
 
                        PyArray_NewFromDescr(subtype, descr,
5846
 
                                             dims.len, dims.ptr,
5847
 
                                             strides.ptr,
5848
 
                                             offset + (char *)buffer.ptr,
5849
 
                                             buffer.flags, NULL);
5850
 
                if (ret == NULL) {descr=NULL; goto fail;}
5851
 
                PyArray_UpdateFlags(ret, UPDATE_ALL);
5852
 
                ret->base = buffer.base;
5853
 
                Py_INCREF(buffer.base);
5854
 
        }
5855
 
 
5856
 
        PyDimMem_FREE(dims.ptr);
5857
 
        if (strides.ptr) PyDimMem_FREE(strides.ptr);
5858
 
        return (PyObject *)ret;
 
6046
            nb = 0;
 
6047
            off = 0;
 
6048
        }
 
6049
        else {
 
6050
            nb = buffer.len;
 
6051
            off = (intp) offset;
 
6052
        }
 
6053
 
 
6054
 
 
6055
        if (!PyArray_CheckStrides(itemsize, dims.len,
 
6056
                                  nb, off,
 
6057
                                  dims.ptr, strides.ptr)) {
 
6058
            PyErr_SetString(PyExc_ValueError,
 
6059
                            "strides is incompatible "      \
 
6060
                            "with shape of requested "      \
 
6061
                            "array and size of buffer");
 
6062
            goto fail;
 
6063
        }
 
6064
    }
 
6065
 
 
6066
    if (buffer.ptr == NULL) {
 
6067
        ret = (PyArrayObject *)                         \
 
6068
            PyArray_NewFromDescr(subtype, descr,
 
6069
                                 (int)dims.len,
 
6070
                                 dims.ptr,
 
6071
                                 strides.ptr, NULL, fortran, NULL);
 
6072
        if (ret == NULL) {descr=NULL;goto fail;}
 
6073
        if (PyDataType_FLAGCHK(descr, NPY_ITEM_HASOBJECT)) {
 
6074
            /* place Py_None in object positions */
 
6075
            PyArray_FillObjectArray(ret, Py_None);
 
6076
            if (PyErr_Occurred()) {
 
6077
                descr=NULL;
 
6078
                goto fail;
 
6079
            }
 
6080
        }
 
6081
    }
 
6082
    else {  /* buffer given -- use it */
 
6083
        if (dims.len == 1 && dims.ptr[0] == -1) {
 
6084
            dims.ptr[0] = (buffer.len-(intp)offset) / itemsize;
 
6085
        }
 
6086
        else if ((strides.ptr == NULL) && \
 
6087
                 (buffer.len < ((intp)itemsize)*                \
 
6088
                  PyArray_MultiplyList(dims.ptr, dims.len))) {
 
6089
            PyErr_SetString(PyExc_TypeError,
 
6090
                            "buffer is too small for "      \
 
6091
                            "requested array");
 
6092
            goto fail;
 
6093
        }
 
6094
        /* get writeable and aligned */
 
6095
        if (fortran) buffer.flags |= FORTRAN;
 
6096
        ret = (PyArrayObject *)\
 
6097
            PyArray_NewFromDescr(subtype, descr,
 
6098
                                 dims.len, dims.ptr,
 
6099
                                 strides.ptr,
 
6100
                                 offset + (char *)buffer.ptr,
 
6101
                                 buffer.flags, NULL);
 
6102
        if (ret == NULL) {descr=NULL; goto fail;}
 
6103
        PyArray_UpdateFlags(ret, UPDATE_ALL);
 
6104
        ret->base = buffer.base;
 
6105
        Py_INCREF(buffer.base);
 
6106
    }
 
6107
 
 
6108
    PyDimMem_FREE(dims.ptr);
 
6109
    if (strides.ptr) PyDimMem_FREE(strides.ptr);
 
6110
    return (PyObject *)ret;
5859
6111
 
5860
6112
 fail:
5861
 
        Py_XDECREF(descr);
5862
 
        if (dims.ptr) PyDimMem_FREE(dims.ptr);
5863
 
        if (strides.ptr) PyDimMem_FREE(strides.ptr);
5864
 
        return NULL;
 
6113
    Py_XDECREF(descr);
 
6114
    if (dims.ptr) PyDimMem_FREE(dims.ptr);
 
6115
    if (strides.ptr) PyDimMem_FREE(strides.ptr);
 
6116
    return NULL;
5865
6117
}
5866
6118
 
5867
6119
 
5868
6120
static PyObject *
5869
6121
array_iter(PyArrayObject *arr)
5870
6122
{
5871
 
        if (arr->nd == 0) {
5872
 
                PyErr_SetString(PyExc_TypeError,
5873
 
                                "iteration over a 0-d array");
5874
 
                return NULL;
5875
 
        }
5876
 
        return PySeqIter_New((PyObject *)arr);
 
6123
    if (arr->nd == 0) {
 
6124
        PyErr_SetString(PyExc_TypeError,
 
6125
                        "iteration over a 0-d array");
 
6126
        return NULL;
 
6127
    }
 
6128
    return PySeqIter_New((PyObject *)arr);
5877
6129
}
5878
6130
 
5879
6131
 
5882
6134
static PyObject *
5883
6135
array_ndim_get(PyArrayObject *self)
5884
6136
{
5885
 
        return PyInt_FromLong(self->nd);
 
6137
    return PyInt_FromLong(self->nd);
5886
6138
}
5887
6139
 
5888
6140
static PyObject *
5889
6141
array_flags_get(PyArrayObject *self)
5890
6142
{
5891
 
        return PyArray_NewFlagsObject((PyObject *)self);
 
6143
    return PyArray_NewFlagsObject((PyObject *)self);
5892
6144
}
5893
6145
 
5894
6146
static PyObject *
5895
6147
array_shape_get(PyArrayObject *self)
5896
6148
{
5897
 
        return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
 
6149
    return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
5898
6150
}
5899
6151
 
5900
6152
 
5901
6153
static int
5902
6154
array_shape_set(PyArrayObject *self, PyObject *val)
5903
6155
{
5904
 
        int nd;
5905
 
        PyObject *ret;
5906
 
 
5907
 
        /* Assumes C-order */
5908
 
        ret = PyArray_Reshape(self, val);
5909
 
        if (ret == NULL) return -1;
5910
 
        if (PyArray_DATA(ret) != PyArray_DATA(self)) {
5911
 
                Py_DECREF(ret);
5912
 
                PyErr_SetString(PyExc_AttributeError,
5913
 
                                "incompatible shape for a non-contiguous "\
5914
 
                                "array");
5915
 
                return -1;
5916
 
        }
5917
 
 
5918
 
        /* Free old dimensions and strides */
5919
 
        PyDimMem_FREE(self->dimensions);
5920
 
        nd = PyArray_NDIM(ret);
5921
 
        self->nd = nd;
5922
 
        if (nd > 0) {  /* create new dimensions and strides */
5923
 
                self->dimensions = PyDimMem_NEW(2*nd);
5924
 
                if (self->dimensions == NULL) {
5925
 
                        Py_DECREF(ret);
5926
 
                        PyErr_SetString(PyExc_MemoryError,"");
5927
 
                        return -1;
5928
 
                }
5929
 
                self->strides = self->dimensions + nd;
5930
 
                memcpy(self->dimensions, PyArray_DIMS(ret),
5931
 
                       nd*sizeof(intp));
5932
 
                memcpy(self->strides, PyArray_STRIDES(ret),
5933
 
                       nd*sizeof(intp));
5934
 
        }
5935
 
        else {self->dimensions=NULL; self->strides=NULL;}
 
6156
    int nd;
 
6157
    PyObject *ret;
 
6158
 
 
6159
    /* Assumes C-order */
 
6160
    ret = PyArray_Reshape(self, val);
 
6161
    if (ret == NULL) return -1;
 
6162
    if (PyArray_DATA(ret) != PyArray_DATA(self)) {
5936
6163
        Py_DECREF(ret);
5937
 
        PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
5938
 
        return 0;
 
6164
        PyErr_SetString(PyExc_AttributeError,
 
6165
                        "incompatible shape for a non-contiguous "\
 
6166
                        "array");
 
6167
        return -1;
 
6168
    }
 
6169
 
 
6170
    /* Free old dimensions and strides */
 
6171
    PyDimMem_FREE(self->dimensions);
 
6172
    nd = PyArray_NDIM(ret);
 
6173
    self->nd = nd;
 
6174
    if (nd > 0) {  /* create new dimensions and strides */
 
6175
        self->dimensions = PyDimMem_NEW(2*nd);
 
6176
        if (self->dimensions == NULL) {
 
6177
            Py_DECREF(ret);
 
6178
            PyErr_SetString(PyExc_MemoryError,"");
 
6179
            return -1;
 
6180
        }
 
6181
        self->strides = self->dimensions + nd;
 
6182
        memcpy(self->dimensions, PyArray_DIMS(ret),
 
6183
               nd*sizeof(intp));
 
6184
        memcpy(self->strides, PyArray_STRIDES(ret),
 
6185
               nd*sizeof(intp));
 
6186
    }
 
6187
    else {self->dimensions=NULL; self->strides=NULL;}
 
6188
    Py_DECREF(ret);
 
6189
    PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
 
6190
    return 0;
5939
6191
}
5940
6192
 
5941
6193
 
5942
6194
static PyObject *
5943
6195
array_strides_get(PyArrayObject *self)
5944
6196
{
5945
 
        return PyArray_IntTupleFromIntp(self->nd, self->strides);
 
6197
    return PyArray_IntTupleFromIntp(self->nd, self->strides);
5946
6198
}
5947
6199
 
5948
6200
static int
5949
6201
array_strides_set(PyArrayObject *self, PyObject *obj)
5950
6202
{
5951
 
        PyArray_Dims newstrides = {NULL, 0};
5952
 
        PyArrayObject *new;
5953
 
        intp numbytes=0;
5954
 
        intp offset=0;
5955
 
        Py_ssize_t buf_len;
5956
 
        char *buf;
5957
 
 
5958
 
        if (!PyArray_IntpConverter(obj, &newstrides) || \
5959
 
            newstrides.ptr == NULL) {
5960
 
                PyErr_SetString(PyExc_TypeError, "invalid strides");
5961
 
                return -1;
5962
 
        }
5963
 
        if (newstrides.len != self->nd) {
5964
 
                PyErr_Format(PyExc_ValueError, "strides must be "       \
5965
 
                             " same length as shape (%d)", self->nd);
5966
 
                goto fail;
5967
 
        }
5968
 
        new = self;
5969
 
        while(new->base && PyArray_Check(new->base)) {
5970
 
                new = (PyArrayObject *)(new->base);
5971
 
        }
5972
 
        /* Get the available memory through the buffer
5973
 
           interface on new->base or if that fails
5974
 
           from the current new */
5975
 
        if (new->base && PyObject_AsReadBuffer(new->base,
5976
 
                                               (const void **)&buf,
5977
 
                                               &buf_len) >= 0) {
5978
 
                offset = self->data - buf;
5979
 
                numbytes = buf_len + offset;
5980
 
        }
5981
 
        else {
5982
 
                PyErr_Clear();
5983
 
                numbytes = PyArray_MultiplyList(new->dimensions,
5984
 
                                                new->nd)*new->descr->elsize;
5985
 
                offset = self->data - new->data;
5986
 
        }
5987
 
 
5988
 
        if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes,
5989
 
                                  offset,
5990
 
                                  self->dimensions, newstrides.ptr)) {
5991
 
                PyErr_SetString(PyExc_ValueError, "strides is not "\
5992
 
                                "compatible with available memory");
5993
 
                goto fail;
5994
 
        }
5995
 
        memcpy(self->strides, newstrides.ptr, sizeof(intp)*newstrides.len);
5996
 
        PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
5997
 
        PyDimMem_FREE(newstrides.ptr);
5998
 
        return 0;
 
6203
    PyArray_Dims newstrides = {NULL, 0};
 
6204
    PyArrayObject *new;
 
6205
    intp numbytes=0;
 
6206
    intp offset=0;
 
6207
    Py_ssize_t buf_len;
 
6208
    char *buf;
 
6209
 
 
6210
    if (!PyArray_IntpConverter(obj, &newstrides) || \
 
6211
        newstrides.ptr == NULL) {
 
6212
        PyErr_SetString(PyExc_TypeError, "invalid strides");
 
6213
        return -1;
 
6214
    }
 
6215
    if (newstrides.len != self->nd) {
 
6216
        PyErr_Format(PyExc_ValueError, "strides must be "       \
 
6217
                     " same length as shape (%d)", self->nd);
 
6218
        goto fail;
 
6219
    }
 
6220
    new = self;
 
6221
    while(new->base && PyArray_Check(new->base)) {
 
6222
        new = (PyArrayObject *)(new->base);
 
6223
    }
 
6224
    /* Get the available memory through the buffer
 
6225
       interface on new->base or if that fails
 
6226
       from the current new */
 
6227
    if (new->base && PyObject_AsReadBuffer(new->base,
 
6228
                                           (const void **)&buf,
 
6229
                                           &buf_len) >= 0) {
 
6230
        offset = self->data - buf;
 
6231
        numbytes = buf_len + offset;
 
6232
    }
 
6233
    else {
 
6234
        PyErr_Clear();
 
6235
        numbytes = PyArray_MultiplyList(new->dimensions,
 
6236
                                        new->nd)*new->descr->elsize;
 
6237
        offset = self->data - new->data;
 
6238
    }
 
6239
 
 
6240
    if (!PyArray_CheckStrides(self->descr->elsize, self->nd, numbytes,
 
6241
                              offset,
 
6242
                              self->dimensions, newstrides.ptr)) {
 
6243
        PyErr_SetString(PyExc_ValueError, "strides is not "\
 
6244
                        "compatible with available memory");
 
6245
        goto fail;
 
6246
    }
 
6247
    memcpy(self->strides, newstrides.ptr, sizeof(intp)*newstrides.len);
 
6248
    PyArray_UpdateFlags(self, CONTIGUOUS | FORTRAN);
 
6249
    PyDimMem_FREE(newstrides.ptr);
 
6250
    return 0;
5999
6251
 
6000
6252
 fail:
6001
 
        PyDimMem_FREE(newstrides.ptr);
6002
 
        return -1;
 
6253
    PyDimMem_FREE(newstrides.ptr);
 
6254
    return -1;
6003
6255
}
6004
6256
 
6005
6257
 
6007
6259
static PyObject *
6008
6260
array_priority_get(PyArrayObject *self)
6009
6261
{
6010
 
        if (PyArray_CheckExact(self))
6011
 
                return PyFloat_FromDouble(PyArray_PRIORITY);
6012
 
        else
6013
 
                return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY);
 
6262
    if (PyArray_CheckExact(self))
 
6263
        return PyFloat_FromDouble(PyArray_PRIORITY);
 
6264
    else
 
6265
        return PyFloat_FromDouble(PyArray_SUBTYPE_PRIORITY);
6014
6266
}
6015
6267
 
6016
6268
static PyObject *arraydescr_protocol_typestr_get(PyArray_Descr *);
6018
6270
static PyObject *
6019
6271
array_typestr_get(PyArrayObject *self)
6020
6272
{
6021
 
        return arraydescr_protocol_typestr_get(self->descr);
 
6273
    return arraydescr_protocol_typestr_get(self->descr);
6022
6274
}
6023
6275
 
6024
6276
static PyObject *
6025
6277
array_descr_get(PyArrayObject *self)
6026
6278
{
6027
 
        Py_INCREF(self->descr);
6028
 
        return (PyObject *)self->descr;
 
6279
    Py_INCREF(self->descr);
 
6280
    return (PyObject *)self->descr;
6029
6281
}
6030
6282
 
6031
6283
static PyObject *arraydescr_protocol_descr_get(PyArray_Descr *self);
6033
6285
static PyObject *
6034
6286
array_protocol_descr_get(PyArrayObject *self)
6035
6287
{
6036
 
        PyObject *res;
6037
 
        PyObject *dobj;
6038
 
 
6039
 
        res = arraydescr_protocol_descr_get(self->descr);
6040
 
        if (res) return res;
6041
 
        PyErr_Clear();
6042
 
 
6043
 
        /* get default */
6044
 
        dobj = PyTuple_New(2);
6045
 
        if (dobj == NULL) return NULL;
6046
 
        PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
6047
 
        PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self));
6048
 
        res = PyList_New(1);
6049
 
        if (res == NULL) {Py_DECREF(dobj); return NULL;}
6050
 
        PyList_SET_ITEM(res, 0, dobj);
6051
 
        return res;
 
6288
    PyObject *res;
 
6289
    PyObject *dobj;
 
6290
 
 
6291
    res = arraydescr_protocol_descr_get(self->descr);
 
6292
    if (res) return res;
 
6293
    PyErr_Clear();
 
6294
 
 
6295
    /* get default */
 
6296
    dobj = PyTuple_New(2);
 
6297
    if (dobj == NULL) return NULL;
 
6298
    PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
 
6299
    PyTuple_SET_ITEM(dobj, 1, array_typestr_get(self));
 
6300
    res = PyList_New(1);
 
6301
    if (res == NULL) {Py_DECREF(dobj); return NULL;}
 
6302
    PyList_SET_ITEM(res, 0, dobj);
 
6303
    return res;
6052
6304
}
6053
6305
 
6054
6306
static PyObject *
6055
6307
array_protocol_strides_get(PyArrayObject *self)
6056
6308
{
6057
 
        if PyArray_ISCONTIGUOUS(self) {
6058
 
                Py_INCREF(Py_None);
6059
 
                return Py_None;
 
6309
    if PyArray_ISCONTIGUOUS(self) {
 
6310
            Py_INCREF(Py_None);
 
6311
            return Py_None;
6060
6312
        }
6061
 
        return PyArray_IntTupleFromIntp(self->nd, self->strides);
 
6313
    return PyArray_IntTupleFromIntp(self->nd, self->strides);
6062
6314
}
6063
6315
 
6064
6316
 
6066
6318
static PyObject *
6067
6319
array_dataptr_get(PyArrayObject *self)
6068
6320
{
6069
 
        return Py_BuildValue("NO",
6070
 
                             PyLong_FromVoidPtr(self->data),
6071
 
                             (self->flags & WRITEABLE ? Py_False :
6072
 
                             Py_True));
 
6321
    return Py_BuildValue("NO",
 
6322
                         PyLong_FromVoidPtr(self->data),
 
6323
                         (self->flags & WRITEABLE ? Py_False :
 
6324
                          Py_True));
6073
6325
}
6074
6326
 
6075
6327
static PyObject *
6076
6328
array_ctypes_get(PyArrayObject *self)
6077
6329
{
6078
 
        return PyObject_CallMethod(_numpy_internal, "_ctypes",
6079
 
                                   "ON", self,
6080
 
                                   PyLong_FromVoidPtr(self->data));
 
6330
    PyObject *_numpy_internal;
 
6331
    PyObject *ret;
 
6332
    _numpy_internal = PyImport_ImportModule("numpy.core._internal");
 
6333
    if (_numpy_internal == NULL) return NULL;
 
6334
    ret = PyObject_CallMethod(_numpy_internal, "_ctypes",
 
6335
                              "ON", self,
 
6336
                              PyLong_FromVoidPtr(self->data));
 
6337
    Py_DECREF(_numpy_internal);
 
6338
    return ret;
6081
6339
}
6082
6340
 
6083
6341
static PyObject *
6084
6342
array_interface_get(PyArrayObject *self)
6085
6343
{
6086
 
        PyObject *dict;
6087
 
        PyObject *obj;
6088
 
        dict = PyDict_New();
6089
 
        if (dict == NULL) return NULL;
6090
 
 
6091
 
        /* dataptr */
6092
 
        obj = array_dataptr_get(self);
6093
 
        PyDict_SetItemString(dict, "data", obj);
6094
 
        Py_DECREF(obj);
6095
 
 
6096
 
        obj = array_protocol_strides_get(self);
6097
 
        PyDict_SetItemString(dict, "strides", obj);
6098
 
        Py_DECREF(obj);
6099
 
 
6100
 
        obj = array_protocol_descr_get(self);
6101
 
        PyDict_SetItemString(dict, "descr", obj);
6102
 
        Py_DECREF(obj);
6103
 
 
6104
 
        obj = arraydescr_protocol_typestr_get(self->descr);
6105
 
        PyDict_SetItemString(dict, "typestr", obj);
6106
 
        Py_DECREF(obj);
6107
 
 
6108
 
        obj = array_shape_get(self);
6109
 
        PyDict_SetItemString(dict, "shape", obj);
6110
 
        Py_DECREF(obj);
6111
 
 
6112
 
        obj = PyInt_FromLong(3);
6113
 
        PyDict_SetItemString(dict, "version", obj);
6114
 
        Py_DECREF(obj);
6115
 
 
6116
 
        return dict;
 
6344
    PyObject *dict;
 
6345
    PyObject *obj;
 
6346
    dict = PyDict_New();
 
6347
    if (dict == NULL) return NULL;
 
6348
 
 
6349
    /* dataptr */
 
6350
    obj = array_dataptr_get(self);
 
6351
    PyDict_SetItemString(dict, "data", obj);
 
6352
    Py_DECREF(obj);
 
6353
 
 
6354
    obj = array_protocol_strides_get(self);
 
6355
    PyDict_SetItemString(dict, "strides", obj);
 
6356
    Py_DECREF(obj);
 
6357
 
 
6358
    obj = array_protocol_descr_get(self);
 
6359
    PyDict_SetItemString(dict, "descr", obj);
 
6360
    Py_DECREF(obj);
 
6361
 
 
6362
    obj = arraydescr_protocol_typestr_get(self->descr);
 
6363
    PyDict_SetItemString(dict, "typestr", obj);
 
6364
    Py_DECREF(obj);
 
6365
 
 
6366
    obj = array_shape_get(self);
 
6367
    PyDict_SetItemString(dict, "shape", obj);
 
6368
    Py_DECREF(obj);
 
6369
 
 
6370
    obj = PyInt_FromLong(3);
 
6371
    PyDict_SetItemString(dict, "version", obj);
 
6372
    Py_DECREF(obj);
 
6373
 
 
6374
    return dict;
6117
6375
}
6118
6376
 
6119
6377
static PyObject *
6120
6378
array_data_get(PyArrayObject *self)
6121
6379
{
6122
 
        intp nbytes;
6123
 
        if (!(PyArray_ISONESEGMENT(self))) {
6124
 
                PyErr_SetString(PyExc_AttributeError, "cannot get single-"\
6125
 
                                "segment buffer for discontiguous array");
6126
 
                return NULL;
6127
 
        }
6128
 
        nbytes = PyArray_NBYTES(self);
6129
 
        if PyArray_ISWRITEABLE(self)
6130
 
                return PyBuffer_FromReadWriteObject((PyObject *)self, 0,
6131
 
                                                    (int) nbytes);
6132
 
        else
6133
 
                return PyBuffer_FromObject((PyObject *)self, 0, (int) nbytes);
 
6380
    intp nbytes;
 
6381
    if (!(PyArray_ISONESEGMENT(self))) {
 
6382
        PyErr_SetString(PyExc_AttributeError, "cannot get single-"\
 
6383
                        "segment buffer for discontiguous array");
 
6384
        return NULL;
 
6385
    }
 
6386
    nbytes = PyArray_NBYTES(self);
 
6387
    if PyArray_ISWRITEABLE(self)
 
6388
                              return PyBuffer_FromReadWriteObject((PyObject *)self, 0,
 
6389
                                                                  (int) nbytes);
 
6390
    else
 
6391
        return PyBuffer_FromObject((PyObject *)self, 0, (int) nbytes);
6134
6392
}
6135
6393
 
6136
6394
static int
6137
6395
array_data_set(PyArrayObject *self, PyObject *op)
6138
6396
{
6139
 
        void *buf;
6140
 
        Py_ssize_t buf_len;
6141
 
        int writeable=1;
 
6397
    void *buf;
 
6398
    Py_ssize_t buf_len;
 
6399
    int writeable=1;
6142
6400
 
6143
 
        if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) {
6144
 
                writeable = 0;
6145
 
                if (PyObject_AsReadBuffer(op, (const void **)&buf,
6146
 
                                          &buf_len) < 0) {
6147
 
                        PyErr_SetString(PyExc_AttributeError,
6148
 
                                        "object does not have single-segment " \
6149
 
                                        "buffer interface");
6150
 
                        return -1;
6151
 
                }
6152
 
        }
6153
 
        if (!PyArray_ISONESEGMENT(self)) {
6154
 
                PyErr_SetString(PyExc_AttributeError, "cannot set single-" \
6155
 
                                "segment buffer for discontiguous array");
6156
 
                return -1;
6157
 
        }
6158
 
        if (PyArray_NBYTES(self) > buf_len) {
6159
 
                PyErr_SetString(PyExc_AttributeError,
6160
 
                                "not enough data for array");
6161
 
                return -1;
6162
 
        }
6163
 
        if (self->flags & OWNDATA) {
6164
 
                PyArray_XDECREF(self);
6165
 
                PyDataMem_FREE(self->data);
6166
 
        }
6167
 
        if (self->base) {
6168
 
                if (self->flags & UPDATEIFCOPY) {
6169
 
                        ((PyArrayObject *)self->base)->flags |= WRITEABLE;
6170
 
                        self->flags &= ~UPDATEIFCOPY;
6171
 
                }
6172
 
                Py_DECREF(self->base);
6173
 
        }
6174
 
        Py_INCREF(op);
6175
 
        self->base = op;
6176
 
        self->data = buf;
6177
 
        self->flags = CARRAY;
6178
 
        if (!writeable)
6179
 
                self->flags &= ~WRITEABLE;
6180
 
        return 0;
 
6401
    if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) {
 
6402
        writeable = 0;
 
6403
        if (PyObject_AsReadBuffer(op, (const void **)&buf,
 
6404
                                  &buf_len) < 0) {
 
6405
            PyErr_SetString(PyExc_AttributeError,
 
6406
                            "object does not have single-segment " \
 
6407
                            "buffer interface");
 
6408
            return -1;
 
6409
        }
 
6410
    }
 
6411
    if (!PyArray_ISONESEGMENT(self)) {
 
6412
        PyErr_SetString(PyExc_AttributeError, "cannot set single-" \
 
6413
                        "segment buffer for discontiguous array");
 
6414
        return -1;
 
6415
    }
 
6416
    if (PyArray_NBYTES(self) > buf_len) {
 
6417
        PyErr_SetString(PyExc_AttributeError,
 
6418
                        "not enough data for array");
 
6419
        return -1;
 
6420
    }
 
6421
    if (self->flags & OWNDATA) {
 
6422
        PyArray_XDECREF(self);
 
6423
        PyDataMem_FREE(self->data);
 
6424
    }
 
6425
    if (self->base) {
 
6426
        if (self->flags & UPDATEIFCOPY) {
 
6427
            ((PyArrayObject *)self->base)->flags |= WRITEABLE;
 
6428
            self->flags &= ~UPDATEIFCOPY;
 
6429
        }
 
6430
        Py_DECREF(self->base);
 
6431
    }
 
6432
    Py_INCREF(op);
 
6433
    self->base = op;
 
6434
    self->data = buf;
 
6435
    self->flags = CARRAY;
 
6436
    if (!writeable)
 
6437
        self->flags &= ~WRITEABLE;
 
6438
    return 0;
6181
6439
}
6182
6440
 
6183
6441
 
6184
6442
static PyObject *
6185
6443
array_itemsize_get(PyArrayObject *self)
6186
6444
{
6187
 
        return PyInt_FromLong((long) self->descr->elsize);
 
6445
    return PyInt_FromLong((long) self->descr->elsize);
6188
6446
}
6189
6447
 
6190
6448
static PyObject *
6191
6449
array_size_get(PyArrayObject *self)
6192
6450
{
6193
 
        intp size=PyArray_SIZE(self);
 
6451
    intp size=PyArray_SIZE(self);
6194
6452
#if SIZEOF_INTP <= SIZEOF_LONG
 
6453
    return PyInt_FromLong((long) size);
 
6454
#else
 
6455
    if (size > MAX_LONG || size < MIN_LONG)
 
6456
        return PyLong_FromLongLong(size);
 
6457
    else
6195
6458
        return PyInt_FromLong((long) size);
6196
 
#else
6197
 
        if (size > MAX_LONG || size < MIN_LONG)
6198
 
                return PyLong_FromLongLong(size);
6199
 
        else
6200
 
                return PyInt_FromLong((long) size);
6201
6459
#endif
6202
6460
}
6203
6461
 
6204
6462
static PyObject *
6205
6463
array_nbytes_get(PyArrayObject *self)
6206
6464
{
6207
 
        intp nbytes = PyArray_NBYTES(self);
 
6465
    intp nbytes = PyArray_NBYTES(self);
6208
6466
#if SIZEOF_INTP <= SIZEOF_LONG
 
6467
    return PyInt_FromLong((long) nbytes);
 
6468
#else
 
6469
    if (nbytes > MAX_LONG || nbytes < MIN_LONG)
 
6470
        return PyLong_FromLongLong(nbytes);
 
6471
    else
6209
6472
        return PyInt_FromLong((long) nbytes);
6210
 
#else
6211
 
        if (nbytes > MAX_LONG || nbytes < MIN_LONG)
6212
 
                return PyLong_FromLongLong(nbytes);
6213
 
        else
6214
 
                return PyInt_FromLong((long) nbytes);
6215
6473
#endif
6216
6474
}
6217
6475
 
6218
6476
 
6219
6477
/* If the type is changed.
6220
 
    Also needing change: strides, itemsize
6221
 
 
6222
 
    Either itemsize is exactly the same
6223
 
    or the array is single-segment (contiguous or fortran) with
6224
 
    compatibile dimensions
6225
 
 
6226
 
    The shape and strides will be adjusted in that case as well.
 
6478
   Also needing change: strides, itemsize
 
6479
 
 
6480
   Either itemsize is exactly the same
 
6481
   or the array is single-segment (contiguous or fortran) with
 
6482
   compatibile dimensions
 
6483
 
 
6484
   The shape and strides will be adjusted in that case as well.
6227
6485
*/
6228
6486
 
6229
6487
static int
6230
6488
array_descr_set(PyArrayObject *self, PyObject *arg)
6231
6489
{
6232
 
        PyArray_Descr *newtype=NULL;
6233
 
        intp newdim;
6234
 
        int index;
6235
 
        char *msg = "new type not compatible with array.";
6236
 
 
6237
 
        if (!(PyArray_DescrConverter(arg, &newtype)) ||
6238
 
            newtype == NULL) {
6239
 
                PyErr_SetString(PyExc_TypeError, "invalid data-type for array");
6240
 
                return -1;
6241
 
        }
6242
 
        if (PyDataType_FLAGCHK(newtype, NPY_ITEM_HASOBJECT) ||
6243
 
            PyDataType_FLAGCHK(newtype, NPY_ITEM_IS_POINTER) ||
6244
 
            PyDataType_FLAGCHK(self->descr, NPY_ITEM_HASOBJECT) || 
6245
 
            PyDataType_FLAGCHK(self->descr, NPY_ITEM_IS_POINTER)) {
6246
 
                PyErr_SetString(PyExc_TypeError,                      \
6247
 
                                "Cannot change data-type for object " \
6248
 
                                "array.");
6249
 
                Py_DECREF(newtype);
6250
 
                return -1;
6251
 
        }
6252
 
 
6253
 
        if (newtype->elsize == 0) {
6254
 
                PyErr_SetString(PyExc_TypeError,
6255
 
                                "data-type must not be 0-sized");
6256
 
                Py_DECREF(newtype);
6257
 
                return -1;
6258
 
        }
6259
 
 
6260
 
 
6261
 
        if ((newtype->elsize != self->descr->elsize) &&         \
6262
 
            (self->nd == 0 || !PyArray_ISONESEGMENT(self) || \
6263
 
             newtype->subarray)) goto fail;
6264
 
 
6265
 
        if (PyArray_ISCONTIGUOUS(self)) index = self->nd - 1;
6266
 
        else index = 0;
6267
 
 
6268
 
        if (newtype->elsize < self->descr->elsize) {
6269
 
                /* if it is compatible increase the size of the
6270
 
                   dimension at end (or at the front for FORTRAN)
6271
 
                */
6272
 
                if (self->descr->elsize % newtype->elsize != 0)
6273
 
                        goto fail;
6274
 
                newdim = self->descr->elsize / newtype->elsize;
6275
 
                self->dimensions[index] *= newdim;
6276
 
                self->strides[index] = newtype->elsize;
6277
 
        }
6278
 
 
6279
 
        else if (newtype->elsize > self->descr->elsize) {
6280
 
 
6281
 
                /* Determine if last (or first if FORTRAN) dimension
6282
 
                   is compatible */
6283
 
 
6284
 
                newdim = self->dimensions[index] * self->descr->elsize;
6285
 
                if ((newdim % newtype->elsize) != 0) goto fail;
6286
 
 
6287
 
                self->dimensions[index] = newdim / newtype->elsize;
6288
 
                self->strides[index] = newtype->elsize;
6289
 
        }
6290
 
 
6291
 
        /* fall through -- adjust type*/
6292
 
 
6293
 
        Py_DECREF(self->descr);
6294
 
        if (newtype->subarray) {
6295
 
                /* create new array object from data and update
6296
 
                   dimensions, strides and descr from it */
6297
 
                PyArrayObject *temp;
6298
 
 
6299
 
                /* We would decref newtype here --- temp will
6300
 
                   steal a reference to it */
6301
 
                temp = (PyArrayObject *)                                \
6302
 
                        PyArray_NewFromDescr(&PyArray_Type, newtype, self->nd,
6303
 
                                             self->dimensions, self->strides,
6304
 
                                             self->data, self->flags, NULL);
6305
 
                if (temp == NULL) return -1;
6306
 
                PyDimMem_FREE(self->dimensions);
6307
 
                self->dimensions = temp->dimensions;
6308
 
                self->nd = temp->nd;
6309
 
                self->strides = temp->strides;
6310
 
                newtype = temp->descr;
6311
 
                Py_INCREF(temp->descr);
6312
 
                /* Fool deallocator not to delete these*/
6313
 
                temp->nd = 0;
6314
 
                temp->dimensions = NULL;
6315
 
                Py_DECREF(temp);
6316
 
        }
6317
 
 
6318
 
        self->descr = newtype;
6319
 
        PyArray_UpdateFlags(self, UPDATE_ALL);
6320
 
 
6321
 
        return 0;
 
6490
    PyArray_Descr *newtype=NULL;
 
6491
    intp newdim;
 
6492
    int index;
 
6493
    char *msg = "new type not compatible with array.";
 
6494
 
 
6495
    if (!(PyArray_DescrConverter(arg, &newtype)) ||
 
6496
        newtype == NULL) {
 
6497
        PyErr_SetString(PyExc_TypeError, "invalid data-type for array");
 
6498
        return -1;
 
6499
    }
 
6500
    if (PyDataType_FLAGCHK(newtype, NPY_ITEM_HASOBJECT) ||
 
6501
        PyDataType_FLAGCHK(newtype, NPY_ITEM_IS_POINTER) ||
 
6502
        PyDataType_FLAGCHK(self->descr, NPY_ITEM_HASOBJECT) ||
 
6503
        PyDataType_FLAGCHK(self->descr, NPY_ITEM_IS_POINTER)) {
 
6504
        PyErr_SetString(PyExc_TypeError,                      \
 
6505
                        "Cannot change data-type for object " \
 
6506
                        "array.");
 
6507
        Py_DECREF(newtype);
 
6508
        return -1;
 
6509
    }
 
6510
 
 
6511
    if (newtype->elsize == 0) {
 
6512
        PyErr_SetString(PyExc_TypeError,
 
6513
                        "data-type must not be 0-sized");
 
6514
        Py_DECREF(newtype);
 
6515
        return -1;
 
6516
    }
 
6517
 
 
6518
 
 
6519
    if ((newtype->elsize != self->descr->elsize) &&         \
 
6520
        (self->nd == 0 || !PyArray_ISONESEGMENT(self) || \
 
6521
         newtype->subarray)) goto fail;
 
6522
 
 
6523
    if (PyArray_ISCONTIGUOUS(self)) index = self->nd - 1;
 
6524
    else index = 0;
 
6525
 
 
6526
    if (newtype->elsize < self->descr->elsize) {
 
6527
        /* if it is compatible increase the size of the
 
6528
           dimension at end (or at the front for FORTRAN)
 
6529
        */
 
6530
        if (self->descr->elsize % newtype->elsize != 0)
 
6531
            goto fail;
 
6532
        newdim = self->descr->elsize / newtype->elsize;
 
6533
        self->dimensions[index] *= newdim;
 
6534
        self->strides[index] = newtype->elsize;
 
6535
    }
 
6536
 
 
6537
    else if (newtype->elsize > self->descr->elsize) {
 
6538
 
 
6539
        /* Determine if last (or first if FORTRAN) dimension
 
6540
           is compatible */
 
6541
 
 
6542
        newdim = self->dimensions[index] * self->descr->elsize;
 
6543
        if ((newdim % newtype->elsize) != 0) goto fail;
 
6544
 
 
6545
        self->dimensions[index] = newdim / newtype->elsize;
 
6546
        self->strides[index] = newtype->elsize;
 
6547
    }
 
6548
 
 
6549
    /* fall through -- adjust type*/
 
6550
 
 
6551
    Py_DECREF(self->descr);
 
6552
    if (newtype->subarray) {
 
6553
        /* create new array object from data and update
 
6554
           dimensions, strides and descr from it */
 
6555
        PyArrayObject *temp;
 
6556
 
 
6557
        /* We would decref newtype here --- temp will
 
6558
           steal a reference to it */
 
6559
        temp = (PyArrayObject *)                                \
 
6560
            PyArray_NewFromDescr(&PyArray_Type, newtype, self->nd,
 
6561
                                 self->dimensions, self->strides,
 
6562
                                 self->data, self->flags, NULL);
 
6563
        if (temp == NULL) return -1;
 
6564
        PyDimMem_FREE(self->dimensions);
 
6565
        self->dimensions = temp->dimensions;
 
6566
        self->nd = temp->nd;
 
6567
        self->strides = temp->strides;
 
6568
        newtype = temp->descr;
 
6569
        Py_INCREF(temp->descr);
 
6570
        /* Fool deallocator not to delete these*/
 
6571
        temp->nd = 0;
 
6572
        temp->dimensions = NULL;
 
6573
        Py_DECREF(temp);
 
6574
    }
 
6575
 
 
6576
    self->descr = newtype;
 
6577
    PyArray_UpdateFlags(self, UPDATE_ALL);
 
6578
 
 
6579
    return 0;
6322
6580
 
6323
6581
 fail:
6324
 
        PyErr_SetString(PyExc_ValueError, msg);
6325
 
        Py_DECREF(newtype);
6326
 
        return -1;
 
6582
    PyErr_SetString(PyExc_ValueError, msg);
 
6583
    Py_DECREF(newtype);
 
6584
    return -1;
6327
6585
}
6328
6586
 
6329
6587
static PyObject *
6330
6588
array_struct_get(PyArrayObject *self)
6331
6589
{
6332
 
        PyArrayInterface *inter;
 
6590
    PyArrayInterface *inter;
6333
6591
 
6334
 
        inter = (PyArrayInterface *)_pya_malloc(sizeof(PyArrayInterface));
6335
 
        if (inter==NULL) return PyErr_NoMemory();
6336
 
        inter->two = 2;
6337
 
        inter->nd = self->nd;
6338
 
        inter->typekind = self->descr->kind;
6339
 
        inter->itemsize = self->descr->elsize;
6340
 
        inter->flags = self->flags;
6341
 
        /* reset unused flags */
6342
 
        inter->flags &= ~(UPDATEIFCOPY | OWNDATA);
6343
 
        if (PyArray_ISNOTSWAPPED(self)) inter->flags |= NOTSWAPPED;
6344
 
        /* Copy shape and strides over since these can be reset
6345
 
           when the array is "reshaped".
6346
 
        */
6347
 
        if (self->nd > 0) {
6348
 
                inter->shape = (intp *)_pya_malloc(2*sizeof(intp)*self->nd);
6349
 
                if (inter->shape == NULL) {
6350
 
                        _pya_free(inter);
6351
 
                        return PyErr_NoMemory();
6352
 
                }
6353
 
                inter->strides = inter->shape + self->nd;
6354
 
                memcpy(inter->shape, self->dimensions, sizeof(intp)*self->nd);
6355
 
                memcpy(inter->strides, self->strides, sizeof(intp)*self->nd);
6356
 
        }
6357
 
        else {
6358
 
                inter->shape = NULL;
6359
 
                inter->strides = NULL;
6360
 
        }
6361
 
        inter->data = self->data;
6362
 
        if (self->descr->names) {
6363
 
                inter->descr = arraydescr_protocol_descr_get(self->descr);
6364
 
                if (inter->descr == NULL) PyErr_Clear();
6365
 
                else inter->flags &= ARR_HAS_DESCR;
6366
 
        }
6367
 
        else inter->descr = NULL;
6368
 
        Py_INCREF(self);
6369
 
        return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free);
 
6592
    inter = (PyArrayInterface *)_pya_malloc(sizeof(PyArrayInterface));
 
6593
    if (inter==NULL) return PyErr_NoMemory();
 
6594
    inter->two = 2;
 
6595
    inter->nd = self->nd;
 
6596
    inter->typekind = self->descr->kind;
 
6597
    inter->itemsize = self->descr->elsize;
 
6598
    inter->flags = self->flags;
 
6599
    /* reset unused flags */
 
6600
    inter->flags &= ~(UPDATEIFCOPY | OWNDATA);
 
6601
    if (PyArray_ISNOTSWAPPED(self)) inter->flags |= NOTSWAPPED;
 
6602
    /* Copy shape and strides over since these can be reset
 
6603
       when the array is "reshaped".
 
6604
    */
 
6605
    if (self->nd > 0) {
 
6606
        inter->shape = (intp *)_pya_malloc(2*sizeof(intp)*self->nd);
 
6607
        if (inter->shape == NULL) {
 
6608
            _pya_free(inter);
 
6609
            return PyErr_NoMemory();
 
6610
        }
 
6611
        inter->strides = inter->shape + self->nd;
 
6612
        memcpy(inter->shape, self->dimensions, sizeof(intp)*self->nd);
 
6613
        memcpy(inter->strides, self->strides, sizeof(intp)*self->nd);
 
6614
    }
 
6615
    else {
 
6616
        inter->shape = NULL;
 
6617
        inter->strides = NULL;
 
6618
    }
 
6619
    inter->data = self->data;
 
6620
    if (self->descr->names) {
 
6621
        inter->descr = arraydescr_protocol_descr_get(self->descr);
 
6622
        if (inter->descr == NULL) PyErr_Clear();
 
6623
        else inter->flags &= ARR_HAS_DESCR;
 
6624
    }
 
6625
    else inter->descr = NULL;
 
6626
    Py_INCREF(self);
 
6627
    return PyCObject_FromVoidPtrAndDesc(inter, self, gentype_struct_free);
6370
6628
}
6371
6629
 
6372
6630
static PyObject *
6373
6631
array_base_get(PyArrayObject *self)
6374
6632
{
6375
 
        if (self->base == NULL) {
6376
 
                Py_INCREF(Py_None);
6377
 
                return Py_None;
6378
 
        }
6379
 
        else {
6380
 
                Py_INCREF(self->base);
6381
 
                return self->base;
6382
 
        }
 
6633
    if (self->base == NULL) {
 
6634
        Py_INCREF(Py_None);
 
6635
        return Py_None;
 
6636
    }
 
6637
    else {
 
6638
        Py_INCREF(self->base);
 
6639
        return self->base;
 
6640
    }
6383
6641
}
6384
6642
 
6385
6643
/* Create a view of a complex array with an equivalent data-type
6389
6647
static PyArrayObject *
6390
6648
_get_part(PyArrayObject *self, int imag)
6391
6649
{
6392
 
        PyArray_Descr *type;
6393
 
        PyArrayObject *ret;
6394
 
        int offset;
6395
 
 
6396
 
        type = PyArray_DescrFromType(self->descr->type_num -
6397
 
                                     PyArray_NUM_FLOATTYPE);
6398
 
        offset = (imag ? type->elsize : 0);
6399
 
 
6400
 
        if (!PyArray_ISNBO(self->descr->byteorder)) {
6401
 
                PyArray_Descr *new;
6402
 
                new = PyArray_DescrNew(type);
6403
 
                new->byteorder = self->descr->byteorder;
6404
 
                Py_DECREF(type);
6405
 
                type = new;
6406
 
        }
6407
 
        ret = (PyArrayObject *)                                 \
6408
 
                PyArray_NewFromDescr(self->ob_type,
6409
 
                                     type,
6410
 
                                     self->nd,
6411
 
                                     self->dimensions,
6412
 
                                     self->strides,
6413
 
                                     self->data + offset,
6414
 
                                     self->flags, (PyObject *)self);
6415
 
        if (ret == NULL) return NULL;
6416
 
        ret->flags &= ~CONTIGUOUS;
6417
 
        ret->flags &= ~FORTRAN;
6418
 
        Py_INCREF(self);
6419
 
        ret->base = (PyObject *)self;
6420
 
        return ret;
 
6650
    PyArray_Descr *type;
 
6651
    PyArrayObject *ret;
 
6652
    int offset;
 
6653
 
 
6654
    type = PyArray_DescrFromType(self->descr->type_num -
 
6655
                                 PyArray_NUM_FLOATTYPE);
 
6656
    offset = (imag ? type->elsize : 0);
 
6657
 
 
6658
    if (!PyArray_ISNBO(self->descr->byteorder)) {
 
6659
        PyArray_Descr *new;
 
6660
        new = PyArray_DescrNew(type);
 
6661
        new->byteorder = self->descr->byteorder;
 
6662
        Py_DECREF(type);
 
6663
        type = new;
 
6664
    }
 
6665
    ret = (PyArrayObject *)                                 \
 
6666
        PyArray_NewFromDescr(self->ob_type,
 
6667
                             type,
 
6668
                             self->nd,
 
6669
                             self->dimensions,
 
6670
                             self->strides,
 
6671
                             self->data + offset,
 
6672
                             self->flags, (PyObject *)self);
 
6673
    if (ret == NULL) return NULL;
 
6674
    ret->flags &= ~CONTIGUOUS;
 
6675
    ret->flags &= ~FORTRAN;
 
6676
    Py_INCREF(self);
 
6677
    ret->base = (PyObject *)self;
 
6678
    return ret;
6421
6679
}
6422
6680
 
6423
6681
static PyObject *
6424
6682
array_real_get(PyArrayObject *self)
6425
6683
{
6426
 
        PyArrayObject *ret;
 
6684
    PyArrayObject *ret;
6427
6685
 
6428
 
        if (PyArray_ISCOMPLEX(self)) {
6429
 
                ret = _get_part(self, 0);
6430
 
                return (PyObject *)ret;
6431
 
        }
6432
 
        else {
6433
 
                Py_INCREF(self);
6434
 
                return (PyObject *)self;
6435
 
        }
 
6686
    if (PyArray_ISCOMPLEX(self)) {
 
6687
        ret = _get_part(self, 0);
 
6688
        return (PyObject *)ret;
 
6689
    }
 
6690
    else {
 
6691
        Py_INCREF(self);
 
6692
        return (PyObject *)self;
 
6693
    }
6436
6694
}
6437
6695
 
6438
6696
 
6439
6697
static int
6440
6698
array_real_set(PyArrayObject *self, PyObject *val)
6441
6699
{
 
6700
    PyArrayObject *ret;
 
6701
    PyArrayObject *new;
 
6702
    int rint;
 
6703
 
 
6704
    if (PyArray_ISCOMPLEX(self)) {
 
6705
        ret = _get_part(self, 0);
 
6706
        if (ret == NULL) return -1;
 
6707
    }
 
6708
    else {
 
6709
        Py_INCREF(self);
 
6710
        ret = self;
 
6711
    }
 
6712
    new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
 
6713
    if (new == NULL) {Py_DECREF(ret); return -1;}
 
6714
    rint = PyArray_MoveInto(ret, new);
 
6715
    Py_DECREF(ret);
 
6716
    Py_DECREF(new);
 
6717
    return rint;
 
6718
}
 
6719
 
 
6720
static PyObject *
 
6721
array_imag_get(PyArrayObject *self)
 
6722
{
 
6723
    PyArrayObject *ret;
 
6724
    PyArray_Descr *type;
 
6725
 
 
6726
    if (PyArray_ISCOMPLEX(self)) {
 
6727
        ret = _get_part(self, 1);
 
6728
        return (PyObject *) ret;
 
6729
    }
 
6730
    else {
 
6731
        type = self->descr;
 
6732
        Py_INCREF(type);
 
6733
        ret = (PyArrayObject *)PyArray_Zeros(self->nd,
 
6734
                                             self->dimensions,
 
6735
                                             type,
 
6736
                                             PyArray_ISFORTRAN(self));
 
6737
        ret->flags &= ~WRITEABLE;
 
6738
        if (PyArray_CheckExact(self))
 
6739
            return (PyObject *)ret;
 
6740
        else {
 
6741
            PyObject *newret;
 
6742
            newret = PyArray_View(ret, NULL, self->ob_type);
 
6743
            Py_DECREF(ret);
 
6744
            return newret;
 
6745
        }
 
6746
    }
 
6747
}
 
6748
 
 
6749
static int
 
6750
array_imag_set(PyArrayObject *self, PyObject *val)
 
6751
{
 
6752
    if (PyArray_ISCOMPLEX(self)) {
6442
6753
        PyArrayObject *ret;
6443
6754
        PyArrayObject *new;
6444
6755
        int rint;
6445
6756
 
6446
 
        if (PyArray_ISCOMPLEX(self)) {
6447
 
                ret = _get_part(self, 0);
6448
 
                if (ret == NULL) return -1;
6449
 
        }
6450
 
        else {
6451
 
                Py_INCREF(self);
6452
 
                ret = self;
6453
 
        }
 
6757
        ret = _get_part(self, 1);
 
6758
        if (ret == NULL) return -1;
6454
6759
        new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
6455
6760
        if (new == NULL) {Py_DECREF(ret); return -1;}
6456
6761
        rint = PyArray_MoveInto(ret, new);
6457
6762
        Py_DECREF(ret);
6458
6763
        Py_DECREF(new);
6459
6764
        return rint;
6460
 
}
6461
 
 
6462
 
static PyObject *
6463
 
array_imag_get(PyArrayObject *self)
6464
 
{
6465
 
        PyArrayObject *ret;
6466
 
        PyArray_Descr *type;
6467
 
 
6468
 
        if (PyArray_ISCOMPLEX(self)) {
6469
 
                ret = _get_part(self, 1);
6470
 
                return (PyObject *) ret;
6471
 
        }
6472
 
        else {
6473
 
                type = self->descr;
6474
 
                Py_INCREF(type);
6475
 
                ret = (PyArrayObject *)PyArray_Zeros(self->nd,
6476
 
                                                     self->dimensions,
6477
 
                                                     type,
6478
 
                                                     PyArray_ISFORTRAN(self));
6479
 
                ret->flags &= ~WRITEABLE;
6480
 
                if (PyArray_CheckExact(self))
6481
 
                        return (PyObject *)ret;
6482
 
                else {
6483
 
                        PyObject *newret;
6484
 
                        newret = PyArray_View(ret, NULL, self->ob_type);
6485
 
                        Py_DECREF(ret);
6486
 
                        return newret;
6487
 
                }
6488
 
        }
6489
 
}
6490
 
 
6491
 
static int
6492
 
array_imag_set(PyArrayObject *self, PyObject *val)
6493
 
{
6494
 
        if (PyArray_ISCOMPLEX(self)) {
6495
 
                PyArrayObject *ret;
6496
 
                PyArrayObject *new;
6497
 
                int rint;
6498
 
 
6499
 
                ret = _get_part(self, 1);
6500
 
                if (ret == NULL) return -1;
6501
 
                new = (PyArrayObject *)PyArray_FromAny(val, NULL, 0, 0, 0, NULL);
6502
 
                if (new == NULL) {Py_DECREF(ret); return -1;}
6503
 
                rint = PyArray_MoveInto(ret, new);
6504
 
                Py_DECREF(ret);
6505
 
                Py_DECREF(new);
6506
 
                return rint;
6507
 
        }
6508
 
        else {
6509
 
                PyErr_SetString(PyExc_TypeError, "array does not have "\
6510
 
                                "imaginary part to set");
6511
 
                return -1;
6512
 
        }
 
6765
    }
 
6766
    else {
 
6767
        PyErr_SetString(PyExc_TypeError, "array does not have "\
 
6768
                        "imaginary part to set");
 
6769
        return -1;
 
6770
    }
6513
6771
}
6514
6772
 
6515
6773
static PyObject *
6516
6774
array_flat_get(PyArrayObject *self)
6517
6775
{
6518
 
        return PyArray_IterNew((PyObject *)self);
 
6776
    return PyArray_IterNew((PyObject *)self);
6519
6777
}
6520
6778
 
6521
6779
static int
6522
6780
array_flat_set(PyArrayObject *self, PyObject *val)
6523
6781
{
6524
 
        PyObject *arr=NULL;
6525
 
        int retval = -1;
6526
 
        PyArrayIterObject *selfit=NULL, *arrit=NULL;
6527
 
        PyArray_Descr *typecode;
6528
 
        int swap;
6529
 
        PyArray_CopySwapFunc *copyswap;
6530
 
 
6531
 
        typecode = self->descr;
6532
 
        Py_INCREF(typecode);
6533
 
        arr = PyArray_FromAny(val, typecode,
6534
 
                              0, 0, FORCECAST | FORTRAN_IF(self), NULL);
6535
 
        if (arr == NULL) return -1;
6536
 
        arrit = (PyArrayIterObject *)PyArray_IterNew(arr);
6537
 
        if (arrit == NULL) goto exit;
6538
 
        selfit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
6539
 
        if (selfit == NULL) goto exit;
6540
 
 
6541
 
        if (arrit->size == 0) {retval = 0; goto exit;}
6542
 
 
6543
 
        swap = PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(arr);
6544
 
        copyswap = self->descr->f->copyswap;
6545
 
        if (PyDataType_REFCHK(self->descr)) {
6546
 
                while(selfit->index < selfit->size) {
6547
 
                        PyArray_Item_XDECREF(selfit->dataptr, self->descr);
6548
 
                        PyArray_Item_INCREF(arrit->dataptr, PyArray_DESCR(arr));
6549
 
                        memmove(selfit->dataptr, arrit->dataptr,
6550
 
                                sizeof(PyObject **));
6551
 
                        if (swap) 
6552
 
                                copyswap(selfit->dataptr, NULL, swap, self);
6553
 
                        PyArray_ITER_NEXT(selfit);
6554
 
                        PyArray_ITER_NEXT(arrit);
6555
 
                        if (arrit->index == arrit->size)
6556
 
                                PyArray_ITER_RESET(arrit);
6557
 
                }
6558
 
                retval = 0;
6559
 
                goto exit;
6560
 
        }
6561
 
 
 
6782
    PyObject *arr=NULL;
 
6783
    int retval = -1;
 
6784
    PyArrayIterObject *selfit=NULL, *arrit=NULL;
 
6785
    PyArray_Descr *typecode;
 
6786
    int swap;
 
6787
    PyArray_CopySwapFunc *copyswap;
 
6788
 
 
6789
    typecode = self->descr;
 
6790
    Py_INCREF(typecode);
 
6791
    arr = PyArray_FromAny(val, typecode,
 
6792
                          0, 0, FORCECAST | FORTRAN_IF(self), NULL);
 
6793
    if (arr == NULL) return -1;
 
6794
    arrit = (PyArrayIterObject *)PyArray_IterNew(arr);
 
6795
    if (arrit == NULL) goto exit;
 
6796
    selfit = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self);
 
6797
    if (selfit == NULL) goto exit;
 
6798
 
 
6799
    if (arrit->size == 0) {retval = 0; goto exit;}
 
6800
 
 
6801
    swap = PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(arr);
 
6802
    copyswap = self->descr->f->copyswap;
 
6803
    if (PyDataType_REFCHK(self->descr)) {
6562
6804
        while(selfit->index < selfit->size) {
6563
 
                memmove(selfit->dataptr, arrit->dataptr, self->descr->elsize);
6564
 
                if (swap)
6565
 
                        copyswap(selfit->dataptr, NULL, swap, self);
6566
 
                PyArray_ITER_NEXT(selfit);
6567
 
                PyArray_ITER_NEXT(arrit);
6568
 
                if (arrit->index == arrit->size)
6569
 
                        PyArray_ITER_RESET(arrit);
 
6805
            PyArray_Item_XDECREF(selfit->dataptr, self->descr);
 
6806
            PyArray_Item_INCREF(arrit->dataptr, PyArray_DESCR(arr));
 
6807
            memmove(selfit->dataptr, arrit->dataptr,
 
6808
                    sizeof(PyObject **));
 
6809
            if (swap)
 
6810
                copyswap(selfit->dataptr, NULL, swap, self);
 
6811
            PyArray_ITER_NEXT(selfit);
 
6812
            PyArray_ITER_NEXT(arrit);
 
6813
            if (arrit->index == arrit->size)
 
6814
                PyArray_ITER_RESET(arrit);
6570
6815
        }
6571
6816
        retval = 0;
 
6817
        goto exit;
 
6818
    }
 
6819
 
 
6820
    while(selfit->index < selfit->size) {
 
6821
        memmove(selfit->dataptr, arrit->dataptr, self->descr->elsize);
 
6822
        if (swap)
 
6823
            copyswap(selfit->dataptr, NULL, swap, self);
 
6824
        PyArray_ITER_NEXT(selfit);
 
6825
        PyArray_ITER_NEXT(arrit);
 
6826
        if (arrit->index == arrit->size)
 
6827
            PyArray_ITER_RESET(arrit);
 
6828
    }
 
6829
    retval = 0;
6572
6830
 exit:
6573
 
        Py_XDECREF(selfit);
6574
 
        Py_XDECREF(arrit);
6575
 
        Py_XDECREF(arr);
6576
 
        return retval;
 
6831
    Py_XDECREF(selfit);
 
6832
    Py_XDECREF(arrit);
 
6833
    Py_XDECREF(arr);
 
6834
    return retval;
6577
6835
}
6578
6836
 
6579
6837
static PyObject *
6580
6838
array_transpose_get(PyArrayObject *self)
6581
6839
{
6582
 
        return PyArray_Transpose(self, NULL);
 
6840
    return PyArray_Transpose(self, NULL);
6583
6841
}
6584
6842
 
6585
6843
/* If this is None, no function call is made
6588
6846
static PyObject *
6589
6847
array_finalize_get(PyArrayObject *self)
6590
6848
{
6591
 
        Py_INCREF(Py_None);
6592
 
        return Py_None;
 
6849
    Py_INCREF(Py_None);
 
6850
    return Py_None;
6593
6851
}
6594
6852
 
6595
6853
static PyGetSetDef array_getsetlist[] = {
6596
 
        {"ndim",
6597
 
         (getter)array_ndim_get,
6598
 
         NULL, NULL},
6599
 
        {"flags",
6600
 
         (getter)array_flags_get,
6601
 
         NULL, NULL},
6602
 
        {"shape",
6603
 
         (getter)array_shape_get,
6604
 
         (setter)array_shape_set,
6605
 
         NULL},
6606
 
        {"strides",
6607
 
         (getter)array_strides_get,
6608
 
         (setter)array_strides_set,
6609
 
         NULL},
6610
 
        {"data",
6611
 
         (getter)array_data_get,
6612
 
         (setter)array_data_set,
6613
 
         NULL},
6614
 
        {"itemsize",
6615
 
         (getter)array_itemsize_get,
6616
 
         NULL, NULL},
6617
 
        {"size",
6618
 
         (getter)array_size_get,
6619
 
         NULL, NULL},
6620
 
        {"nbytes",
6621
 
         (getter)array_nbytes_get,
6622
 
         NULL, NULL},
6623
 
        {"base",
6624
 
         (getter)array_base_get,
6625
 
         NULL, NULL},
6626
 
        {"dtype",
6627
 
         (getter)array_descr_get,
6628
 
         (setter)array_descr_set,
6629
 
         NULL},
6630
 
        {"real",
6631
 
         (getter)array_real_get,
6632
 
         (setter)array_real_set,
6633
 
         NULL},
6634
 
        {"imag",
6635
 
         (getter)array_imag_get,
6636
 
         (setter)array_imag_set,
6637
 
         NULL},
6638
 
        {"flat",
6639
 
         (getter)array_flat_get,
6640
 
         (setter)array_flat_set,
6641
 
         NULL},
6642
 
        {"ctypes",
6643
 
         (getter)array_ctypes_get,
6644
 
         NULL, NULL},
6645
 
        {"T",
6646
 
         (getter)array_transpose_get,
6647
 
         NULL, NULL},
6648
 
        {"__array_interface__",
6649
 
         (getter)array_interface_get,
6650
 
         NULL, NULL},
6651
 
        {"__array_struct__",
6652
 
         (getter)array_struct_get,
6653
 
         NULL, NULL},
6654
 
        {"__array_priority__",
6655
 
         (getter)array_priority_get,
6656
 
         NULL, NULL},
6657
 
        {"__array_finalize__",
6658
 
         (getter)array_finalize_get,
6659
 
         NULL, NULL},
6660
 
        {NULL, NULL, NULL, NULL},  /* Sentinel */
 
6854
    {"ndim",
 
6855
     (getter)array_ndim_get,
 
6856
     NULL, NULL},
 
6857
    {"flags",
 
6858
     (getter)array_flags_get,
 
6859
     NULL, NULL},
 
6860
    {"shape",
 
6861
     (getter)array_shape_get,
 
6862
     (setter)array_shape_set,
 
6863
     NULL},
 
6864
    {"strides",
 
6865
     (getter)array_strides_get,
 
6866
     (setter)array_strides_set,
 
6867
     NULL},
 
6868
    {"data",
 
6869
     (getter)array_data_get,
 
6870
     (setter)array_data_set,
 
6871
     NULL},
 
6872
    {"itemsize",
 
6873
     (getter)array_itemsize_get,
 
6874
     NULL, NULL},
 
6875
    {"size",
 
6876
     (getter)array_size_get,
 
6877
     NULL, NULL},
 
6878
    {"nbytes",
 
6879
     (getter)array_nbytes_get,
 
6880
     NULL, NULL},
 
6881
    {"base",
 
6882
     (getter)array_base_get,
 
6883
     NULL, NULL},
 
6884
    {"dtype",
 
6885
     (getter)array_descr_get,
 
6886
     (setter)array_descr_set,
 
6887
     NULL},
 
6888
    {"real",
 
6889
     (getter)array_real_get,
 
6890
     (setter)array_real_set,
 
6891
     NULL},
 
6892
    {"imag",
 
6893
     (getter)array_imag_get,
 
6894
     (setter)array_imag_set,
 
6895
     NULL},
 
6896
    {"flat",
 
6897
     (getter)array_flat_get,
 
6898
     (setter)array_flat_set,
 
6899
     NULL},
 
6900
    {"ctypes",
 
6901
     (getter)array_ctypes_get,
 
6902
     NULL, NULL},
 
6903
    {"T",
 
6904
     (getter)array_transpose_get,
 
6905
     NULL, NULL},
 
6906
    {"__array_interface__",
 
6907
     (getter)array_interface_get,
 
6908
     NULL, NULL},
 
6909
    {"__array_struct__",
 
6910
     (getter)array_struct_get,
 
6911
     NULL, NULL},
 
6912
    {"__array_priority__",
 
6913
     (getter)array_priority_get,
 
6914
     NULL, NULL},
 
6915
    {"__array_finalize__",
 
6916
     (getter)array_finalize_get,
 
6917
     NULL, NULL},
 
6918
    {NULL, NULL, NULL, NULL},  /* Sentinel */
6661
6919
};
6662
6920
 
6663
6921
/****************** end of attribute get and set routines *******************/
6666
6924
static PyObject *
6667
6925
array_alloc(PyTypeObject *type, Py_ssize_t nitems)
6668
6926
{
6669
 
        PyObject *obj;
6670
 
        /* nitems will always be 0 */
6671
 
        obj = (PyObject *)_pya_malloc(sizeof(PyArrayObject));
6672
 
        PyObject_Init(obj, type);
6673
 
        return obj;
 
6927
    PyObject *obj;
 
6928
    /* nitems will always be 0 */
 
6929
    obj = (PyObject *)_pya_malloc(sizeof(PyArrayObject));
 
6930
    PyObject_Init(obj, type);
 
6931
    return obj;
6674
6932
}
6675
6933
 
6676
6934
 
6677
6935
static PyTypeObject PyArray_Type = {
6678
 
        PyObject_HEAD_INIT(NULL)
6679
 
        0,                                        /*ob_size*/
6680
 
        "numpy.ndarray",                          /*tp_name*/
6681
 
        sizeof(PyArrayObject),                    /*tp_basicsize*/
6682
 
        0,                                        /*tp_itemsize*/
6683
 
        /* methods */
6684
 
        (destructor)array_dealloc,                /*tp_dealloc  */
6685
 
        (printfunc)NULL,                          /*tp_print*/
6686
 
        0,                                        /*tp_getattr*/
6687
 
        0,                                        /*tp_setattr*/
6688
 
        (cmpfunc)0,                       /*tp_compare*/
6689
 
        (reprfunc)array_repr,                     /*tp_repr*/
6690
 
        &array_as_number,                         /*tp_as_number*/
6691
 
        &array_as_sequence,                       /*tp_as_sequence*/
6692
 
        &array_as_mapping,                        /*tp_as_mapping*/
6693
 
        (hashfunc)0,                              /*tp_hash*/
6694
 
        (ternaryfunc)0,                           /*tp_call*/
6695
 
        (reprfunc)array_str,              /*tp_str*/
6696
 
 
6697
 
        (getattrofunc)0,                          /*tp_getattro*/
6698
 
        (setattrofunc)0,                          /*tp_setattro*/
6699
 
        &array_as_buffer,                         /*tp_as_buffer*/
6700
 
        (Py_TPFLAGS_DEFAULT
6701
 
         | Py_TPFLAGS_BASETYPE
6702
 
         | Py_TPFLAGS_CHECKTYPES),                /*tp_flags*/
6703
 
        /*Documentation string */
6704
 
        0,                                        /*tp_doc*/
6705
 
 
6706
 
        (traverseproc)0,                          /*tp_traverse */
6707
 
        (inquiry)0,                               /*tp_clear */
6708
 
        (richcmpfunc)array_richcompare,           /*tp_richcompare */
6709
 
        offsetof(PyArrayObject, weakreflist),     /*tp_weaklistoffset */
6710
 
 
6711
 
        /* Iterator support (use standard) */
6712
 
 
6713
 
        (getiterfunc)array_iter,                  /* tp_iter */
6714
 
        (iternextfunc)0,                          /* tp_iternext */
6715
 
 
6716
 
        /* Sub-classing (new-style object) support */
6717
 
 
6718
 
        array_methods,                            /* tp_methods */
6719
 
        0,                                        /* tp_members */
6720
 
        array_getsetlist,                         /* tp_getset */
6721
 
        0,                                        /* tp_base */
6722
 
        0,                                        /* tp_dict */
6723
 
        0,                                        /* tp_descr_get */
6724
 
        0,                                        /* tp_descr_set */
6725
 
        0,                                        /* tp_dictoffset */
6726
 
        (initproc)0,                              /* tp_init */
6727
 
        array_alloc,                              /* tp_alloc */
6728
 
        (newfunc)array_new,                       /* tp_new */
6729
 
        0,                                        /* tp_free */
6730
 
        0,                                        /* tp_is_gc */
6731
 
        0,                                        /* tp_bases */
6732
 
        0,                                        /* tp_mro */
6733
 
        0,                                        /* tp_cache */
6734
 
        0,                                        /* tp_subclasses */
6735
 
        0                                         /* tp_weaklist */
 
6936
    PyObject_HEAD_INIT(NULL)
 
6937
    0,                                          /*ob_size*/
 
6938
    "numpy.ndarray",                            /*tp_name*/
 
6939
    sizeof(PyArrayObject),                      /*tp_basicsize*/
 
6940
    0,                                          /*tp_itemsize*/
 
6941
    /* methods */
 
6942
    (destructor)array_dealloc,                  /*tp_dealloc  */
 
6943
    (printfunc)NULL,                            /*tp_print*/
 
6944
    0,                                          /*tp_getattr*/
 
6945
    0,                                          /*tp_setattr*/
 
6946
    (cmpfunc)0,                                 /*tp_compare*/
 
6947
    (reprfunc)array_repr,                       /*tp_repr*/
 
6948
    &array_as_number,                           /*tp_as_number*/
 
6949
    &array_as_sequence,                         /*tp_as_sequence*/
 
6950
    &array_as_mapping,                          /*tp_as_mapping*/
 
6951
    (hashfunc)0,                                /*tp_hash*/
 
6952
    (ternaryfunc)0,                             /*tp_call*/
 
6953
    (reprfunc)array_str,                        /*tp_str*/
 
6954
 
 
6955
    (getattrofunc)0,                            /*tp_getattro*/
 
6956
    (setattrofunc)0,                            /*tp_setattro*/
 
6957
    &array_as_buffer,                           /*tp_as_buffer*/
 
6958
    (Py_TPFLAGS_DEFAULT
 
6959
     | Py_TPFLAGS_BASETYPE
 
6960
     | Py_TPFLAGS_CHECKTYPES),                  /*tp_flags*/
 
6961
    /*Documentation string */
 
6962
    0,                                          /*tp_doc*/
 
6963
 
 
6964
    (traverseproc)0,                            /*tp_traverse */
 
6965
    (inquiry)0,                                 /*tp_clear */
 
6966
    (richcmpfunc)array_richcompare,             /*tp_richcompare */
 
6967
    offsetof(PyArrayObject, weakreflist),       /*tp_weaklistoffset */
 
6968
 
 
6969
    /* Iterator support (use standard) */
 
6970
 
 
6971
    (getiterfunc)array_iter,                    /* tp_iter */
 
6972
    (iternextfunc)0,                            /* tp_iternext */
 
6973
 
 
6974
    /* Sub-classing (new-style object) support */
 
6975
 
 
6976
    array_methods,                              /* tp_methods */
 
6977
    0,                                          /* tp_members */
 
6978
    array_getsetlist,                           /* tp_getset */
 
6979
    0,                                          /* tp_base */
 
6980
    0,                                          /* tp_dict */
 
6981
    0,                                          /* tp_descr_get */
 
6982
    0,                                          /* tp_descr_set */
 
6983
    0,                                          /* tp_dictoffset */
 
6984
    (initproc)0,                                /* tp_init */
 
6985
    array_alloc,                                /* tp_alloc */
 
6986
    (newfunc)array_new,                         /* tp_new */
 
6987
    0,                                          /* tp_free */
 
6988
    0,                                          /* tp_is_gc */
 
6989
    0,                                          /* tp_bases */
 
6990
    0,                                          /* tp_mro */
 
6991
    0,                                          /* tp_cache */
 
6992
    0,                                          /* tp_subclasses */
 
6993
    0                                           /* tp_weaklist */
6736
6994
};
6737
6995
 
6738
6996
/* The rest of this code is to build the right kind of array from a python */
6741
6999
static int
6742
7000
discover_depth(PyObject *s, int max, int stop_at_string, int stop_at_tuple)
6743
7001
{
6744
 
        int d=0;
6745
 
        PyObject *e;
6746
 
 
6747
 
        if(max < 1) return -1;
6748
 
 
6749
 
        if(! PySequence_Check(s) || PyInstance_Check(s) || \
6750
 
           PySequence_Length(s) < 0) {
6751
 
                PyErr_Clear(); return 0;
6752
 
        }
6753
 
        if (PyArray_Check(s))
6754
 
                return PyArray_NDIM(s);
6755
 
        if (PyArray_IsScalar(s, Generic)) return 0;
6756
 
        if (PyString_Check(s) || PyBuffer_Check(s) || PyUnicode_Check(s))
6757
 
                return stop_at_string ? 0:1;
6758
 
        if (stop_at_tuple && PyTuple_Check(s)) return 0;
6759
 
        if ((e=PyObject_GetAttrString(s, "__array_struct__")) != NULL) {
6760
 
                d = -1;
6761
 
                if (PyCObject_Check(e)) {
6762
 
                        PyArrayInterface *inter;
6763
 
                        inter = (PyArrayInterface *)PyCObject_AsVoidPtr(e);
6764
 
                        if (inter->two == 2) {
6765
 
                                d = inter->nd;
6766
 
                        }
6767
 
                }
6768
 
                Py_DECREF(e);
6769
 
                if (d > -1) return d;
6770
 
        }
6771
 
        else PyErr_Clear();
6772
 
        if ((e=PyObject_GetAttrString(s, "__array_interface__")) != NULL) {
6773
 
                d = -1;
6774
 
                if (PyDict_Check(e)) {
6775
 
                        PyObject *new;
6776
 
                        new = PyDict_GetItemString(e, "shape");
6777
 
                        if (new && PyTuple_Check(new))
6778
 
                                d = PyTuple_GET_SIZE(new);
6779
 
                }
6780
 
                Py_DECREF(e);
6781
 
                if (d>-1) return d;
6782
 
        }
6783
 
        else PyErr_Clear();
6784
 
 
6785
 
        if (PySequence_Length(s) == 0)
6786
 
                return 1;
6787
 
        if ((e=PySequence_GetItem(s,0)) == NULL) return -1;
6788
 
        if(e!=s) {
6789
 
                d=discover_depth(e, max-1, stop_at_string, stop_at_tuple);
6790
 
                if(d >= 0) d++;
6791
 
        }
6792
 
        Py_DECREF(e);
6793
 
        return d;
 
7002
    int d = 0;
 
7003
    PyObject *e;
 
7004
 
 
7005
    if(max < 1) {
 
7006
        return -1;
 
7007
    }
 
7008
    if(!PySequence_Check(s) || PyInstance_Check(s) ||
 
7009
            PySequence_Length(s) < 0) {
 
7010
        PyErr_Clear();
 
7011
        return 0;
 
7012
    }
 
7013
    if (PyArray_Check(s)) {
 
7014
        return PyArray_NDIM(s);
 
7015
    }
 
7016
    if (PyArray_IsScalar(s, Generic)) {
 
7017
        return 0;
 
7018
    }
 
7019
    if (PyString_Check(s) || PyBuffer_Check(s) || PyUnicode_Check(s)) {
 
7020
        return stop_at_string ? 0:1;
 
7021
    }
 
7022
    if (stop_at_tuple && PyTuple_Check(s)) {
 
7023
        return 0;
 
7024
    }
 
7025
    if ((e = PyObject_GetAttrString(s, "__array_struct__")) != NULL) {
 
7026
        d = -1;
 
7027
        if (PyCObject_Check(e)) {
 
7028
            PyArrayInterface *inter;
 
7029
            inter = (PyArrayInterface *)PyCObject_AsVoidPtr(e);
 
7030
            if (inter->two == 2) {
 
7031
                d = inter->nd;
 
7032
            }
 
7033
        }
 
7034
        Py_DECREF(e);
 
7035
        if (d > -1) {
 
7036
            return d;
 
7037
        }
 
7038
    }
 
7039
    else {
 
7040
        PyErr_Clear();
 
7041
    }
 
7042
    if ((e=PyObject_GetAttrString(s, "__array_interface__")) != NULL) {
 
7043
        d = -1;
 
7044
        if (PyDict_Check(e)) {
 
7045
            PyObject *new;
 
7046
            new = PyDict_GetItemString(e, "shape");
 
7047
            if (new && PyTuple_Check(new)) {
 
7048
                d = PyTuple_GET_SIZE(new);
 
7049
            }
 
7050
        }
 
7051
        Py_DECREF(e);
 
7052
        if (d>-1) {
 
7053
            return d;
 
7054
        }
 
7055
    }
 
7056
    else PyErr_Clear();
 
7057
 
 
7058
    if (PySequence_Length(s) == 0) {
 
7059
        return 1;
 
7060
    }
 
7061
    if ((e=PySequence_GetItem(s,0)) == NULL) {
 
7062
        return -1;
 
7063
    }
 
7064
    if (e != s) {
 
7065
        d = discover_depth(e, max-1, stop_at_string, stop_at_tuple);
 
7066
        if (d >= 0) {
 
7067
            d++;
 
7068
        }
 
7069
    }
 
7070
    Py_DECREF(e);
 
7071
    return d;
6794
7072
}
6795
7073
 
6796
7074
static int
6797
7075
discover_itemsize(PyObject *s, int nd, int *itemsize)
6798
7076
{
6799
 
        int n, r, i;
6800
 
        PyObject *e;
6801
 
 
6802
 
        n = PyObject_Length(s);
6803
 
 
6804
 
        if ((nd == 0) || PyString_Check(s) ||           \
 
7077
    int n, r, i;
 
7078
    PyObject *e;
 
7079
 
 
7080
    if (PyArray_Check(s)) {
 
7081
        *itemsize = MAX(*itemsize, PyArray_ITEMSIZE(s));
 
7082
        return 0;
 
7083
    }
 
7084
 
 
7085
    n = PyObject_Length(s);
 
7086
 
 
7087
    if ((nd == 0) || PyString_Check(s) ||
6805
7088
            PyUnicode_Check(s) || PyBuffer_Check(s)) {
6806
 
                if PyUnicode_Check(s)
6807
 
                        *itemsize = MAX(*itemsize, 4*n);
6808
 
                else
6809
 
                        *itemsize = MAX(*itemsize, n);
6810
 
                return 0;
6811
 
        }
6812
 
        for (i=0; i<n; i++) {
6813
 
                if ((e=PySequence_GetItem(s,i))==NULL) return -1;
6814
 
                r=discover_itemsize(e,nd-1,itemsize);
6815
 
                Py_DECREF(e);
6816
 
                if (r == -1) return -1;
6817
 
        }
 
7089
        *itemsize = MAX(*itemsize, n);
6818
7090
        return 0;
 
7091
    }
 
7092
    for(i = 0; i < n; i++) {
 
7093
        if ((e = PySequence_GetItem(s,i))==NULL) {
 
7094
            return -1;
 
7095
        }
 
7096
        r = discover_itemsize(e,nd-1,itemsize);
 
7097
        Py_DECREF(e);
 
7098
        if (r == -1) {
 
7099
            return -1;
 
7100
        }
 
7101
    }
 
7102
    return 0;
6819
7103
}
6820
7104
 
6821
 
/* Take an arbitrary object known to represent
6822
 
   an array of ndim nd, and determine the size in each dimension
6823
 
*/
6824
 
 
 
7105
/*
 
7106
 * Take an arbitrary object known to represent
 
7107
 * an array of ndim nd, and determine the size in each dimension
 
7108
 */
6825
7109
static int
6826
7110
discover_dimensions(PyObject *s, int nd, intp *d, int check_it)
6827
7111
{
6828
 
        PyObject *e;
6829
 
        int r, n, i, n_lower;
6830
 
 
6831
 
        n=PyObject_Length(s);
6832
 
        *d = n;
6833
 
        if(*d < 0) return -1;
6834
 
        if(nd <= 1) return 0;
6835
 
        n_lower = 0;
6836
 
        for(i=0; i<n; i++) {
6837
 
                if ((e=PySequence_GetItem(s,i)) == NULL) return -1;
6838
 
                r=discover_dimensions(e,nd-1,d+1,check_it);
6839
 
                Py_DECREF(e);
6840
 
 
6841
 
                if (r == -1) return -1;
6842
 
                if (check_it && n_lower != 0 && n_lower != d[1]) {
6843
 
                        PyErr_SetString(PyExc_ValueError,
6844
 
                                        "inconsistent shape in sequence");
6845
 
                        return -1;
6846
 
                }
6847
 
                if (d[1] > n_lower) n_lower = d[1];
6848
 
        }
6849
 
        d[1] = n_lower;
6850
 
 
 
7112
    PyObject *e;
 
7113
    int r, n, i, n_lower;
 
7114
 
 
7115
 
 
7116
    if (PyArray_Check(s)) {
 
7117
        for (i=0; i<nd; i++) {
 
7118
            d[i] = PyArray_DIM(s,i);
 
7119
        }
 
7120
        return 0;
 
7121
    }
 
7122
    
 
7123
    n=PyObject_Length(s);
 
7124
    *d = n;
 
7125
    if (*d < 0) {
 
7126
        return -1;
 
7127
    }
 
7128
    if (nd <= 1) {
6851
7129
        return 0;
 
7130
    }
 
7131
    n_lower = 0;
 
7132
    for(i = 0; i < n; i++) {
 
7133
        if ((e = PySequence_GetItem(s,i)) == NULL) {
 
7134
            return -1;
 
7135
        }
 
7136
        r = discover_dimensions(e, nd - 1, d + 1, check_it);
 
7137
        Py_DECREF(e);
 
7138
 
 
7139
        if (r == -1) {
 
7140
            return -1;
 
7141
        }
 
7142
        if (check_it && n_lower != 0 && n_lower != d[1]) {
 
7143
            PyErr_SetString(PyExc_ValueError,
 
7144
                            "inconsistent shape in sequence");
 
7145
            return -1;
 
7146
        }
 
7147
        if (d[1] > n_lower) {
 
7148
            n_lower = d[1];
 
7149
        }
 
7150
    }
 
7151
    d[1] = n_lower;
 
7152
 
 
7153
    return 0;
6852
7154
}
6853
7155
 
6854
 
/* new reference */
6855
 
/* doesn't alter refcount of chktype or mintype ---
6856
 
   unless one of them is returned */
 
7156
/*
 
7157
 * new reference
 
7158
 * doesn't alter refcount of chktype or mintype ---
 
7159
 * unless one of them is returned
 
7160
 */
6857
7161
static PyArray_Descr *
6858
7162
_array_small_type(PyArray_Descr *chktype, PyArray_Descr* mintype)
6859
7163
{
6860
 
        PyArray_Descr *outtype;
6861
 
        int outtype_num, save_num;
6862
 
 
6863
 
        if (PyArray_EquivTypes(chktype, mintype)) {
6864
 
                Py_INCREF(mintype);
6865
 
                return mintype;
6866
 
        }
6867
 
 
6868
 
        if (chktype->type_num > mintype->type_num)
6869
 
                outtype_num = chktype->type_num;
6870
 
        else
6871
 
                outtype_num = mintype->type_num;
6872
 
 
6873
 
        save_num = outtype_num;
6874
 
        while(outtype_num < PyArray_NTYPES &&
6875
 
              !(PyArray_CanCastSafely(chktype->type_num, outtype_num)
6876
 
                && PyArray_CanCastSafely(mintype->type_num, outtype_num)))
6877
 
                outtype_num++;
6878
 
        if (outtype_num == PyArray_NTYPES) {
6879
 
                outtype = PyArray_DescrFromType(save_num);
6880
 
        }
6881
 
        else {
6882
 
                outtype = PyArray_DescrFromType(outtype_num);
6883
 
        }
6884
 
        if (PyTypeNum_ISEXTENDED(outtype->type_num) &&          \
6885
 
            (PyTypeNum_ISEXTENDED(mintype->type_num) ||         \
6886
 
             mintype->type_num==0)) {
6887
 
                int testsize = outtype->elsize;
6888
 
                register int chksize, minsize;
6889
 
                chksize = chktype->elsize;
6890
 
                minsize = mintype->elsize;
6891
 
                /* Handle string->unicode case separately
6892
 
                   because string itemsize is twice as large */
6893
 
                if (outtype->type_num == PyArray_UNICODE &&
6894
 
                    mintype->type_num == PyArray_STRING) {
6895
 
                        testsize = MAX(chksize, 4*minsize);
6896
 
                }
6897
 
                else {
6898
 
                        testsize = MAX(chksize, minsize);
6899
 
                }
6900
 
                if (testsize != outtype->elsize) {
6901
 
                        PyArray_DESCR_REPLACE(outtype);
6902
 
                        outtype->elsize = testsize;
6903
 
                        Py_XDECREF(outtype->fields);
6904
 
                        outtype->fields = NULL;
6905
 
                        Py_XDECREF(outtype->names);
6906
 
                        outtype->names = NULL;
6907
 
                }
6908
 
        }
6909
 
        return outtype;
 
7164
    PyArray_Descr *outtype;
 
7165
    int outtype_num, save_num;
 
7166
 
 
7167
    if (PyArray_EquivTypes(chktype, mintype)) {
 
7168
        Py_INCREF(mintype);
 
7169
        return mintype;
 
7170
    }
 
7171
 
 
7172
 
 
7173
    if (chktype->type_num > mintype->type_num)
 
7174
        outtype_num = chktype->type_num;
 
7175
    else {
 
7176
        if (PyDataType_ISOBJECT(chktype) && \
 
7177
            PyDataType_ISSTRING(mintype)) {
 
7178
            return PyArray_DescrFromType(NPY_OBJECT);
 
7179
        }
 
7180
        else {
 
7181
            outtype_num = mintype->type_num;
 
7182
        }
 
7183
    }
 
7184
 
 
7185
    save_num = outtype_num;
 
7186
    while(outtype_num < PyArray_NTYPES &&
 
7187
          !(PyArray_CanCastSafely(chktype->type_num, outtype_num)
 
7188
            && PyArray_CanCastSafely(mintype->type_num, outtype_num)))
 
7189
        outtype_num++;
 
7190
    if (outtype_num == PyArray_NTYPES) {
 
7191
        outtype = PyArray_DescrFromType(save_num);
 
7192
    }
 
7193
    else {
 
7194
        outtype = PyArray_DescrFromType(outtype_num);
 
7195
    }
 
7196
    if (PyTypeNum_ISEXTENDED(outtype->type_num)) {
 
7197
        int testsize = outtype->elsize;
 
7198
        register int chksize, minsize;
 
7199
        chksize = chktype->elsize;
 
7200
        minsize = mintype->elsize;
 
7201
        /* Handle string->unicode case separately
 
7202
           because string itemsize is 4* as large */
 
7203
        if (outtype->type_num == PyArray_UNICODE &&
 
7204
            mintype->type_num == PyArray_STRING) {
 
7205
            testsize = MAX(chksize, 4*minsize);
 
7206
        }
 
7207
        else {
 
7208
            testsize = MAX(chksize, minsize);
 
7209
        }
 
7210
        if (testsize != outtype->elsize) {
 
7211
            PyArray_DESCR_REPLACE(outtype);
 
7212
            outtype->elsize = testsize;
 
7213
            Py_XDECREF(outtype->fields);
 
7214
            outtype->fields = NULL;
 
7215
            Py_XDECREF(outtype->names);
 
7216
            outtype->names = NULL;
 
7217
        }
 
7218
    }
 
7219
    return outtype;
6910
7220
}
6911
7221
 
6912
7222
static PyArray_Descr *
6914
7224
{
6915
7225
    if (PyFloat_Check(op)) {
6916
7226
        return PyArray_DescrFromType(PyArray_DOUBLE);
6917
 
    } else if (PyComplex_Check(op)) {
 
7227
    }
 
7228
    else if (PyComplex_Check(op)) {
6918
7229
        return PyArray_DescrFromType(PyArray_CDOUBLE);
6919
 
    } else if (PyInt_Check(op)) {
 
7230
    }
 
7231
    else if (PyInt_Check(op)) {
6920
7232
        /* bools are a subclass of int */
6921
7233
        if (PyBool_Check(op)) {
6922
7234
            return PyArray_DescrFromType(PyArray_BOOL);
6923
7235
        } else {
6924
7236
            return  PyArray_DescrFromType(PyArray_LONG);
6925
7237
        }
6926
 
    } else if (PyLong_Check(op)) {
6927
 
        /* if integer can fit into a longlong then return that
6928
 
         */
 
7238
    }
 
7239
    else if (PyLong_Check(op)) {
 
7240
        /* if integer can fit into a longlong then return that*/
6929
7241
        if ((PyLong_AsLongLong(op) == -1) && PyErr_Occurred()) {
6930
7242
            PyErr_Clear();
6931
7243
            return PyArray_DescrFromType(PyArray_OBJECT);
6935
7247
    return NULL;
6936
7248
}
6937
7249
 
 
7250
static PyArray_Descr *
 
7251
_use_default_type(PyObject *op)
 
7252
{
 
7253
    int typenum, l;
 
7254
    PyObject *type;
 
7255
 
 
7256
    typenum = -1;
 
7257
    l = 0;
 
7258
    type = (PyObject *)op->ob_type;
 
7259
    while (l < PyArray_NUMUSERTYPES) {
 
7260
        if (type == (PyObject *)(userdescrs[l]->typeobj)) {
 
7261
            typenum = l + PyArray_USERDEF;
 
7262
            break;
 
7263
        }
 
7264
        l++;
 
7265
    }
 
7266
    if (typenum == -1) {
 
7267
        typenum = PyArray_OBJECT;
 
7268
    }
 
7269
    return PyArray_DescrFromType(typenum);
 
7270
}
 
7271
 
 
7272
 
6938
7273
/* op is an object to be converted to an ndarray.
6939
7274
 
6940
7275
   minitype is the minimum type-descriptor needed.
6947
7282
static PyArray_Descr *
6948
7283
_array_find_type(PyObject *op, PyArray_Descr *minitype, int max)
6949
7284
{
6950
 
        int l;
6951
 
        PyObject *ip;
6952
 
        PyArray_Descr *chktype=NULL;
6953
 
        PyArray_Descr *outtype;
6954
 
 
6955
 
        /* These need to come first because if op already carries
6956
 
           a descr structure, then we want it to be the result if minitype
6957
 
           is NULL.
6958
 
        */
6959
 
 
6960
 
        if (PyArray_Check(op)) {
6961
 
                chktype = PyArray_DESCR(op);
6962
 
                Py_INCREF(chktype);
6963
 
                if (minitype == NULL) return chktype;
6964
 
                Py_INCREF(minitype);
6965
 
                goto finish;
6966
 
        }
6967
 
 
6968
 
        if (PyArray_IsScalar(op, Generic)) {
6969
 
                chktype = PyArray_DescrFromScalar(op);
6970
 
                if (minitype == NULL) return chktype;
6971
 
                Py_INCREF(minitype);
6972
 
                goto finish;
6973
 
        }
6974
 
 
6975
 
        if (minitype == NULL) {
6976
 
                minitype = PyArray_DescrFromType(PyArray_BOOL);
6977
 
        }
6978
 
        else Py_INCREF(minitype);
6979
 
 
6980
 
        if (max < 0) goto deflt;
6981
 
 
6982
 
        chktype = _array_find_python_scalar_type(op);
6983
 
        if (chktype) {
6984
 
            goto finish;
6985
 
        }
6986
 
 
6987
 
        if ((ip=PyObject_GetAttrString(op, "__array_interface__"))!=NULL) {
6988
 
                if (PyDict_Check(ip)) {
6989
 
                        PyObject *new;
6990
 
                        new = PyDict_GetItemString(ip, "typestr");
6991
 
                        if (new && PyString_Check(new)) {
6992
 
                                chktype =_array_typedescr_fromstr       \
6993
 
                                        (PyString_AS_STRING(new));
6994
 
                        }
6995
 
                }
6996
 
                Py_DECREF(ip);
6997
 
                if (chktype) goto finish;
6998
 
        }
6999
 
        else PyErr_Clear();
7000
 
 
7001
 
        if ((ip=PyObject_GetAttrString(op, "__array_struct__")) != NULL) {
7002
 
                PyArrayInterface *inter;
7003
 
                char buf[40];
7004
 
                if (PyCObject_Check(ip)) {
7005
 
                        inter=(PyArrayInterface *)PyCObject_AsVoidPtr(ip);
7006
 
                        if (inter->two == 2) {
7007
 
                                snprintf(buf, 40, "|%c%d", inter->typekind,
7008
 
                                         inter->itemsize);
7009
 
                                chktype = _array_typedescr_fromstr(buf);
7010
 
                        }
7011
 
                }
7012
 
                Py_DECREF(ip);
7013
 
                if (chktype) goto finish;
7014
 
        }
7015
 
        else PyErr_Clear();
7016
 
 
7017
 
        if (PyString_Check(op)) {
7018
 
                chktype = PyArray_DescrNewFromType(PyArray_STRING);
7019
 
                chktype->elsize = PyString_GET_SIZE(op);
7020
 
                goto finish;
7021
 
        }
7022
 
 
7023
 
        if (PyUnicode_Check(op)) {
7024
 
                chktype = PyArray_DescrNewFromType(PyArray_UNICODE);
7025
 
                chktype->elsize = PyUnicode_GET_DATA_SIZE(op);
 
7285
    int l;
 
7286
    PyObject *ip;
 
7287
    PyArray_Descr *chktype=NULL;
 
7288
    PyArray_Descr *outtype;
 
7289
 
 
7290
    /* These need to come first because if op already carries
 
7291
       a descr structure, then we want it to be the result if minitype
 
7292
       is NULL.
 
7293
    */
 
7294
 
 
7295
    if (PyArray_Check(op)) {
 
7296
        chktype = PyArray_DESCR(op);
 
7297
        Py_INCREF(chktype);
 
7298
        if (minitype == NULL) return chktype;
 
7299
        Py_INCREF(minitype);
 
7300
        goto finish;
 
7301
    }
 
7302
 
 
7303
    if (PyArray_IsScalar(op, Generic)) {
 
7304
        chktype = PyArray_DescrFromScalar(op);
 
7305
        if (minitype == NULL) return chktype;
 
7306
        Py_INCREF(minitype);
 
7307
        goto finish;
 
7308
    }
 
7309
 
 
7310
    if (minitype == NULL) {
 
7311
        minitype = PyArray_DescrFromType(PyArray_BOOL);
 
7312
    }
 
7313
    else Py_INCREF(minitype);
 
7314
 
 
7315
    if (max < 0) goto deflt;
 
7316
 
 
7317
    chktype = _array_find_python_scalar_type(op);
 
7318
    if (chktype) {
 
7319
        goto finish;
 
7320
    }
 
7321
 
 
7322
    if ((ip=PyObject_GetAttrString(op, "__array_interface__"))!=NULL) {
 
7323
        if (PyDict_Check(ip)) {
 
7324
            PyObject *new;
 
7325
            new = PyDict_GetItemString(ip, "typestr");
 
7326
            if (new && PyString_Check(new)) {
 
7327
                chktype =_array_typedescr_fromstr       \
 
7328
                    (PyString_AS_STRING(new));
 
7329
            }
 
7330
        }
 
7331
        Py_DECREF(ip);
 
7332
        if (chktype) goto finish;
 
7333
    }
 
7334
    else PyErr_Clear();
 
7335
 
 
7336
    if ((ip=PyObject_GetAttrString(op, "__array_struct__")) != NULL) {
 
7337
        PyArrayInterface *inter;
 
7338
        char buf[40];
 
7339
        if (PyCObject_Check(ip)) {
 
7340
            inter=(PyArrayInterface *)PyCObject_AsVoidPtr(ip);
 
7341
            if (inter->two == 2) {
 
7342
                snprintf(buf, 40, "|%c%d", inter->typekind,
 
7343
                         inter->itemsize);
 
7344
                chktype = _array_typedescr_fromstr(buf);
 
7345
            }
 
7346
        }
 
7347
        Py_DECREF(ip);
 
7348
        if (chktype) goto finish;
 
7349
    }
 
7350
    else PyErr_Clear();
 
7351
 
 
7352
    if (PyString_Check(op)) {
 
7353
        chktype = PyArray_DescrNewFromType(PyArray_STRING);
 
7354
        chktype->elsize = PyString_GET_SIZE(op);
 
7355
        goto finish;
 
7356
    }
 
7357
 
 
7358
    if (PyUnicode_Check(op)) {
 
7359
        chktype = PyArray_DescrNewFromType(PyArray_UNICODE);
 
7360
        chktype->elsize = PyUnicode_GET_DATA_SIZE(op);
7026
7361
#ifndef Py_UNICODE_WIDE
7027
 
                chktype->elsize <<= 1;
 
7362
        chktype->elsize <<= 1;
7028
7363
#endif
7029
 
                goto finish;
7030
 
        }
7031
 
 
7032
 
        if (PyBuffer_Check(op)) {
7033
 
                chktype = PyArray_DescrNewFromType(PyArray_VOID);
7034
 
                chktype->elsize = op->ob_type->tp_as_sequence->sq_length(op);
 
7364
        goto finish;
 
7365
    }
 
7366
 
 
7367
    if (PyBuffer_Check(op)) {
 
7368
        chktype = PyArray_DescrNewFromType(PyArray_VOID);
 
7369
        chktype->elsize = op->ob_type->tp_as_sequence->sq_length(op);
 
7370
        PyErr_Clear();
 
7371
        goto finish;
 
7372
    }
 
7373
 
 
7374
    if (PyObject_HasAttrString(op, "__array__")) {
 
7375
        ip = PyObject_CallMethod(op, "__array__", NULL);
 
7376
        if(ip && PyArray_Check(ip)) {
 
7377
            chktype = PyArray_DESCR(ip);
 
7378
            Py_INCREF(chktype);
 
7379
            Py_DECREF(ip);
 
7380
            goto finish;
 
7381
        }
 
7382
        Py_XDECREF(ip);
 
7383
        if (PyErr_Occurred()) PyErr_Clear();
 
7384
    }
 
7385
 
 
7386
    if (PyInstance_Check(op)) goto deflt;
 
7387
 
 
7388
    if (PySequence_Check(op)) {
 
7389
 
 
7390
        l = PyObject_Length(op);
 
7391
        if (l < 0 && PyErr_Occurred()) {
 
7392
            PyErr_Clear();
 
7393
            goto deflt;
 
7394
        }
 
7395
        if (l == 0 && minitype->type_num == PyArray_BOOL) {
 
7396
            Py_DECREF(minitype);
 
7397
            minitype = PyArray_DescrFromType(PyArray_DEFAULT);
 
7398
        }
 
7399
        while (--l >= 0) {
 
7400
            PyArray_Descr *newtype;
 
7401
            ip = PySequence_GetItem(op, l);
 
7402
            if (ip==NULL) {
7035
7403
                PyErr_Clear();
7036
 
                goto finish;
7037
 
        }
7038
 
 
7039
 
        if (PyObject_HasAttrString(op, "__array__")) {
7040
 
                ip = PyObject_CallMethod(op, "__array__", NULL);
7041
 
                if(ip && PyArray_Check(ip)) {
7042
 
                        chktype = PyArray_DESCR(ip);
7043
 
                        Py_INCREF(chktype);
7044
 
                        Py_DECREF(ip);
7045
 
                        goto finish;
7046
 
                }
7047
 
                Py_XDECREF(ip);
7048
 
                if (PyErr_Occurred()) PyErr_Clear();
7049
 
        }
7050
 
 
7051
 
        if (PyInstance_Check(op)) goto deflt;
7052
 
 
7053
 
        if (PySequence_Check(op)) {
7054
 
 
7055
 
                l = PyObject_Length(op);
7056
 
                if (l < 0 && PyErr_Occurred()) {
7057
 
                        PyErr_Clear();
7058
 
                        goto deflt;
7059
 
                }
7060
 
                if (l == 0 && minitype->type_num == PyArray_BOOL) {
7061
 
                        Py_DECREF(minitype);
7062
 
                        minitype = PyArray_DescrFromType(PyArray_DEFAULT);
7063
 
                }
7064
 
                while (--l >= 0) {
7065
 
                        PyArray_Descr *newtype;
7066
 
                        ip = PySequence_GetItem(op, l);
7067
 
                        if (ip==NULL) {
7068
 
                                PyErr_Clear();
7069
 
                                goto deflt;
7070
 
                        }
7071
 
                        chktype = _array_find_type(ip, minitype, max-1);
7072
 
                        newtype = _array_small_type(chktype, minitype);
7073
 
                        Py_DECREF(minitype);
7074
 
                        minitype = newtype;
7075
 
                        Py_DECREF(chktype);
7076
 
                        Py_DECREF(ip);
7077
 
                }
7078
 
                chktype = minitype;
7079
 
                Py_INCREF(minitype);
7080
 
                goto finish;
7081
 
        }
 
7404
                goto deflt;
 
7405
            }
 
7406
            chktype = _array_find_type(ip, minitype, max-1);
 
7407
            newtype = _array_small_type(chktype, minitype);
 
7408
            Py_DECREF(minitype);
 
7409
            minitype = newtype;
 
7410
            Py_DECREF(chktype);
 
7411
            Py_DECREF(ip);
 
7412
        }
 
7413
        chktype = minitype;
 
7414
        Py_INCREF(minitype);
 
7415
        goto finish;
 
7416
    }
7082
7417
 
7083
7418
 
7084
7419
 deflt:
7085
 
        chktype = PyArray_DescrFromType(PyArray_OBJECT);
 
7420
    chktype = _use_default_type(op);
7086
7421
 
7087
7422
 finish:
7088
7423
 
7089
 
        outtype = _array_small_type(chktype, minitype);
7090
 
        Py_DECREF(chktype);
7091
 
        Py_DECREF(minitype);
7092
 
        /* VOID Arrays should not occur by "default" 
7093
 
           unless input was already a VOID */
7094
 
        if (outtype->type_num == PyArray_VOID && \
7095
 
            minitype->type_num != PyArray_VOID) {
7096
 
                Py_DECREF(outtype);
7097
 
                return PyArray_DescrFromType(PyArray_OBJECT);
7098
 
        }
7099
 
        return outtype;
 
7424
    outtype = _array_small_type(chktype, minitype);
 
7425
    Py_DECREF(chktype);
 
7426
    Py_DECREF(minitype);
 
7427
    /* VOID Arrays should not occur by "default"
 
7428
       unless input was already a VOID */
 
7429
    if (outtype->type_num == PyArray_VOID && \
 
7430
        minitype->type_num != PyArray_VOID) {
 
7431
        Py_DECREF(outtype);
 
7432
        return PyArray_DescrFromType(PyArray_OBJECT);
 
7433
    }
 
7434
    return outtype;
7100
7435
}
7101
7436
 
7102
7437
/* adapted from Numarray */
7103
 
static int 
 
7438
static int
7104
7439
setArrayFromSequence(PyArrayObject *a, PyObject *s, int dim, intp offset)
7105
7440
{
7106
 
        Py_ssize_t i, slen = PySequence_Length(s);
7107
 
        int res = 0;
7108
 
 
7109
 
        if (dim > a->nd) {
7110
 
                PyErr_Format(PyExc_ValueError,
7111
 
                             "setArrayFromSequence: sequence/array dimensions mismatch.");
7112
 
                return -1;
7113
 
        }
7114
 
 
7115
 
        if (slen != a->dimensions[dim]) {
7116
 
                PyErr_Format(PyExc_ValueError,
7117
 
                             "setArrayFromSequence: sequence/array shape mismatch.");
7118
 
                return -1;
7119
 
        }
7120
 
 
7121
 
        for(i=0; i<slen; i++) {
7122
 
                PyObject *o = PySequence_GetItem(s, i);
7123
 
                if ((a->nd - dim) > 1) {
7124
 
                        res = setArrayFromSequence(a, o, dim+1, offset);
7125
 
                }
7126
 
                else {
7127
 
                        res = a->descr->f->setitem(o, (a->data + offset), a);
7128
 
                }
7129
 
                Py_DECREF(o);
7130
 
                if (res < 0) return res;
7131
 
                offset += a->strides[dim];
7132
 
        }
7133
 
        return 0;
 
7441
    Py_ssize_t i, slen;
 
7442
    int res = 0;
 
7443
 
 
7444
    /* This code is to ensure that the sequence access below will 
 
7445
       return a lower-dimensional sequence.
 
7446
     */
 
7447
    if (PyArray_Check(s) && !(PyArray_CheckExact(s))) {
 
7448
      /* FIXME:  This could probably copy the entire subarray
 
7449
         at once here using a faster algorithm.
 
7450
         Right now, just make sure a base-class array
 
7451
         is used so that the dimensionality reduction assumption
 
7452
         is correct. 
 
7453
       */
 
7454
        s = PyArray_EnsureArray(s);
 
7455
    }
 
7456
 
 
7457
    if (dim > a->nd) {
 
7458
        PyErr_Format(PyExc_ValueError,
 
7459
                     "setArrayFromSequence: sequence/array dimensions mismatch.");
 
7460
        return -1;
 
7461
    }
 
7462
 
 
7463
    slen = PySequence_Length(s);
 
7464
 
 
7465
    if (slen != a->dimensions[dim]) {
 
7466
        PyErr_Format(PyExc_ValueError,
 
7467
                     "setArrayFromSequence: sequence/array shape mismatch.");
 
7468
        return -1;
 
7469
    }
 
7470
 
 
7471
    for(i=0; i<slen; i++) {
 
7472
        PyObject *o = PySequence_GetItem(s, i);
 
7473
        if ((a->nd - dim) > 1) {
 
7474
            res = setArrayFromSequence(a, o, dim+1, offset);
 
7475
        }
 
7476
        else {
 
7477
            res = a->descr->f->setitem(o, (a->data + offset), a);
 
7478
        }
 
7479
        Py_DECREF(o);
 
7480
        if (res < 0) return res;
 
7481
        offset += a->strides[dim];
 
7482
    }
 
7483
    return 0;
7134
7484
}
7135
7485
 
7136
7486
 
7137
7487
static int
7138
7488
Assign_Array(PyArrayObject *self, PyObject *v)
7139
7489
{
7140
 
        if (!PySequence_Check(v)) {
7141
 
                PyErr_SetString(PyExc_ValueError,
7142
 
                                "assignment from non-sequence");
7143
 
                return -1;
7144
 
        }
7145
 
        if (self->nd == 0) {
7146
 
                PyErr_SetString(PyExc_ValueError,
7147
 
                                "assignment to 0-d array");
7148
 
                return -1;
7149
 
        }
 
7490
    if (!PySequence_Check(v)) {
 
7491
        PyErr_SetString(PyExc_ValueError,
 
7492
                        "assignment from non-sequence");
 
7493
        return -1;
 
7494
    }
 
7495
    if (self->nd == 0) {
 
7496
        PyErr_SetString(PyExc_ValueError,
 
7497
                        "assignment to 0-d array");
 
7498
        return -1;
 
7499
    }
7150
7500
 
7151
 
        return setArrayFromSequence(self, v, 0, 0);
 
7501
    return setArrayFromSequence(self, v, 0, 0);
7152
7502
}
7153
7503
 
7154
7504
/* "Array Scalars don't call this code" */
7156
7506
static PyObject *
7157
7507
Array_FromPyScalar(PyObject *op, PyArray_Descr *typecode)
7158
7508
{
7159
 
        PyArrayObject *ret;
7160
 
        int itemsize;
7161
 
        int type;
7162
 
 
7163
 
        itemsize = typecode->elsize;
7164
 
        type = typecode->type_num;
7165
 
 
7166
 
        if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
7167
 
                itemsize = PyObject_Length(op);
7168
 
                if (type == PyArray_UNICODE) itemsize *= 4;
7169
 
 
7170
 
                if (itemsize != typecode->elsize) {
7171
 
                        PyArray_DESCR_REPLACE(typecode);
7172
 
                        typecode->elsize = itemsize;
7173
 
                }
7174
 
        }
7175
 
 
7176
 
        ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode,
7177
 
                                                    0, NULL,
7178
 
                                                    NULL, NULL, 0, NULL);
7179
 
        if (ret == NULL) return NULL;
7180
 
        if (ret->nd > 0) {
7181
 
                PyErr_SetString(PyExc_ValueError,
7182
 
                                "shape-mismatch on array construction");
7183
 
                Py_DECREF(ret);
7184
 
                return NULL;
7185
 
        }
7186
 
 
7187
 
        ret->descr->f->setitem(op, ret->data, ret);
7188
 
 
7189
 
        if (PyErr_Occurred()) {
7190
 
                Py_DECREF(ret);
7191
 
                return NULL;
7192
 
        } else {
7193
 
                return (PyObject *)ret;
7194
 
        }
 
7509
    PyArrayObject *ret;
 
7510
    int itemsize;
 
7511
    int type;
 
7512
 
 
7513
    itemsize = typecode->elsize;
 
7514
    type = typecode->type_num;
 
7515
 
 
7516
    if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
 
7517
        itemsize = PyObject_Length(op);
 
7518
 
 
7519
        if (type == PyArray_UNICODE) {
 
7520
            itemsize *= 4;
 
7521
        }
 
7522
        if (itemsize != typecode->elsize) {
 
7523
            PyArray_DESCR_REPLACE(typecode);
 
7524
            typecode->elsize = itemsize;
 
7525
        }
 
7526
    }
 
7527
 
 
7528
    ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, typecode,
 
7529
                                                0, NULL,
 
7530
                                                NULL, NULL, 0, NULL);
 
7531
    if (ret == NULL) {
 
7532
        return NULL;
 
7533
    }
 
7534
    if (ret->nd > 0) {
 
7535
        PyErr_SetString(PyExc_ValueError,
 
7536
                        "shape-mismatch on array construction");
 
7537
        Py_DECREF(ret);
 
7538
        return NULL;
 
7539
    }
 
7540
 
 
7541
    ret->descr->f->setitem(op, ret->data, ret);
 
7542
    if (PyErr_Occurred()) {
 
7543
        Py_DECREF(ret);
 
7544
        return NULL;
 
7545
    } 
 
7546
    else {
 
7547
        return (PyObject *)ret;
 
7548
    }
7195
7549
}
7196
7550
 
7197
7551
 
7206
7560
static int
7207
7561
object_depth_and_dimension(PyObject *s, int max, intp *dims)
7208
7562
{
7209
 
        intp *newdims, *test_dims;
7210
 
        int nd, test_nd;
7211
 
        int i, islist;
7212
 
        intp size;
7213
 
        PyObject *obj;
7214
 
 
7215
 
        islist = PyList_Check(s);
7216
 
        if (!(islist || PyTuple_Check(s)) ||
7217
 
            ((size = PySequence_Size(s)) == 0))
7218
 
                return 0;
7219
 
        if (max < 2) {
7220
 
                if (max < 1) return 0;
7221
 
                dims[0] = size;
7222
 
                return 1;
7223
 
        }
7224
 
        newdims = PyDimMem_NEW(2*(max-1));
7225
 
        test_dims = newdims + (max-1);
7226
 
        if (islist) obj = PyList_GET_ITEM(s, 0);
7227
 
        else obj = PyTuple_GET_ITEM(s, 0);
7228
 
        nd = object_depth_and_dimension(obj, max-1, newdims);
7229
 
        for (i=1; i<size; i++) {
7230
 
                if (islist) obj = PyList_GET_ITEM(s, i);
7231
 
                else obj = PyTuple_GET_ITEM(s, i);
7232
 
                test_nd = object_depth_and_dimension(obj, max-1, test_dims);
7233
 
                if ((nd != test_nd) ||
7234
 
                    (!PyArray_CompareLists(newdims, test_dims, nd))) {
7235
 
                        nd = 0;
7236
 
                        break;
7237
 
                }
7238
 
        }
7239
 
 
7240
 
        for (i=1; i<=nd; i++) dims[i] = newdims[i-1];
 
7563
    intp *newdims, *test_dims;
 
7564
    int nd, test_nd;
 
7565
    int i, islist, istuple;
 
7566
    intp size;
 
7567
    PyObject *obj;
 
7568
 
 
7569
    islist = PyList_Check(s);
 
7570
    istuple = PyTuple_Check(s);
 
7571
    if (!(islist || istuple)) {
 
7572
        return 0;
 
7573
    }
 
7574
 
 
7575
    size = PySequence_Size(s);
 
7576
    if (size == 0) {
 
7577
        return 0;
 
7578
    }
 
7579
    if (max < 1) {
 
7580
        return 0;
 
7581
    }
 
7582
    if (max < 2) {
7241
7583
        dims[0] = size;
7242
 
        PyDimMem_FREE(newdims);
7243
 
        return nd+1;
 
7584
        return 1;
 
7585
    }
 
7586
 
 
7587
    newdims = PyDimMem_NEW(2*(max - 1));
 
7588
    test_dims = newdims + (max - 1);
 
7589
    if (islist) {
 
7590
        obj = PyList_GET_ITEM(s, 0);
 
7591
    }
 
7592
    else {
 
7593
        obj = PyTuple_GET_ITEM(s, 0);
 
7594
    }
 
7595
    nd = object_depth_and_dimension(obj, max - 1, newdims);
 
7596
 
 
7597
    for(i = 1; i < size; i++) {
 
7598
        if (islist) {
 
7599
            obj = PyList_GET_ITEM(s, i);
 
7600
        }
 
7601
        else {
 
7602
            obj = PyTuple_GET_ITEM(s, i);
 
7603
        }
 
7604
        test_nd = object_depth_and_dimension(obj, max-1, test_dims);
 
7605
 
 
7606
        if ((nd != test_nd) ||
 
7607
            (!PyArray_CompareLists(newdims, test_dims, nd))) {
 
7608
            nd = 0;
 
7609
            break;
 
7610
        }
 
7611
    }
 
7612
 
 
7613
    for(i = 1; i <= nd; i++) {
 
7614
        dims[i] = newdims[i-1];
 
7615
    }
 
7616
    dims[0] = size;
 
7617
    PyDimMem_FREE(newdims);
 
7618
    return nd + 1;
7244
7619
}
7245
7620
 
7246
7621
static PyObject *
7247
7622
ObjectArray_FromNestedList(PyObject *s, PyArray_Descr *typecode, int fortran)
7248
7623
{
7249
 
        int nd;
7250
 
        intp d[MAX_DIMS];
7251
 
        PyArrayObject *r;
7252
 
 
7253
 
        /* Get the depth and the number of dimensions */
7254
 
        nd = object_depth_and_dimension(s, MAX_DIMS, d);
7255
 
        if (nd < 0) return NULL;
7256
 
 
7257
 
        if (nd == 0) return Array_FromPyScalar(s, typecode);
7258
 
 
7259
 
        r=(PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, typecode,
7260
 
                                               nd, d,
7261
 
                                               NULL, NULL,
7262
 
                                               fortran, NULL);
7263
 
 
7264
 
        if(!r) return NULL;
7265
 
        if(Assign_Array(r,s) == -1) {
7266
 
                Py_DECREF(r);
7267
 
                return NULL;
7268
 
        }
7269
 
        return (PyObject*)r;
 
7624
    int nd;
 
7625
    intp d[MAX_DIMS];
 
7626
    PyArrayObject *r;
 
7627
 
 
7628
    /* Get the depth and the number of dimensions */
 
7629
    nd = object_depth_and_dimension(s, MAX_DIMS, d);
 
7630
    if (nd < 0) {
 
7631
        return NULL;
 
7632
    }
 
7633
    if (nd == 0) {
 
7634
        return Array_FromPyScalar(s, typecode);
 
7635
    }
 
7636
 
 
7637
    r = (PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, typecode,
 
7638
                                             nd, d,
 
7639
                                             NULL, NULL,
 
7640
                                             fortran, NULL);
 
7641
 
 
7642
    if (!r) {
 
7643
        return NULL;
 
7644
    }
 
7645
    if(Assign_Array(r,s) == -1) {
 
7646
        Py_DECREF(r);
 
7647
        return NULL;
 
7648
    }
 
7649
    return (PyObject*)r;
7270
7650
}
7271
7651
 
7272
 
/* isobject means that we are constructing an
7273
 
   object array on-purpose with a nested list.
7274
 
   Only a list is interpreted as a sequence with these rules
 
7652
/* 
 
7653
 * isobject means that we are constructing an
 
7654
 * object array on-purpose with a nested list.
 
7655
 * Only a list is interpreted as a sequence with these rules
7275
7656
 */
7276
7657
/* steals reference to typecode */
7277
7658
static PyObject *
7278
7659
Array_FromSequence(PyObject *s, PyArray_Descr *typecode, int fortran,
7279
7660
                   int min_depth, int max_depth)
7280
7661
{
7281
 
        PyArrayObject *r;
7282
 
        int nd;
7283
 
        intp d[MAX_DIMS];
7284
 
        int stop_at_string;
7285
 
        int stop_at_tuple;
7286
 
        int check_it;
7287
 
        int type = typecode->type_num;
7288
 
        int itemsize = typecode->elsize;
7289
 
 
7290
 
        check_it = (typecode->type != PyArray_CHARLTR);
7291
 
 
7292
 
        stop_at_string = ((type == PyArray_OBJECT) ||   
7293
 
                          (type == PyArray_STRING && 
7294
 
                           typecode->type == PyArray_STRINGLTR) ||     
7295
 
                          (type == PyArray_UNICODE) ||  
7296
 
                          (type == PyArray_VOID));
7297
 
        
7298
 
        stop_at_tuple = (type == PyArray_VOID && (typecode->names       \
7299
 
                                                  || typecode->subarray));
7300
 
        
7301
 
        if (!((nd=discover_depth(s, MAX_DIMS+1, stop_at_string,
7302
 
                                 stop_at_tuple)) > 0)) {
7303
 
                if (nd==0)
7304
 
                        return Array_FromPyScalar(s, typecode);
7305
 
                PyErr_SetString(PyExc_ValueError,
7306
 
                                "invalid input sequence");
7307
 
                goto fail;
7308
 
        }
7309
 
 
7310
 
        if (max_depth && PyTypeNum_ISOBJECT(type) && (nd > max_depth)) {
7311
 
                nd = max_depth;
7312
 
        }
7313
 
 
7314
 
        if ((max_depth && nd > max_depth) ||    \
7315
 
            (min_depth && nd < min_depth)) {
7316
 
                PyErr_SetString(PyExc_ValueError,
7317
 
                                "invalid number of dimensions");
7318
 
                goto fail;
7319
 
        }
7320
 
 
7321
 
        if(discover_dimensions(s,nd,d, check_it) == -1) goto fail;
7322
 
 
7323
 
        if (typecode->type == PyArray_CHARLTR && nd > 0 && d[nd-1]==1) {
7324
 
                nd = nd-1;
7325
 
        }
7326
 
 
7327
 
        if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
7328
 
                if (discover_itemsize(s, nd, &itemsize) == -1) goto fail;
7329
 
                if (type == PyArray_UNICODE) itemsize*=4;
7330
 
        }
7331
 
 
7332
 
        if (itemsize != typecode->elsize) {
7333
 
                PyArray_DESCR_REPLACE(typecode);
7334
 
                typecode->elsize = itemsize;
7335
 
        }
7336
 
 
7337
 
        r=(PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, typecode,
7338
 
                                               nd, d,
7339
 
                                               NULL, NULL,
7340
 
                                               fortran, NULL);
7341
 
 
7342
 
        if(!r) return NULL;
7343
 
        if(Assign_Array(r,s) == -1) {
7344
 
                Py_DECREF(r);
7345
 
                return NULL;
7346
 
        }
7347
 
        return (PyObject*)r;
 
7662
    PyArrayObject *r;
 
7663
    int nd;
 
7664
    int err;
 
7665
    intp d[MAX_DIMS];
 
7666
    int stop_at_string;
 
7667
    int stop_at_tuple;
 
7668
    int check_it;
 
7669
    int type = typecode->type_num;
 
7670
    int itemsize = typecode->elsize;
 
7671
 
 
7672
    check_it = (typecode->type != PyArray_CHARLTR);
 
7673
 
 
7674
    stop_at_string = (type != PyArray_STRING) ||
 
7675
                     (typecode->type == PyArray_STRINGLTR);
 
7676
 
 
7677
    stop_at_tuple = (type == PyArray_VOID && (typecode->names       \
 
7678
                                              || typecode->subarray));
 
7679
 
 
7680
    nd = discover_depth(s, MAX_DIMS + 1, stop_at_string, stop_at_tuple);
 
7681
    if (nd == 0) {
 
7682
        return Array_FromPyScalar(s, typecode);
 
7683
    }
 
7684
    else if (nd < 0) {
 
7685
        PyErr_SetString(PyExc_ValueError,
 
7686
                "invalid input sequence");
 
7687
        goto fail;
 
7688
    }
 
7689
    if (max_depth && PyTypeNum_ISOBJECT(type) && (nd > max_depth)) {
 
7690
        nd = max_depth;
 
7691
    }
 
7692
    if ((max_depth && nd > max_depth) || (min_depth && nd < min_depth)) {
 
7693
        PyErr_SetString(PyExc_ValueError,
 
7694
                "invalid number of dimensions");
 
7695
        goto fail;
 
7696
    }
 
7697
 
 
7698
    err = discover_dimensions(s, nd, d, check_it);
 
7699
    if (err == -1) {
 
7700
        goto fail;
 
7701
    }
 
7702
    if (typecode->type == PyArray_CHARLTR && nd > 0 && d[nd - 1] == 1) {
 
7703
        nd = nd - 1;
 
7704
    }
 
7705
 
 
7706
    if (itemsize == 0 && PyTypeNum_ISEXTENDED(type)) {
 
7707
        err = discover_itemsize(s, nd, &itemsize);
 
7708
        if (err == -1) {
 
7709
            goto fail;
 
7710
        }
 
7711
        if (type == PyArray_UNICODE) {
 
7712
            itemsize *= 4;
 
7713
        }
 
7714
    }
 
7715
    if (itemsize != typecode->elsize) {
 
7716
        PyArray_DESCR_REPLACE(typecode);
 
7717
        typecode->elsize = itemsize;
 
7718
    }
 
7719
 
 
7720
    r = (PyArrayObject*)PyArray_NewFromDescr(&PyArray_Type, typecode,
 
7721
                                             nd, d,
 
7722
                                             NULL, NULL,
 
7723
                                             fortran, NULL);
 
7724
    if (!r) {
 
7725
        return NULL;
 
7726
    }
 
7727
 
 
7728
    err = Assign_Array(r,s);
 
7729
    if (err == -1) {
 
7730
        Py_DECREF(r);
 
7731
        return NULL;
 
7732
    }
 
7733
    return (PyObject*)r;
7348
7734
 
7349
7735
 fail:
7350
 
        Py_DECREF(typecode);
7351
 
        return NULL;
 
7736
    Py_DECREF(typecode);
 
7737
    return NULL;
7352
7738
}
7353
7739
 
7354
7740
 
7355
7741
/*OBJECT_API
7356
 
 Is the typenum valid?
 
7742
  Is the typenum valid?
7357
7743
*/
7358
7744
static int
7359
7745
PyArray_ValidType(int type)
7360
7746
{
7361
 
        PyArray_Descr *descr;
7362
 
        int res=TRUE;
 
7747
    PyArray_Descr *descr;
 
7748
    int res=TRUE;
7363
7749
 
7364
 
        descr = PyArray_DescrFromType(type);
7365
 
        if (descr==NULL) res = FALSE;
7366
 
        Py_DECREF(descr);
7367
 
        return res;
 
7750
    descr = PyArray_DescrFromType(type);
 
7751
    if (descr == NULL) {
 
7752
        res = FALSE;
 
7753
    }
 
7754
    Py_DECREF(descr);
 
7755
    return res;
7368
7756
}
7369
7757
 
7370
7758
/* For backward compatibility */
7371
7759
 
7372
7760
/* steals reference to at --- cannot be NULL*/
7373
7761
/*OBJECT_API
7374
 
 Cast an array using typecode structure.
7375
 
*/
 
7762
 *Cast an array using typecode structure.
 
7763
 */
7376
7764
static PyObject *
7377
7765
PyArray_CastToType(PyArrayObject *mp, PyArray_Descr *at, int fortran)
7378
7766
{
7379
 
        PyObject *out;
7380
 
        int ret;
7381
 
        PyArray_Descr *mpd;
7382
 
 
7383
 
        mpd = mp->descr;
7384
 
 
7385
 
        if (((mpd == at) || ((mpd->type_num == at->type_num) &&         \
7386
 
                             PyArray_EquivByteorders(mpd->byteorder,\
7387
 
                                                     at->byteorder) &&  \
7388
 
                             ((mpd->elsize == at->elsize) ||            \
7389
 
                              (at->elsize==0)))) &&                     \
7390
 
            PyArray_ISBEHAVED_RO(mp)) {
7391
 
                Py_DECREF(at);
7392
 
                Py_INCREF(mp);
7393
 
                return (PyObject *)mp;
7394
 
        }
7395
 
 
7396
 
        if (at->elsize == 0) {
7397
 
                PyArray_DESCR_REPLACE(at);
7398
 
                if (at == NULL) return NULL;
7399
 
                if (mpd->type_num == PyArray_STRING &&  \
7400
 
                    at->type_num == PyArray_UNICODE)
7401
 
                        at->elsize = mpd->elsize << 2;
7402
 
                if (mpd->type_num == PyArray_UNICODE &&
7403
 
                    at->type_num == PyArray_STRING)
7404
 
                        at->elsize = mpd->elsize >> 2;
7405
 
                if (at->type_num == PyArray_VOID)
7406
 
                        at->elsize = mpd->elsize;
7407
 
        }
7408
 
 
7409
 
        out = PyArray_NewFromDescr(mp->ob_type, at,
7410
 
                                   mp->nd,
7411
 
                                   mp->dimensions,
7412
 
                                   NULL, NULL,
7413
 
                                   fortran,
7414
 
                                   (PyObject *)mp);
7415
 
 
7416
 
        if (out == NULL) return NULL;
7417
 
        ret = PyArray_CastTo((PyArrayObject *)out, mp);
7418
 
        if (ret != -1) return out;
7419
 
 
7420
 
        Py_DECREF(out);
 
7767
    PyObject *out;
 
7768
    int ret;
 
7769
    PyArray_Descr *mpd;
 
7770
 
 
7771
    mpd = mp->descr;
 
7772
 
 
7773
    if (((mpd == at) || ((mpd->type_num == at->type_num) &&         \
 
7774
                         PyArray_EquivByteorders(mpd->byteorder,\
 
7775
                                                 at->byteorder) &&  \
 
7776
                         ((mpd->elsize == at->elsize) ||            \
 
7777
                          (at->elsize==0)))) &&                     \
 
7778
        PyArray_ISBEHAVED_RO(mp)) {
 
7779
        Py_DECREF(at);
 
7780
        Py_INCREF(mp);
 
7781
        return (PyObject *)mp;
 
7782
    }
 
7783
 
 
7784
    if (at->elsize == 0) {
 
7785
        PyArray_DESCR_REPLACE(at);
 
7786
        if (at == NULL) {
 
7787
            return NULL;
 
7788
        }
 
7789
        if (mpd->type_num == PyArray_STRING && 
 
7790
            at->type_num == PyArray_UNICODE) {
 
7791
            at->elsize = mpd->elsize << 2;
 
7792
        }
 
7793
        if (mpd->type_num == PyArray_UNICODE &&
 
7794
            at->type_num == PyArray_STRING) {
 
7795
            at->elsize = mpd->elsize >> 2;
 
7796
        }
 
7797
        if (at->type_num == PyArray_VOID) {
 
7798
            at->elsize = mpd->elsize;
 
7799
        }
 
7800
    }
 
7801
 
 
7802
    out = PyArray_NewFromDescr(mp->ob_type, at,
 
7803
                               mp->nd,
 
7804
                               mp->dimensions,
 
7805
                               NULL, NULL,
 
7806
                               fortran,
 
7807
                               (PyObject *)mp);
 
7808
 
 
7809
    if (out == NULL) {
7421
7810
        return NULL;
 
7811
    }
 
7812
    ret = PyArray_CastTo((PyArrayObject *)out, mp);
 
7813
    if (ret != -1) {
 
7814
        return out;
 
7815
    }
 
7816
 
 
7817
    Py_DECREF(out);
 
7818
    return NULL;
7422
7819
 
7423
7820
}
7424
7821
 
7425
7822
/*OBJECT_API
7426
 
   Get a cast function to cast from the input descriptor to the
7427
 
   output type_number (must be a registered data-type).
7428
 
   Returns NULL if un-successful.
 
7823
  Get a cast function to cast from the input descriptor to the
 
7824
  output type_number (must be a registered data-type).
 
7825
  Returns NULL if un-successful.
7429
7826
*/
7430
7827
static PyArray_VectorUnaryFunc *
7431
7828
PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
7432
7829
{
7433
 
        PyArray_VectorUnaryFunc *castfunc=NULL;
7434
 
        if (type_num < PyArray_NTYPES) {
7435
 
                castfunc = descr->f->cast[type_num];
7436
 
        }
7437
 
        if (castfunc == NULL) {
7438
 
                PyObject *obj = descr->f->castdict;
7439
 
                if (obj && PyDict_Check(obj)) {
7440
 
                        PyObject *key;
7441
 
                        PyObject *cobj;
7442
 
                        key = PyInt_FromLong(type_num);
7443
 
                        cobj = PyDict_GetItem(obj, key);
7444
 
                        Py_DECREF(key);
7445
 
                        if (PyCObject_Check(cobj)) {
7446
 
                                castfunc = PyCObject_AsVoidPtr(cobj);
7447
 
                        }
7448
 
                }
7449
 
                if (castfunc) return castfunc;
7450
 
        }
7451
 
        else return castfunc;
7452
 
 
7453
 
        PyErr_SetString(PyExc_ValueError,
7454
 
                        "No cast function available.");
7455
 
        return NULL;
 
7830
    PyArray_VectorUnaryFunc *castfunc=NULL;
 
7831
    if (type_num < PyArray_NTYPES) {
 
7832
        castfunc = descr->f->cast[type_num];
 
7833
    }
 
7834
    if (castfunc == NULL) {
 
7835
        PyObject *obj = descr->f->castdict;
 
7836
        if (obj && PyDict_Check(obj)) {
 
7837
            PyObject *key;
 
7838
            PyObject *cobj;
 
7839
 
 
7840
            key = PyInt_FromLong(type_num);
 
7841
            cobj = PyDict_GetItem(obj, key);
 
7842
            Py_DECREF(key);
 
7843
            if (PyCObject_Check(cobj)) {
 
7844
                castfunc = PyCObject_AsVoidPtr(cobj);
 
7845
            }
 
7846
        }
 
7847
        if (castfunc) {
 
7848
            return castfunc;
 
7849
        }
 
7850
    }
 
7851
    else {
 
7852
        return castfunc;
 
7853
    }
 
7854
 
 
7855
    PyErr_SetString(PyExc_ValueError,
 
7856
                    "No cast function available.");
 
7857
    return NULL;
7456
7858
}
7457
7859
 
7458
7860
/* Reference counts:
7472
7874
                       PyArray_VectorUnaryFunc *castfunc,
7473
7875
                       PyArrayObject *dest, PyArrayObject *src)
7474
7876
{
7475
 
        int i;
7476
 
        if (N <= bufsize) {
7477
 
                /* 1. copy input to buffer and swap
7478
 
                   2. cast input to output
7479
 
                   3. swap output if necessary and copy from output buffer
7480
 
                */
7481
 
                scopyfunc(buffers[1], selsize, sptr, sstride, N, sswap, src);
7482
 
                castfunc(buffers[1], buffers[0], N, src, dest);
7483
 
                dcopyfunc(dptr, dstride, buffers[0], delsize, N, dswap, dest);
7484
 
                return;
7485
 
        }
7486
 
 
7487
 
        /* otherwise we need to divide up into bufsize pieces */
7488
 
        i = 0;
7489
 
        while(N > 0) {
7490
 
                int newN;
7491
 
                newN = MIN(N, bufsize);
7492
 
                _strided_buffered_cast(dptr+i*dstride, dstride, delsize,
7493
 
                                       dswap, dcopyfunc,
7494
 
                                       sptr+i*sstride, sstride, selsize,
7495
 
                                       sswap, scopyfunc,
7496
 
                                       newN, buffers, bufsize, castfunc, dest, src);
7497
 
                i += newN;
7498
 
                N -= bufsize;
7499
 
        }
 
7877
    int i;
 
7878
    if (N <= bufsize) {
 
7879
        /* 1. copy input to buffer and swap
 
7880
           2. cast input to output
 
7881
           3. swap output if necessary and copy from output buffer
 
7882
        */
 
7883
        scopyfunc(buffers[1], selsize, sptr, sstride, N, sswap, src);
 
7884
        castfunc(buffers[1], buffers[0], N, src, dest);
 
7885
        dcopyfunc(dptr, dstride, buffers[0], delsize, N, dswap, dest);
7500
7886
        return;
 
7887
    }
 
7888
 
 
7889
    /* otherwise we need to divide up into bufsize pieces */
 
7890
    i = 0;
 
7891
    while(N > 0) {
 
7892
        int newN;
 
7893
        newN = MIN(N, bufsize);
 
7894
        _strided_buffered_cast(dptr+i*dstride, dstride, delsize,
 
7895
                               dswap, dcopyfunc,
 
7896
                               sptr+i*sstride, sstride, selsize,
 
7897
                               sswap, scopyfunc,
 
7898
                               newN, buffers, bufsize, castfunc, dest, src);
 
7899
        i += newN;
 
7900
        N -= bufsize;
 
7901
    }
 
7902
    return;
7501
7903
}
7502
7904
 
7503
7905
static int
7504
7906
_broadcast_cast(PyArrayObject *out, PyArrayObject *in,
7505
7907
                PyArray_VectorUnaryFunc *castfunc, int iswap, int oswap)
7506
7908
{
7507
 
        int delsize, selsize, maxaxis, i, N;
7508
 
        PyArrayMultiIterObject *multi;
7509
 
        intp maxdim, ostrides, istrides;
7510
 
        char *buffers[2];
7511
 
        PyArray_CopySwapNFunc *ocopyfunc, *icopyfunc;
7512
 
        char *obptr;
7513
 
 
7514
 
        NPY_BEGIN_THREADS_DEF
7515
 
 
7516
 
        delsize = PyArray_ITEMSIZE(out);
7517
 
        selsize = PyArray_ITEMSIZE(in);
7518
 
        multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, out, in);
7519
 
        if (multi == NULL) return -1;
7520
 
 
7521
 
        if (multi->size != PyArray_SIZE(out)) {
7522
 
                PyErr_SetString(PyExc_ValueError,
7523
 
                                "array dimensions are not "\
7524
 
                                "compatible for copy");
7525
 
                Py_DECREF(multi);
7526
 
                return -1;
7527
 
        }
7528
 
 
7529
 
        icopyfunc = in->descr->f->copyswapn;
7530
 
        ocopyfunc = out->descr->f->copyswapn;
7531
 
        maxaxis = PyArray_RemoveSmallest(multi);
7532
 
        if (maxaxis < 0) { /* cast 1 0-d array to another */
7533
 
                N = 1;
7534
 
                maxdim = 1;
7535
 
                ostrides = delsize;
7536
 
                istrides = selsize;
7537
 
        }
7538
 
        else {
7539
 
                maxdim = multi->dimensions[maxaxis];
7540
 
                N = (int) (MIN(maxdim, PyArray_BUFSIZE));
7541
 
                ostrides = multi->iters[0]->strides[maxaxis];
7542
 
                istrides = multi->iters[1]->strides[maxaxis];
7543
 
 
7544
 
        }
7545
 
        buffers[0] = _pya_malloc(N*delsize);
7546
 
        if (buffers[0] == NULL) {
7547
 
                PyErr_NoMemory();
7548
 
                return -1;
7549
 
        }
7550
 
        buffers[1] = _pya_malloc(N*selsize);
7551
 
        if (buffers[1] == NULL) {
7552
 
                _pya_free(buffers[0]);
7553
 
                PyErr_NoMemory();
7554
 
                return -1;
7555
 
        }
7556
 
        if (PyDataType_FLAGCHK(out->descr, NPY_NEEDS_INIT))
7557
 
                memset(buffers[0], 0, N*delsize);
7558
 
        if (PyDataType_FLAGCHK(in->descr, NPY_NEEDS_INIT))
7559
 
                memset(buffers[1], 0, N*selsize);
7560
 
 
7561
 
#if NPY_ALLOW_THREADS
7562
 
        if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
7563
 
                NPY_BEGIN_THREADS
7564
 
                        }
7565
 
#endif
7566
 
 
7567
 
        while(multi->index < multi->size) {
7568
 
                _strided_buffered_cast(multi->iters[0]->dataptr,
7569
 
                                       ostrides,
7570
 
                                       delsize, oswap, ocopyfunc,
7571
 
                                       multi->iters[1]->dataptr,
7572
 
                                       istrides,
7573
 
                                       selsize, iswap, icopyfunc,
7574
 
                                       maxdim, buffers, N,
7575
 
                                       castfunc, out, in);
7576
 
                PyArray_MultiIter_NEXT(multi);
7577
 
        }
7578
 
#if NPY_ALLOW_THREADS
7579
 
        if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
7580
 
                NPY_END_THREADS
7581
 
                        }
7582
 
#endif
 
7909
    int delsize, selsize, maxaxis, i, N;
 
7910
    PyArrayMultiIterObject *multi;
 
7911
    intp maxdim, ostrides, istrides;
 
7912
    char *buffers[2];
 
7913
    PyArray_CopySwapNFunc *ocopyfunc, *icopyfunc;
 
7914
    char *obptr;
 
7915
    NPY_BEGIN_THREADS_DEF;
 
7916
 
 
7917
    delsize = PyArray_ITEMSIZE(out);
 
7918
    selsize = PyArray_ITEMSIZE(in);
 
7919
    multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, out, in);
 
7920
    if (multi == NULL) {
 
7921
        return -1;
 
7922
    }
 
7923
 
 
7924
    if (multi->size != PyArray_SIZE(out)) {
 
7925
        PyErr_SetString(PyExc_ValueError,
 
7926
                "array dimensions are not "\
 
7927
                "compatible for copy");
7583
7928
        Py_DECREF(multi);
7584
 
        if (PyDataType_REFCHK(in->descr)) {
7585
 
                obptr = buffers[1];
7586
 
                for (i=0; i<N; i++, obptr+=selsize)
7587
 
                        PyArray_Item_XDECREF(obptr, out->descr);
7588
 
        }
7589
 
        if (PyDataType_REFCHK(out->descr)) {
7590
 
                obptr = buffers[0];
7591
 
                for (i=0; i<N; i++, obptr+=delsize)
7592
 
                        PyArray_Item_XDECREF(obptr, out->descr);
7593
 
        }
 
7929
        return -1;
 
7930
    }
 
7931
 
 
7932
    icopyfunc = in->descr->f->copyswapn;
 
7933
    ocopyfunc = out->descr->f->copyswapn;
 
7934
    maxaxis = PyArray_RemoveSmallest(multi);
 
7935
    if (maxaxis < 0) {
 
7936
        /* cast 1 0-d array to another */
 
7937
        N = 1;
 
7938
        maxdim = 1;
 
7939
        ostrides = delsize;
 
7940
        istrides = selsize;
 
7941
    }
 
7942
    else {
 
7943
        maxdim = multi->dimensions[maxaxis];
 
7944
        N = (int) (MIN(maxdim, PyArray_BUFSIZE));
 
7945
        ostrides = multi->iters[0]->strides[maxaxis];
 
7946
        istrides = multi->iters[1]->strides[maxaxis];
 
7947
 
 
7948
    }
 
7949
    buffers[0] = _pya_malloc(N*delsize);
 
7950
    if (buffers[0] == NULL) {
 
7951
        PyErr_NoMemory();
 
7952
        return -1;
 
7953
    }
 
7954
    buffers[1] = _pya_malloc(N*selsize);
 
7955
    if (buffers[1] == NULL) {
7594
7956
        _pya_free(buffers[0]);
7595
 
        _pya_free(buffers[1]);
7596
 
        if (PyErr_Occurred()) return -1;
7597
 
        return 0;
 
7957
        PyErr_NoMemory();
 
7958
        return -1;
 
7959
    }
 
7960
    if (PyDataType_FLAGCHK(out->descr, NPY_NEEDS_INIT)) {
 
7961
        memset(buffers[0], 0, N*delsize);
 
7962
    }
 
7963
    if (PyDataType_FLAGCHK(in->descr, NPY_NEEDS_INIT)) {
 
7964
        memset(buffers[1], 0, N*selsize);
 
7965
    }
 
7966
 
 
7967
#if NPY_ALLOW_THREADS
 
7968
    if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
 
7969
        NPY_BEGIN_THREADS;
 
7970
    }
 
7971
#endif
 
7972
 
 
7973
    while(multi->index < multi->size) {
 
7974
        _strided_buffered_cast(multi->iters[0]->dataptr,
 
7975
                ostrides,
 
7976
                delsize, oswap, ocopyfunc,
 
7977
                multi->iters[1]->dataptr,
 
7978
                istrides,
 
7979
                selsize, iswap, icopyfunc,
 
7980
                maxdim, buffers, N,
 
7981
                castfunc, out, in);
 
7982
        PyArray_MultiIter_NEXT(multi);
 
7983
    }
 
7984
#if NPY_ALLOW_THREADS
 
7985
    if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
 
7986
        NPY_END_THREADS;
 
7987
    }
 
7988
#endif
 
7989
    Py_DECREF(multi);
 
7990
    if (PyDataType_REFCHK(in->descr)) {
 
7991
        obptr = buffers[1];
 
7992
        for(i = 0; i < N; i++, obptr+=selsize) {
 
7993
            PyArray_Item_XDECREF(obptr, out->descr);
 
7994
        }
 
7995
    }
 
7996
    if (PyDataType_REFCHK(out->descr)) {
 
7997
        obptr = buffers[0];
 
7998
        for(i = 0; i < N; i++, obptr+=delsize) {
 
7999
            PyArray_Item_XDECREF(obptr, out->descr);
 
8000
        }
 
8001
    }
 
8002
    _pya_free(buffers[0]);
 
8003
    _pya_free(buffers[1]);
 
8004
    if (PyErr_Occurred()) {
 
8005
        return -1;
 
8006
    }
 
8007
 
 
8008
    return 0;
7598
8009
}
7599
8010
 
7600
8011
 
7601
8012
 
7602
 
/* Must be broadcastable.
7603
 
   This code is very similar to PyArray_CopyInto/PyArray_MoveInto
7604
 
   except casting is done --- PyArray_BUFSIZE is used
7605
 
   as the size of the casting buffer.
7606
 
*/
 
8013
/*
 
8014
 * Must be broadcastable.
 
8015
 * This code is very similar to PyArray_CopyInto/PyArray_MoveInto
 
8016
 * except casting is done --- PyArray_BUFSIZE is used
 
8017
 * as the size of the casting buffer.
 
8018
 */
7607
8019
 
7608
8020
/*OBJECT_API
7609
 
 Cast to an already created array.
7610
 
*/
 
8021
 * Cast to an already created array.
 
8022
 */
7611
8023
static int
7612
8024
PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
7613
8025
{
7614
 
 
7615
 
        int simple;
7616
 
        int same;
7617
 
        PyArray_VectorUnaryFunc *castfunc=NULL;
7618
 
        int mpsize = PyArray_SIZE(mp);
 
8026
    int simple;
 
8027
    int same;
 
8028
    PyArray_VectorUnaryFunc *castfunc=NULL;
 
8029
    int mpsize = PyArray_SIZE(mp);
 
8030
    int iswap, oswap;
 
8031
    NPY_BEGIN_THREADS_DEF;
 
8032
 
 
8033
    if (mpsize == 0) {
 
8034
        return 0;
 
8035
    }
 
8036
    if (!PyArray_ISWRITEABLE(out)) {
 
8037
        PyErr_SetString(PyExc_ValueError,
 
8038
                "output array is not writeable");
 
8039
        return -1;
 
8040
    }
 
8041
 
 
8042
    castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
 
8043
    if (castfunc == NULL) {
 
8044
        return -1;
 
8045
    }
 
8046
 
 
8047
    same = PyArray_SAMESHAPE(out, mp);
 
8048
    simple = same && ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
 
8049
            (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
 
8050
    if (simple) {
 
8051
#if NPY_ALLOW_THREADS
 
8052
        if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
 
8053
            NPY_BEGIN_THREADS;
 
8054
        }
 
8055
#endif
 
8056
        castfunc(mp->data, out->data, mpsize, mp, out);
 
8057
 
 
8058
#if NPY_ALLOW_THREADS
 
8059
        if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
 
8060
            NPY_END_THREADS;
 
8061
        }
 
8062
#endif
 
8063
        if (PyErr_Occurred()) {
 
8064
            return -1;
 
8065
        }
 
8066
        return 0;
 
8067
    }
 
8068
 
 
8069
    /*
 
8070
     * If the input or output is OBJECT, STRING, UNICODE, or VOID
 
8071
     *  then getitem and setitem are used for the cast
 
8072
     *  and byteswapping is handled by those methods
 
8073
     */
 
8074
    if (PyArray_ISFLEXIBLE(mp) || PyArray_ISOBJECT(mp) || PyArray_ISOBJECT(out) ||
 
8075
            PyArray_ISFLEXIBLE(out)) {
 
8076
        iswap = oswap = 0;
 
8077
    }
 
8078
    else {
 
8079
        iswap = PyArray_ISBYTESWAPPED(mp);
 
8080
        oswap = PyArray_ISBYTESWAPPED(out);
 
8081
    }
 
8082
 
 
8083
    return _broadcast_cast(out, mp, castfunc, iswap, oswap);
 
8084
}
 
8085
 
 
8086
 
 
8087
static int
 
8088
_bufferedcast(PyArrayObject *out, PyArrayObject *in,
 
8089
              PyArray_VectorUnaryFunc *castfunc)
 
8090
{
 
8091
    char *inbuffer, *bptr, *optr;
 
8092
    char *outbuffer=NULL;
 
8093
    PyArrayIterObject *it_in=NULL, *it_out=NULL;
 
8094
    register intp i, index;
 
8095
    intp ncopies = PyArray_SIZE(out) / PyArray_SIZE(in);
 
8096
    int elsize=in->descr->elsize;
 
8097
    int nels = PyArray_BUFSIZE;
 
8098
    int el;
 
8099
    int inswap, outswap=0;
 
8100
    int obuf=!PyArray_ISCARRAY(out);
 
8101
    int oelsize = out->descr->elsize;
 
8102
    PyArray_CopySwapFunc *in_csn;
 
8103
    PyArray_CopySwapFunc *out_csn;
 
8104
    int retval = -1;
 
8105
 
 
8106
    in_csn = in->descr->f->copyswap;
 
8107
    out_csn = out->descr->f->copyswap;
 
8108
 
 
8109
    /*
 
8110
     * If the input or output is STRING, UNICODE, or VOID
 
8111
     * then getitem and setitem are used for the cast
 
8112
     *  and byteswapping is handled by those methods
 
8113
     */
 
8114
 
 
8115
    inswap = !(PyArray_ISFLEXIBLE(in) || PyArray_ISNOTSWAPPED(in));
 
8116
 
 
8117
    inbuffer = PyDataMem_NEW(PyArray_BUFSIZE*elsize);
 
8118
    if (inbuffer == NULL) return -1;
 
8119
    if (PyArray_ISOBJECT(in))
 
8120
        memset(inbuffer, 0, PyArray_BUFSIZE*elsize);
 
8121
    it_in = (PyArrayIterObject *)PyArray_IterNew((PyObject *)in);
 
8122
    if (it_in == NULL) goto exit;
 
8123
 
 
8124
    if (obuf) {
 
8125
        outswap = !(PyArray_ISFLEXIBLE(out) || \
 
8126
                    PyArray_ISNOTSWAPPED(out));
 
8127
        outbuffer = PyDataMem_NEW(PyArray_BUFSIZE*oelsize);
 
8128
        if (outbuffer == NULL) goto exit;
 
8129
        if (PyArray_ISOBJECT(out))
 
8130
            memset(outbuffer, 0, PyArray_BUFSIZE*oelsize);
 
8131
 
 
8132
        it_out = (PyArrayIterObject *)PyArray_IterNew((PyObject *)out);
 
8133
        if (it_out == NULL) goto exit;
 
8134
 
 
8135
        nels = MIN(nels, PyArray_BUFSIZE);
 
8136
    }
 
8137
 
 
8138
    optr = (obuf) ? outbuffer: out->data;
 
8139
    bptr = inbuffer;
 
8140
    el = 0;
 
8141
    while(ncopies--) {
 
8142
        index = it_in->size;
 
8143
        PyArray_ITER_RESET(it_in);
 
8144
        while(index--) {
 
8145
            in_csn(bptr, it_in->dataptr, inswap, in);
 
8146
            bptr += elsize;
 
8147
            PyArray_ITER_NEXT(it_in);
 
8148
            el += 1;
 
8149
            if ((el == nels) || (index == 0)) {
 
8150
                /* buffer filled, do cast */
 
8151
 
 
8152
                castfunc(inbuffer, optr, el, in, out);
 
8153
 
 
8154
                if (obuf) {
 
8155
                    /* Copy from outbuffer to array */
 
8156
                    for(i=0; i<el; i++) {
 
8157
                        out_csn(it_out->dataptr,
 
8158
                                optr, outswap,
 
8159
                                out);
 
8160
                        optr += oelsize;
 
8161
                        PyArray_ITER_NEXT(it_out);
 
8162
                    }
 
8163
                    optr = outbuffer;
 
8164
                }
 
8165
                else {
 
8166
                    optr += out->descr->elsize * nels;
 
8167
                }
 
8168
                el = 0;
 
8169
                bptr = inbuffer;
 
8170
            }
 
8171
        }
 
8172
    }
 
8173
    retval = 0;
 
8174
 exit:
 
8175
    Py_XDECREF(it_in);
 
8176
    PyDataMem_FREE(inbuffer);
 
8177
    PyDataMem_FREE(outbuffer);
 
8178
    if (obuf) {
 
8179
        Py_XDECREF(it_out);
 
8180
    }
 
8181
    return retval;
 
8182
}
 
8183
 
 
8184
/*OBJECT_API
 
8185
  Cast to an already created array.  Arrays don't have to be "broadcastable"
 
8186
  Only requirement is they have the same number of elements.
 
8187
*/
 
8188
static int
 
8189
PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
 
8190
{
 
8191
    int simple;
 
8192
    PyArray_VectorUnaryFunc *castfunc=NULL;
 
8193
    int mpsize = PyArray_SIZE(mp);
 
8194
 
 
8195
    if (mpsize == 0) return 0;
 
8196
    if (!PyArray_ISWRITEABLE(out)) {
 
8197
        PyErr_SetString(PyExc_ValueError,
 
8198
                        "output array is not writeable");
 
8199
        return -1;
 
8200
    }
 
8201
 
 
8202
    if (!(mpsize == PyArray_SIZE(out))) {
 
8203
        PyErr_SetString(PyExc_ValueError,
 
8204
                        "arrays must have the same number of"
 
8205
                        " elements for the cast.");
 
8206
        return -1;
 
8207
    }
 
8208
 
 
8209
    castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
 
8210
    if (castfunc == NULL) return -1;
 
8211
 
 
8212
 
 
8213
    simple = ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
 
8214
              (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
 
8215
 
 
8216
    if (simple) {
 
8217
        castfunc(mp->data, out->data, mpsize, mp, out);
 
8218
        return 0;
 
8219
    }
 
8220
 
 
8221
    if (PyArray_SAMESHAPE(out, mp)) {
7619
8222
        int iswap, oswap;
7620
 
 
7621
 
        NPY_BEGIN_THREADS_DEF
7622
 
 
7623
 
        if (mpsize == 0) return 0;
7624
 
        if (!PyArray_ISWRITEABLE(out)) {
7625
 
                PyErr_SetString(PyExc_ValueError,
7626
 
                                "output array is not writeable");
7627
 
                return -1;
7628
 
        }
7629
 
 
7630
 
        castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
7631
 
        if (castfunc == NULL) return -1;
7632
 
 
7633
 
 
7634
 
        same = PyArray_SAMESHAPE(out, mp);
7635
 
        simple = same && ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
7636
 
                          (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
7637
 
 
7638
 
        if (simple) {
7639
 
 
7640
 
#if NPY_ALLOW_THREADS
7641
 
                if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
7642
 
                        NPY_BEGIN_THREADS }
7643
 
#endif
7644
 
                castfunc(mp->data, out->data, mpsize, mp, out);
7645
 
 
7646
 
#if NPY_ALLOW_THREADS
7647
 
                if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
7648
 
                        NPY_END_THREADS   }
7649
 
#endif
7650
 
                if (!PyArray_ISNUMBER(mp) && PyErr_Occurred()) return -1;
7651
 
        }
7652
 
 
7653
 
        /* If the input or output is STRING, UNICODE, or VOID */
7654
 
        /*  then getitem and setitem are used for the cast */
7655
 
        /*  and byteswapping is handled by those methods */
7656
 
 
7657
8223
        iswap = PyArray_ISBYTESWAPPED(mp) && !PyArray_ISFLEXIBLE(mp);
7658
8224
        oswap = PyArray_ISBYTESWAPPED(out) && !PyArray_ISFLEXIBLE(out);
7659
 
 
7660
8225
        return _broadcast_cast(out, mp, castfunc, iswap, oswap);
7661
 
}
7662
 
 
7663
 
 
7664
 
static int
7665
 
_bufferedcast(PyArrayObject *out, PyArrayObject *in,
7666
 
              PyArray_VectorUnaryFunc *castfunc)
7667
 
{
7668
 
        char *inbuffer, *bptr, *optr;
7669
 
        char *outbuffer=NULL;
7670
 
        PyArrayIterObject *it_in=NULL, *it_out=NULL;
7671
 
        register intp i, index;
7672
 
        intp ncopies = PyArray_SIZE(out) / PyArray_SIZE(in);
7673
 
        int elsize=in->descr->elsize;
7674
 
        int nels = PyArray_BUFSIZE;
7675
 
        int el;
7676
 
        int inswap, outswap=0;
7677
 
        int obuf=!PyArray_ISCARRAY(out);
7678
 
        int oelsize = out->descr->elsize;
7679
 
        PyArray_CopySwapFunc *in_csn;
7680
 
        PyArray_CopySwapFunc *out_csn;
7681
 
        int retval = -1;
7682
 
 
7683
 
        in_csn = in->descr->f->copyswap;
7684
 
        out_csn = out->descr->f->copyswap;
7685
 
 
7686
 
        /* If the input or output is STRING, UNICODE, or VOID */
7687
 
        /*  then getitem and setitem are used for the cast */
7688
 
        /*  and byteswapping is handled by those methods */
7689
 
 
7690
 
        inswap = !(PyArray_ISFLEXIBLE(in) || PyArray_ISNOTSWAPPED(in));
7691
 
 
7692
 
        inbuffer = PyDataMem_NEW(PyArray_BUFSIZE*elsize);
7693
 
        if (inbuffer == NULL) return -1;
7694
 
        if (PyArray_ISOBJECT(in))
7695
 
                memset(inbuffer, 0, PyArray_BUFSIZE*elsize);
7696
 
        it_in = (PyArrayIterObject *)PyArray_IterNew((PyObject *)in);
7697
 
        if (it_in == NULL) goto exit;
7698
 
 
7699
 
        if (obuf) {
7700
 
                outswap = !(PyArray_ISFLEXIBLE(out) || \
7701
 
                            PyArray_ISNOTSWAPPED(out));
7702
 
                outbuffer = PyDataMem_NEW(PyArray_BUFSIZE*oelsize);
7703
 
                if (outbuffer == NULL) goto exit;
7704
 
                if (PyArray_ISOBJECT(out))
7705
 
                        memset(outbuffer, 0, PyArray_BUFSIZE*oelsize);
7706
 
 
7707
 
                it_out = (PyArrayIterObject *)PyArray_IterNew((PyObject *)out);
7708
 
                if (it_out == NULL) goto exit;
7709
 
 
7710
 
                nels = MIN(nels, PyArray_BUFSIZE);
7711
 
        }
7712
 
 
7713
 
        optr = (obuf) ? outbuffer: out->data;
7714
 
        bptr = inbuffer;
7715
 
        el = 0;
7716
 
        while(ncopies--) {
7717
 
                index = it_in->size;
7718
 
                PyArray_ITER_RESET(it_in);
7719
 
                while(index--) {
7720
 
                        in_csn(bptr, it_in->dataptr, inswap, in);
7721
 
                        bptr += elsize;
7722
 
                        PyArray_ITER_NEXT(it_in);
7723
 
                        el += 1;
7724
 
                        if ((el == nels) || (index == 0)) {
7725
 
                                /* buffer filled, do cast */
7726
 
 
7727
 
                                castfunc(inbuffer, optr, el, in, out);
7728
 
 
7729
 
                                if (obuf) {
7730
 
                                        /* Copy from outbuffer to array */
7731
 
                                        for(i=0; i<el; i++) {
7732
 
                                                out_csn(it_out->dataptr,
7733
 
                                                        optr, outswap,
7734
 
                                                        out);
7735
 
                                                optr += oelsize;
7736
 
                                                PyArray_ITER_NEXT(it_out);
7737
 
                                        }
7738
 
                                        optr = outbuffer;
7739
 
                                }
7740
 
                                else {
7741
 
                                        optr += out->descr->elsize * nels;
7742
 
                                }
7743
 
                                el = 0;
7744
 
                                bptr = inbuffer;
7745
 
                        }
7746
 
                }
7747
 
        }
7748
 
        retval = 0;
7749
 
 exit:
7750
 
        Py_XDECREF(it_in);
7751
 
        PyDataMem_FREE(inbuffer);
7752
 
        PyDataMem_FREE(outbuffer);
7753
 
        if (obuf) {
7754
 
                Py_XDECREF(it_out);
7755
 
        }
7756
 
        return retval;
7757
 
}
7758
 
 
7759
 
/*OBJECT_API
7760
 
 Cast to an already created array.  Arrays don't have to be "broadcastable"
7761
 
 Only requirement is they have the same number of elements.
7762
 
*/
7763
 
static int
7764
 
PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
7765
 
{
7766
 
        int simple;
7767
 
        PyArray_VectorUnaryFunc *castfunc=NULL;
7768
 
        int mpsize = PyArray_SIZE(mp);
7769
 
 
7770
 
        if (mpsize == 0) return 0;
7771
 
        if (!PyArray_ISWRITEABLE(out)) {
7772
 
                PyErr_SetString(PyExc_ValueError,
7773
 
                                "output array is not writeable");
7774
 
                return -1;
7775
 
        }
7776
 
 
7777
 
        if (!(mpsize == PyArray_SIZE(out))) {
7778
 
                PyErr_SetString(PyExc_ValueError,
7779
 
                                "arrays must have the same number of"
7780
 
                                " elements for the cast.");
7781
 
                return -1;
7782
 
        }
7783
 
 
7784
 
        castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
7785
 
        if (castfunc == NULL) return -1;
7786
 
 
7787
 
 
7788
 
        simple = ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
7789
 
                  (PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
7790
 
 
7791
 
        if (simple) {
7792
 
                castfunc(mp->data, out->data, mpsize, mp, out);
7793
 
                return 0;
7794
 
        }
7795
 
 
7796
 
        if (PyArray_SAMESHAPE(out, mp)) {
7797
 
                int iswap, oswap;
7798
 
                iswap = PyArray_ISBYTESWAPPED(mp) && !PyArray_ISFLEXIBLE(mp);
7799
 
                oswap = PyArray_ISBYTESWAPPED(out) && !PyArray_ISFLEXIBLE(out);
7800
 
                return _broadcast_cast(out, mp, castfunc, iswap, oswap);
7801
 
        }
7802
 
 
7803
 
        return _bufferedcast(out, mp, castfunc);
 
8226
    }
 
8227
 
 
8228
    return _bufferedcast(out, mp, castfunc);
7804
8229
}
7805
8230
 
7806
8231
 
7811
8236
PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags)
7812
8237
{
7813
8238
 
7814
 
        PyArrayObject *ret=NULL;
7815
 
        int itemsize;
7816
 
        int copy = 0;
7817
 
        int arrflags;
7818
 
        PyArray_Descr *oldtype;
7819
 
        char *msg = "cannot copy back to a read-only array";
7820
 
        PyTypeObject *subtype;
7821
 
 
7822
 
        oldtype = PyArray_DESCR(arr);
7823
 
 
7824
 
        subtype = arr->ob_type;
7825
 
 
7826
 
        if (newtype == NULL) {newtype = oldtype; Py_INCREF(oldtype);}
 
8239
    PyArrayObject *ret=NULL;
 
8240
    int itemsize;
 
8241
    int copy = 0;
 
8242
    int arrflags;
 
8243
    PyArray_Descr *oldtype;
 
8244
    char *msg = "cannot copy back to a read-only array";
 
8245
    PyTypeObject *subtype;
 
8246
 
 
8247
    oldtype = PyArray_DESCR(arr);
 
8248
 
 
8249
    subtype = arr->ob_type;
 
8250
 
 
8251
    if (newtype == NULL) {
 
8252
        newtype = oldtype; Py_INCREF(oldtype);
 
8253
    }
 
8254
    itemsize = newtype->elsize;
 
8255
    if (itemsize == 0) {
 
8256
        PyArray_DESCR_REPLACE(newtype);
 
8257
        if (newtype == NULL) {
 
8258
            return NULL;
 
8259
        }
 
8260
        newtype->elsize = oldtype->elsize;
7827
8261
        itemsize = newtype->elsize;
7828
 
        if (itemsize == 0) {
7829
 
                PyArray_DESCR_REPLACE(newtype);
7830
 
                if (newtype == NULL) return NULL;
7831
 
                newtype->elsize = oldtype->elsize;
7832
 
                itemsize = newtype->elsize;
7833
 
        }
7834
 
 
7835
 
        /* Can't cast unless ndim-0 array, FORCECAST is specified
7836
 
           or the cast is safe.
7837
 
        */
7838
 
        if (!(flags & FORCECAST) && !PyArray_NDIM(arr)==0 && 
7839
 
            !PyArray_CanCastTo(oldtype, newtype)) {
 
8262
    }
 
8263
 
 
8264
    /* Can't cast unless ndim-0 array, FORCECAST is specified
 
8265
       or the cast is safe.
 
8266
    */
 
8267
    if (!(flags & FORCECAST) && !PyArray_NDIM(arr)==0 &&
 
8268
        !PyArray_CanCastTo(oldtype, newtype)) {
 
8269
        Py_DECREF(newtype);
 
8270
        PyErr_SetString(PyExc_TypeError,
 
8271
                        "array cannot be safely cast "  \
 
8272
                        "to required type");
 
8273
        return NULL;
 
8274
    }
 
8275
 
 
8276
    /* Don't copy if sizes are compatible */
 
8277
    if ((flags & ENSURECOPY) || PyArray_EquivTypes(oldtype, newtype)) {
 
8278
        arrflags = arr->flags;
 
8279
 
 
8280
        copy = (flags & ENSURECOPY) || \
 
8281
            ((flags & CONTIGUOUS) && (!(arrflags & CONTIGUOUS))) \
 
8282
            || ((flags & ALIGNED) && (!(arrflags & ALIGNED))) \
 
8283
            || (arr->nd > 1 &&                              \
 
8284
                ((flags & FORTRAN) && (!(arrflags & FORTRAN)))) \
 
8285
            || ((flags & WRITEABLE) && (!(arrflags & WRITEABLE)));
 
8286
 
 
8287
        if (copy) {
 
8288
            if ((flags & UPDATEIFCOPY) && \
 
8289
                (!PyArray_ISWRITEABLE(arr))) {
7840
8290
                Py_DECREF(newtype);
7841
 
                PyErr_SetString(PyExc_TypeError,
7842
 
                                "array cannot be safely cast "  \
7843
 
                                "to required type");
7844
 
                return NULL;
7845
 
        }
7846
 
        
7847
 
        /* Don't copy if sizes are compatible */
7848
 
        if ((flags & ENSURECOPY) || PyArray_EquivTypes(oldtype, newtype)) {
7849
 
                arrflags = arr->flags;
7850
 
 
7851
 
                copy = (flags & ENSURECOPY) || \
7852
 
                        ((flags & CONTIGUOUS) && (!(arrflags & CONTIGUOUS))) \
7853
 
                        || ((flags & ALIGNED) && (!(arrflags & ALIGNED))) \
7854
 
                        || (arr->nd > 1 &&                              \
7855
 
                            ((flags & FORTRAN) && (!(arrflags & FORTRAN)))) \
7856
 
                        || ((flags & WRITEABLE) && (!(arrflags & WRITEABLE)));
7857
 
 
7858
 
                if (copy) {
7859
 
                        if ((flags & UPDATEIFCOPY) && \
7860
 
                            (!PyArray_ISWRITEABLE(arr))) {
7861
 
                                Py_DECREF(newtype);
7862
 
                                PyErr_SetString(PyExc_ValueError, msg);
7863
 
                                return NULL;
7864
 
                        }
7865
 
                        if ((flags & ENSUREARRAY)) {
7866
 
                                subtype = &PyArray_Type;
7867
 
                        }
7868
 
                        ret = (PyArrayObject *)         \
7869
 
                                PyArray_NewFromDescr(subtype, newtype,
7870
 
                                                     arr->nd,
7871
 
                                                     arr->dimensions,
7872
 
                                                     NULL, NULL,
7873
 
                                                     flags & FORTRAN,
7874
 
                                                     (PyObject *)arr);
7875
 
                        if (ret == NULL) return NULL;
7876
 
                        if (PyArray_CopyInto(ret, arr) == -1)
7877
 
                                {Py_DECREF(ret); return NULL;}
7878
 
                        if (flags & UPDATEIFCOPY)  {
7879
 
                                ret->flags |= UPDATEIFCOPY;
7880
 
                                ret->base = (PyObject *)arr;
7881
 
                                PyArray_FLAGS(ret->base) &= ~WRITEABLE;
7882
 
                                Py_INCREF(arr);
7883
 
                        }
7884
 
                }
7885
 
                /* If no copy then just increase the reference
7886
 
                   count and return the input */
7887
 
                else {
7888
 
                        Py_DECREF(newtype);
7889
 
                        if ((flags & ENSUREARRAY) && 
7890
 
                            !PyArray_CheckExact(arr)) {
7891
 
                                Py_INCREF(arr->descr);
7892
 
                                ret = (PyArrayObject *)                 \
7893
 
                                        PyArray_NewFromDescr(&PyArray_Type,
7894
 
                                                             arr->descr,
7895
 
                                                             arr->nd,
7896
 
                                                             arr->dimensions,
7897
 
                                                             arr->strides,
7898
 
                                                             arr->data,
7899
 
                                                             arr->flags,NULL);
7900
 
                                if (ret == NULL) return NULL;
7901
 
                                ret->base = (PyObject *)arr;
7902
 
                        }
7903
 
                        else {
7904
 
                                ret = arr;
7905
 
                        }
7906
 
                        Py_INCREF(arr);
7907
 
                }
7908
 
        }
7909
 
 
7910
 
        /* The desired output type is different than the input
7911
 
           array type and copy was not specified */
 
8291
                PyErr_SetString(PyExc_ValueError, msg);
 
8292
                return NULL;
 
8293
            }
 
8294
            if ((flags & ENSUREARRAY)) {
 
8295
                subtype = &PyArray_Type;
 
8296
            }
 
8297
            ret = (PyArrayObject *)         \
 
8298
                PyArray_NewFromDescr(subtype, newtype,
 
8299
                                     arr->nd,
 
8300
                                     arr->dimensions,
 
8301
                                     NULL, NULL,
 
8302
                                     flags & FORTRAN,
 
8303
                                     (PyObject *)arr);
 
8304
            if (ret == NULL) {
 
8305
                return NULL;
 
8306
            }
 
8307
            if (PyArray_CopyInto(ret, arr) == -1) {
 
8308
                Py_DECREF(ret);
 
8309
                return NULL;
 
8310
            }
 
8311
            if (flags & UPDATEIFCOPY)  {
 
8312
                ret->flags |= UPDATEIFCOPY;
 
8313
                ret->base = (PyObject *)arr;
 
8314
                PyArray_FLAGS(ret->base) &= ~WRITEABLE;
 
8315
                Py_INCREF(arr);
 
8316
            }
 
8317
        }
 
8318
        /* If no copy then just increase the reference
 
8319
           count and return the input */
7912
8320
        else {
7913
 
                if ((flags & UPDATEIFCOPY) &&                   \
7914
 
                    (!PyArray_ISWRITEABLE(arr))) {
7915
 
                        Py_DECREF(newtype);
7916
 
                        PyErr_SetString(PyExc_ValueError, msg);
7917
 
                        return NULL;
7918
 
                }
7919
 
                if ((flags & ENSUREARRAY)) {
7920
 
                        subtype = &PyArray_Type;
7921
 
                }
7922
 
                ret = (PyArrayObject *)                         \
7923
 
                        PyArray_NewFromDescr(subtype, newtype,
7924
 
                                             arr->nd, arr->dimensions,
7925
 
                                             NULL, NULL,
7926
 
                                             flags & FORTRAN,
7927
 
                                             (PyObject *)arr);
7928
 
                if (ret == NULL) return NULL;
7929
 
                if (PyArray_CastTo(ret, arr) < 0) {
7930
 
                        Py_DECREF(ret);
7931
 
                        return NULL;
7932
 
                }
7933
 
                if (flags & UPDATEIFCOPY)  {
7934
 
                        ret->flags |= UPDATEIFCOPY;
7935
 
                        ret->base = (PyObject *)arr;
7936
 
                        PyArray_FLAGS(ret->base) &= ~WRITEABLE;
7937
 
                        Py_INCREF(arr);
7938
 
                }
7939
 
        }
7940
 
        return (PyObject *)ret;
 
8321
            Py_DECREF(newtype);
 
8322
            if ((flags & ENSUREARRAY) &&
 
8323
                !PyArray_CheckExact(arr)) {
 
8324
                Py_INCREF(arr->descr);
 
8325
                ret = (PyArrayObject *)                 \
 
8326
                    PyArray_NewFromDescr(&PyArray_Type,
 
8327
                                         arr->descr,
 
8328
                                         arr->nd,
 
8329
                                         arr->dimensions,
 
8330
                                         arr->strides,
 
8331
                                         arr->data,
 
8332
                                         arr->flags,NULL);
 
8333
                if (ret == NULL) {
 
8334
                    return NULL;
 
8335
                }
 
8336
                ret->base = (PyObject *)arr;
 
8337
            }
 
8338
            else {
 
8339
                ret = arr;
 
8340
            }
 
8341
            Py_INCREF(arr);
 
8342
        }
 
8343
    }
 
8344
 
 
8345
    /* The desired output type is different than the input
 
8346
       array type and copy was not specified */
 
8347
    else {
 
8348
        if ((flags & UPDATEIFCOPY) &&                   \
 
8349
            (!PyArray_ISWRITEABLE(arr))) {
 
8350
            Py_DECREF(newtype);
 
8351
            PyErr_SetString(PyExc_ValueError, msg);
 
8352
            return NULL;
 
8353
        }
 
8354
        if ((flags & ENSUREARRAY)) {
 
8355
            subtype = &PyArray_Type;
 
8356
        }
 
8357
        ret = (PyArrayObject *)                         \
 
8358
            PyArray_NewFromDescr(subtype, newtype,
 
8359
                                 arr->nd, arr->dimensions,
 
8360
                                 NULL, NULL,
 
8361
                                 flags & FORTRAN,
 
8362
                                 (PyObject *)arr);
 
8363
        if (ret == NULL) {
 
8364
            return NULL;
 
8365
        }
 
8366
        if (PyArray_CastTo(ret, arr) < 0) {
 
8367
            Py_DECREF(ret);
 
8368
            return NULL;
 
8369
        }
 
8370
        if (flags & UPDATEIFCOPY)  {
 
8371
            ret->flags |= UPDATEIFCOPY;
 
8372
            ret->base = (PyObject *)arr;
 
8373
            PyArray_FLAGS(ret->base) &= ~WRITEABLE;
 
8374
            Py_INCREF(arr);
 
8375
        }
 
8376
    }
 
8377
    return (PyObject *)ret;
7941
8378
}
7942
8379
 
7943
8380
/* new reference */
7944
8381
static PyArray_Descr *
7945
8382
_array_typedescr_fromstr(char *str)
7946
8383
{
7947
 
        PyArray_Descr *descr;
7948
 
        int type_num;
7949
 
        char typechar;
7950
 
        int size;
7951
 
        char msg[] = "unsupported typestring";
7952
 
        int swap;
7953
 
        char swapchar;
7954
 
 
7955
 
        swapchar = str[0];
7956
 
        str += 1;
7957
 
 
7958
 
#define _MY_FAIL {                                  \
7959
 
                PyErr_SetString(PyExc_ValueError, msg); \
7960
 
                return NULL;                            \
7961
 
        }
7962
 
 
7963
 
        typechar = str[0];
7964
 
        size = atoi(str + 1);
7965
 
        switch (typechar) {
7966
 
        case 'b':
7967
 
                if (size == sizeof(Bool))
7968
 
                        type_num = PyArray_BOOL;
7969
 
                else _MY_FAIL
7970
 
                        break;
7971
 
        case 'u':
7972
 
                if (size == sizeof(uintp))
7973
 
                        type_num = PyArray_UINTP;
7974
 
                else if (size == sizeof(char))
7975
 
                        type_num = PyArray_UBYTE;
7976
 
                else if (size == sizeof(short))
7977
 
                        type_num = PyArray_USHORT;
7978
 
                else if (size == sizeof(ulong))
7979
 
                        type_num = PyArray_ULONG;
7980
 
                else if (size == sizeof(int))
7981
 
                        type_num = PyArray_UINT;
7982
 
                else if (size == sizeof(ulonglong))
7983
 
                        type_num = PyArray_ULONGLONG;
7984
 
                else _MY_FAIL
7985
 
                        break;
7986
 
        case 'i':
7987
 
                if (size == sizeof(intp))
7988
 
                        type_num = PyArray_INTP;
7989
 
                else if (size == sizeof(char))
7990
 
                    type_num = PyArray_BYTE;
7991
 
                else if (size == sizeof(short))
7992
 
                        type_num = PyArray_SHORT;
7993
 
                else if (size == sizeof(long))
7994
 
                        type_num = PyArray_LONG;
7995
 
                else if (size == sizeof(int))
7996
 
                        type_num = PyArray_INT;
7997
 
                else if (size == sizeof(longlong))
7998
 
                        type_num = PyArray_LONGLONG;
7999
 
                else _MY_FAIL
8000
 
                        break;
8001
 
        case 'f':
8002
 
                if (size == sizeof(float))
8003
 
                        type_num = PyArray_FLOAT;
8004
 
                else if (size == sizeof(double))
8005
 
                        type_num = PyArray_DOUBLE;
8006
 
                else if (size == sizeof(longdouble))
8007
 
                        type_num = PyArray_LONGDOUBLE;
8008
 
                else _MY_FAIL
8009
 
                        break;
8010
 
        case 'c':
8011
 
                if (size == sizeof(float)*2)
8012
 
                        type_num = PyArray_CFLOAT;
8013
 
                else if (size == sizeof(double)*2)
8014
 
                        type_num = PyArray_CDOUBLE;
8015
 
                else if (size == sizeof(longdouble)*2)
8016
 
                        type_num = PyArray_CLONGDOUBLE;
8017
 
                else _MY_FAIL
8018
 
                        break;
8019
 
        case 'O':
8020
 
                if (size == sizeof(PyObject *))
8021
 
                        type_num = PyArray_OBJECT;
8022
 
                else _MY_FAIL
8023
 
                break;
8024
 
        case PyArray_STRINGLTR:
8025
 
                type_num = PyArray_STRING;
8026
 
                break;
8027
 
        case PyArray_UNICODELTR:
8028
 
                type_num = PyArray_UNICODE;
8029
 
                size <<= 2;
8030
 
                break;
8031
 
        case 'V':
8032
 
                type_num = PyArray_VOID;
8033
 
                break;
8034
 
        default:
8035
 
                _MY_FAIL
8036
 
        }
 
8384
    PyArray_Descr *descr;
 
8385
    int type_num;
 
8386
    char typechar;
 
8387
    int size;
 
8388
    char msg[] = "unsupported typestring";
 
8389
    int swap;
 
8390
    char swapchar;
 
8391
 
 
8392
    swapchar = str[0];
 
8393
    str += 1;
 
8394
 
 
8395
#define _MY_FAIL {                              \
 
8396
        PyErr_SetString(PyExc_ValueError, msg); \
 
8397
        return NULL;                            \
 
8398
    }
 
8399
 
 
8400
    typechar = str[0];
 
8401
    size = atoi(str + 1);
 
8402
    switch (typechar) {
 
8403
    case 'b':
 
8404
        if (size == sizeof(Bool))
 
8405
            type_num = PyArray_BOOL;
 
8406
        else _MY_FAIL
 
8407
                 break;
 
8408
    case 'u':
 
8409
        if (size == sizeof(uintp))
 
8410
            type_num = PyArray_UINTP;
 
8411
        else if (size == sizeof(char))
 
8412
            type_num = PyArray_UBYTE;
 
8413
        else if (size == sizeof(short))
 
8414
            type_num = PyArray_USHORT;
 
8415
        else if (size == sizeof(ulong))
 
8416
            type_num = PyArray_ULONG;
 
8417
        else if (size == sizeof(int))
 
8418
            type_num = PyArray_UINT;
 
8419
        else if (size == sizeof(ulonglong))
 
8420
            type_num = PyArray_ULONGLONG;
 
8421
        else _MY_FAIL
 
8422
                 break;
 
8423
    case 'i':
 
8424
        if (size == sizeof(intp))
 
8425
            type_num = PyArray_INTP;
 
8426
        else if (size == sizeof(char))
 
8427
            type_num = PyArray_BYTE;
 
8428
        else if (size == sizeof(short))
 
8429
            type_num = PyArray_SHORT;
 
8430
        else if (size == sizeof(long))
 
8431
            type_num = PyArray_LONG;
 
8432
        else if (size == sizeof(int))
 
8433
            type_num = PyArray_INT;
 
8434
        else if (size == sizeof(longlong))
 
8435
            type_num = PyArray_LONGLONG;
 
8436
        else _MY_FAIL
 
8437
                 break;
 
8438
    case 'f':
 
8439
        if (size == sizeof(float))
 
8440
            type_num = PyArray_FLOAT;
 
8441
        else if (size == sizeof(double))
 
8442
            type_num = PyArray_DOUBLE;
 
8443
        else if (size == sizeof(longdouble))
 
8444
            type_num = PyArray_LONGDOUBLE;
 
8445
        else _MY_FAIL
 
8446
                 break;
 
8447
    case 'c':
 
8448
        if (size == sizeof(float)*2)
 
8449
            type_num = PyArray_CFLOAT;
 
8450
        else if (size == sizeof(double)*2)
 
8451
            type_num = PyArray_CDOUBLE;
 
8452
        else if (size == sizeof(longdouble)*2)
 
8453
            type_num = PyArray_CLONGDOUBLE;
 
8454
        else _MY_FAIL
 
8455
                 break;
 
8456
    case 'O':
 
8457
        if (size == sizeof(PyObject *))
 
8458
            type_num = PyArray_OBJECT;
 
8459
        else _MY_FAIL
 
8460
                 break;
 
8461
    case PyArray_STRINGLTR:
 
8462
        type_num = PyArray_STRING;
 
8463
        break;
 
8464
    case PyArray_UNICODELTR:
 
8465
        type_num = PyArray_UNICODE;
 
8466
        size <<= 2;
 
8467
        break;
 
8468
    case 'V':
 
8469
        type_num = PyArray_VOID;
 
8470
        break;
 
8471
    default:
 
8472
        _MY_FAIL
 
8473
            }
8037
8474
 
8038
8475
#undef _MY_FAIL
8039
8476
 
8041
8478
    if (descr == NULL) return NULL;
8042
8479
    swap = !PyArray_ISNBO(swapchar);
8043
8480
    if (descr->elsize == 0 || swap) {
8044
 
            /* Need to make a new PyArray_Descr */
8045
 
            PyArray_DESCR_REPLACE(descr);
8046
 
            if (descr==NULL) return NULL;
8047
 
            if (descr->elsize == 0)
8048
 
                    descr->elsize = size;
8049
 
            if (swap)
8050
 
                    descr->byteorder = swapchar;
 
8481
        /* Need to make a new PyArray_Descr */
 
8482
        PyArray_DESCR_REPLACE(descr);
 
8483
        if (descr==NULL) return NULL;
 
8484
        if (descr->elsize == 0)
 
8485
            descr->elsize = size;
 
8486
        if (swap)
 
8487
            descr->byteorder = swapchar;
8051
8488
    }
8052
8489
    return descr;
8053
8490
}
8056
8493
static PyObject *
8057
8494
PyArray_FromStructInterface(PyObject *input)
8058
8495
{
8059
 
        PyArray_Descr *thetype=NULL;
8060
 
        char buf[40];
8061
 
        PyArrayInterface *inter;
8062
 
        PyObject *attr, *r;
8063
 
        char endian = PyArray_NATBYTE;
8064
 
 
8065
 
        attr = PyObject_GetAttrString(input, "__array_struct__");
8066
 
        if (attr == NULL) {
8067
 
                PyErr_Clear();
8068
 
                return Py_NotImplemented;
8069
 
        }
8070
 
        if (!PyCObject_Check(attr)) goto fail;
8071
 
        inter = PyCObject_AsVoidPtr(attr);
8072
 
        if (inter->two != 2) goto fail;
8073
 
        if ((inter->flags & NOTSWAPPED) != NOTSWAPPED) {
8074
 
                endian = PyArray_OPPBYTE;
8075
 
                inter->flags &= ~NOTSWAPPED;
8076
 
        }
8077
 
 
8078
 
        if (inter->flags & ARR_HAS_DESCR) {
8079
 
                if (PyArray_DescrConverter(inter->descr, &thetype) == PY_FAIL) {
8080
 
                        thetype = NULL;
8081
 
                        PyErr_Clear();
8082
 
                }
8083
 
        }
8084
 
 
8085
 
        if (thetype == NULL) {
8086
 
                snprintf(buf, 40, "%c%c%d", endian, inter->typekind, inter->itemsize);
8087
 
                if (!(thetype=_array_typedescr_fromstr(buf))) {
8088
 
                        Py_DECREF(attr);
8089
 
                        return NULL;
8090
 
                }
8091
 
        }
8092
 
 
8093
 
        r = PyArray_NewFromDescr(&PyArray_Type, thetype,
8094
 
                                 inter->nd, inter->shape,
8095
 
                                 inter->strides, inter->data,
8096
 
                                 inter->flags, NULL);
8097
 
        Py_INCREF(input);
8098
 
        PyArray_BASE(r) = input;
8099
 
        Py_DECREF(attr);
8100
 
        PyArray_UpdateFlags((PyArrayObject *)r, UPDATE_ALL);
8101
 
        return r;
 
8496
    PyArray_Descr *thetype=NULL;
 
8497
    char buf[40];
 
8498
    PyArrayInterface *inter;
 
8499
    PyObject *attr, *r;
 
8500
    char endian = PyArray_NATBYTE;
 
8501
 
 
8502
    attr = PyObject_GetAttrString(input, "__array_struct__");
 
8503
    if (attr == NULL) {
 
8504
        PyErr_Clear();
 
8505
        return Py_NotImplemented;
 
8506
    }
 
8507
    if (!PyCObject_Check(attr)) goto fail;
 
8508
    inter = PyCObject_AsVoidPtr(attr);
 
8509
    if (inter->two != 2) goto fail;
 
8510
    if ((inter->flags & NOTSWAPPED) != NOTSWAPPED) {
 
8511
        endian = PyArray_OPPBYTE;
 
8512
        inter->flags &= ~NOTSWAPPED;
 
8513
    }
 
8514
 
 
8515
    if (inter->flags & ARR_HAS_DESCR) {
 
8516
        if (PyArray_DescrConverter(inter->descr, &thetype) == PY_FAIL) {
 
8517
            thetype = NULL;
 
8518
            PyErr_Clear();
 
8519
        }
 
8520
    }
 
8521
 
 
8522
    if (thetype == NULL) {
 
8523
        snprintf(buf, 40, "%c%c%d", endian, inter->typekind, inter->itemsize);
 
8524
        if (!(thetype=_array_typedescr_fromstr(buf))) {
 
8525
            Py_DECREF(attr);
 
8526
            return NULL;
 
8527
        }
 
8528
    }
 
8529
 
 
8530
    r = PyArray_NewFromDescr(&PyArray_Type, thetype,
 
8531
                             inter->nd, inter->shape,
 
8532
                             inter->strides, inter->data,
 
8533
                             inter->flags, NULL);
 
8534
    Py_INCREF(input);
 
8535
    PyArray_BASE(r) = input;
 
8536
    Py_DECREF(attr);
 
8537
    PyArray_UpdateFlags((PyArrayObject *)r, UPDATE_ALL);
 
8538
    return r;
8102
8539
 
8103
8540
 fail:
8104
 
        PyErr_SetString(PyExc_ValueError, "invalid __array_struct__");
8105
 
        Py_DECREF(attr);
8106
 
        return NULL;
 
8541
    PyErr_SetString(PyExc_ValueError, "invalid __array_struct__");
 
8542
    Py_DECREF(attr);
 
8543
    return NULL;
8107
8544
}
8108
8545
 
8109
8546
#define PyIntOrLong_Check(obj) (PyInt_Check(obj) || PyLong_Check(obj))
8112
8549
static PyObject *
8113
8550
PyArray_FromInterface(PyObject *input)
8114
8551
{
8115
 
        PyObject *attr=NULL, *item=NULL;
8116
 
        PyObject *tstr=NULL, *shape=NULL;
8117
 
        PyObject *inter=NULL;
8118
 
        PyObject *base=NULL;
8119
 
        PyArrayObject *ret;
8120
 
        PyArray_Descr *type=NULL;
8121
 
        char *data;
8122
 
        Py_ssize_t buffer_len;
8123
 
        int res, i, n;
8124
 
        intp dims[MAX_DIMS], strides[MAX_DIMS];
8125
 
        int dataflags = BEHAVED;
8126
 
 
8127
 
        /* Get the memory from __array_data__ and __array_offset__ */
8128
 
        /* Get the shape */
8129
 
        /* Get the typestring -- ignore array_descr */
8130
 
        /* Get the strides */
8131
 
 
8132
 
        inter = PyObject_GetAttrString(input, "__array_interface__");
8133
 
        if (inter == NULL) {PyErr_Clear(); return Py_NotImplemented;}
8134
 
        if (!PyDict_Check(inter)) {Py_DECREF(inter); return Py_NotImplemented;}
8135
 
 
8136
 
        shape = PyDict_GetItemString(inter, "shape");
8137
 
        if (shape == NULL) {Py_DECREF(inter); return Py_NotImplemented;}
8138
 
        tstr = PyDict_GetItemString(inter, "typestr");
8139
 
        if (tstr == NULL) {Py_DECREF(inter); return Py_NotImplemented;}
8140
 
 
8141
 
        attr = PyDict_GetItemString(inter, "data");
8142
 
        base = input;
8143
 
        if ((attr == NULL) || (attr==Py_None) || (!PyTuple_Check(attr))) {
8144
 
                if (attr && (attr != Py_None)) item=attr;
8145
 
                else item=input;
8146
 
                res = PyObject_AsWriteBuffer(item, (void **)&data,
8147
 
                                             &buffer_len);
8148
 
                if (res < 0) {
8149
 
                        PyErr_Clear();
8150
 
                        res = PyObject_AsReadBuffer(item, (const void **)&data,
8151
 
                                                    &buffer_len);
8152
 
                        if (res < 0) goto fail;
8153
 
                        dataflags &= ~WRITEABLE;
8154
 
                }
8155
 
                attr = PyDict_GetItemString(inter, "offset");
8156
 
                if (attr) {
8157
 
                        longlong num = PyLong_AsLongLong(attr);
8158
 
                        if (error_converting(num)) {
8159
 
                                PyErr_SetString(PyExc_TypeError,
8160
 
                                                "offset "\
8161
 
                                                "must be an integer");
8162
 
                                goto fail;
8163
 
                        }
8164
 
                        data += num;
8165
 
                }
8166
 
                base = item;
 
8552
    PyObject *attr=NULL, *item=NULL;
 
8553
    PyObject *tstr=NULL, *shape=NULL;
 
8554
    PyObject *inter=NULL;
 
8555
    PyObject *base=NULL;
 
8556
    PyArrayObject *ret;
 
8557
    PyArray_Descr *type=NULL;
 
8558
    char *data;
 
8559
    Py_ssize_t buffer_len;
 
8560
    int res, i, n;
 
8561
    intp dims[MAX_DIMS], strides[MAX_DIMS];
 
8562
    int dataflags = BEHAVED;
 
8563
 
 
8564
    /* Get the memory from __array_data__ and __array_offset__ */
 
8565
    /* Get the shape */
 
8566
    /* Get the typestring -- ignore array_descr */
 
8567
    /* Get the strides */
 
8568
 
 
8569
    inter = PyObject_GetAttrString(input, "__array_interface__");
 
8570
    if (inter == NULL) {PyErr_Clear(); return Py_NotImplemented;}
 
8571
    if (!PyDict_Check(inter)) {Py_DECREF(inter); return Py_NotImplemented;}
 
8572
 
 
8573
    shape = PyDict_GetItemString(inter, "shape");
 
8574
    if (shape == NULL) {Py_DECREF(inter); return Py_NotImplemented;}
 
8575
    tstr = PyDict_GetItemString(inter, "typestr");
 
8576
    if (tstr == NULL) {Py_DECREF(inter); return Py_NotImplemented;}
 
8577
 
 
8578
    attr = PyDict_GetItemString(inter, "data");
 
8579
    base = input;
 
8580
    if ((attr == NULL) || (attr==Py_None) || (!PyTuple_Check(attr))) {
 
8581
        if (attr && (attr != Py_None)) item=attr;
 
8582
        else item=input;
 
8583
        res = PyObject_AsWriteBuffer(item, (void **)&data,
 
8584
                                     &buffer_len);
 
8585
        if (res < 0) {
 
8586
            PyErr_Clear();
 
8587
            res = PyObject_AsReadBuffer(item, (const void **)&data,
 
8588
                                        &buffer_len);
 
8589
            if (res < 0) goto fail;
 
8590
            dataflags &= ~WRITEABLE;
 
8591
        }
 
8592
        attr = PyDict_GetItemString(inter, "offset");
 
8593
        if (attr) {
 
8594
            longlong num = PyLong_AsLongLong(attr);
 
8595
            if (error_converting(num)) {
 
8596
                PyErr_SetString(PyExc_TypeError,
 
8597
                                "offset "\
 
8598
                                "must be an integer");
 
8599
                goto fail;
 
8600
            }
 
8601
            data += num;
 
8602
        }
 
8603
        base = item;
 
8604
    }
 
8605
    else {
 
8606
        PyObject *dataptr;
 
8607
        if (PyTuple_GET_SIZE(attr) != 2) {
 
8608
            PyErr_SetString(PyExc_TypeError,
 
8609
                            "data must return "     \
 
8610
                            "a 2-tuple with (data pointer "\
 
8611
                            "integer, read-only flag)");
 
8612
            goto fail;
 
8613
        }
 
8614
        dataptr = PyTuple_GET_ITEM(attr, 0);
 
8615
        if (PyString_Check(dataptr)) {
 
8616
            res = sscanf(PyString_AsString(dataptr),
 
8617
                         "%p", (void **)&data);
 
8618
            if (res < 1) {
 
8619
                PyErr_SetString(PyExc_TypeError,
 
8620
                                "data string cannot be " \
 
8621
                                "converted");
 
8622
                goto fail;
 
8623
            }
 
8624
        }
 
8625
        else if (PyIntOrLong_Check(dataptr)) {
 
8626
            data = PyLong_AsVoidPtr(dataptr);
8167
8627
        }
8168
8628
        else {
8169
 
                PyObject *dataptr;
8170
 
                if (PyTuple_GET_SIZE(attr) != 2) {
8171
 
                        PyErr_SetString(PyExc_TypeError,
8172
 
                                        "data must return "     \
8173
 
                                        "a 2-tuple with (data pointer "\
8174
 
                                        "integer, read-only flag)");
8175
 
                        goto fail;
8176
 
                }
8177
 
                dataptr = PyTuple_GET_ITEM(attr, 0);
8178
 
                if (PyString_Check(dataptr)) {
8179
 
                        res = sscanf(PyString_AsString(dataptr),
8180
 
                                     "%p", (void **)&data);
8181
 
                        if (res < 1) {
8182
 
                                PyErr_SetString(PyExc_TypeError,
8183
 
                                                "data string cannot be " \
8184
 
                                                "converted");
8185
 
                                goto fail;
8186
 
                        }
8187
 
                }
8188
 
                else if (PyIntOrLong_Check(dataptr)) {
8189
 
                        data = PyLong_AsVoidPtr(dataptr);
8190
 
                }
8191
 
                else {
8192
 
                        PyErr_SetString(PyExc_TypeError, "first element " \
8193
 
                                        "of data tuple must be integer" \
8194
 
                                        " or string.");
8195
 
                        goto fail;
8196
 
                }
8197
 
                if (PyObject_IsTrue(PyTuple_GET_ITEM(attr,1))) {
8198
 
                        dataflags &= ~WRITEABLE;
8199
 
                }
8200
 
        }
8201
 
        attr = tstr;
8202
 
        if (!PyString_Check(attr)) {
8203
 
                PyErr_SetString(PyExc_TypeError, "typestr must be a string");
8204
 
                goto fail;
8205
 
        }
8206
 
        type = _array_typedescr_fromstr(PyString_AS_STRING(attr));
8207
 
        if (type==NULL) goto fail;
8208
 
        attr = shape;
 
8629
            PyErr_SetString(PyExc_TypeError, "first element " \
 
8630
                            "of data tuple must be integer" \
 
8631
                            " or string.");
 
8632
            goto fail;
 
8633
        }
 
8634
        if (PyObject_IsTrue(PyTuple_GET_ITEM(attr,1))) {
 
8635
            dataflags &= ~WRITEABLE;
 
8636
        }
 
8637
    }
 
8638
    attr = tstr;
 
8639
    if (!PyString_Check(attr)) {
 
8640
        PyErr_SetString(PyExc_TypeError, "typestr must be a string");
 
8641
        goto fail;
 
8642
    }
 
8643
    type = _array_typedescr_fromstr(PyString_AS_STRING(attr));
 
8644
    if (type==NULL) goto fail;
 
8645
    attr = shape;
 
8646
    if (!PyTuple_Check(attr)) {
 
8647
        PyErr_SetString(PyExc_TypeError, "shape must be a tuple");
 
8648
        Py_DECREF(type);
 
8649
        goto fail;
 
8650
    }
 
8651
    n = PyTuple_GET_SIZE(attr);
 
8652
    for(i=0; i<n; i++) {
 
8653
        item = PyTuple_GET_ITEM(attr, i);
 
8654
        dims[i] = PyArray_PyIntAsIntp(item);
 
8655
        if (error_converting(dims[i])) break;
 
8656
    }
 
8657
 
 
8658
    ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, type,
 
8659
                                                n, dims,
 
8660
                                                NULL, data,
 
8661
                                                dataflags, NULL);
 
8662
    if (ret == NULL) return NULL;
 
8663
    Py_INCREF(base);
 
8664
    ret->base = base;
 
8665
 
 
8666
    attr = PyDict_GetItemString(inter, "strides");
 
8667
    if (attr != NULL && attr != Py_None) {
8209
8668
        if (!PyTuple_Check(attr)) {
8210
 
                PyErr_SetString(PyExc_TypeError, "shape must be a tuple");
8211
 
                Py_DECREF(type);
8212
 
                goto fail;
8213
 
        }
8214
 
        n = PyTuple_GET_SIZE(attr);
8215
 
        for (i=0; i<n; i++) {
8216
 
                item = PyTuple_GET_ITEM(attr, i);
8217
 
                dims[i] = PyArray_PyIntAsIntp(item);
8218
 
                if (error_converting(dims[i])) break;
8219
 
        }
8220
 
 
8221
 
        ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, type,
8222
 
                                                    n, dims,
8223
 
                                                    NULL, data,
8224
 
                                                    dataflags, NULL);
8225
 
        if (ret == NULL) return NULL;
8226
 
        Py_INCREF(base);
8227
 
        ret->base = base;
8228
 
 
8229
 
        attr = PyDict_GetItemString(inter, "strides");
8230
 
        if (attr != NULL && attr != Py_None) {
8231
 
                if (!PyTuple_Check(attr)) {
8232
 
                        PyErr_SetString(PyExc_TypeError,
8233
 
                                        "strides must be a tuple");
8234
 
                        Py_DECREF(ret);
8235
 
                        return NULL;
8236
 
                }
8237
 
                if (n != PyTuple_GET_SIZE(attr)) {
8238
 
                        PyErr_SetString(PyExc_ValueError,
8239
 
                                        "mismatch in length of "\
8240
 
                                        "strides and shape");
8241
 
                        Py_DECREF(ret);
8242
 
                        return NULL;
8243
 
                }
8244
 
                for (i=0; i<n; i++) {
8245
 
                        item = PyTuple_GET_ITEM(attr, i);
8246
 
                        strides[i] = PyArray_PyIntAsIntp(item);
8247
 
                        if (error_converting(strides[i])) break;
8248
 
                }
8249
 
                if (PyErr_Occurred()) PyErr_Clear();
8250
 
                memcpy(ret->strides, strides, n*sizeof(intp));
8251
 
        }
8252
 
        else PyErr_Clear();
8253
 
        PyArray_UpdateFlags(ret, UPDATE_ALL);
8254
 
        Py_DECREF(inter);
8255
 
        return (PyObject *)ret;
 
8669
            PyErr_SetString(PyExc_TypeError,
 
8670
                            "strides must be a tuple");
 
8671
            Py_DECREF(ret);
 
8672
            return NULL;
 
8673
        }
 
8674
        if (n != PyTuple_GET_SIZE(attr)) {
 
8675
            PyErr_SetString(PyExc_ValueError,
 
8676
                            "mismatch in length of "\
 
8677
                            "strides and shape");
 
8678
            Py_DECREF(ret);
 
8679
            return NULL;
 
8680
        }
 
8681
        for(i=0; i<n; i++) {
 
8682
            item = PyTuple_GET_ITEM(attr, i);
 
8683
            strides[i] = PyArray_PyIntAsIntp(item);
 
8684
            if (error_converting(strides[i])) break;
 
8685
        }
 
8686
        if (PyErr_Occurred()) PyErr_Clear();
 
8687
        memcpy(ret->strides, strides, n*sizeof(intp));
 
8688
    }
 
8689
    else PyErr_Clear();
 
8690
    PyArray_UpdateFlags(ret, UPDATE_ALL);
 
8691
    Py_DECREF(inter);
 
8692
    return (PyObject *)ret;
8256
8693
 
8257
8694
 fail:
8258
 
        Py_XDECREF(inter);
8259
 
        return NULL;
 
8695
    Py_XDECREF(inter);
 
8696
    return NULL;
8260
8697
}
8261
8698
 
8262
8699
/*OBJECT_API*/
8263
8700
static PyObject *
8264
8701
PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
8265
8702
{
8266
 
        PyObject *new;
8267
 
        PyObject *array_meth;
 
8703
    PyObject *new;
 
8704
    PyObject *array_meth;
8268
8705
 
8269
 
        array_meth = PyObject_GetAttrString(op, "__array__");
8270
 
        if (array_meth == NULL) {PyErr_Clear(); return Py_NotImplemented;}
8271
 
        if (context == NULL) {
8272
 
                if (typecode == NULL) new = PyObject_CallFunction(array_meth,
8273
 
                                                                  NULL);
8274
 
                else new = PyObject_CallFunction(array_meth, "O", typecode);
 
8706
    array_meth = PyObject_GetAttrString(op, "__array__");
 
8707
    if (array_meth == NULL) {PyErr_Clear(); return Py_NotImplemented;}
 
8708
    if (context == NULL) {
 
8709
        if (typecode == NULL) new = PyObject_CallFunction(array_meth,
 
8710
                                                          NULL);
 
8711
        else new = PyObject_CallFunction(array_meth, "O", typecode);
 
8712
    }
 
8713
    else {
 
8714
        if (typecode == NULL) {
 
8715
            new = PyObject_CallFunction(array_meth, "OO", Py_None,
 
8716
                                        context);
 
8717
            if (new == NULL && \
 
8718
                PyErr_ExceptionMatches(PyExc_TypeError)) {
 
8719
                PyErr_Clear();
 
8720
                new = PyObject_CallFunction(array_meth, "");
 
8721
            }
8275
8722
        }
8276
8723
        else {
8277
 
                if (typecode == NULL) {
8278
 
                        new = PyObject_CallFunction(array_meth, "OO", Py_None,
8279
 
                                                    context);
8280
 
                        if (new == NULL && \
8281
 
                            PyErr_ExceptionMatches(PyExc_TypeError)) {
8282
 
                                PyErr_Clear();
8283
 
                                new = PyObject_CallFunction(array_meth, "");
8284
 
                        }
8285
 
                }
8286
 
                else {
8287
 
                        new = PyObject_CallFunction(array_meth, "OO",
8288
 
                                                    typecode, context);
8289
 
                        if (new == NULL && \
8290
 
                            PyErr_ExceptionMatches(PyExc_TypeError)) {
8291
 
                                PyErr_Clear();
8292
 
                                new = PyObject_CallFunction(array_meth, "O",
8293
 
                                                            typecode);
8294
 
                        }
8295
 
                }
8296
 
        }
8297
 
        Py_DECREF(array_meth);
8298
 
        if (new == NULL) return NULL;
8299
 
        if (!PyArray_Check(new)) {
8300
 
                PyErr_SetString(PyExc_ValueError,
8301
 
                                "object __array__ method not "  \
8302
 
                                "producing an array");
8303
 
                Py_DECREF(new);
8304
 
                return NULL;
8305
 
        }
8306
 
        return new;
 
8724
            new = PyObject_CallFunction(array_meth, "OO",
 
8725
                                        typecode, context);
 
8726
            if (new == NULL && \
 
8727
                PyErr_ExceptionMatches(PyExc_TypeError)) {
 
8728
                PyErr_Clear();
 
8729
                new = PyObject_CallFunction(array_meth, "O",
 
8730
                                            typecode);
 
8731
            }
 
8732
        }
 
8733
    }
 
8734
    Py_DECREF(array_meth);
 
8735
    if (new == NULL) return NULL;
 
8736
    if (!PyArray_Check(new)) {
 
8737
        PyErr_SetString(PyExc_ValueError,
 
8738
                        "object __array__ method not "  \
 
8739
                        "producing an array");
 
8740
        Py_DECREF(new);
 
8741
        return NULL;
 
8742
    }
 
8743
    return new;
8307
8744
}
8308
8745
 
8309
8746
/* Does not check for ENSURECOPY and NOTSWAPPED in flags */
8313
8750
PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
8314
8751
                int max_depth, int flags, PyObject *context)
8315
8752
{
8316
 
        /* This is the main code to make a NumPy array from a Python
8317
 
           Object.  It is called from lot's of different places which
8318
 
           is why there are so many checks.  The comments try to
8319
 
           explain some of the checks. */
8320
 
 
8321
 
        PyObject *r=NULL;
8322
 
        int seq = FALSE;
8323
 
 
8324
 
        /* Is input object already an array? */
8325
 
        /*  This is where the flags are used */
8326
 
        if (PyArray_Check(op))
8327
 
                r = PyArray_FromArray((PyArrayObject *)op, newtype, flags);
8328
 
        else if (PyArray_IsScalar(op, Generic)) {
8329
 
                if (flags & UPDATEIFCOPY) goto err;
8330
 
                r = PyArray_FromScalar(op, newtype);
8331
 
        } else if (newtype == NULL &&
8332
 
                   (newtype = _array_find_python_scalar_type(op))) {
8333
 
            if (flags & UPDATEIFCOPY) goto err;
 
8753
    /* This is the main code to make a NumPy array from a Python
 
8754
       Object.  It is called from lot's of different places which
 
8755
       is why there are so many checks.  The comments try to
 
8756
       explain some of the checks. */
 
8757
 
 
8758
    PyObject *r=NULL;
 
8759
    int seq = FALSE;
 
8760
 
 
8761
    /* Is input object already an array? */
 
8762
    /*  This is where the flags are used */
 
8763
    if (PyArray_Check(op)) {
 
8764
        r = PyArray_FromArray((PyArrayObject *)op, newtype, flags);
 
8765
    }
 
8766
    else if (PyArray_IsScalar(op, Generic)) {
 
8767
        if (flags & UPDATEIFCOPY) {
 
8768
            goto err;
 
8769
        }
 
8770
        r = PyArray_FromScalar(op, newtype);
 
8771
    }
 
8772
    else if (newtype == NULL &&
 
8773
               (newtype = _array_find_python_scalar_type(op))) {
 
8774
        if (flags & UPDATEIFCOPY) {
 
8775
            goto err;
 
8776
        }
 
8777
        r = Array_FromPyScalar(op, newtype);
 
8778
    }
 
8779
    else if (PyArray_HasArrayInterfaceType(op, newtype, context, r)) {
 
8780
        PyObject *new;
 
8781
        if (r == NULL) {
 
8782
            Py_XDECREF(newtype);
 
8783
            return NULL;
 
8784
        }
 
8785
        if (newtype != NULL || flags != 0) {
 
8786
            new = PyArray_FromArray((PyArrayObject *)r, newtype,
 
8787
                                    flags);
 
8788
            Py_DECREF(r);
 
8789
            r = new;
 
8790
        }
 
8791
    }
 
8792
    else {
 
8793
        int isobject = 0;
 
8794
 
 
8795
        if (flags & UPDATEIFCOPY) {
 
8796
            goto err;
 
8797
        }
 
8798
        if (newtype == NULL) {
 
8799
            newtype = _array_find_type(op, NULL, MAX_DIMS);
 
8800
        }
 
8801
        else if (newtype->type_num == PyArray_OBJECT) {
 
8802
            isobject = 1;
 
8803
        }
 
8804
        if (!PyString_Check(op) && PySequence_Check(op)) {
 
8805
            PyObject *thiserr = NULL;
 
8806
 
 
8807
            /* necessary but not sufficient */
 
8808
            Py_INCREF(newtype);
 
8809
            r = Array_FromSequence(op, newtype, flags & FORTRAN,
 
8810
                                   min_depth, max_depth);
 
8811
            if (r == NULL && (thiserr=PyErr_Occurred())) {
 
8812
                if (PyErr_GivenExceptionMatches(thiserr,
 
8813
                                                PyExc_MemoryError)) {
 
8814
                    return NULL;
 
8815
                }
 
8816
                /*
 
8817
                 * If object was explicitly requested,
 
8818
                 * then try nested list object array creation
 
8819
                 */
 
8820
                PyErr_Clear();
 
8821
                if (isobject) {
 
8822
                    Py_INCREF(newtype);
 
8823
                    r = ObjectArray_FromNestedList  \
 
8824
                        (op, newtype, flags & FORTRAN);
 
8825
                    seq = TRUE;
 
8826
                    Py_DECREF(newtype);
 
8827
                }
 
8828
            }
 
8829
            else {
 
8830
                seq = TRUE;
 
8831
                Py_DECREF(newtype);
 
8832
            }
 
8833
        }
 
8834
        if (!seq) {
8334
8835
            r = Array_FromPyScalar(op, newtype);
8335
8836
        }
8336
 
        else if (PyArray_HasArrayInterfaceType(op, newtype, context, r)) {
8337
 
                PyObject *new;
8338
 
                if (r == NULL) {Py_XDECREF(newtype); return NULL;}
8339
 
                if (newtype != NULL || flags != 0) {
8340
 
                        new = PyArray_FromArray((PyArrayObject *)r, newtype,
8341
 
                                                flags);
8342
 
                        Py_DECREF(r);
8343
 
                        r = new;
8344
 
                }
8345
 
        }
8346
 
        else {
8347
 
                int isobject=0;
8348
 
                if (flags & UPDATEIFCOPY) goto err;
8349
 
                if (newtype == NULL) {
8350
 
                        newtype = _array_find_type(op, NULL, MAX_DIMS);
8351
 
                }
8352
 
                else if (newtype->type_num == PyArray_OBJECT) {
8353
 
                        isobject = 1;
8354
 
                }
8355
 
                if (PySequence_Check(op)) {
8356
 
                        PyObject *thiserr=NULL;
8357
 
                        /* necessary but not sufficient */
8358
 
                        Py_INCREF(newtype);
8359
 
                        r = Array_FromSequence(op, newtype, flags & FORTRAN,
8360
 
                                               min_depth, max_depth);
8361
 
                        if (r == NULL && (thiserr=PyErr_Occurred())) {
8362
 
                                if (PyErr_GivenExceptionMatches(thiserr, 
8363
 
                                                                PyExc_MemoryError))
8364
 
                                        return NULL;
8365
 
                                /* If object was explicitly requested, 
8366
 
                                   then try nested list object array creation
8367
 
                                */
8368
 
                                PyErr_Clear();
8369
 
                                if (isobject) {
8370
 
                                        Py_INCREF(newtype);
8371
 
                                        r = ObjectArray_FromNestedList  \
8372
 
                                                (op, newtype, flags & FORTRAN);
8373
 
                                        seq = TRUE;
8374
 
                                        Py_DECREF(newtype);
8375
 
                                }
8376
 
                        }
8377
 
                        else {
8378
 
                                seq = TRUE;
8379
 
                                Py_DECREF(newtype);
8380
 
                        }
8381
 
                }
8382
 
                if (!seq)
8383
 
                        r = Array_FromPyScalar(op, newtype);
8384
 
        }
8385
 
 
8386
 
        /* If we didn't succeed return NULL */
8387
 
        if (r == NULL) return NULL;
8388
 
 
8389
 
        /* Be sure we succeed here */
8390
 
 
8391
 
        if(!PyArray_Check(r)) {
8392
 
                PyErr_SetString(PyExc_RuntimeError,
8393
 
                                "internal error: PyArray_FromAny "\
8394
 
                                "not producing an array");
8395
 
                Py_DECREF(r);
8396
 
                return NULL;
8397
 
        }
8398
 
 
8399
 
        if (min_depth != 0 && ((PyArrayObject *)r)->nd < min_depth) {
8400
 
                PyErr_SetString(PyExc_ValueError,
8401
 
                                "object of too small depth for desired array");
8402
 
                Py_DECREF(r);
8403
 
                return NULL;
8404
 
        }
8405
 
        if (max_depth != 0 && ((PyArrayObject *)r)->nd > max_depth) {
8406
 
                PyErr_SetString(PyExc_ValueError,
8407
 
                                "object too deep for desired array");
8408
 
                Py_DECREF(r);
8409
 
                return NULL;
8410
 
        }
8411
 
        return r;
 
8837
    }
 
8838
 
 
8839
    /* If we didn't succeed return NULL */
 
8840
    if (r == NULL) {
 
8841
        return NULL;
 
8842
    }
 
8843
 
 
8844
    /* Be sure we succeed here */
 
8845
 
 
8846
    if(!PyArray_Check(r)) {
 
8847
        PyErr_SetString(PyExc_RuntimeError,
 
8848
                        "internal error: PyArray_FromAny "\
 
8849
                        "not producing an array");
 
8850
        Py_DECREF(r);
 
8851
        return NULL;
 
8852
    }
 
8853
 
 
8854
    if (min_depth != 0 && ((PyArrayObject *)r)->nd < min_depth) {
 
8855
        PyErr_SetString(PyExc_ValueError,
 
8856
                        "object of too small depth for desired array");
 
8857
        Py_DECREF(r);
 
8858
        return NULL;
 
8859
    }
 
8860
    if (max_depth != 0 && ((PyArrayObject *)r)->nd > max_depth) {
 
8861
        PyErr_SetString(PyExc_ValueError,
 
8862
                        "object too deep for desired array");
 
8863
        Py_DECREF(r);
 
8864
        return NULL;
 
8865
    }
 
8866
    return r;
8412
8867
 
8413
8868
 err:
8414
 
        Py_XDECREF(newtype);
8415
 
        PyErr_SetString(PyExc_TypeError,
8416
 
                        "UPDATEIFCOPY used for non-array input.");
8417
 
        return NULL;
 
8869
    Py_XDECREF(newtype);
 
8870
    PyErr_SetString(PyExc_TypeError,
 
8871
                    "UPDATEIFCOPY used for non-array input.");
 
8872
    return NULL;
8418
8873
}
8419
8874
 
8420
8875
/* new reference -- accepts NULL for mintype*/
8422
8877
static PyArray_Descr *
8423
8878
PyArray_DescrFromObject(PyObject *op, PyArray_Descr *mintype)
8424
8879
{
8425
 
        return _array_find_type(op, mintype, MAX_DIMS);
 
8880
    return _array_find_type(op, mintype, MAX_DIMS);
8426
8881
}
8427
8882
 
8428
8883
/*OBJECT_API
8429
 
 Return the typecode of the array a Python object would be converted
8430
 
 to
 
8884
  Return the typecode of the array a Python object would be converted
 
8885
  to
8431
8886
*/
8432
8887
static int
8433
8888
PyArray_ObjectType(PyObject *op, int minimum_type)
8434
8889
{
8435
 
        PyArray_Descr *intype;
8436
 
        PyArray_Descr *outtype;
8437
 
        int ret;
 
8890
    PyArray_Descr *intype;
 
8891
    PyArray_Descr *outtype;
 
8892
    int ret;
8438
8893
 
8439
 
        intype = PyArray_DescrFromType(minimum_type);
8440
 
        if (intype == NULL) PyErr_Clear();
8441
 
        outtype = _array_find_type(op, intype, MAX_DIMS);
8442
 
        ret = outtype->type_num;
8443
 
        Py_DECREF(outtype);
8444
 
        Py_XDECREF(intype);
8445
 
        return ret;
 
8894
    intype = PyArray_DescrFromType(minimum_type);
 
8895
    if (intype == NULL) PyErr_Clear();
 
8896
    outtype = _array_find_type(op, intype, MAX_DIMS);
 
8897
    ret = outtype->type_num;
 
8898
    Py_DECREF(outtype);
 
8899
    Py_XDECREF(intype);
 
8900
    return ret;
8446
8901
}
8447
8902
 
8448
8903
 
8449
8904
/* flags is any of
8450
 
  CONTIGUOUS,
8451
 
  FORTRAN,
8452
 
  ALIGNED,
8453
 
  WRITEABLE,
8454
 
  NOTSWAPPED,
8455
 
  ENSURECOPY,
8456
 
  UPDATEIFCOPY,
8457
 
  FORCECAST,
8458
 
  ENSUREARRAY,
8459
 
  ELEMENTSTRIDES
 
8905
   CONTIGUOUS,
 
8906
   FORTRAN,
 
8907
   ALIGNED,
 
8908
   WRITEABLE,
 
8909
   NOTSWAPPED,
 
8910
   ENSURECOPY,
 
8911
   UPDATEIFCOPY,
 
8912
   FORCECAST,
 
8913
   ENSUREARRAY,
 
8914
   ELEMENTSTRIDES
8460
8915
 
8461
8916
   or'd (|) together
8462
8917
 
8493
8948
PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth,
8494
8949
                     int max_depth, int requires, PyObject *context)
8495
8950
{
8496
 
        PyObject *obj;
8497
 
        if (requires & NOTSWAPPED) {
8498
 
                if (!descr && PyArray_Check(op) && \
8499
 
                    !PyArray_ISNBO(PyArray_DESCR(op)->byteorder)) {
8500
 
                        descr = PyArray_DescrNew(PyArray_DESCR(op));
8501
 
                }
8502
 
                else if (descr && !PyArray_ISNBO(descr->byteorder)) {
8503
 
                        PyArray_DESCR_REPLACE(descr);
8504
 
                }
8505
 
                if (descr) {
8506
 
                        descr->byteorder = PyArray_NATIVE;
8507
 
                }
8508
 
        }
 
8951
    PyObject *obj;
 
8952
    if (requires & NOTSWAPPED) {
 
8953
        if (!descr && PyArray_Check(op) && \
 
8954
            !PyArray_ISNBO(PyArray_DESCR(op)->byteorder)) {
 
8955
            descr = PyArray_DescrNew(PyArray_DESCR(op));
 
8956
        }
 
8957
        else if (descr && !PyArray_ISNBO(descr->byteorder)) {
 
8958
            PyArray_DESCR_REPLACE(descr);
 
8959
        }
 
8960
        if (descr) {
 
8961
            descr->byteorder = PyArray_NATIVE;
 
8962
        }
 
8963
    }
8509
8964
 
8510
 
        obj = PyArray_FromAny(op, descr, min_depth, max_depth,
8511
 
                              requires, context);
8512
 
        if (obj == NULL) return NULL;
8513
 
        if ((requires & ELEMENTSTRIDES) &&
8514
 
            !PyArray_ElementStrides(obj)) {
8515
 
                PyObject *new;
8516
 
                new = PyArray_NewCopy((PyArrayObject *)obj, PyArray_ANYORDER);
8517
 
                Py_DECREF(obj);
8518
 
                obj = new;
8519
 
        }
8520
 
        return obj;
 
8965
    obj = PyArray_FromAny(op, descr, min_depth, max_depth,
 
8966
                          requires, context);
 
8967
    if (obj == NULL) return NULL;
 
8968
    if ((requires & ELEMENTSTRIDES) &&
 
8969
        !PyArray_ElementStrides(obj)) {
 
8970
        PyObject *new;
 
8971
        new = PyArray_NewCopy((PyArrayObject *)obj, PyArray_ANYORDER);
 
8972
        Py_DECREF(obj);
 
8973
        obj = new;
 
8974
    }
 
8975
    return obj;
8521
8976
}
8522
8977
 
8523
8978
/* This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0,
8524
 
    ENSUREARRAY) */
 
8979
   ENSUREARRAY) */
8525
8980
/*  that special cases Arrays and PyArray_Scalars up front */
8526
8981
/*  It *steals a reference* to the object */
8527
8982
/*  It also guarantees that the result is PyArray_Type */
8533
8988
static PyObject *
8534
8989
PyArray_EnsureArray(PyObject *op)
8535
8990
{
8536
 
        PyObject *new;
8537
 
 
8538
 
        if (op == NULL) return NULL;
8539
 
 
8540
 
        if (PyArray_CheckExact(op)) return op;
8541
 
 
8542
 
        if (PyArray_Check(op)) {
8543
 
                new = PyArray_View((PyArrayObject *)op, NULL, &PyArray_Type);
8544
 
                Py_DECREF(op);
8545
 
                return new;
8546
 
        }
8547
 
        if (PyArray_IsScalar(op, Generic)) {
8548
 
                new = PyArray_FromScalar(op, NULL);
8549
 
                Py_DECREF(op);
8550
 
                return new;
8551
 
        }
8552
 
        new = PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY, NULL);
8553
 
        Py_DECREF(op);
8554
 
        return new;
 
8991
    PyObject *new;
 
8992
 
 
8993
    if (op == NULL) return NULL;
 
8994
 
 
8995
    if (PyArray_CheckExact(op)) return op;
 
8996
 
 
8997
    if (PyArray_Check(op)) {
 
8998
        new = PyArray_View((PyArrayObject *)op, NULL, &PyArray_Type);
 
8999
        Py_DECREF(op);
 
9000
        return new;
 
9001
    }
 
9002
    if (PyArray_IsScalar(op, Generic)) {
 
9003
        new = PyArray_FromScalar(op, NULL);
 
9004
        Py_DECREF(op);
 
9005
        return new;
 
9006
    }
 
9007
    new = PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY, NULL);
 
9008
    Py_DECREF(op);
 
9009
    return new;
8555
9010
}
8556
9011
 
8557
9012
/*OBJECT_API*/
8558
9013
static PyObject *
8559
9014
PyArray_EnsureAnyArray(PyObject *op)
8560
9015
{
8561
 
        if (op && PyArray_Check(op)) return op;
8562
 
        return PyArray_EnsureArray(op);
 
9016
    if (op && PyArray_Check(op)) return op;
 
9017
    return PyArray_EnsureArray(op);
8563
9018
}
8564
9019
 
8565
9020
/*OBJECT_API
8566
 
 Check the type coercion rules.
 
9021
  Check the type coercion rules.
8567
9022
*/
8568
9023
static int
8569
9024
PyArray_CanCastSafely(int fromtype, int totype)
8570
9025
{
8571
 
        PyArray_Descr *from, *to;
8572
 
        register int felsize, telsize;
8573
 
 
8574
 
        if (fromtype == totype) return 1;
8575
 
        if (fromtype == PyArray_BOOL) return 1;
8576
 
        if (totype == PyArray_BOOL) return 0;
8577
 
        if (totype == PyArray_OBJECT || totype == PyArray_VOID) return 1;
8578
 
        if (fromtype == PyArray_OBJECT || fromtype == PyArray_VOID) return 0;
8579
 
 
8580
 
        from = PyArray_DescrFromType(fromtype);
8581
 
        /* cancastto is a PyArray_NOTYPE terminated C-int-array of types that
8582
 
           the data-type can be cast to safely.
8583
 
        */
8584
 
        if (from->f->cancastto) {
8585
 
                int *curtype;
8586
 
                curtype = from->f->cancastto;
8587
 
                while (*curtype != PyArray_NOTYPE) {
8588
 
                        if (*curtype++ == totype) return 1;
8589
 
                }
 
9026
    PyArray_Descr *from, *to;
 
9027
    register int felsize, telsize;
 
9028
 
 
9029
    if (fromtype == totype) return 1;
 
9030
    if (fromtype == PyArray_BOOL) return 1;
 
9031
    if (totype == PyArray_BOOL) return 0;
 
9032
    if (totype == PyArray_OBJECT || totype == PyArray_VOID) return 1;
 
9033
    if (fromtype == PyArray_OBJECT || fromtype == PyArray_VOID) return 0;
 
9034
 
 
9035
    from = PyArray_DescrFromType(fromtype);
 
9036
    /* cancastto is a PyArray_NOTYPE terminated C-int-array of types that
 
9037
       the data-type can be cast to safely.
 
9038
    */
 
9039
    if (from->f->cancastto) {
 
9040
        int *curtype;
 
9041
        curtype = from->f->cancastto;
 
9042
        while (*curtype != PyArray_NOTYPE) {
 
9043
            if (*curtype++ == totype) return 1;
8590
9044
        }
8591
 
        if (PyTypeNum_ISUSERDEF(totype)) return 0;
8592
 
 
8593
 
        to = PyArray_DescrFromType(totype);
8594
 
        telsize = to->elsize;
8595
 
        felsize = from->elsize;
8596
 
        Py_DECREF(from);
8597
 
        Py_DECREF(to);
8598
 
 
8599
 
        switch(fromtype) {
8600
 
        case PyArray_BYTE:
8601
 
        case PyArray_SHORT:
8602
 
        case PyArray_INT:
8603
 
        case PyArray_LONG:
8604
 
        case PyArray_LONGLONG:
8605
 
                if (PyTypeNum_ISINTEGER(totype)) {
8606
 
                        if (PyTypeNum_ISUNSIGNED(totype)) {
8607
 
                                return 0;
8608
 
                        }
8609
 
                        else {
8610
 
                                return (telsize >= felsize);
8611
 
                        }
8612
 
                }
8613
 
                else if (PyTypeNum_ISFLOAT(totype)) {
8614
 
                        if (felsize < 8)
8615
 
                                return (telsize > felsize);
8616
 
                        else
8617
 
                                return (telsize >= felsize);
8618
 
                }
8619
 
                else if (PyTypeNum_ISCOMPLEX(totype)) {
8620
 
                        if (felsize < 8)
8621
 
                                return ((telsize >> 1) > felsize);
8622
 
                        else
8623
 
                                return ((telsize >> 1) >= felsize);
8624
 
                }
8625
 
                else return totype > fromtype;
8626
 
        case PyArray_UBYTE:
8627
 
        case PyArray_USHORT:
8628
 
        case PyArray_UINT:
8629
 
        case PyArray_ULONG:
8630
 
        case PyArray_ULONGLONG:
8631
 
                if (PyTypeNum_ISINTEGER(totype)) {
8632
 
                        if (PyTypeNum_ISSIGNED(totype)) {
8633
 
                                return (telsize > felsize);
8634
 
                        }
8635
 
                        else {
8636
 
                                return (telsize >= felsize);
8637
 
                        }
8638
 
                }
8639
 
                else if (PyTypeNum_ISFLOAT(totype)) {
8640
 
                        if (felsize < 8)
8641
 
                                return (telsize > felsize);
8642
 
                        else
8643
 
                                return (telsize >= felsize);
8644
 
                }
8645
 
                else if (PyTypeNum_ISCOMPLEX(totype)) {
8646
 
                        if (felsize < 8)
8647
 
                                return ((telsize >> 1) > felsize);
8648
 
                        else
8649
 
                                return ((telsize >> 1) >= felsize);
8650
 
                }
8651
 
                else return totype > fromtype;
8652
 
        case PyArray_FLOAT:
8653
 
        case PyArray_DOUBLE:
8654
 
        case PyArray_LONGDOUBLE:
8655
 
                if (PyTypeNum_ISCOMPLEX(totype))
8656
 
                        return ((telsize >> 1) >= felsize);
8657
 
                else
8658
 
                        return (totype > fromtype);
8659
 
        case PyArray_CFLOAT:
8660
 
        case PyArray_CDOUBLE:
8661
 
        case PyArray_CLONGDOUBLE:
8662
 
                return (totype > fromtype);
8663
 
        case PyArray_STRING:
8664
 
        case PyArray_UNICODE:
8665
 
                return (totype > fromtype);
8666
 
        default:
 
9045
    }
 
9046
    if (PyTypeNum_ISUSERDEF(totype)) return 0;
 
9047
 
 
9048
    to = PyArray_DescrFromType(totype);
 
9049
    telsize = to->elsize;
 
9050
    felsize = from->elsize;
 
9051
    Py_DECREF(from);
 
9052
    Py_DECREF(to);
 
9053
 
 
9054
    switch(fromtype) {
 
9055
    case PyArray_BYTE:
 
9056
    case PyArray_SHORT:
 
9057
    case PyArray_INT:
 
9058
    case PyArray_LONG:
 
9059
    case PyArray_LONGLONG:
 
9060
        if (PyTypeNum_ISINTEGER(totype)) {
 
9061
            if (PyTypeNum_ISUNSIGNED(totype)) {
8667
9062
                return 0;
8668
 
        }
 
9063
            }
 
9064
            else {
 
9065
                return (telsize >= felsize);
 
9066
            }
 
9067
        }
 
9068
        else if (PyTypeNum_ISFLOAT(totype)) {
 
9069
            if (felsize < 8)
 
9070
                return (telsize > felsize);
 
9071
            else
 
9072
                return (telsize >= felsize);
 
9073
        }
 
9074
        else if (PyTypeNum_ISCOMPLEX(totype)) {
 
9075
            if (felsize < 8)
 
9076
                return ((telsize >> 1) > felsize);
 
9077
            else
 
9078
                return ((telsize >> 1) >= felsize);
 
9079
        }
 
9080
        else return totype > fromtype;
 
9081
    case PyArray_UBYTE:
 
9082
    case PyArray_USHORT:
 
9083
    case PyArray_UINT:
 
9084
    case PyArray_ULONG:
 
9085
    case PyArray_ULONGLONG:
 
9086
        if (PyTypeNum_ISINTEGER(totype)) {
 
9087
            if (PyTypeNum_ISSIGNED(totype)) {
 
9088
                return (telsize > felsize);
 
9089
            }
 
9090
            else {
 
9091
                return (telsize >= felsize);
 
9092
            }
 
9093
        }
 
9094
        else if (PyTypeNum_ISFLOAT(totype)) {
 
9095
            if (felsize < 8)
 
9096
                return (telsize > felsize);
 
9097
            else
 
9098
                return (telsize >= felsize);
 
9099
        }
 
9100
        else if (PyTypeNum_ISCOMPLEX(totype)) {
 
9101
            if (felsize < 8)
 
9102
                return ((telsize >> 1) > felsize);
 
9103
            else
 
9104
                return ((telsize >> 1) >= felsize);
 
9105
        }
 
9106
        else return totype > fromtype;
 
9107
    case PyArray_FLOAT:
 
9108
    case PyArray_DOUBLE:
 
9109
    case PyArray_LONGDOUBLE:
 
9110
        if (PyTypeNum_ISCOMPLEX(totype))
 
9111
            return ((telsize >> 1) >= felsize);
 
9112
        else
 
9113
            return (totype > fromtype);
 
9114
    case PyArray_CFLOAT:
 
9115
    case PyArray_CDOUBLE:
 
9116
    case PyArray_CLONGDOUBLE:
 
9117
        return (totype > fromtype);
 
9118
    case PyArray_STRING:
 
9119
    case PyArray_UNICODE:
 
9120
        return (totype > fromtype);
 
9121
    default:
 
9122
        return 0;
 
9123
    }
8669
9124
}
8670
9125
 
8671
9126
/* leaves reference count alone --- cannot be NULL*/
8673
9128
static Bool
8674
9129
PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
8675
9130
{
8676
 
        int fromtype=from->type_num;
8677
 
        int totype=to->type_num;
8678
 
        Bool ret;
 
9131
    int fromtype=from->type_num;
 
9132
    int totype=to->type_num;
 
9133
    Bool ret;
8679
9134
 
8680
 
        ret = (Bool) PyArray_CanCastSafely(fromtype, totype);
8681
 
        if (ret) { /* Check String and Unicode more closely */
8682
 
                if (fromtype == PyArray_STRING) {
8683
 
                        if (totype == PyArray_STRING) {
8684
 
                                ret = (from->elsize <= to->elsize);
8685
 
                        }
8686
 
                        else if (totype == PyArray_UNICODE) {
8687
 
                                ret = (from->elsize << 2 \
8688
 
                                       <= to->elsize);
8689
 
                        }
8690
 
                }
8691
 
                else if (fromtype == PyArray_UNICODE) {
8692
 
                        if (totype == PyArray_UNICODE) {
8693
 
                                ret = (from->elsize <= to->elsize);
8694
 
                        }
8695
 
                }
8696
 
                /* TODO: If totype is STRING or unicode
8697
 
                    see if the length is long enough to hold the
8698
 
                    stringified value of the object.
8699
 
                */
8700
 
        }
8701
 
        return ret;
 
9135
    ret = (Bool) PyArray_CanCastSafely(fromtype, totype);
 
9136
    if (ret) { /* Check String and Unicode more closely */
 
9137
        if (fromtype == PyArray_STRING) {
 
9138
            if (totype == PyArray_STRING) {
 
9139
                ret = (from->elsize <= to->elsize);
 
9140
            }
 
9141
            else if (totype == PyArray_UNICODE) {
 
9142
                ret = (from->elsize << 2 \
 
9143
                       <= to->elsize);
 
9144
            }
 
9145
        }
 
9146
        else if (fromtype == PyArray_UNICODE) {
 
9147
            if (totype == PyArray_UNICODE) {
 
9148
                ret = (from->elsize <= to->elsize);
 
9149
            }
 
9150
        }
 
9151
        /* TODO: If totype is STRING or unicode
 
9152
           see if the length is long enough to hold the
 
9153
           stringified value of the object.
 
9154
        */
 
9155
    }
 
9156
    return ret;
8702
9157
}
8703
9158
 
8704
9159
/*OBJECT_API
8705
9160
  See if array scalars can be cast.
8706
 
 */
 
9161
*/
8707
9162
static Bool
8708
9163
PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
8709
9164
{
8710
 
        int fromtype;
8711
 
        int totype;
 
9165
    int fromtype;
 
9166
    int totype;
8712
9167
 
8713
 
        fromtype = _typenum_fromtypeobj((PyObject *)from, 0);
8714
 
        totype = _typenum_fromtypeobj((PyObject *)to, 0);
8715
 
        if (fromtype == PyArray_NOTYPE || totype == PyArray_NOTYPE)
8716
 
                return FALSE;
8717
 
        return (Bool) PyArray_CanCastSafely(fromtype, totype);
 
9168
    fromtype = _typenum_fromtypeobj((PyObject *)from, 0);
 
9169
    totype = _typenum_fromtypeobj((PyObject *)to, 0);
 
9170
    if (fromtype == PyArray_NOTYPE || totype == PyArray_NOTYPE)
 
9171
        return FALSE;
 
9172
    return (Bool) PyArray_CanCastSafely(fromtype, totype);
8718
9173
}
8719
9174
 
8720
9175
 
8723
9178
/*         and Python's array iterator                                   ***/
8724
9179
 
8725
9180
/*OBJECT_API
8726
 
 Get Iterator.
 
9181
  Get Iterator.
8727
9182
*/
8728
9183
static PyObject *
8729
9184
PyArray_IterNew(PyObject *obj)
8730
9185
{
8731
 
        PyArrayIterObject *it;
8732
 
        int i, nd;
8733
 
        PyArrayObject *ao = (PyArrayObject *)obj;
8734
 
 
8735
 
        if (!PyArray_Check(ao)) {
8736
 
                PyErr_BadInternalCall();
8737
 
                return NULL;
8738
 
        }
8739
 
 
8740
 
        it = (PyArrayIterObject *)_pya_malloc(sizeof(PyArrayIterObject));
8741
 
        PyObject_Init((PyObject *)it, &PyArrayIter_Type);
8742
 
        /* it = PyObject_New(PyArrayIterObject, &PyArrayIter_Type);*/
8743
 
        if (it == NULL)
8744
 
                return NULL;
8745
 
 
8746
 
        nd = ao->nd;
8747
 
        PyArray_UpdateFlags(ao, CONTIGUOUS);
8748
 
        if PyArray_ISCONTIGUOUS(ao) it->contiguous = 1;
8749
 
        else it->contiguous = 0;
8750
 
        Py_INCREF(ao);
8751
 
        it->ao = ao;
8752
 
        it->size = PyArray_SIZE(ao);
8753
 
        it->nd_m1 = nd - 1;
8754
 
        it->factors[nd-1] = 1;
8755
 
        for (i=0; i < nd; i++) {
8756
 
                it->dims_m1[i] = ao->dimensions[i] - 1;
8757
 
                it->strides[i] = ao->strides[i];
8758
 
                it->backstrides[i] = it->strides[i] *   \
8759
 
                        it->dims_m1[i];
8760
 
                if (i > 0)
8761
 
                        it->factors[nd-i-1] = it->factors[nd-i] *       \
8762
 
                                ao->dimensions[nd-i];
8763
 
        }
8764
 
        PyArray_ITER_RESET(it);
8765
 
 
8766
 
        return (PyObject *)it;
 
9186
    PyArrayIterObject *it;
 
9187
    int i, nd;
 
9188
    PyArrayObject *ao = (PyArrayObject *)obj;
 
9189
 
 
9190
    if (!PyArray_Check(ao)) {
 
9191
        PyErr_BadInternalCall();
 
9192
        return NULL;
 
9193
    }
 
9194
 
 
9195
    it = (PyArrayIterObject *)_pya_malloc(sizeof(PyArrayIterObject));
 
9196
    PyObject_Init((PyObject *)it, &PyArrayIter_Type);
 
9197
    /* it = PyObject_New(PyArrayIterObject, &PyArrayIter_Type);*/
 
9198
    if (it == NULL)
 
9199
        return NULL;
 
9200
 
 
9201
    nd = ao->nd;
 
9202
    PyArray_UpdateFlags(ao, CONTIGUOUS);
 
9203
    if PyArray_ISCONTIGUOUS(ao) it->contiguous = 1;
 
9204
    else it->contiguous = 0;
 
9205
    Py_INCREF(ao);
 
9206
    it->ao = ao;
 
9207
    it->size = PyArray_SIZE(ao);
 
9208
    it->nd_m1 = nd - 1;
 
9209
    it->factors[nd-1] = 1;
 
9210
    for(i=0; i < nd; i++) {
 
9211
        it->dims_m1[i] = ao->dimensions[i] - 1;
 
9212
        it->strides[i] = ao->strides[i];
 
9213
        it->backstrides[i] = it->strides[i] *   \
 
9214
            it->dims_m1[i];
 
9215
        if (i > 0)
 
9216
            it->factors[nd-i-1] = it->factors[nd-i] *       \
 
9217
                ao->dimensions[nd-i];
 
9218
    }
 
9219
    PyArray_ITER_RESET(it);
 
9220
 
 
9221
    return (PyObject *)it;
8767
9222
}
8768
9223
 
8769
9224
/*MULTIARRAY_API
8770
9225
  Get Iterator broadcast to a particular shape
8771
 
 */
 
9226
*/
8772
9227
static PyObject *
8773
9228
PyArray_BroadcastToShape(PyObject *obj, intp *dims, int nd)
8774
9229
{
8775
 
        PyArrayIterObject *it;
8776
 
        int i, diff, j, compat, k;
8777
 
        PyArrayObject *ao = (PyArrayObject *)obj;
8778
 
 
8779
 
        if (ao->nd > nd) goto err;
8780
 
        compat = 1;
8781
 
        diff = j = nd - ao->nd;
8782
 
        for (i=0; i<ao->nd; i++, j++) {
8783
 
                if (ao->dimensions[i] == 1) continue;
8784
 
                if (ao->dimensions[i] != dims[j]) {
8785
 
                        compat = 0;
8786
 
                        break;
8787
 
                }
8788
 
        }
8789
 
        if (!compat) goto err;
8790
 
 
8791
 
        it = (PyArrayIterObject *)_pya_malloc(sizeof(PyArrayIterObject));
8792
 
        PyObject_Init((PyObject *)it, &PyArrayIter_Type);
8793
 
 
8794
 
        if (it == NULL)
8795
 
                return NULL;
8796
 
 
8797
 
        PyArray_UpdateFlags(ao, CONTIGUOUS);
8798
 
        if PyArray_ISCONTIGUOUS(ao) it->contiguous = 1;
8799
 
        else it->contiguous = 0;
8800
 
        Py_INCREF(ao);
8801
 
        it->ao = ao;
8802
 
        it->size = PyArray_MultiplyList(dims, nd);
8803
 
        it->nd_m1 = nd - 1;
8804
 
        it->factors[nd-1] = 1;
8805
 
        for (i=0; i < nd; i++) {
8806
 
                it->dims_m1[i] = dims[i] - 1;
8807
 
                k = i - diff;
8808
 
                if ((k < 0) ||
8809
 
                    ao->dimensions[k] != dims[i]) {
8810
 
                        it->contiguous = 0;
8811
 
                        it->strides[i] = 0;
8812
 
                }
8813
 
                else {
8814
 
                        it->strides[i] = ao->strides[i];
8815
 
                }
8816
 
                it->backstrides[i] = it->strides[i] *   \
8817
 
                        it->dims_m1[i];
8818
 
                if (i > 0)
8819
 
                        it->factors[nd-i-1] = it->factors[nd-i] *       \
8820
 
                                dims[nd-i];
8821
 
        }
8822
 
        PyArray_ITER_RESET(it);
8823
 
 
8824
 
        return (PyObject *)it;
 
9230
    PyArrayIterObject *it;
 
9231
    int i, diff, j, compat, k;
 
9232
    PyArrayObject *ao = (PyArrayObject *)obj;
 
9233
 
 
9234
    if (ao->nd > nd) goto err;
 
9235
    compat = 1;
 
9236
    diff = j = nd - ao->nd;
 
9237
    for(i=0; i<ao->nd; i++, j++) {
 
9238
        if (ao->dimensions[i] == 1) continue;
 
9239
        if (ao->dimensions[i] != dims[j]) {
 
9240
            compat = 0;
 
9241
            break;
 
9242
        }
 
9243
    }
 
9244
    if (!compat) goto err;
 
9245
 
 
9246
    it = (PyArrayIterObject *)_pya_malloc(sizeof(PyArrayIterObject));
 
9247
    PyObject_Init((PyObject *)it, &PyArrayIter_Type);
 
9248
 
 
9249
    if (it == NULL)
 
9250
        return NULL;
 
9251
 
 
9252
    PyArray_UpdateFlags(ao, CONTIGUOUS);
 
9253
    if PyArray_ISCONTIGUOUS(ao) it->contiguous = 1;
 
9254
    else it->contiguous = 0;
 
9255
    Py_INCREF(ao);
 
9256
    it->ao = ao;
 
9257
    it->size = PyArray_MultiplyList(dims, nd);
 
9258
    it->nd_m1 = nd - 1;
 
9259
    it->factors[nd-1] = 1;
 
9260
    for(i=0; i < nd; i++) {
 
9261
        it->dims_m1[i] = dims[i] - 1;
 
9262
        k = i - diff;
 
9263
        if ((k < 0) ||
 
9264
            ao->dimensions[k] != dims[i]) {
 
9265
            it->contiguous = 0;
 
9266
            it->strides[i] = 0;
 
9267
        }
 
9268
        else {
 
9269
            it->strides[i] = ao->strides[k];
 
9270
        }
 
9271
        it->backstrides[i] = it->strides[i] *   \
 
9272
            it->dims_m1[i];
 
9273
        if (i > 0)
 
9274
            it->factors[nd-i-1] = it->factors[nd-i] *       \
 
9275
                dims[nd-i];
 
9276
    }
 
9277
    PyArray_ITER_RESET(it);
 
9278
 
 
9279
    return (PyObject *)it;
8825
9280
 
8826
9281
 err:
8827
 
        PyErr_SetString(PyExc_ValueError, "array is not broadcastable to "\
8828
 
                        "correct shape");
8829
 
        return NULL;
 
9282
    PyErr_SetString(PyExc_ValueError, "array is not broadcastable to "\
 
9283
                    "correct shape");
 
9284
    return NULL;
8830
9285
}
8831
9286
 
8832
9287
 
8834
9289
 
8835
9290
 
8836
9291
/*OBJECT_API
8837
 
 Get Iterator that iterates over all but one axis (don't use this with
8838
 
 PyArray_ITER_GOTO1D).  The axis will be over-written if negative
8839
 
 with the axis having the smallest stride. 
 
9292
  Get Iterator that iterates over all but one axis (don't use this with
 
9293
  PyArray_ITER_GOTO1D).  The axis will be over-written if negative
 
9294
  with the axis having the smallest stride.
8840
9295
*/
8841
9296
static PyObject *
8842
9297
PyArray_IterAllButAxis(PyObject *obj, int *inaxis)
8843
9298
{
8844
 
        PyArrayIterObject *it;
8845
 
        int axis;
8846
 
        it = (PyArrayIterObject *)PyArray_IterNew(obj);
8847
 
        if (it == NULL) return NULL;
8848
 
 
8849
 
        if (PyArray_NDIM(obj)==0)
8850
 
                return (PyObject *)it;
8851
 
        if (*inaxis < 0) {
8852
 
                int i, minaxis=0;
8853
 
                intp minstride=0;
8854
 
                i = 0;
8855
 
                while (minstride==0 && i<PyArray_NDIM(obj)) {
8856
 
                        minstride = PyArray_STRIDE(obj,i);
8857
 
                        i++;
8858
 
                }
8859
 
                for (i=1; i<PyArray_NDIM(obj); i++) {
8860
 
                        if (PyArray_STRIDE(obj,i) > 0 && 
8861
 
                            PyArray_STRIDE(obj, i) < minstride) {
8862
 
                                minaxis = i;
8863
 
                                minstride = PyArray_STRIDE(obj,i);
8864
 
                        }
8865
 
                }
8866
 
                *inaxis = minaxis;
8867
 
        }
8868
 
        axis = *inaxis;
8869
 
        /* adjust so that will not iterate over axis */
8870
 
        it->contiguous = 0;
8871
 
        if (it->size != 0) {
8872
 
                it->size /= PyArray_DIM(obj,axis);
8873
 
        }
8874
 
        it->dims_m1[axis] = 0;
8875
 
        it->backstrides[axis] = 0;
8876
 
 
8877
 
        /* (won't fix factors so don't use
8878
 
           PyArray_ITER_GOTO1D with this iterator) */
 
9299
    PyArrayIterObject *it;
 
9300
    int axis;
 
9301
    it = (PyArrayIterObject *)PyArray_IterNew(obj);
 
9302
    if (it == NULL) return NULL;
 
9303
 
 
9304
    if (PyArray_NDIM(obj)==0)
8879
9305
        return (PyObject *)it;
 
9306
    if (*inaxis < 0) {
 
9307
        int i, minaxis=0;
 
9308
        intp minstride=0;
 
9309
        i = 0;
 
9310
        while (minstride==0 && i<PyArray_NDIM(obj)) {
 
9311
            minstride = PyArray_STRIDE(obj,i);
 
9312
            i++;
 
9313
        }
 
9314
        for(i=1; i<PyArray_NDIM(obj); i++) {
 
9315
            if (PyArray_STRIDE(obj,i) > 0 &&
 
9316
                PyArray_STRIDE(obj, i) < minstride) {
 
9317
                minaxis = i;
 
9318
                minstride = PyArray_STRIDE(obj,i);
 
9319
            }
 
9320
        }
 
9321
        *inaxis = minaxis;
 
9322
    }
 
9323
    axis = *inaxis;
 
9324
    /* adjust so that will not iterate over axis */
 
9325
    it->contiguous = 0;
 
9326
    if (it->size != 0) {
 
9327
        it->size /= PyArray_DIM(obj,axis);
 
9328
    }
 
9329
    it->dims_m1[axis] = 0;
 
9330
    it->backstrides[axis] = 0;
 
9331
 
 
9332
    /* (won't fix factors so don't use
 
9333
       PyArray_ITER_GOTO1D with this iterator) */
 
9334
    return (PyObject *)it;
8880
9335
}
8881
9336
 
8882
9337
 
8884
9339
   adjusted */
8885
9340
 
8886
9341
/*OBJECT_API
8887
 
  Adjusts previously broadcasted iterators so that the axis with 
 
9342
  Adjusts previously broadcasted iterators so that the axis with
8888
9343
  the smallest sum of iterator strides is not iterated over.
8889
9344
  Returns dimension which is smallest in the range [0,multi->nd).
8890
9345
  A -1 is returned if multi->nd == 0.
8891
 
 */
 
9346
*/
8892
9347
static int
8893
9348
PyArray_RemoveSmallest(PyArrayMultiIterObject *multi)
8894
9349
{
8895
 
        PyArrayIterObject *it;
8896
 
        int i, j;
8897
 
        int axis;
8898
 
        intp smallest;
8899
 
        intp sumstrides[NPY_MAXDIMS];
8900
 
 
8901
 
        if (multi->nd == 0) return -1;
8902
 
 
8903
 
 
8904
 
        for (i=0; i<multi->nd; i++) {
8905
 
                sumstrides[i] = 0;
8906
 
                for (j=0; j<multi->numiter; j++) {
8907
 
                        sumstrides[i] = multi->iters[j]->strides[i];
8908
 
                }
8909
 
        }
8910
 
        axis=0;
8911
 
        smallest = sumstrides[0];
8912
 
        /* Find longest dimension */
8913
 
        for (i=1; i<multi->nd; i++) {
8914
 
                if (sumstrides[i] < smallest) {
8915
 
                        axis = i;
8916
 
                        smallest = sumstrides[i];
8917
 
                }
8918
 
        }
8919
 
 
8920
 
        for (i=0; i<multi->numiter; i++) {
8921
 
                it = multi->iters[i];
8922
 
                it->contiguous = 0;
8923
 
                if (it->size != 0)
8924
 
                        it->size /= (it->dims_m1[axis]+1);
8925
 
                it->dims_m1[axis] = 0;
8926
 
                it->backstrides[axis] = 0;
8927
 
        }
8928
 
 
8929
 
        multi->size = multi->iters[0]->size;
8930
 
        return axis;
 
9350
    PyArrayIterObject *it;
 
9351
    int i, j;
 
9352
    int axis;
 
9353
    intp smallest;
 
9354
    intp sumstrides[NPY_MAXDIMS];
 
9355
 
 
9356
    if (multi->nd == 0) return -1;
 
9357
 
 
9358
 
 
9359
    for(i=0; i<multi->nd; i++) {
 
9360
        sumstrides[i] = 0;
 
9361
        for(j=0; j<multi->numiter; j++) {
 
9362
            sumstrides[i] += multi->iters[j]->strides[i];
 
9363
        }
 
9364
    }
 
9365
    axis=0;
 
9366
    smallest = sumstrides[0];
 
9367
    /* Find longest dimension */
 
9368
    for(i=1; i<multi->nd; i++) {
 
9369
        if (sumstrides[i] < smallest) {
 
9370
            axis = i;
 
9371
            smallest = sumstrides[i];
 
9372
        }
 
9373
    }
 
9374
 
 
9375
    for(i=0; i<multi->numiter; i++) {
 
9376
        it = multi->iters[i];
 
9377
        it->contiguous = 0;
 
9378
        if (it->size != 0)
 
9379
            it->size /= (it->dims_m1[axis]+1);
 
9380
        it->dims_m1[axis] = 0;
 
9381
        it->backstrides[axis] = 0;
 
9382
    }
 
9383
 
 
9384
    multi->size = multi->iters[0]->size;
 
9385
    return axis;
8931
9386
}
8932
9387
 
8933
9388
/* Returns an array scalar holding the element desired */
8935
9390
static PyObject *
8936
9391
arrayiter_next(PyArrayIterObject *it)
8937
9392
{
8938
 
        PyObject *ret;
 
9393
    PyObject *ret;
8939
9394
 
8940
 
        if (it->index < it->size) {
8941
 
                ret = PyArray_ToScalar(it->dataptr, it->ao);
8942
 
                PyArray_ITER_NEXT(it);
8943
 
                return ret;
8944
 
        }
8945
 
        return NULL;
 
9395
    if (it->index < it->size) {
 
9396
        ret = PyArray_ToScalar(it->dataptr, it->ao);
 
9397
        PyArray_ITER_NEXT(it);
 
9398
        return ret;
 
9399
    }
 
9400
    return NULL;
8946
9401
}
8947
9402
 
8948
9403
static void
8949
9404
arrayiter_dealloc(PyArrayIterObject *it)
8950
9405
{
8951
 
        Py_XDECREF(it->ao);
8952
 
        _pya_free(it);
 
9406
    Py_XDECREF(it->ao);
 
9407
    _pya_free(it);
8953
9408
}
8954
9409
 
8955
9410
static Py_ssize_t
8956
9411
iter_length(PyArrayIterObject *self)
8957
9412
{
8958
 
        return self->size;
 
9413
    return self->size;
8959
9414
}
8960
9415
 
8961
9416
 
8962
9417
static PyObject *
8963
9418
iter_subscript_Bool(PyArrayIterObject *self, PyArrayObject *ind)
8964
9419
{
8965
 
        int index, strides, itemsize;
8966
 
        intp count=0;
8967
 
        char *dptr, *optr;
8968
 
        PyObject *r;
8969
 
        int swap;
8970
 
        PyArray_CopySwapFunc *copyswap;
8971
 
 
8972
 
 
8973
 
        if (ind->nd != 1) {
8974
 
                PyErr_SetString(PyExc_ValueError,
8975
 
                                "boolean index array should have 1 dimension");
8976
 
                return NULL;
8977
 
        }
8978
 
        index = ind->dimensions[0];
8979
 
        if (index > self->size) {
8980
 
                PyErr_SetString(PyExc_ValueError,
8981
 
                                "too many boolean indices");
8982
 
                return NULL;
8983
 
        }
8984
 
 
8985
 
        strides = ind->strides[0];
8986
 
        dptr = ind->data;
8987
 
        /* Get size of return array */
8988
 
        while(index--) {
8989
 
                if (*((Bool *)dptr) != 0)
8990
 
                        count++;
8991
 
                dptr += strides;
8992
 
        }
8993
 
        itemsize = self->ao->descr->elsize;
 
9420
    int index, strides, itemsize;
 
9421
    intp count=0;
 
9422
    char *dptr, *optr;
 
9423
    PyObject *r;
 
9424
    int swap;
 
9425
    PyArray_CopySwapFunc *copyswap;
 
9426
 
 
9427
 
 
9428
    if (ind->nd != 1) {
 
9429
        PyErr_SetString(PyExc_ValueError,
 
9430
                        "boolean index array should have 1 dimension");
 
9431
        return NULL;
 
9432
    }
 
9433
    index = ind->dimensions[0];
 
9434
    if (index > self->size) {
 
9435
        PyErr_SetString(PyExc_ValueError,
 
9436
                        "too many boolean indices");
 
9437
        return NULL;
 
9438
    }
 
9439
 
 
9440
    strides = ind->strides[0];
 
9441
    dptr = ind->data;
 
9442
    /* Get size of return array */
 
9443
    while(index--) {
 
9444
        if (*((Bool *)dptr) != 0)
 
9445
            count++;
 
9446
        dptr += strides;
 
9447
    }
 
9448
    itemsize = self->ao->descr->elsize;
 
9449
    Py_INCREF(self->ao->descr);
 
9450
    r = PyArray_NewFromDescr(self->ao->ob_type,
 
9451
                             self->ao->descr, 1, &count,
 
9452
                             NULL, NULL,
 
9453
                             0, (PyObject *)self->ao);
 
9454
    if (r==NULL) return NULL;
 
9455
 
 
9456
    /* Set up loop */
 
9457
    optr = PyArray_DATA(r);
 
9458
    index = ind->dimensions[0];
 
9459
    dptr = ind->data;
 
9460
 
 
9461
    copyswap = self->ao->descr->f->copyswap;
 
9462
    /* Loop over Boolean array */
 
9463
    swap = (PyArray_ISNOTSWAPPED(self->ao) != PyArray_ISNOTSWAPPED(r));
 
9464
    while(index--) {
 
9465
        if (*((Bool *)dptr) != 0) {
 
9466
            copyswap(optr, self->dataptr, swap, self->ao);
 
9467
            optr += itemsize;
 
9468
        }
 
9469
        dptr += strides;
 
9470
        PyArray_ITER_NEXT(self);
 
9471
    }
 
9472
    PyArray_ITER_RESET(self);
 
9473
    return r;
 
9474
}
 
9475
 
 
9476
static PyObject *
 
9477
iter_subscript_int(PyArrayIterObject *self, PyArrayObject *ind)
 
9478
{
 
9479
    intp num;
 
9480
    PyObject *r;
 
9481
    PyArrayIterObject *ind_it;
 
9482
    int itemsize;
 
9483
    int swap;
 
9484
    char *optr;
 
9485
    int index;
 
9486
    PyArray_CopySwapFunc *copyswap;
 
9487
 
 
9488
    itemsize = self->ao->descr->elsize;
 
9489
    if (ind->nd == 0) {
 
9490
        num = *((intp *)ind->data);
 
9491
        if (num < 0) num += self->size;
 
9492
        if (num < 0 || num >= self->size) {
 
9493
            PyErr_Format(PyExc_IndexError,
 
9494
                         "index %d out of bounds"   \
 
9495
                         " 0<=index<%d", (int) num,
 
9496
                         (int) self->size);
 
9497
            r = NULL;
 
9498
        }
 
9499
        else {
 
9500
            PyArray_ITER_GOTO1D(self, num);
 
9501
            r = PyArray_ToScalar(self->dataptr, self->ao);
 
9502
        }
 
9503
        PyArray_ITER_RESET(self);
 
9504
        return r;
 
9505
    }
 
9506
 
 
9507
    Py_INCREF(self->ao->descr);
 
9508
    r = PyArray_NewFromDescr(self->ao->ob_type, self->ao->descr,
 
9509
                             ind->nd, ind->dimensions,
 
9510
                             NULL, NULL,
 
9511
                             0, (PyObject *)self->ao);
 
9512
    if (r==NULL) return NULL;
 
9513
 
 
9514
    optr = PyArray_DATA(r);
 
9515
    ind_it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ind);
 
9516
    if (ind_it == NULL) {Py_DECREF(r); return NULL;}
 
9517
    index = ind_it->size;
 
9518
    copyswap = PyArray_DESCR(r)->f->copyswap;
 
9519
    swap = (PyArray_ISNOTSWAPPED(r) != PyArray_ISNOTSWAPPED(self->ao));
 
9520
    while(index--) {
 
9521
        num = *((intp *)(ind_it->dataptr));
 
9522
        if (num < 0) num += self->size;
 
9523
        if (num < 0 || num >= self->size) {
 
9524
            PyErr_Format(PyExc_IndexError,
 
9525
                         "index %d out of bounds"           \
 
9526
                         " 0<=index<%d", (int) num,
 
9527
                         (int) self->size);
 
9528
            Py_DECREF(ind_it);
 
9529
            Py_DECREF(r);
 
9530
            PyArray_ITER_RESET(self);
 
9531
            return NULL;
 
9532
        }
 
9533
        PyArray_ITER_GOTO1D(self, num);
 
9534
        copyswap(optr, self->dataptr, swap, r);
 
9535
        optr += itemsize;
 
9536
        PyArray_ITER_NEXT(ind_it);
 
9537
    }
 
9538
    Py_DECREF(ind_it);
 
9539
    PyArray_ITER_RESET(self);
 
9540
    return r;
 
9541
}
 
9542
 
 
9543
 
 
9544
static PyObject *
 
9545
iter_subscript(PyArrayIterObject *self, PyObject *ind)
 
9546
{
 
9547
    PyArray_Descr *indtype=NULL;
 
9548
    intp start, step_size;
 
9549
    intp n_steps;
 
9550
    PyObject *r;
 
9551
    char *dptr;
 
9552
    int size;
 
9553
    PyObject *obj = NULL;
 
9554
    PyArray_CopySwapFunc *copyswap;
 
9555
 
 
9556
    if (ind == Py_Ellipsis) {
 
9557
        ind = PySlice_New(NULL, NULL, NULL);
 
9558
        obj = iter_subscript(self, ind);
 
9559
        Py_DECREF(ind);
 
9560
        return obj;
 
9561
    }
 
9562
    if (PyTuple_Check(ind)) {
 
9563
        int len;
 
9564
        len = PyTuple_GET_SIZE(ind);
 
9565
        if (len > 1) goto fail;
 
9566
        if (len == 0) {
 
9567
            Py_INCREF(self->ao);
 
9568
            return (PyObject *)self->ao;
 
9569
        }
 
9570
        ind = PyTuple_GET_ITEM(ind, 0);
 
9571
    }
 
9572
 
 
9573
    /* Tuples >1d not accepted --- i.e. no newaxis */
 
9574
    /* Could implement this with adjusted strides
 
9575
       and dimensions in iterator */
 
9576
 
 
9577
    /* Check for Boolean -- this is first becasue
 
9578
       Bool is a subclass of Int */
 
9579
    PyArray_ITER_RESET(self);
 
9580
 
 
9581
    if (PyBool_Check(ind)) {
 
9582
        if (PyObject_IsTrue(ind)) {
 
9583
            return PyArray_ToScalar(self->dataptr, self->ao);
 
9584
        }
 
9585
        else { /* empty array */
 
9586
            intp ii = 0;
 
9587
            Py_INCREF(self->ao->descr);
 
9588
            r = PyArray_NewFromDescr(self->ao->ob_type,
 
9589
                                     self->ao->descr,
 
9590
                                     1, &ii,
 
9591
                                     NULL, NULL, 0,
 
9592
                                     (PyObject *)self->ao);
 
9593
            return r;
 
9594
        }
 
9595
    }
 
9596
 
 
9597
    /* Check for Integer or Slice */
 
9598
 
 
9599
    if (PyLong_Check(ind) || PyInt_Check(ind) || PySlice_Check(ind)) {
 
9600
        start = parse_subindex(ind, &step_size, &n_steps,
 
9601
                               self->size);
 
9602
        if (start == -1)
 
9603
            goto fail;
 
9604
        if (n_steps == RubberIndex || n_steps == PseudoIndex) {
 
9605
            PyErr_SetString(PyExc_IndexError,
 
9606
                            "cannot use Ellipsis or newaxes here");
 
9607
            goto fail;
 
9608
        }
 
9609
        PyArray_ITER_GOTO1D(self, start)
 
9610
            if (n_steps == SingleIndex) { /* Integer */
 
9611
                r = PyArray_ToScalar(self->dataptr, self->ao);
 
9612
                PyArray_ITER_RESET(self);
 
9613
                return r;
 
9614
            }
 
9615
        size = self->ao->descr->elsize;
8994
9616
        Py_INCREF(self->ao->descr);
8995
9617
        r = PyArray_NewFromDescr(self->ao->ob_type,
8996
 
                                 self->ao->descr, 1, &count,
8997
 
                                 NULL, NULL,
8998
 
                                 0, (PyObject *)self->ao);
8999
 
        if (r==NULL) return NULL;
9000
 
 
9001
 
        /* Set up loop */
9002
 
        optr = PyArray_DATA(r);
9003
 
        index = ind->dimensions[0];
9004
 
        dptr = ind->data;
9005
 
 
9006
 
        copyswap = self->ao->descr->f->copyswap;
9007
 
        /* Loop over Boolean array */
9008
 
        swap = (PyArray_ISNOTSWAPPED(self->ao) != PyArray_ISNOTSWAPPED(r));
9009
 
        while(index--) {
9010
 
                if (*((Bool *)dptr) != 0) {
9011
 
                        copyswap(optr, self->dataptr, swap, self->ao);
9012
 
                        optr += itemsize;
9013
 
                }
9014
 
                dptr += strides;
9015
 
                PyArray_ITER_NEXT(self);
9016
 
        }
9017
 
        PyArray_ITER_RESET(self);
9018
 
        return r;
9019
 
}
9020
 
 
9021
 
static PyObject *
9022
 
iter_subscript_int(PyArrayIterObject *self, PyArrayObject *ind)
9023
 
{
9024
 
        intp num;
9025
 
        PyObject *r;
9026
 
        PyArrayIterObject *ind_it;
9027
 
        int itemsize;
9028
 
        int swap;
9029
 
        char *optr;
9030
 
        int index;
9031
 
        PyArray_CopySwapFunc *copyswap;
9032
 
 
9033
 
        itemsize = self->ao->descr->elsize;
9034
 
        if (ind->nd == 0) {
9035
 
                num = *((intp *)ind->data);
9036
 
                if (num < 0) num += self->size;
9037
 
                if (num < 0 || num >= self->size) {
9038
 
                        PyErr_Format(PyExc_IndexError,
9039
 
                                     "index %d out of bounds"   \
9040
 
                                     " 0<=index<%d", (int) num,
9041
 
                                     (int) self->size);
9042
 
                        r = NULL;
9043
 
                }
9044
 
                else {
9045
 
                        PyArray_ITER_GOTO1D(self, num);
9046
 
                        r = PyArray_ToScalar(self->dataptr, self->ao);
9047
 
                }
9048
 
                PyArray_ITER_RESET(self);
9049
 
                return r;
9050
 
        }
9051
 
 
9052
 
        Py_INCREF(self->ao->descr);
9053
 
        r = PyArray_NewFromDescr(self->ao->ob_type, self->ao->descr,
9054
 
                                 ind->nd, ind->dimensions,
9055
 
                                 NULL, NULL,
9056
 
                                 0, (PyObject *)self->ao);
9057
 
        if (r==NULL) return NULL;
9058
 
 
9059
 
        optr = PyArray_DATA(r);
9060
 
        ind_it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ind);
9061
 
        if (ind_it == NULL) {Py_DECREF(r); return NULL;}
9062
 
        index = ind_it->size;
 
9618
                                 self->ao->descr,
 
9619
                                 1, &n_steps,
 
9620
                                 NULL, NULL,
 
9621
                                 0, (PyObject *)self->ao);
 
9622
        if (r==NULL) goto fail;
 
9623
        dptr = PyArray_DATA(r);
9063
9624
        copyswap = PyArray_DESCR(r)->f->copyswap;
9064
 
        swap = (PyArray_ISNOTSWAPPED(r) != PyArray_ISNOTSWAPPED(self->ao));
9065
 
        while(index--) {
9066
 
                num = *((intp *)(ind_it->dataptr));
9067
 
                if (num < 0) num += self->size;
9068
 
                if (num < 0 || num >= self->size) {
9069
 
                        PyErr_Format(PyExc_IndexError,
9070
 
                                     "index %d out of bounds"           \
9071
 
                                     " 0<=index<%d", (int) num,
9072
 
                                     (int) self->size);
9073
 
                        Py_DECREF(ind_it);
9074
 
                        Py_DECREF(r);
9075
 
                        PyArray_ITER_RESET(self);
9076
 
                        return NULL;
9077
 
                }
9078
 
                PyArray_ITER_GOTO1D(self, num);
9079
 
                copyswap(optr, self->dataptr, swap, r);
9080
 
                optr += itemsize;
9081
 
                PyArray_ITER_NEXT(ind_it);
 
9625
        while(n_steps--) {
 
9626
            copyswap(dptr, self->dataptr, 0, r);
 
9627
            start += step_size;
 
9628
            PyArray_ITER_GOTO1D(self, start)
 
9629
                dptr += size;
9082
9630
        }
9083
 
        Py_DECREF(ind_it);
9084
9631
        PyArray_ITER_RESET(self);
9085
9632
        return r;
9086
 
}
9087
 
 
9088
 
 
9089
 
static PyObject *
9090
 
iter_subscript(PyArrayIterObject *self, PyObject *ind)
9091
 
{
9092
 
        PyArray_Descr *indtype=NULL;
9093
 
        intp start, step_size;
9094
 
        intp n_steps;
9095
 
        PyObject *r;
9096
 
        char *dptr;
9097
 
        int size;
9098
 
        PyObject *obj = NULL;
9099
 
        int swap;
9100
 
        PyArray_CopySwapFunc *copyswap;
9101
 
 
9102
 
        if (ind == Py_Ellipsis) {
9103
 
                ind = PySlice_New(NULL, NULL, NULL);
9104
 
                obj = iter_subscript(self, ind);
9105
 
                Py_DECREF(ind);
9106
 
                return obj;
9107
 
        }
9108
 
        if (PyTuple_Check(ind)) {
9109
 
                int len;
9110
 
                len = PyTuple_GET_SIZE(ind);
9111
 
                if (len > 1) goto fail;
9112
 
                if (len == 0) {
9113
 
                        Py_INCREF(self->ao);
9114
 
                        return (PyObject *)self->ao;
9115
 
                }
9116
 
                ind = PyTuple_GET_ITEM(ind, 0);
9117
 
        }
9118
 
 
9119
 
        /* Tuples >1d not accepted --- i.e. no newaxis */
9120
 
        /* Could implement this with adjusted strides
9121
 
           and dimensions in iterator */
9122
 
 
9123
 
        /* Check for Boolean -- this is first becasue
9124
 
           Bool is a subclass of Int */
9125
 
        PyArray_ITER_RESET(self);
9126
 
 
9127
 
        if (PyBool_Check(ind)) {
9128
 
                if (PyObject_IsTrue(ind)) {
9129
 
                        return PyArray_ToScalar(self->dataptr, self->ao);
9130
 
                }
9131
 
                else { /* empty array */
9132
 
                        intp ii = 0;
9133
 
                        Py_INCREF(self->ao->descr);
9134
 
                        r = PyArray_NewFromDescr(self->ao->ob_type,
9135
 
                                                 self->ao->descr,
9136
 
                                                 1, &ii,
9137
 
                                                 NULL, NULL, 0,
9138
 
                                                 (PyObject *)self->ao);
9139
 
                        return r;
9140
 
                }
9141
 
        }
9142
 
 
9143
 
        /* Check for Integer or Slice */
9144
 
 
9145
 
        if (PyLong_Check(ind) || PyInt_Check(ind) || PySlice_Check(ind)) {
9146
 
                start = parse_subindex(ind, &step_size, &n_steps,
9147
 
                                       self->size);
9148
 
                if (start == -1)
9149
 
                        goto fail;
9150
 
                if (n_steps == RubberIndex || n_steps == PseudoIndex) {
9151
 
                        PyErr_SetString(PyExc_IndexError,
9152
 
                                        "cannot use Ellipsis or newaxes here");
9153
 
                        goto fail;
9154
 
                }
9155
 
                PyArray_ITER_GOTO1D(self, start)
9156
 
                if (n_steps == SingleIndex) { /* Integer */
9157
 
                        r = PyArray_ToScalar(self->dataptr, self->ao);
9158
 
                        PyArray_ITER_RESET(self);
9159
 
                        return r;
9160
 
                }
9161
 
                size = self->ao->descr->elsize;
9162
 
                Py_INCREF(self->ao->descr);
9163
 
                r = PyArray_NewFromDescr(self->ao->ob_type,
9164
 
                                         self->ao->descr,
9165
 
                                         1, &n_steps,
9166
 
                                         NULL, NULL,
9167
 
                                         0, (PyObject *)self->ao);
9168
 
                if (r==NULL) goto fail;
9169
 
                dptr = PyArray_DATA(r);
9170
 
                swap = !PyArray_ISNOTSWAPPED(self->ao);
9171
 
                copyswap = PyArray_DESCR(r)->f->copyswap;
9172
 
                while(n_steps--) {
9173
 
                        copyswap(dptr, self->dataptr, swap, r);
9174
 
                        start += step_size;
9175
 
                        PyArray_ITER_GOTO1D(self, start)
9176
 
                        dptr += size;
9177
 
                }
9178
 
                PyArray_ITER_RESET(self);
9179
 
                return r;
9180
 
        }
9181
 
 
9182
 
        /* convert to INTP array if Integer array scalar or List */
9183
 
 
9184
 
        indtype = PyArray_DescrFromType(PyArray_INTP);
9185
 
        if (PyArray_IsScalar(ind, Integer) || PyList_Check(ind)) {
9186
 
                Py_INCREF(indtype);
9187
 
                obj = PyArray_FromAny(ind, indtype, 0, 0, FORCECAST, NULL);
9188
 
                if (obj == NULL) goto fail;
 
9633
    }
 
9634
 
 
9635
    /* convert to INTP array if Integer array scalar or List */
 
9636
 
 
9637
    indtype = PyArray_DescrFromType(PyArray_INTP);
 
9638
    if (PyArray_IsScalar(ind, Integer) || PyList_Check(ind)) {
 
9639
        Py_INCREF(indtype);
 
9640
        obj = PyArray_FromAny(ind, indtype, 0, 0, FORCECAST, NULL);
 
9641
        if (obj == NULL) goto fail;
 
9642
    }
 
9643
    else {
 
9644
        Py_INCREF(ind);
 
9645
        obj = ind;
 
9646
    }
 
9647
 
 
9648
    if (PyArray_Check(obj)) {
 
9649
        /* Check for Boolean object */
 
9650
        if (PyArray_TYPE(obj)==PyArray_BOOL) {
 
9651
            r = iter_subscript_Bool(self, (PyArrayObject *)obj);
 
9652
            Py_DECREF(indtype);
 
9653
        }
 
9654
        /* Check for integer array */
 
9655
        else if (PyArray_ISINTEGER(obj)) {
 
9656
            PyObject *new;
 
9657
            new = PyArray_FromAny(obj, indtype, 0, 0,
 
9658
                                  FORCECAST | ALIGNED, NULL);
 
9659
            if (new==NULL) goto fail;
 
9660
            Py_DECREF(obj);
 
9661
            obj = new;
 
9662
            r = iter_subscript_int(self, (PyArrayObject *)obj);
9189
9663
        }
9190
9664
        else {
9191
 
                Py_INCREF(ind);
9192
 
                obj = ind;
9193
 
        }
9194
 
 
9195
 
        if (PyArray_Check(obj)) {
9196
 
                /* Check for Boolean object */
9197
 
                if (PyArray_TYPE(obj)==PyArray_BOOL) {
9198
 
                        r = iter_subscript_Bool(self, (PyArrayObject *)obj);
9199
 
                        Py_DECREF(indtype);
9200
 
                }
9201
 
                /* Check for integer array */
9202
 
                else if (PyArray_ISINTEGER(obj)) {
9203
 
                        PyObject *new;
9204
 
                        new = PyArray_FromAny(obj, indtype, 0, 0,
9205
 
                                              FORCECAST | ALIGNED, NULL);
9206
 
                        if (new==NULL) goto fail;
9207
 
                        Py_DECREF(obj);
9208
 
                        obj = new;
9209
 
                        r = iter_subscript_int(self, (PyArrayObject *)obj);
9210
 
                }
9211
 
                else {
9212
 
                        goto fail;
9213
 
                }
9214
 
                Py_DECREF(obj);
9215
 
                return r;
9216
 
        }
9217
 
        else Py_DECREF(indtype);
 
9665
            goto fail;
 
9666
        }
 
9667
        Py_DECREF(obj);
 
9668
        return r;
 
9669
    }
 
9670
    else Py_DECREF(indtype);
9218
9671
 
9219
9672
 
9220
9673
 fail:
9221
 
        if (!PyErr_Occurred())
9222
 
                PyErr_SetString(PyExc_IndexError, "unsupported iterator index");
9223
 
        Py_XDECREF(indtype);
9224
 
        Py_XDECREF(obj);
9225
 
        return NULL;
 
9674
    if (!PyErr_Occurred())
 
9675
        PyErr_SetString(PyExc_IndexError, "unsupported iterator index");
 
9676
    Py_XDECREF(indtype);
 
9677
    Py_XDECREF(obj);
 
9678
    return NULL;
9226
9679
 
9227
9680
}
9228
9681
 
9231
9684
iter_ass_sub_Bool(PyArrayIterObject *self, PyArrayObject *ind,
9232
9685
                  PyArrayIterObject *val, int swap)
9233
9686
{
9234
 
        int index, strides;
9235
 
        char *dptr;
9236
 
        PyArray_CopySwapFunc *copyswap;
9237
 
 
9238
 
        if (ind->nd != 1) {
9239
 
                PyErr_SetString(PyExc_ValueError,
9240
 
                                "boolean index array should have 1 dimension");
9241
 
                return -1;
9242
 
        }
9243
 
        index = ind->dimensions[0];
9244
 
        strides = ind->strides[0];
9245
 
        dptr = ind->data;
9246
 
        PyArray_ITER_RESET(self);
9247
 
        /* Loop over Boolean array */
9248
 
        copyswap = self->ao->descr->f->copyswap;
9249
 
        while(index--) {
9250
 
                if (*((Bool *)dptr) != 0) {
9251
 
                        copyswap(self->dataptr, val->dataptr, swap, self->ao);
9252
 
                        PyArray_ITER_NEXT(val);
9253
 
                        if (val->index==val->size)
9254
 
                                PyArray_ITER_RESET(val);
9255
 
                }
9256
 
                dptr += strides;
9257
 
                PyArray_ITER_NEXT(self);
9258
 
        }
9259
 
        PyArray_ITER_RESET(self);
9260
 
        return 0;
 
9687
    int index, strides;
 
9688
    char *dptr;
 
9689
    PyArray_CopySwapFunc *copyswap;
 
9690
 
 
9691
    if (ind->nd != 1) {
 
9692
        PyErr_SetString(PyExc_ValueError,
 
9693
                        "boolean index array should have 1 dimension");
 
9694
        return -1;
 
9695
    }
 
9696
 
 
9697
    index = ind->dimensions[0];
 
9698
    if (index > self->size) {
 
9699
        PyErr_SetString(PyExc_ValueError,
 
9700
                        "boolean index array has too many values");
 
9701
        return -1;
 
9702
    }
 
9703
 
 
9704
    strides = ind->strides[0];
 
9705
    dptr = ind->data;
 
9706
    PyArray_ITER_RESET(self);
 
9707
    /* Loop over Boolean array */
 
9708
    copyswap = self->ao->descr->f->copyswap;
 
9709
    while(index--) {
 
9710
        if (*((Bool *)dptr) != 0) {
 
9711
            copyswap(self->dataptr, val->dataptr, swap, self->ao);
 
9712
            PyArray_ITER_NEXT(val);
 
9713
            if (val->index==val->size)
 
9714
                PyArray_ITER_RESET(val);
 
9715
        }
 
9716
        dptr += strides;
 
9717
        PyArray_ITER_NEXT(self);
 
9718
    }
 
9719
    PyArray_ITER_RESET(self);
 
9720
    return 0;
9261
9721
}
9262
9722
 
9263
9723
static int
9264
9724
iter_ass_sub_int(PyArrayIterObject *self, PyArrayObject *ind,
9265
 
                   PyArrayIterObject *val, int swap)
 
9725
                 PyArrayIterObject *val, int swap)
9266
9726
{
9267
 
        PyArray_Descr *typecode;
9268
 
        intp num;
9269
 
        PyArrayIterObject *ind_it;
9270
 
        int index;
9271
 
        PyArray_CopySwapFunc *copyswap;
 
9727
    PyArray_Descr *typecode;
 
9728
    intp num;
 
9729
    PyArrayIterObject *ind_it;
 
9730
    int index;
 
9731
    PyArray_CopySwapFunc *copyswap;
9272
9732
 
9273
 
        typecode = self->ao->descr;
9274
 
        copyswap = self->ao->descr->f->copyswap;
9275
 
        if (ind->nd == 0) {
9276
 
                num = *((intp *)ind->data);
9277
 
                PyArray_ITER_GOTO1D(self, num);
9278
 
                copyswap(self->dataptr, val->dataptr, swap, self->ao);
9279
 
                return 0;
9280
 
        }
9281
 
        ind_it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ind);
9282
 
        if (ind_it == NULL) return -1;
9283
 
        index = ind_it->size;
9284
 
        while(index--) {
9285
 
                num = *((intp *)(ind_it->dataptr));
9286
 
                if (num < 0) num += self->size;
9287
 
                if ((num < 0) || (num >= self->size)) {
9288
 
                        PyErr_Format(PyExc_IndexError,
9289
 
                                     "index %d out of bounds"           \
9290
 
                                     " 0<=index<%d", (int) num,
9291
 
                                     (int) self->size);
9292
 
                        Py_DECREF(ind_it);
9293
 
                        return -1;
9294
 
                }
9295
 
                PyArray_ITER_GOTO1D(self, num);
9296
 
                copyswap(self->dataptr, val->dataptr, swap, self->ao);
9297
 
                PyArray_ITER_NEXT(ind_it);
9298
 
                PyArray_ITER_NEXT(val);
9299
 
                if (val->index == val->size)
9300
 
                        PyArray_ITER_RESET(val);
9301
 
        }
9302
 
        Py_DECREF(ind_it);
 
9733
    typecode = self->ao->descr;
 
9734
    copyswap = self->ao->descr->f->copyswap;
 
9735
    if (ind->nd == 0) {
 
9736
        num = *((intp *)ind->data);
 
9737
        PyArray_ITER_GOTO1D(self, num);
 
9738
        copyswap(self->dataptr, val->dataptr, swap, self->ao);
9303
9739
        return 0;
 
9740
    }
 
9741
    ind_it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)ind);
 
9742
    if (ind_it == NULL) return -1;
 
9743
    index = ind_it->size;
 
9744
    while(index--) {
 
9745
        num = *((intp *)(ind_it->dataptr));
 
9746
        if (num < 0) num += self->size;
 
9747
        if ((num < 0) || (num >= self->size)) {
 
9748
            PyErr_Format(PyExc_IndexError,
 
9749
                         "index %d out of bounds"           \
 
9750
                         " 0<=index<%d", (int) num,
 
9751
                         (int) self->size);
 
9752
            Py_DECREF(ind_it);
 
9753
            return -1;
 
9754
        }
 
9755
        PyArray_ITER_GOTO1D(self, num);
 
9756
        copyswap(self->dataptr, val->dataptr, swap, self->ao);
 
9757
        PyArray_ITER_NEXT(ind_it);
 
9758
        PyArray_ITER_NEXT(val);
 
9759
        if (val->index == val->size)
 
9760
            PyArray_ITER_RESET(val);
 
9761
    }
 
9762
    Py_DECREF(ind_it);
 
9763
    return 0;
9304
9764
}
9305
9765
 
9306
9766
static int
9307
9767
iter_ass_subscript(PyArrayIterObject *self, PyObject *ind, PyObject *val)
9308
9768
{
9309
 
        PyObject *arrval=NULL;
9310
 
        PyArrayIterObject *val_it=NULL;
9311
 
        PyArray_Descr *type;
9312
 
        PyArray_Descr *indtype=NULL;
9313
 
        int swap, retval=-1;
9314
 
        intp start, step_size;
9315
 
        intp n_steps;
9316
 
        PyObject *obj=NULL;
9317
 
        PyArray_CopySwapFunc *copyswap;
9318
 
 
9319
 
 
9320
 
        if (ind == Py_Ellipsis) {
9321
 
                ind = PySlice_New(NULL, NULL, NULL);
9322
 
                retval = iter_ass_subscript(self, ind, val);
9323
 
                Py_DECREF(ind);
9324
 
                return retval;
9325
 
        }
9326
 
 
9327
 
        if (PyTuple_Check(ind)) {
9328
 
                int len;
9329
 
                len = PyTuple_GET_SIZE(ind);
9330
 
                if (len > 1) goto finish;
9331
 
                ind = PyTuple_GET_ITEM(ind, 0);
9332
 
        }
9333
 
 
9334
 
        type = self->ao->descr;
9335
 
 
9336
 
        /* Check for Boolean -- this is first becasue
9337
 
           Bool is a subclass of Int */
9338
 
 
9339
 
        if (PyBool_Check(ind)) {
9340
 
                retval = 0;
9341
 
                if (PyObject_IsTrue(ind)) {
9342
 
                        retval = type->f->setitem(val, self->dataptr, self->ao);
9343
 
                }
9344
 
                goto finish;
9345
 
        }
9346
 
 
9347
 
        if (PySequence_Check(ind) || PySlice_Check(ind)) goto skip;
9348
 
        start = PyArray_PyIntAsIntp(ind);
9349
 
        if (start==-1 && PyErr_Occurred()) PyErr_Clear();
9350
 
        else {
9351
 
                if (start < -self->size || start >= self->size) {
9352
 
                        PyErr_Format(PyExc_ValueError,
9353
 
                                     "index (%" NPY_INTP_FMT \
9354
 
                                     ") out of range", start);
9355
 
                        goto finish;
9356
 
                }
9357
 
                retval = 0;
9358
 
                PyArray_ITER_GOTO1D(self, start);
9359
 
                retval = type->f->setitem(val, self->dataptr, self->ao);
9360
 
                PyArray_ITER_RESET(self);
9361
 
                if (retval < 0) {
9362
 
                        PyErr_SetString(PyExc_ValueError, 
9363
 
                                        "Error setting single item of array.");
9364
 
                }
9365
 
                goto finish;
9366
 
        }
 
9769
    PyObject *arrval=NULL;
 
9770
    PyArrayIterObject *val_it=NULL;
 
9771
    PyArray_Descr *type;
 
9772
    PyArray_Descr *indtype=NULL;
 
9773
    int swap, retval=-1;
 
9774
    intp start, step_size;
 
9775
    intp n_steps;
 
9776
    PyObject *obj=NULL;
 
9777
    PyArray_CopySwapFunc *copyswap;
 
9778
 
 
9779
 
 
9780
    if (ind == Py_Ellipsis) {
 
9781
        ind = PySlice_New(NULL, NULL, NULL);
 
9782
        retval = iter_ass_subscript(self, ind, val);
 
9783
        Py_DECREF(ind);
 
9784
        return retval;
 
9785
    }
 
9786
 
 
9787
    if (PyTuple_Check(ind)) {
 
9788
        int len;
 
9789
        len = PyTuple_GET_SIZE(ind);
 
9790
        if (len > 1) goto finish;
 
9791
        ind = PyTuple_GET_ITEM(ind, 0);
 
9792
    }
 
9793
 
 
9794
    type = self->ao->descr;
 
9795
 
 
9796
    /* Check for Boolean -- this is first becasue
 
9797
       Bool is a subclass of Int */
 
9798
 
 
9799
    if (PyBool_Check(ind)) {
 
9800
        retval = 0;
 
9801
        if (PyObject_IsTrue(ind)) {
 
9802
            retval = type->f->setitem(val, self->dataptr, self->ao);
 
9803
        }
 
9804
        goto finish;
 
9805
    }
 
9806
 
 
9807
    if (PySequence_Check(ind) || PySlice_Check(ind)) goto skip;
 
9808
    start = PyArray_PyIntAsIntp(ind);
 
9809
    if (start==-1 && PyErr_Occurred()) PyErr_Clear();
 
9810
    else {
 
9811
        if (start < -self->size || start >= self->size) {
 
9812
            PyErr_Format(PyExc_ValueError,
 
9813
                         "index (%" NPY_INTP_FMT \
 
9814
                         ") out of range", start);
 
9815
            goto finish;
 
9816
        }
 
9817
        retval = 0;
 
9818
        PyArray_ITER_GOTO1D(self, start);
 
9819
        retval = type->f->setitem(val, self->dataptr, self->ao);
 
9820
        PyArray_ITER_RESET(self);
 
9821
        if (retval < 0) {
 
9822
            PyErr_SetString(PyExc_ValueError,
 
9823
                            "Error setting single item of array.");
 
9824
        }
 
9825
        goto finish;
 
9826
    }
9367
9827
 
9368
9828
 skip:
9369
 
        Py_INCREF(type);
9370
 
        arrval = PyArray_FromAny(val, type, 0, 0, 0, NULL);
9371
 
        if (arrval==NULL) return -1;
9372
 
        val_it = (PyArrayIterObject *)PyArray_IterNew(arrval);
9373
 
        if (val_it==NULL) goto finish;
9374
 
        if (val_it->size == 0) {retval = 0; goto finish;}
9375
 
 
9376
 
        copyswap = PyArray_DESCR(arrval)->f->copyswap;
9377
 
        swap = (PyArray_ISNOTSWAPPED(self->ao)!=PyArray_ISNOTSWAPPED(arrval));
9378
 
        
9379
 
        /* Check Slice */
9380
 
 
9381
 
        if (PySlice_Check(ind)) {
9382
 
                start = parse_subindex(ind, &step_size, &n_steps,
9383
 
                                       self->size);
9384
 
                if (start == -1) goto finish;
9385
 
                if (n_steps == RubberIndex || n_steps == PseudoIndex) {
9386
 
                        PyErr_SetString(PyExc_IndexError,
9387
 
                                        "cannot use Ellipsis or newaxes here");
9388
 
                        goto finish;
9389
 
                }
9390
 
                PyArray_ITER_GOTO1D(self, start);
9391
 
                if (n_steps == SingleIndex) { /* Integer */
9392
 
                        copyswap(self->dataptr, PyArray_DATA(arrval),
9393
 
                                  swap, arrval);
9394
 
                        PyArray_ITER_RESET(self);
9395
 
                        retval=0;
9396
 
                        goto finish;
9397
 
                }
9398
 
                while(n_steps--) {
9399
 
                        copyswap(self->dataptr, val_it->dataptr,
9400
 
                                  swap, arrval);
9401
 
                        start += step_size;
9402
 
                        PyArray_ITER_GOTO1D(self, start)
9403
 
                        PyArray_ITER_NEXT(val_it);
9404
 
                        if (val_it->index == val_it->size)
9405
 
                                PyArray_ITER_RESET(val_it);
9406
 
                }
9407
 
                PyArray_ITER_RESET(self);
9408
 
                retval = 0;
9409
 
                goto finish;
9410
 
        }
9411
 
 
9412
 
        /* convert to INTP array if Integer array scalar or List */
9413
 
 
9414
 
        indtype = PyArray_DescrFromType(PyArray_INTP);
9415
 
        if (PyList_Check(ind)) {
9416
 
                Py_INCREF(indtype);
9417
 
                obj = PyArray_FromAny(ind, indtype, 0, 0, FORCECAST, NULL);
9418
 
        }
9419
 
        else {
9420
 
                Py_INCREF(ind);
9421
 
                obj = ind;
9422
 
        }
9423
 
 
9424
 
        if (obj != NULL && PyArray_Check(obj)) {
9425
 
                /* Check for Boolean object */
9426
 
                if (PyArray_TYPE(obj)==PyArray_BOOL) {
9427
 
                        if (iter_ass_sub_Bool(self, (PyArrayObject *)obj,
9428
 
                                              val_it, swap) < 0)
9429
 
                                goto finish;
9430
 
                        retval=0;
9431
 
                }
9432
 
                /* Check for integer array */
9433
 
                else if (PyArray_ISINTEGER(obj)) {
9434
 
                        PyObject *new;
9435
 
                        Py_INCREF(indtype);
9436
 
                        new = PyArray_CheckFromAny(obj, indtype, 0, 0,
9437
 
                                                   FORCECAST | BEHAVED_NS, NULL);
9438
 
                        Py_DECREF(obj);
9439
 
                        obj = new;
9440
 
                        if (new==NULL) goto finish;
9441
 
                        if (iter_ass_sub_int(self, (PyArrayObject *)obj,
9442
 
                                             val_it, swap) < 0)
9443
 
                                goto finish;
9444
 
                        retval=0;
9445
 
                }
9446
 
        }
 
9829
    Py_INCREF(type);
 
9830
    arrval = PyArray_FromAny(val, type, 0, 0, 0, NULL);
 
9831
    if (arrval==NULL) return -1;
 
9832
    val_it = (PyArrayIterObject *)PyArray_IterNew(arrval);
 
9833
    if (val_it==NULL) goto finish;
 
9834
    if (val_it->size == 0) {retval = 0; goto finish;}
 
9835
 
 
9836
    copyswap = PyArray_DESCR(arrval)->f->copyswap;
 
9837
    swap = (PyArray_ISNOTSWAPPED(self->ao)!=PyArray_ISNOTSWAPPED(arrval));
 
9838
 
 
9839
    /* Check Slice */
 
9840
 
 
9841
    if (PySlice_Check(ind)) {
 
9842
        start = parse_subindex(ind, &step_size, &n_steps,
 
9843
                               self->size);
 
9844
        if (start == -1) goto finish;
 
9845
        if (n_steps == RubberIndex || n_steps == PseudoIndex) {
 
9846
            PyErr_SetString(PyExc_IndexError,
 
9847
                            "cannot use Ellipsis or newaxes here");
 
9848
            goto finish;
 
9849
        }
 
9850
        PyArray_ITER_GOTO1D(self, start);
 
9851
        if (n_steps == SingleIndex) { /* Integer */
 
9852
            copyswap(self->dataptr, PyArray_DATA(arrval),
 
9853
                     swap, arrval);
 
9854
            PyArray_ITER_RESET(self);
 
9855
            retval=0;
 
9856
            goto finish;
 
9857
        }
 
9858
        while(n_steps--) {
 
9859
            copyswap(self->dataptr, val_it->dataptr,
 
9860
                     swap, arrval);
 
9861
            start += step_size;
 
9862
            PyArray_ITER_GOTO1D(self, start)
 
9863
                PyArray_ITER_NEXT(val_it);
 
9864
            if (val_it->index == val_it->size)
 
9865
                PyArray_ITER_RESET(val_it);
 
9866
        }
 
9867
        PyArray_ITER_RESET(self);
 
9868
        retval = 0;
 
9869
        goto finish;
 
9870
    }
 
9871
 
 
9872
    /* convert to INTP array if Integer array scalar or List */
 
9873
 
 
9874
    indtype = PyArray_DescrFromType(PyArray_INTP);
 
9875
    if (PyList_Check(ind)) {
 
9876
        Py_INCREF(indtype);
 
9877
        obj = PyArray_FromAny(ind, indtype, 0, 0, FORCECAST, NULL);
 
9878
    }
 
9879
    else {
 
9880
        Py_INCREF(ind);
 
9881
        obj = ind;
 
9882
    }
 
9883
 
 
9884
    if (obj != NULL && PyArray_Check(obj)) {
 
9885
        /* Check for Boolean object */
 
9886
        if (PyArray_TYPE(obj)==PyArray_BOOL) {
 
9887
            if (iter_ass_sub_Bool(self, (PyArrayObject *)obj,
 
9888
                                  val_it, swap) < 0)
 
9889
                goto finish;
 
9890
            retval=0;
 
9891
        }
 
9892
        /* Check for integer array */
 
9893
        else if (PyArray_ISINTEGER(obj)) {
 
9894
            PyObject *new;
 
9895
            Py_INCREF(indtype);
 
9896
            new = PyArray_CheckFromAny(obj, indtype, 0, 0,
 
9897
                                       FORCECAST | BEHAVED_NS, NULL);
 
9898
            Py_DECREF(obj);
 
9899
            obj = new;
 
9900
            if (new==NULL) goto finish;
 
9901
            if (iter_ass_sub_int(self, (PyArrayObject *)obj,
 
9902
                                 val_it, swap) < 0)
 
9903
                goto finish;
 
9904
            retval=0;
 
9905
        }
 
9906
    }
9447
9907
 
9448
9908
 finish:
9449
 
        if (!PyErr_Occurred() && retval < 0)
9450
 
                PyErr_SetString(PyExc_IndexError,
9451
 
                                "unsupported iterator index");
9452
 
        Py_XDECREF(indtype);
9453
 
        Py_XDECREF(obj);
9454
 
        Py_XDECREF(val_it);
9455
 
        Py_XDECREF(arrval);
9456
 
        return retval;
 
9909
    if (!PyErr_Occurred() && retval < 0)
 
9910
        PyErr_SetString(PyExc_IndexError,
 
9911
                        "unsupported iterator index");
 
9912
    Py_XDECREF(indtype);
 
9913
    Py_XDECREF(obj);
 
9914
    Py_XDECREF(val_it);
 
9915
    Py_XDECREF(arrval);
 
9916
    return retval;
9457
9917
 
9458
9918
}
9459
9919
 
9460
9920
 
9461
9921
static PyMappingMethods iter_as_mapping = {
9462
9922
#if PY_VERSION_HEX >= 0x02050000
9463
 
        (lenfunc)iter_length,                   /*mp_length*/
 
9923
    (lenfunc)iter_length,                   /*mp_length*/
9464
9924
#else
9465
 
        (inquiry)iter_length,                   /*mp_length*/
 
9925
    (inquiry)iter_length,                   /*mp_length*/
9466
9926
#endif
9467
 
        (binaryfunc)iter_subscript,             /*mp_subscript*/
9468
 
        (objobjargproc)iter_ass_subscript,      /*mp_ass_subscript*/
 
9927
    (binaryfunc)iter_subscript,             /*mp_subscript*/
 
9928
    (objobjargproc)iter_ass_subscript,      /*mp_ass_subscript*/
9469
9929
};
9470
9930
 
9471
9931
 
9474
9934
iter_array(PyArrayIterObject *it, PyObject *op)
9475
9935
{
9476
9936
 
9477
 
        PyObject *r;
9478
 
        intp size;
9479
 
 
9480
 
        /* Any argument ignored */
9481
 
 
9482
 
        /* Two options:
9483
 
            1) underlying array is contiguous
9484
 
               -- return 1-d wrapper around it
9485
 
            2) underlying array is not contiguous
9486
 
               -- make new 1-d contiguous array with updateifcopy flag set
9487
 
                  to copy back to the old array
9488
 
        */
9489
 
 
9490
 
        size = PyArray_SIZE(it->ao);
9491
 
        Py_INCREF(it->ao->descr);
9492
 
        if (PyArray_ISCONTIGUOUS(it->ao)) {
9493
 
                r = PyArray_NewFromDescr(&PyArray_Type,
9494
 
                                         it->ao->descr,
9495
 
                                         1, &size,
9496
 
                                         NULL, it->ao->data,
9497
 
                                         it->ao->flags,
9498
 
                                         (PyObject *)it->ao);
9499
 
                if (r==NULL) return NULL;
9500
 
        }
9501
 
        else {
9502
 
                r = PyArray_NewFromDescr(&PyArray_Type,
9503
 
                                         it->ao->descr,
9504
 
                                         1, &size,
9505
 
                                         NULL, NULL,
9506
 
                                         0, (PyObject *)it->ao);
9507
 
                if (r==NULL) return NULL;
9508
 
                if (_flat_copyinto(r, (PyObject *)it->ao,
9509
 
                                   PyArray_CORDER) < 0) {
9510
 
                        Py_DECREF(r);
9511
 
                        return NULL;
9512
 
                }
9513
 
                PyArray_FLAGS(r) |= UPDATEIFCOPY;
9514
 
                it->ao->flags &= ~WRITEABLE;
9515
 
        }
9516
 
        Py_INCREF(it->ao);
9517
 
        PyArray_BASE(r) = (PyObject *)it->ao;
9518
 
        return r;
 
9937
    PyObject *r;
 
9938
    intp size;
 
9939
 
 
9940
    /* Any argument ignored */
 
9941
 
 
9942
    /* Two options:
 
9943
       1) underlying array is contiguous
 
9944
       -- return 1-d wrapper around it
 
9945
       2) underlying array is not contiguous
 
9946
       -- make new 1-d contiguous array with updateifcopy flag set
 
9947
       to copy back to the old array
 
9948
    */
 
9949
 
 
9950
    size = PyArray_SIZE(it->ao);
 
9951
    Py_INCREF(it->ao->descr);
 
9952
    if (PyArray_ISCONTIGUOUS(it->ao)) {
 
9953
        r = PyArray_NewFromDescr(&PyArray_Type,
 
9954
                                 it->ao->descr,
 
9955
                                 1, &size,
 
9956
                                 NULL, it->ao->data,
 
9957
                                 it->ao->flags,
 
9958
                                 (PyObject *)it->ao);
 
9959
        if (r==NULL) return NULL;
 
9960
    }
 
9961
    else {
 
9962
        r = PyArray_NewFromDescr(&PyArray_Type,
 
9963
                                 it->ao->descr,
 
9964
                                 1, &size,
 
9965
                                 NULL, NULL,
 
9966
                                 0, (PyObject *)it->ao);
 
9967
        if (r==NULL) return NULL;
 
9968
        if (_flat_copyinto(r, (PyObject *)it->ao,
 
9969
                           PyArray_CORDER) < 0) {
 
9970
            Py_DECREF(r);
 
9971
            return NULL;
 
9972
        }
 
9973
        PyArray_FLAGS(r) |= UPDATEIFCOPY;
 
9974
        it->ao->flags &= ~WRITEABLE;
 
9975
    }
 
9976
    Py_INCREF(it->ao);
 
9977
    PyArray_BASE(r) = (PyObject *)it->ao;
 
9978
    return r;
9519
9979
 
9520
9980
}
9521
9981
 
9522
9982
static PyObject *
9523
9983
iter_copy(PyArrayIterObject *it, PyObject *args)
9524
9984
{
9525
 
        if (!PyArg_ParseTuple(args, "")) return NULL;
9526
 
        return PyArray_Flatten(it->ao, 0);
 
9985
    if (!PyArg_ParseTuple(args, "")) return NULL;
 
9986
    return PyArray_Flatten(it->ao, 0);
9527
9987
}
9528
9988
 
9529
9989
static PyMethodDef iter_methods[] = {
9530
 
        /* to get array */
9531
 
        {"__array__", (PyCFunction)iter_array, 1, NULL},
9532
 
        {"copy", (PyCFunction)iter_copy, 1, NULL},
9533
 
        {NULL,          NULL}           /* sentinel */
 
9990
    /* to get array */
 
9991
    {"__array__", (PyCFunction)iter_array, 1, NULL},
 
9992
    {"copy", (PyCFunction)iter_copy, 1, NULL},
 
9993
    {NULL,          NULL}           /* sentinel */
9534
9994
};
9535
9995
 
9536
9996
static PyObject *
9537
9997
iter_richcompare(PyArrayIterObject *self, PyObject *other, int cmp_op)
9538
9998
{
9539
 
        PyArrayObject *new;
9540
 
        PyObject *ret;
9541
 
        new = (PyArrayObject *)iter_array(self, NULL);
9542
 
        if (new == NULL) return NULL;
9543
 
        ret = array_richcompare(new, other, cmp_op);
9544
 
        Py_DECREF(new);
9545
 
        return ret;
 
9999
    PyArrayObject *new;
 
10000
    PyObject *ret;
 
10001
    new = (PyArrayObject *)iter_array(self, NULL);
 
10002
    if (new == NULL) return NULL;
 
10003
    ret = array_richcompare(new, other, cmp_op);
 
10004
    Py_DECREF(new);
 
10005
    return ret;
9546
10006
}
9547
10007
 
9548
10008
 
9549
10009
static PyMemberDef iter_members[] = {
9550
 
        {"base", T_OBJECT, offsetof(PyArrayIterObject, ao), RO, NULL},
9551
 
        {"index", T_INT, offsetof(PyArrayIterObject, index), RO, NULL},
9552
 
        {NULL},
 
10010
    {"base", T_OBJECT, offsetof(PyArrayIterObject, ao), RO, NULL},
 
10011
    {"index", T_INT, offsetof(PyArrayIterObject, index), RO, NULL},
 
10012
    {NULL},
9553
10013
};
9554
10014
 
9555
10015
static PyObject *
9556
10016
iter_coords_get(PyArrayIterObject *self)
9557
10017
{
9558
 
        int nd;
9559
 
        nd = self->ao->nd;
9560
 
        if (self->contiguous) { /* coordinates not kept track of --- need to generate
9561
 
                                   from index */
9562
 
                intp val;
9563
 
                int i;
9564
 
                val = self->index;
9565
 
                for (i=0;i<nd; i++) {
9566
 
                        self->coordinates[i] = val / self->factors[i];
9567
 
                        val = val % self->factors[i];
9568
 
                }
 
10018
    int nd;
 
10019
    nd = self->ao->nd;
 
10020
    if (self->contiguous) { /* coordinates not kept track of --- need to generate
 
10021
                               from index */
 
10022
        intp val;
 
10023
        int i;
 
10024
        val = self->index;
 
10025
        for(i=0;i<nd; i++) {
 
10026
            self->coordinates[i] = val / self->factors[i];
 
10027
            val = val % self->factors[i];
9569
10028
        }
9570
 
        return PyArray_IntTupleFromIntp(nd, self->coordinates);
 
10029
    }
 
10030
    return PyArray_IntTupleFromIntp(nd, self->coordinates);
9571
10031
}
9572
10032
 
9573
10033
static PyGetSetDef iter_getsets[] = {
9574
 
        {"coords",
9575
 
         (getter)iter_coords_get,
9576
 
         NULL,
9577
 
         NULL},
9578
 
        {NULL, NULL, NULL, NULL},
 
10034
    {"coords",
 
10035
     (getter)iter_coords_get,
 
10036
     NULL,
 
10037
     NULL},
 
10038
    {NULL, NULL, NULL, NULL},
9579
10039
};
9580
10040
 
9581
10041
static PyTypeObject PyArrayIter_Type = {
9582
 
        PyObject_HEAD_INIT(NULL)
9583
 
        0,                                       /* ob_size */
9584
 
        "numpy.flatiter",                        /* tp_name */
9585
 
        sizeof(PyArrayIterObject),               /* tp_basicsize */
9586
 
        0,                                       /* tp_itemsize */
9587
 
        /* methods */
9588
 
        (destructor)arrayiter_dealloc,          /* tp_dealloc */
9589
 
        0,                                      /* tp_print */
9590
 
        0,                                      /* tp_getattr */
9591
 
        0,                                      /* tp_setattr */
9592
 
        0,                                      /* tp_compare */
9593
 
        0,                                      /* tp_repr */
9594
 
        0,                                      /* tp_as_number */
9595
 
        0,                                      /* tp_as_sequence */
9596
 
        &iter_as_mapping,                       /* tp_as_mapping */
9597
 
        0,                                      /* tp_hash */
9598
 
        0,                                      /* tp_call */
9599
 
        0,                                      /* tp_str */
9600
 
        0,                                      /* tp_getattro */
9601
 
        0,                                      /* tp_setattro */
9602
 
        0,                                      /* tp_as_buffer */
9603
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
9604
 
        0,                                      /* tp_doc */
9605
 
        0,                                      /* tp_traverse */
9606
 
        0,                                      /* tp_clear */
9607
 
        (richcmpfunc)iter_richcompare,          /* tp_richcompare */
9608
 
        0,                                      /* tp_weaklistoffset */
9609
 
        0,                              /* tp_iter */
9610
 
        (iternextfunc)arrayiter_next,           /* tp_iternext */
9611
 
        iter_methods,                           /* tp_methods */
9612
 
        iter_members,                   /* tp_members */
9613
 
        iter_getsets,                           /* tp_getset */
 
10042
    PyObject_HEAD_INIT(NULL)
 
10043
    0,                                       /* ob_size */
 
10044
    "numpy.flatiter",                        /* tp_name */
 
10045
    sizeof(PyArrayIterObject),               /* tp_basicsize */
 
10046
    0,                                       /* tp_itemsize */
 
10047
    /* methods */
 
10048
    (destructor)arrayiter_dealloc,          /* tp_dealloc */
 
10049
    0,                                      /* tp_print */
 
10050
    0,                                      /* tp_getattr */
 
10051
    0,                                      /* tp_setattr */
 
10052
    0,                                      /* tp_compare */
 
10053
    0,                                      /* tp_repr */
 
10054
    0,                                      /* tp_as_number */
 
10055
    0,                                      /* tp_as_sequence */
 
10056
    &iter_as_mapping,                       /* tp_as_mapping */
 
10057
    0,                                      /* tp_hash */
 
10058
    0,                                      /* tp_call */
 
10059
    0,                                      /* tp_str */
 
10060
    0,                                      /* tp_getattro */
 
10061
    0,                                      /* tp_setattro */
 
10062
    0,                                      /* tp_as_buffer */
 
10063
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
10064
    0,                                      /* tp_doc */
 
10065
    0,                                      /* tp_traverse */
 
10066
    0,                                      /* tp_clear */
 
10067
    (richcmpfunc)iter_richcompare,          /* tp_richcompare */
 
10068
    0,                                      /* tp_weaklistoffset */
 
10069
    0,                              /* tp_iter */
 
10070
    (iternextfunc)arrayiter_next,           /* tp_iternext */
 
10071
    iter_methods,                           /* tp_methods */
 
10072
    iter_members,                   /* tp_members */
 
10073
    iter_getsets,                           /* tp_getset */
9614
10074
 
9615
10075
};
9616
10076
 
9633
10093
   if possible -- otherwise, it is a Slice or Ellipsis object
9634
10094
   and has to be interpreted on bind to a particular
9635
10095
   array so leave it NULL for now.
9636
 
 */
 
10096
*/
9637
10097
static int
9638
10098
_convert_obj(PyObject *obj, PyArrayIterObject **iter)
9639
10099
{
9640
 
        PyArray_Descr *indtype;
9641
 
        PyObject *arr;
 
10100
    PyArray_Descr *indtype;
 
10101
    PyObject *arr;
9642
10102
 
9643
 
        if (PySlice_Check(obj) || (obj == Py_Ellipsis))
9644
 
                return 0;
9645
 
        else if (PyArray_Check(obj) && PyArray_ISBOOL(obj)) {
9646
 
                return _nonzero_indices(obj, iter);
9647
 
        }
9648
 
        else {
9649
 
                indtype = PyArray_DescrFromType(PyArray_INTP);
9650
 
                arr = PyArray_FromAny(obj, indtype, 0, 0, FORCECAST, NULL);
9651
 
                if (arr == NULL) return -1;
9652
 
                *iter = (PyArrayIterObject *)PyArray_IterNew(arr);
9653
 
                Py_DECREF(arr);
9654
 
                if (*iter == NULL) return -1;
9655
 
        }
9656
 
        return 1;
 
10103
    if (PySlice_Check(obj) || (obj == Py_Ellipsis))
 
10104
        return 0;
 
10105
    else if (PyArray_Check(obj) && PyArray_ISBOOL(obj)) {
 
10106
        return _nonzero_indices(obj, iter);
 
10107
    }
 
10108
    else {
 
10109
        indtype = PyArray_DescrFromType(PyArray_INTP);
 
10110
        arr = PyArray_FromAny(obj, indtype, 0, 0, FORCECAST, NULL);
 
10111
        if (arr == NULL) return -1;
 
10112
        *iter = (PyArrayIterObject *)PyArray_IterNew(arr);
 
10113
        Py_DECREF(arr);
 
10114
        if (*iter == NULL) return -1;
 
10115
    }
 
10116
    return 1;
9657
10117
}
9658
10118
 
9659
10119
/* Adjust dimensionality and strides for index object iterators
9660
10120
   --- i.e. broadcast
9661
 
 */
 
10121
*/
9662
10122
/*OBJECT_API*/
9663
10123
static int
9664
10124
PyArray_Broadcast(PyArrayMultiIterObject *mit)
9665
10125
{
9666
 
        int i, nd, k, j;
9667
 
        intp tmp;
9668
 
        PyArrayIterObject *it;
9669
 
 
9670
 
        /* Discover the broadcast number of dimensions */
9671
 
        for (i=0, nd=0; i<mit->numiter; i++)
9672
 
                nd = MAX(nd, mit->iters[i]->ao->nd);
9673
 
        mit->nd = nd;
9674
 
 
9675
 
        /* Discover the broadcast shape in each dimension */
9676
 
        for (i=0; i<nd; i++) {
9677
 
                mit->dimensions[i] = 1;
9678
 
                for (j=0; j<mit->numiter; j++) {
9679
 
                        it = mit->iters[j];
9680
 
                        /* This prepends 1 to shapes not already
9681
 
                           equal to nd */
9682
 
                        k = i + it->ao->nd - nd;
9683
 
                        if (k>=0) {
9684
 
                                tmp = it->ao->dimensions[k];
9685
 
                                if (tmp == 1) continue;
9686
 
                                if (mit->dimensions[i] == 1)
9687
 
                                        mit->dimensions[i] = tmp;
9688
 
                                else if (mit->dimensions[i] != tmp) {
9689
 
                                        PyErr_SetString(PyExc_ValueError,
9690
 
                                                        "shape mismatch: objects" \
9691
 
                                                        " cannot be broadcast" \
9692
 
                                                        " to a single shape");
9693
 
                                        return -1;
9694
 
                                }
9695
 
                        }
9696
 
                }
9697
 
        }
9698
 
 
9699
 
        /* Reset the iterator dimensions and strides of each iterator
9700
 
           object -- using 0 valued strides for broadcasting */
9701
 
 
9702
 
        tmp = PyArray_MultiplyList(mit->dimensions, mit->nd);
9703
 
        mit->size = tmp;
9704
 
        for (i=0; i<mit->numiter; i++) {
9705
 
                it = mit->iters[i];
9706
 
                it->nd_m1 = mit->nd - 1;
9707
 
                it->size = tmp;
9708
 
                nd = it->ao->nd;
9709
 
                it->factors[mit->nd-1] = 1;
9710
 
                for (j=0; j < mit->nd; j++) {
9711
 
                        it->dims_m1[j] = mit->dimensions[j] - 1;
9712
 
                        k = j + nd - mit->nd;
9713
 
                        /* If this dimension was added or shape
9714
 
                           of underlying array was 1 */
9715
 
                        if ((k < 0) || \
9716
 
                            it->ao->dimensions[k] != mit->dimensions[j]) {
9717
 
                                it->contiguous = 0;
9718
 
                                it->strides[j] = 0;
9719
 
                        }
9720
 
                        else {
9721
 
                                it->strides[j] = it->ao->strides[k];
9722
 
                        }
9723
 
                        it->backstrides[j] = it->strides[j] *   \
9724
 
                                it->dims_m1[j];
9725
 
                        if (j > 0)
9726
 
                                it->factors[mit->nd-j-1] =              \
9727
 
                                        it->factors[mit->nd-j] *        \
9728
 
                                        mit->dimensions[mit->nd-j];
9729
 
                }
9730
 
                PyArray_ITER_RESET(it);
9731
 
        }
9732
 
        return 0;
 
10126
    int i, nd, k, j;
 
10127
    intp tmp;
 
10128
    PyArrayIterObject *it;
 
10129
 
 
10130
    /* Discover the broadcast number of dimensions */
 
10131
    for(i=0, nd=0; i<mit->numiter; i++)
 
10132
        nd = MAX(nd, mit->iters[i]->ao->nd);
 
10133
    mit->nd = nd;
 
10134
 
 
10135
    /* Discover the broadcast shape in each dimension */
 
10136
    for(i=0; i<nd; i++) {
 
10137
        mit->dimensions[i] = 1;
 
10138
        for(j=0; j<mit->numiter; j++) {
 
10139
            it = mit->iters[j];
 
10140
            /* This prepends 1 to shapes not already
 
10141
               equal to nd */
 
10142
            k = i + it->ao->nd - nd;
 
10143
            if (k>=0) {
 
10144
                tmp = it->ao->dimensions[k];
 
10145
                if (tmp == 1) continue;
 
10146
                if (mit->dimensions[i] == 1)
 
10147
                    mit->dimensions[i] = tmp;
 
10148
                else if (mit->dimensions[i] != tmp) {
 
10149
                    PyErr_SetString(PyExc_ValueError,
 
10150
                                    "shape mismatch: objects" \
 
10151
                                    " cannot be broadcast" \
 
10152
                                    " to a single shape");
 
10153
                    return -1;
 
10154
                }
 
10155
            }
 
10156
        }
 
10157
    }
 
10158
 
 
10159
    /* Reset the iterator dimensions and strides of each iterator
 
10160
       object -- using 0 valued strides for broadcasting */
 
10161
    /* Need to check for overflow */
 
10162
    tmp = PyArray_OverflowMultiplyList(mit->dimensions, mit->nd);
 
10163
    if (tmp < 0) {
 
10164
        PyErr_SetString(PyExc_ValueError, 
 
10165
                        "broadcast dimensions too large.");
 
10166
        return -1;
 
10167
    }
 
10168
    mit->size = tmp;
 
10169
    for(i=0; i<mit->numiter; i++) {
 
10170
        it = mit->iters[i];
 
10171
        it->nd_m1 = mit->nd - 1;
 
10172
        it->size = tmp;
 
10173
        nd = it->ao->nd;
 
10174
        it->factors[mit->nd-1] = 1;
 
10175
        for(j=0; j < mit->nd; j++) {
 
10176
            it->dims_m1[j] = mit->dimensions[j] - 1;
 
10177
            k = j + nd - mit->nd;
 
10178
            /* If this dimension was added or shape
 
10179
               of underlying array was 1 */
 
10180
            if ((k < 0) || \
 
10181
                it->ao->dimensions[k] != mit->dimensions[j]) {
 
10182
                it->contiguous = 0;
 
10183
                it->strides[j] = 0;
 
10184
            }
 
10185
            else {
 
10186
                it->strides[j] = it->ao->strides[k];
 
10187
            }
 
10188
            it->backstrides[j] = it->strides[j] *   \
 
10189
                it->dims_m1[j];
 
10190
            if (j > 0)
 
10191
                it->factors[mit->nd-j-1] =              \
 
10192
                    it->factors[mit->nd-j] *        \
 
10193
                    mit->dimensions[mit->nd-j];
 
10194
        }
 
10195
        PyArray_ITER_RESET(it);
 
10196
    }
 
10197
    return 0;
9733
10198
}
9734
10199
 
9735
10200
/* Reset the map iterator to the beginning */
9736
10201
static void
9737
10202
PyArray_MapIterReset(PyArrayMapIterObject *mit)
9738
10203
{
9739
 
        int i,j; intp coord[MAX_DIMS];
9740
 
        PyArrayIterObject *it;
9741
 
        PyArray_CopySwapFunc *copyswap;
9742
 
 
9743
 
        mit->index = 0;
9744
 
 
9745
 
        copyswap = mit->iters[0]->ao->descr->f->copyswap;
9746
 
 
9747
 
        if (mit->subspace != NULL) {
9748
 
                memcpy(coord, mit->bscoord, sizeof(intp)*mit->ait->ao->nd);
9749
 
                PyArray_ITER_RESET(mit->subspace);
9750
 
                for (i=0; i<mit->numiter; i++) {
9751
 
                        it = mit->iters[i];
9752
 
                        PyArray_ITER_RESET(it);
9753
 
                        j = mit->iteraxes[i];
9754
 
                        copyswap(coord+j,it->dataptr,
9755
 
                                 !PyArray_ISNOTSWAPPED(it->ao),
9756
 
                                 it->ao);
9757
 
                }
9758
 
                PyArray_ITER_GOTO(mit->ait, coord);
9759
 
                mit->subspace->dataptr = mit->ait->dataptr;
9760
 
                mit->dataptr = mit->subspace->dataptr;
9761
 
        }
9762
 
        else {
9763
 
                for (i=0; i<mit->numiter; i++) {
9764
 
                        it = mit->iters[i];
9765
 
                        if (it->size != 0) {
9766
 
                                PyArray_ITER_RESET(it);
9767
 
                                copyswap(coord+i,it->dataptr,
9768
 
                                         !PyArray_ISNOTSWAPPED(it->ao),
9769
 
                                         it->ao);
9770
 
                        }
9771
 
                        else coord[i] = 0;
9772
 
                }
9773
 
                PyArray_ITER_GOTO(mit->ait, coord);
9774
 
                mit->dataptr = mit->ait->dataptr;
9775
 
        }
9776
 
        return;
 
10204
    int i,j; intp coord[MAX_DIMS];
 
10205
    PyArrayIterObject *it;
 
10206
    PyArray_CopySwapFunc *copyswap;
 
10207
 
 
10208
    mit->index = 0;
 
10209
 
 
10210
    copyswap = mit->iters[0]->ao->descr->f->copyswap;
 
10211
 
 
10212
    if (mit->subspace != NULL) {
 
10213
        memcpy(coord, mit->bscoord, sizeof(intp)*mit->ait->ao->nd);
 
10214
        PyArray_ITER_RESET(mit->subspace);
 
10215
        for(i=0; i<mit->numiter; i++) {
 
10216
            it = mit->iters[i];
 
10217
            PyArray_ITER_RESET(it);
 
10218
            j = mit->iteraxes[i];
 
10219
            copyswap(coord+j,it->dataptr,
 
10220
                     !PyArray_ISNOTSWAPPED(it->ao),
 
10221
                     it->ao);
 
10222
        }
 
10223
        PyArray_ITER_GOTO(mit->ait, coord);
 
10224
        mit->subspace->dataptr = mit->ait->dataptr;
 
10225
        mit->dataptr = mit->subspace->dataptr;
 
10226
    }
 
10227
    else {
 
10228
        for(i=0; i<mit->numiter; i++) {
 
10229
            it = mit->iters[i];
 
10230
            if (it->size != 0) {
 
10231
                PyArray_ITER_RESET(it);
 
10232
                copyswap(coord+i,it->dataptr,
 
10233
                         !PyArray_ISNOTSWAPPED(it->ao),
 
10234
                         it->ao);
 
10235
            }
 
10236
            else coord[i] = 0;
 
10237
        }
 
10238
        PyArray_ITER_GOTO(mit->ait, coord);
 
10239
        mit->dataptr = mit->ait->dataptr;
 
10240
    }
 
10241
    return;
9777
10242
}
9778
10243
 
9779
10244
/* This function needs to update the state of the map iterator
9782
10247
static void
9783
10248
PyArray_MapIterNext(PyArrayMapIterObject *mit)
9784
10249
{
9785
 
        int i, j;
9786
 
        intp coord[MAX_DIMS];
9787
 
        PyArrayIterObject *it;
9788
 
        PyArray_CopySwapFunc *copyswap;
 
10250
    int i, j;
 
10251
    intp coord[MAX_DIMS];
 
10252
    PyArrayIterObject *it;
 
10253
    PyArray_CopySwapFunc *copyswap;
9789
10254
 
9790
 
        mit->index += 1;
9791
 
        if (mit->index >= mit->size) return;
9792
 
        copyswap = mit->iters[0]->ao->descr->f->copyswap;
9793
 
        /* Sub-space iteration */
9794
 
        if (mit->subspace != NULL) {
9795
 
                PyArray_ITER_NEXT(mit->subspace);
9796
 
                if (mit->subspace->index >= mit->subspace->size) {
9797
 
                        /* reset coord to coordinates of
9798
 
                           beginning of the subspace */
9799
 
                        memcpy(coord, mit->bscoord,
9800
 
                               sizeof(intp)*mit->ait->ao->nd);
9801
 
                        PyArray_ITER_RESET(mit->subspace);
9802
 
                        for (i=0; i<mit->numiter; i++) {
9803
 
                                it = mit->iters[i];
9804
 
                                PyArray_ITER_NEXT(it);
9805
 
                                j = mit->iteraxes[i];
9806
 
                                copyswap(coord+j,it->dataptr,
9807
 
                                         !PyArray_ISNOTSWAPPED(it->ao),
9808
 
                                         it->ao);
9809
 
                        }
9810
 
                        PyArray_ITER_GOTO(mit->ait, coord);
9811
 
                        mit->subspace->dataptr = mit->ait->dataptr;
9812
 
                }
9813
 
                mit->dataptr = mit->subspace->dataptr;
9814
 
        }
9815
 
        else {
9816
 
                for (i=0; i<mit->numiter; i++) {
9817
 
                        it = mit->iters[i];
9818
 
                        PyArray_ITER_NEXT(it);
9819
 
                        copyswap(coord+i,it->dataptr,
9820
 
                                 !PyArray_ISNOTSWAPPED(it->ao),
9821
 
                                 it->ao);
9822
 
                }
9823
 
                PyArray_ITER_GOTO(mit->ait, coord);
9824
 
                mit->dataptr = mit->ait->dataptr;
9825
 
        }
9826
 
        return;
 
10255
    mit->index += 1;
 
10256
    if (mit->index >= mit->size) return;
 
10257
    copyswap = mit->iters[0]->ao->descr->f->copyswap;
 
10258
    /* Sub-space iteration */
 
10259
    if (mit->subspace != NULL) {
 
10260
        PyArray_ITER_NEXT(mit->subspace);
 
10261
        if (mit->subspace->index >= mit->subspace->size) {
 
10262
            /* reset coord to coordinates of
 
10263
               beginning of the subspace */
 
10264
            memcpy(coord, mit->bscoord,
 
10265
                   sizeof(intp)*mit->ait->ao->nd);
 
10266
            PyArray_ITER_RESET(mit->subspace);
 
10267
            for(i=0; i<mit->numiter; i++) {
 
10268
                it = mit->iters[i];
 
10269
                PyArray_ITER_NEXT(it);
 
10270
                j = mit->iteraxes[i];
 
10271
                copyswap(coord+j,it->dataptr,
 
10272
                         !PyArray_ISNOTSWAPPED(it->ao),
 
10273
                         it->ao);
 
10274
            }
 
10275
            PyArray_ITER_GOTO(mit->ait, coord);
 
10276
            mit->subspace->dataptr = mit->ait->dataptr;
 
10277
        }
 
10278
        mit->dataptr = mit->subspace->dataptr;
 
10279
    }
 
10280
    else {
 
10281
        for(i=0; i<mit->numiter; i++) {
 
10282
            it = mit->iters[i];
 
10283
            PyArray_ITER_NEXT(it);
 
10284
            copyswap(coord+i,it->dataptr,
 
10285
                     !PyArray_ISNOTSWAPPED(it->ao),
 
10286
                     it->ao);
 
10287
        }
 
10288
        PyArray_ITER_GOTO(mit->ait, coord);
 
10289
        mit->dataptr = mit->ait->dataptr;
 
10290
    }
 
10291
    return;
9827
10292
}
9828
10293
 
9829
10294
/*  Bind a mapiteration to a particular array */
9830
10295
 
9831
10296
/*  Determine if subspace iteration is necessary.  If so,
9832
 
         1) Fill in mit->iteraxes
9833
 
         2) Create subspace iterator
9834
 
         3) Update nd, dimensions, and size.
 
10297
    1) Fill in mit->iteraxes
 
10298
    2) Create subspace iterator
 
10299
    3) Update nd, dimensions, and size.
9835
10300
 
9836
10301
    Subspace iteration is necessary if:  arr->nd > mit->numiter
9837
10302
*/
9844
10309
static void
9845
10310
PyArray_MapIterBind(PyArrayMapIterObject *mit, PyArrayObject *arr)
9846
10311
{
9847
 
        int subnd;
9848
 
        PyObject *sub, *obj=NULL;
9849
 
        int i, j, n, curraxis, ellipexp, noellip;
9850
 
        PyArrayIterObject *it;
9851
 
        intp dimsize;
9852
 
        intp *indptr;
9853
 
 
9854
 
        subnd = arr->nd - mit->numiter;
9855
 
        if (subnd < 0) {
9856
 
                PyErr_SetString(PyExc_ValueError,
9857
 
                                "too many indices for array");
9858
 
                return;
9859
 
        }
9860
 
 
9861
 
        mit->ait = (PyArrayIterObject *)PyArray_IterNew((PyObject *)arr);
9862
 
        if (mit->ait == NULL) return;
9863
 
 
9864
 
        /* no subspace iteration needed.  Finish up and Return */
9865
 
        if (subnd == 0) {
9866
 
                n = arr->nd;
9867
 
                for (i=0; i<n; i++) {
9868
 
                        mit->iteraxes[i] = i;
9869
 
                }
9870
 
                goto finish;
9871
 
        }
9872
 
 
9873
 
        /* all indexing arrays have been converted to 0
9874
 
           therefore we can extract the subspace with a simple
9875
 
           getitem call which will use view semantics
9876
 
        */
9877
 
        /* But, be sure to do it with a true array.
9878
 
         */
9879
 
        if (PyArray_CheckExact(arr)) {
9880
 
                sub = array_subscript_simple(arr, mit->indexobj);
 
10312
    int subnd;
 
10313
    PyObject *sub, *obj=NULL;
 
10314
    int i, j, n, curraxis, ellipexp, noellip;
 
10315
    PyArrayIterObject *it;
 
10316
    intp dimsize;
 
10317
    intp *indptr;
 
10318
 
 
10319
    subnd = arr->nd - mit->numiter;
 
10320
    if (subnd < 0) {
 
10321
        PyErr_SetString(PyExc_ValueError,
 
10322
                        "too many indices for array");
 
10323
        return;
 
10324
    }
 
10325
 
 
10326
    mit->ait = (PyArrayIterObject *)PyArray_IterNew((PyObject *)arr);
 
10327
    if (mit->ait == NULL) return;
 
10328
 
 
10329
    /* no subspace iteration needed.  Finish up and Return */
 
10330
    if (subnd == 0) {
 
10331
        n = arr->nd;
 
10332
        for(i=0; i<n; i++) {
 
10333
            mit->iteraxes[i] = i;
 
10334
        }
 
10335
        goto finish;
 
10336
    }
 
10337
 
 
10338
    /* all indexing arrays have been converted to 0
 
10339
       therefore we can extract the subspace with a simple
 
10340
       getitem call which will use view semantics
 
10341
    */
 
10342
    /* But, be sure to do it with a true array.
 
10343
     */
 
10344
    if (PyArray_CheckExact(arr)) {
 
10345
        sub = array_subscript_simple(arr, mit->indexobj);
 
10346
    }
 
10347
    else {
 
10348
        Py_INCREF(arr);
 
10349
        obj = PyArray_EnsureArray((PyObject *)arr);
 
10350
        if (obj == NULL) goto fail;
 
10351
        sub = array_subscript_simple((PyArrayObject *)obj, mit->indexobj);
 
10352
        Py_DECREF(obj);
 
10353
    }
 
10354
 
 
10355
    if (sub == NULL) goto fail;
 
10356
    mit->subspace = (PyArrayIterObject *)PyArray_IterNew(sub);
 
10357
    Py_DECREF(sub);
 
10358
    if (mit->subspace == NULL) goto fail;
 
10359
 
 
10360
    /* Expand dimensions of result */
 
10361
    n = mit->subspace->ao->nd;
 
10362
    for(i=0; i<n; i++)
 
10363
        mit->dimensions[mit->nd+i] = mit->subspace->ao->dimensions[i];
 
10364
    mit->nd += n;
 
10365
 
 
10366
    /* Now, we still need to interpret the ellipsis and slice objects
 
10367
       to determine which axes the indexing arrays are referring to
 
10368
    */
 
10369
    n = PyTuple_GET_SIZE(mit->indexobj);
 
10370
 
 
10371
    /* The number of dimensions an ellipsis takes up */
 
10372
    ellipexp = arr->nd - n + 1;
 
10373
    /* Now fill in iteraxes -- remember indexing arrays have been
 
10374
       converted to 0's in mit->indexobj */
 
10375
    curraxis = 0;
 
10376
    j = 0;
 
10377
    noellip = 1;  /* Only expand the first ellipsis */
 
10378
    memset(mit->bscoord, 0, sizeof(intp)*arr->nd);
 
10379
    for(i=0; i<n; i++) {
 
10380
        /* We need to fill in the starting coordinates for
 
10381
           the subspace */
 
10382
        obj = PyTuple_GET_ITEM(mit->indexobj, i);
 
10383
        if (PyInt_Check(obj) || PyLong_Check(obj))
 
10384
            mit->iteraxes[j++] = curraxis++;
 
10385
        else if (noellip && obj == Py_Ellipsis) {
 
10386
            curraxis += ellipexp;
 
10387
            noellip = 0;
9881
10388
        }
9882
10389
        else {
9883
 
                Py_INCREF(arr);
9884
 
                obj = PyArray_EnsureArray((PyObject *)arr);
9885
 
                if (obj == NULL) goto fail;
9886
 
                sub = array_subscript_simple((PyArrayObject *)obj, mit->indexobj);
9887
 
                Py_DECREF(obj);
9888
 
        }
9889
 
 
9890
 
        if (sub == NULL) goto fail;
9891
 
        mit->subspace = (PyArrayIterObject *)PyArray_IterNew(sub);
9892
 
        Py_DECREF(sub);
9893
 
        if (mit->subspace == NULL) goto fail;
9894
 
 
9895
 
        /* Expand dimensions of result */
9896
 
        n = mit->subspace->ao->nd;
9897
 
        for (i=0; i<n; i++)
9898
 
                mit->dimensions[mit->nd+i] = mit->subspace->ao->dimensions[i];
9899
 
        mit->nd += n;
9900
 
 
9901
 
        /* Now, we still need to interpret the ellipsis and slice objects
9902
 
           to determine which axes the indexing arrays are referring to
9903
 
        */
9904
 
        n = PyTuple_GET_SIZE(mit->indexobj);
9905
 
 
9906
 
        /* The number of dimensions an ellipsis takes up */
9907
 
        ellipexp = arr->nd - n + 1;
9908
 
        /* Now fill in iteraxes -- remember indexing arrays have been
9909
 
           converted to 0's in mit->indexobj */
9910
 
        curraxis = 0;
9911
 
        j = 0;
9912
 
        noellip = 1;  /* Only expand the first ellipsis */
9913
 
        memset(mit->bscoord, 0, sizeof(intp)*arr->nd);
9914
 
        for (i=0; i<n; i++) {
9915
 
                /* We need to fill in the starting coordinates for
9916
 
                   the subspace */
9917
 
                obj = PyTuple_GET_ITEM(mit->indexobj, i);
9918
 
                if (PyInt_Check(obj) || PyLong_Check(obj))
9919
 
                        mit->iteraxes[j++] = curraxis++;
9920
 
                else if (noellip && obj == Py_Ellipsis) {
9921
 
                        curraxis += ellipexp;
9922
 
                        noellip = 0;
9923
 
                }
9924
 
                else {
9925
 
                        intp start=0;
9926
 
                        intp stop, step;
9927
 
                        /* Should be slice object or
9928
 
                           another Ellipsis */
9929
 
                        if (obj == Py_Ellipsis) {
9930
 
                                mit->bscoord[curraxis] = 0;
9931
 
                        }
9932
 
                        else if (!PySlice_Check(obj) || \
9933
 
                                 (slice_GetIndices((PySliceObject *)obj,
9934
 
                                                   arr->dimensions[curraxis],
9935
 
                                                   &start, &stop, &step,
9936
 
                                                   &dimsize) < 0)) {
9937
 
                                PyErr_Format(PyExc_ValueError,
9938
 
                                             "unexpected object "       \
9939
 
                                             "(%s) in selection position %d",
9940
 
                                             obj->ob_type->tp_name, i);
9941
 
                                goto fail;
9942
 
                        }
9943
 
                        else {
9944
 
                                mit->bscoord[curraxis] = start;
9945
 
                        }
9946
 
                        curraxis += 1;
9947
 
                }
9948
 
        }
 
10390
            intp start=0;
 
10391
            intp stop, step;
 
10392
            /* Should be slice object or
 
10393
               another Ellipsis */
 
10394
            if (obj == Py_Ellipsis) {
 
10395
                mit->bscoord[curraxis] = 0;
 
10396
            }
 
10397
            else if (!PySlice_Check(obj) || \
 
10398
                     (slice_GetIndices((PySliceObject *)obj,
 
10399
                                       arr->dimensions[curraxis],
 
10400
                                       &start, &stop, &step,
 
10401
                                       &dimsize) < 0)) {
 
10402
                PyErr_Format(PyExc_ValueError,
 
10403
                             "unexpected object "       \
 
10404
                             "(%s) in selection position %d",
 
10405
                             obj->ob_type->tp_name, i);
 
10406
                goto fail;
 
10407
            }
 
10408
            else {
 
10409
                mit->bscoord[curraxis] = start;
 
10410
            }
 
10411
            curraxis += 1;
 
10412
        }
 
10413
    }
9949
10414
 finish:
9950
 
        /* Here check the indexes (now that we have iteraxes) */
9951
 
        mit->size = PyArray_MultiplyList(mit->dimensions, mit->nd);
9952
 
        if (mit->ait->size == 0 && mit->size != 0) {
9953
 
                PyErr_SetString(PyExc_ValueError,
9954
 
                                "invalid index into a 0-size array");
 
10415
    /* Here check the indexes (now that we have iteraxes) */
 
10416
    mit->size = PyArray_OverflowMultiplyList(mit->dimensions, mit->nd);
 
10417
    if (mit->size < 0) {
 
10418
        PyErr_SetString(PyExc_ValueError, 
 
10419
                        "dimensions too large in fancy indexing");
 
10420
        goto fail;
 
10421
    }
 
10422
    if (mit->ait->size == 0 && mit->size != 0) {
 
10423
        PyErr_SetString(PyExc_ValueError,
 
10424
                        "invalid index into a 0-size array");
 
10425
        goto fail;
 
10426
    }
 
10427
 
 
10428
    for(i=0; i<mit->numiter; i++) {
 
10429
        intp indval;
 
10430
        it = mit->iters[i];
 
10431
        PyArray_ITER_RESET(it);
 
10432
        dimsize = arr->dimensions[mit->iteraxes[i]];
 
10433
        while(it->index < it->size) {
 
10434
            indptr = ((intp *)it->dataptr);
 
10435
            indval = *indptr;
 
10436
            if (indval < 0) indval += dimsize;
 
10437
            if (indval < 0 || indval >= dimsize) {
 
10438
                PyErr_Format(PyExc_IndexError,
 
10439
                             "index (%d) out of range "\
 
10440
                             "(0<=index<%d) in dimension %d",
 
10441
                             (int) indval, (int) (dimsize-1),
 
10442
                             mit->iteraxes[i]);
9955
10443
                goto fail;
9956
 
        }
9957
 
 
9958
 
        for (i=0; i<mit->numiter; i++) {
9959
 
                intp indval;
9960
 
                it = mit->iters[i];
9961
 
                PyArray_ITER_RESET(it);
9962
 
                dimsize = arr->dimensions[mit->iteraxes[i]];
9963
 
                while(it->index < it->size) {
9964
 
                        indptr = ((intp *)it->dataptr);
9965
 
                        indval = *indptr;
9966
 
                        if (indval < 0) indval += dimsize;
9967
 
                        if (indval < 0 || indval >= dimsize) {
9968
 
                                PyErr_Format(PyExc_IndexError,
9969
 
                                             "index (%d) out of range "\
9970
 
                                             "(0<=index<=%d) in dimension %d",
9971
 
                                             (int) indval, (int) (dimsize-1),
9972
 
                                             mit->iteraxes[i]);
9973
 
                                goto fail;
9974
 
                        }
9975
 
                        PyArray_ITER_NEXT(it);
9976
 
                }
9977
 
                PyArray_ITER_RESET(it);
9978
 
        }
9979
 
        return;
 
10444
            }
 
10445
            PyArray_ITER_NEXT(it);
 
10446
        }
 
10447
        PyArray_ITER_RESET(it);
 
10448
    }
 
10449
    return;
9980
10450
 
9981
10451
 fail:
9982
 
        Py_XDECREF(mit->subspace);
9983
 
        Py_XDECREF(mit->ait);
9984
 
        mit->subspace = NULL;
9985
 
        mit->ait = NULL;
9986
 
        return;
 
10452
    Py_XDECREF(mit->subspace);
 
10453
    Py_XDECREF(mit->ait);
 
10454
    mit->subspace = NULL;
 
10455
    mit->ait = NULL;
 
10456
    return;
9987
10457
}
9988
10458
 
9989
10459
/* This function takes a Boolean array and constructs index objects and
9992
10462
static int
9993
10463
_nonzero_indices(PyObject *myBool, PyArrayIterObject **iters)
9994
10464
{
9995
 
        PyArray_Descr *typecode;
9996
 
        PyArrayObject *ba =NULL, *new=NULL;
9997
 
        int nd, j;
9998
 
        intp size, i, count;
9999
 
        Bool *ptr;
10000
 
        intp coords[MAX_DIMS], dims_m1[MAX_DIMS];
10001
 
        intp *dptr[MAX_DIMS];
10002
 
 
10003
 
        typecode=PyArray_DescrFromType(PyArray_BOOL);
10004
 
        ba = (PyArrayObject *)PyArray_FromAny(myBool, typecode, 0, 0,
10005
 
                                              CARRAY, NULL);
10006
 
        if (ba == NULL) return -1;
10007
 
        nd = ba->nd;
10008
 
        for (j=0; j<nd; j++) iters[j] = NULL;
10009
 
        size = PyArray_SIZE(ba);
10010
 
        ptr = (Bool *)ba->data;
10011
 
        count = 0;
10012
 
 
10013
 
        /* pre-determine how many nonzero entries there are */
10014
 
        for (i=0; i<size; i++)
10015
 
                if (*(ptr++)) count++;
10016
 
 
10017
 
        /* create count-sized index arrays for each dimension */
10018
 
        for (j=0; j<nd; j++) {
10019
 
                new = (PyArrayObject *)PyArray_New(&PyArray_Type, 1, &count,
10020
 
                                                   PyArray_INTP, NULL, NULL,
10021
 
                                                   0, 0, NULL);
10022
 
                if (new == NULL) goto fail;
10023
 
                iters[j] = (PyArrayIterObject *)        \
10024
 
                        PyArray_IterNew((PyObject *)new);
10025
 
                Py_DECREF(new);
10026
 
                if (iters[j] == NULL) goto fail;
10027
 
                dptr[j] = (intp *)iters[j]->ao->data;
 
10465
    PyArray_Descr *typecode;
 
10466
    PyArrayObject *ba =NULL, *new=NULL;
 
10467
    int nd, j;
 
10468
    intp size, i, count;
 
10469
    Bool *ptr;
 
10470
    intp coords[MAX_DIMS], dims_m1[MAX_DIMS];
 
10471
    intp *dptr[MAX_DIMS];
 
10472
 
 
10473
    typecode=PyArray_DescrFromType(PyArray_BOOL);
 
10474
    ba = (PyArrayObject *)PyArray_FromAny(myBool, typecode, 0, 0,
 
10475
                                          CARRAY, NULL);
 
10476
    if (ba == NULL) return -1;
 
10477
    nd = ba->nd;
 
10478
    for(j=0; j<nd; j++) iters[j] = NULL;
 
10479
    size = PyArray_SIZE(ba);
 
10480
    ptr = (Bool *)ba->data;
 
10481
    count = 0;
 
10482
 
 
10483
    /* pre-determine how many nonzero entries there are */
 
10484
    for(i=0; i<size; i++)
 
10485
        if (*(ptr++)) count++;
 
10486
 
 
10487
    /* create count-sized index arrays for each dimension */
 
10488
    for(j=0; j<nd; j++) {
 
10489
        new = (PyArrayObject *)PyArray_New(&PyArray_Type, 1, &count,
 
10490
                                           PyArray_INTP, NULL, NULL,
 
10491
                                           0, 0, NULL);
 
10492
        if (new == NULL) goto fail;
 
10493
        iters[j] = (PyArrayIterObject *)        \
 
10494
            PyArray_IterNew((PyObject *)new);
 
10495
        Py_DECREF(new);
 
10496
        if (iters[j] == NULL) goto fail;
 
10497
        dptr[j] = (intp *)iters[j]->ao->data;
 
10498
        coords[j] = 0;
 
10499
        dims_m1[j] = ba->dimensions[j]-1;
 
10500
    }
 
10501
 
 
10502
    ptr = (Bool *)ba->data;
 
10503
 
 
10504
    if (count == 0) goto finish;
 
10505
 
 
10506
    /* Loop through the Boolean array  and copy coordinates
 
10507
       for non-zero entries */
 
10508
    for(i=0; i<size; i++) {
 
10509
        if (*(ptr++)) {
 
10510
            for(j=0; j<nd; j++)
 
10511
                *(dptr[j]++) = coords[j];
 
10512
        }
 
10513
        /* Borrowed from ITER_NEXT macro */
 
10514
        for(j=nd-1; j>=0; j--) {
 
10515
            if (coords[j] < dims_m1[j]) {
 
10516
                coords[j]++;
 
10517
                break;
 
10518
            }
 
10519
            else {
10028
10520
                coords[j] = 0;
10029
 
                dims_m1[j] = ba->dimensions[j]-1;
10030
 
        }
10031
 
 
10032
 
        ptr = (Bool *)ba->data;
10033
 
 
10034
 
        if (count == 0) goto finish;
10035
 
 
10036
 
        /* Loop through the Boolean array  and copy coordinates
10037
 
           for non-zero entries */
10038
 
        for (i=0; i<size; i++) {
10039
 
                if (*(ptr++)) {
10040
 
                        for (j=0; j<nd; j++)
10041
 
                                *(dptr[j]++) = coords[j];
10042
 
                }
10043
 
                /* Borrowed from ITER_NEXT macro */
10044
 
                for (j=nd-1; j>=0; j--) {
10045
 
                        if (coords[j] < dims_m1[j]) {
10046
 
                                coords[j]++;
10047
 
                                break;
10048
 
                        }
10049
 
                        else {
10050
 
                                coords[j] = 0;
10051
 
                        }
10052
 
                }
10053
 
        }
 
10521
            }
 
10522
        }
 
10523
    }
10054
10524
 
10055
10525
 finish:
10056
 
        Py_DECREF(ba);
10057
 
        return nd;
 
10526
    Py_DECREF(ba);
 
10527
    return nd;
10058
10528
 
10059
10529
 fail:
10060
 
        for (j=0; j<nd; j++) {
10061
 
                Py_XDECREF(iters[j]);
10062
 
        }
10063
 
        Py_XDECREF(ba);
10064
 
        return -1;
 
10530
    for(j=0; j<nd; j++) {
 
10531
        Py_XDECREF(iters[j]);
 
10532
    }
 
10533
    Py_XDECREF(ba);
 
10534
    return -1;
10065
10535
}
10066
10536
 
10067
10537
static PyObject *
10068
10538
PyArray_MapIterNew(PyObject *indexobj, int oned, int fancy)
10069
10539
{
10070
 
        PyArrayMapIterObject *mit;
10071
 
        PyArray_Descr *indtype;
10072
 
        PyObject *arr = NULL;
10073
 
        int i, n, started, nonindex;
10074
 
 
10075
 
        if (fancy == SOBJ_BADARRAY) {
10076
 
                PyErr_SetString(PyExc_IndexError,                       \
10077
 
                                "arrays used as indices must be of "    \
10078
 
                                "integer (or boolean) type");
10079
 
                return NULL;
10080
 
        }
10081
 
        if (fancy == SOBJ_TOOMANY) {
10082
 
                PyErr_SetString(PyExc_IndexError, "too many indices");
10083
 
                return NULL;
10084
 
        }
10085
 
 
10086
 
        mit = (PyArrayMapIterObject *)_pya_malloc(sizeof(PyArrayMapIterObject));
10087
 
        PyObject_Init((PyObject *)mit, &PyArrayMapIter_Type);
10088
 
        if (mit == NULL)
10089
 
                return NULL;
10090
 
        for (i=0; i<MAX_DIMS; i++)
10091
 
                mit->iters[i] = NULL;
10092
 
        mit->index = 0;
10093
 
        mit->ait = NULL;
10094
 
        mit->subspace = NULL;
10095
 
        mit->numiter = 0;
10096
 
        mit->consec = 1;
10097
 
        Py_INCREF(indexobj);
 
10540
    PyArrayMapIterObject *mit;
 
10541
    PyArray_Descr *indtype;
 
10542
    PyObject *arr = NULL;
 
10543
    int i, n, started, nonindex;
 
10544
 
 
10545
    if (fancy == SOBJ_BADARRAY) {
 
10546
        PyErr_SetString(PyExc_IndexError,                       \
 
10547
                        "arrays used as indices must be of "    \
 
10548
                        "integer (or boolean) type");
 
10549
        return NULL;
 
10550
    }
 
10551
    if (fancy == SOBJ_TOOMANY) {
 
10552
        PyErr_SetString(PyExc_IndexError, "too many indices");
 
10553
        return NULL;
 
10554
    }
 
10555
 
 
10556
    mit = (PyArrayMapIterObject *)_pya_malloc(sizeof(PyArrayMapIterObject));
 
10557
    PyObject_Init((PyObject *)mit, &PyArrayMapIter_Type);
 
10558
    if (mit == NULL)
 
10559
        return NULL;
 
10560
    for(i=0; i<MAX_DIMS; i++)
 
10561
        mit->iters[i] = NULL;
 
10562
    mit->index = 0;
 
10563
    mit->ait = NULL;
 
10564
    mit->subspace = NULL;
 
10565
    mit->numiter = 0;
 
10566
    mit->consec = 1;
 
10567
    Py_INCREF(indexobj);
 
10568
    mit->indexobj = indexobj;
 
10569
 
 
10570
    if (fancy == SOBJ_LISTTUP) {
 
10571
        PyObject *newobj;
 
10572
        newobj = PySequence_Tuple(indexobj);
 
10573
        if (newobj == NULL) goto fail;
 
10574
        Py_DECREF(indexobj);
 
10575
        indexobj = newobj;
10098
10576
        mit->indexobj = indexobj;
10099
 
 
10100
 
        if (fancy == SOBJ_LISTTUP) {
10101
 
                PyObject *newobj;
10102
 
                newobj = PySequence_Tuple(indexobj);
10103
 
                if (newobj == NULL) goto fail;
10104
 
                Py_DECREF(indexobj);
10105
 
                indexobj = newobj;
10106
 
                mit->indexobj = indexobj;
10107
 
        }
 
10577
    }
10108
10578
 
10109
10579
#undef SOBJ_NOTFANCY
10110
10580
#undef SOBJ_ISFANCY
10112
10582
#undef SOBJ_TOOMANY
10113
10583
#undef SOBJ_LISTTUP
10114
10584
 
10115
 
        if (oned) return (PyObject *)mit;
10116
 
 
10117
 
        /* Must have some kind of fancy indexing if we are here */
10118
 
        /* indexobj is either a list, an arrayobject, or a tuple
10119
 
           (with at least 1 list or arrayobject or Bool object), */
10120
 
 
10121
 
        /* convert all inputs to iterators */
10122
 
        if (PyArray_Check(indexobj) &&                  \
10123
 
            (PyArray_TYPE(indexobj) == PyArray_BOOL)) {
10124
 
                mit->numiter = _nonzero_indices(indexobj, mit->iters);
10125
 
                if (mit->numiter < 0) goto fail;
10126
 
                mit->nd = 1;
10127
 
                mit->dimensions[0] = mit->iters[0]->dims_m1[0]+1;
10128
 
                Py_DECREF(mit->indexobj);
10129
 
                mit->indexobj = PyTuple_New(mit->numiter);
10130
 
                if (mit->indexobj == NULL) goto fail;
10131
 
                for (i=0; i<mit->numiter; i++) {
10132
 
                        PyTuple_SET_ITEM(mit->indexobj, i,
10133
 
                                         PyInt_FromLong(0));
10134
 
                }
10135
 
        }
10136
 
 
10137
 
        else if (PyArray_Check(indexobj) || !PyTuple_Check(indexobj)) {
10138
 
                mit->numiter = 1;
10139
 
                indtype = PyArray_DescrFromType(PyArray_INTP);
10140
 
                arr = PyArray_FromAny(indexobj, indtype, 0, 0, FORCECAST, NULL);
10141
 
                if (arr == NULL) goto fail;
10142
 
                mit->iters[0] = (PyArrayIterObject *)PyArray_IterNew(arr);
10143
 
                if (mit->iters[0] == NULL) {Py_DECREF(arr); goto fail;}
10144
 
                mit->nd = PyArray_NDIM(arr);
10145
 
                memcpy(mit->dimensions,PyArray_DIMS(arr),mit->nd*sizeof(intp));
10146
 
                mit->size = PyArray_SIZE(arr);
10147
 
                Py_DECREF(arr);
10148
 
                Py_DECREF(mit->indexobj);
10149
 
                mit->indexobj = Py_BuildValue("(N)", PyInt_FromLong(0));
10150
 
        }
10151
 
        else { /* must be a tuple */
10152
 
                PyObject *obj;
10153
 
                PyArrayIterObject **iterp;
10154
 
                PyObject *new;
10155
 
                int numiters, j, n2;
10156
 
                /* Make a copy of the tuple -- we will be replacing
10157
 
                    index objects with 0's */
10158
 
                n = PyTuple_GET_SIZE(indexobj);
10159
 
                n2 = n;
10160
 
                new = PyTuple_New(n2);
10161
 
                if (new == NULL) goto fail;
10162
 
                started = 0;
10163
 
                nonindex = 0;
10164
 
                j = 0;
10165
 
                for (i=0; i<n; i++) {
10166
 
                        obj = PyTuple_GET_ITEM(indexobj,i);
10167
 
                        iterp = mit->iters + mit->numiter;
10168
 
                        if ((numiters=_convert_obj(obj, iterp)) < 0) {
10169
 
                                Py_DECREF(new);
10170
 
                                goto fail;
10171
 
                        }
10172
 
                        if (numiters > 0) {
10173
 
                                started = 1;
10174
 
                                if (nonindex) mit->consec = 0;
10175
 
                                mit->numiter += numiters;
10176
 
                                if (numiters == 1) {
10177
 
                                        PyTuple_SET_ITEM(new,j++,
10178
 
                                                         PyInt_FromLong(0));
10179
 
                                }
10180
 
                                else { /* we need to grow the
10181
 
                                          new indexing object and fill
10182
 
                                          it with 0s for each of the iterators
10183
 
                                          produced */
10184
 
                                        int k;
10185
 
                                        n2 += numiters - 1;
10186
 
                                        if (_PyTuple_Resize(&new, n2) < 0)
10187
 
                                                goto fail;
10188
 
                                        for (k=0;k<numiters;k++) {
10189
 
                                                PyTuple_SET_ITEM        \
10190
 
                                                        (new,j++,
10191
 
                                                         PyInt_FromLong(0));
10192
 
                                        }
10193
 
                                }
10194
 
                        }
10195
 
                        else {
10196
 
                                if (started) nonindex = 1;
10197
 
                                Py_INCREF(obj);
10198
 
                                PyTuple_SET_ITEM(new,j++,obj);
10199
 
                        }
10200
 
                }
10201
 
                Py_DECREF(mit->indexobj);
10202
 
                mit->indexobj = new;
10203
 
                /* Store the number of iterators actually converted */
10204
 
                /*  These will be mapped to actual axes at bind time */
10205
 
                if (PyArray_Broadcast((PyArrayMultiIterObject *)mit) < 0)
 
10585
    if (oned) return (PyObject *)mit;
 
10586
 
 
10587
    /* Must have some kind of fancy indexing if we are here */
 
10588
    /* indexobj is either a list, an arrayobject, or a tuple
 
10589
       (with at least 1 list or arrayobject or Bool object), */
 
10590
 
 
10591
    /* convert all inputs to iterators */
 
10592
    if (PyArray_Check(indexobj) &&                  \
 
10593
        (PyArray_TYPE(indexobj) == PyArray_BOOL)) {
 
10594
        mit->numiter = _nonzero_indices(indexobj, mit->iters);
 
10595
        if (mit->numiter < 0) goto fail;
 
10596
        mit->nd = 1;
 
10597
        mit->dimensions[0] = mit->iters[0]->dims_m1[0]+1;
 
10598
        Py_DECREF(mit->indexobj);
 
10599
        mit->indexobj = PyTuple_New(mit->numiter);
 
10600
        if (mit->indexobj == NULL) goto fail;
 
10601
        for(i=0; i<mit->numiter; i++) {
 
10602
            PyTuple_SET_ITEM(mit->indexobj, i,
 
10603
                             PyInt_FromLong(0));
 
10604
        }
 
10605
    }
 
10606
 
 
10607
    else if (PyArray_Check(indexobj) || !PyTuple_Check(indexobj)) {
 
10608
        mit->numiter = 1;
 
10609
        indtype = PyArray_DescrFromType(PyArray_INTP);
 
10610
        arr = PyArray_FromAny(indexobj, indtype, 0, 0, FORCECAST, NULL);
 
10611
        if (arr == NULL) goto fail;
 
10612
        mit->iters[0] = (PyArrayIterObject *)PyArray_IterNew(arr);
 
10613
        if (mit->iters[0] == NULL) {Py_DECREF(arr); goto fail;}
 
10614
        mit->nd = PyArray_NDIM(arr);
 
10615
        memcpy(mit->dimensions,PyArray_DIMS(arr),mit->nd*sizeof(intp));
 
10616
        mit->size = PyArray_SIZE(arr);
 
10617
        Py_DECREF(arr);
 
10618
        Py_DECREF(mit->indexobj);
 
10619
        mit->indexobj = Py_BuildValue("(N)", PyInt_FromLong(0));
 
10620
    }
 
10621
    else { /* must be a tuple */
 
10622
        PyObject *obj;
 
10623
        PyArrayIterObject **iterp;
 
10624
        PyObject *new;
 
10625
        int numiters, j, n2;
 
10626
        /* Make a copy of the tuple -- we will be replacing
 
10627
           index objects with 0's */
 
10628
        n = PyTuple_GET_SIZE(indexobj);
 
10629
        n2 = n;
 
10630
        new = PyTuple_New(n2);
 
10631
        if (new == NULL) goto fail;
 
10632
        started = 0;
 
10633
        nonindex = 0;
 
10634
        j = 0;
 
10635
        for(i=0; i<n; i++) {
 
10636
            obj = PyTuple_GET_ITEM(indexobj,i);
 
10637
            iterp = mit->iters + mit->numiter;
 
10638
            if ((numiters=_convert_obj(obj, iterp)) < 0) {
 
10639
                Py_DECREF(new);
 
10640
                goto fail;
 
10641
            }
 
10642
            if (numiters > 0) {
 
10643
                started = 1;
 
10644
                if (nonindex) mit->consec = 0;
 
10645
                mit->numiter += numiters;
 
10646
                if (numiters == 1) {
 
10647
                    PyTuple_SET_ITEM(new,j++,
 
10648
                                     PyInt_FromLong(0));
 
10649
                }
 
10650
                else { /* we need to grow the
 
10651
                          new indexing object and fill
 
10652
                          it with 0s for each of the iterators
 
10653
                          produced */
 
10654
                    int k;
 
10655
                    n2 += numiters - 1;
 
10656
                    if (_PyTuple_Resize(&new, n2) < 0)
10206
10657
                        goto fail;
 
10658
                    for(k=0;k<numiters;k++) {
 
10659
                        PyTuple_SET_ITEM        \
 
10660
                            (new,j++,
 
10661
                             PyInt_FromLong(0));
 
10662
                    }
 
10663
                }
 
10664
            }
 
10665
            else {
 
10666
                if (started) nonindex = 1;
 
10667
                Py_INCREF(obj);
 
10668
                PyTuple_SET_ITEM(new,j++,obj);
 
10669
            }
10207
10670
        }
 
10671
        Py_DECREF(mit->indexobj);
 
10672
        mit->indexobj = new;
 
10673
        /* Store the number of iterators actually converted */
 
10674
        /*  These will be mapped to actual axes at bind time */
 
10675
        if (PyArray_Broadcast((PyArrayMultiIterObject *)mit) < 0)
 
10676
            goto fail;
 
10677
    }
10208
10678
 
10209
 
        return (PyObject *)mit;
 
10679
    return (PyObject *)mit;
10210
10680
 
10211
10681
 fail:
10212
 
        Py_DECREF(mit);
10213
 
        return NULL;
 
10682
    Py_DECREF(mit);
 
10683
    return NULL;
10214
10684
}
10215
10685
 
10216
10686
 
10217
10687
static void
10218
10688
arraymapiter_dealloc(PyArrayMapIterObject *mit)
10219
10689
{
10220
 
        int i;
10221
 
        Py_XDECREF(mit->indexobj);
10222
 
        Py_XDECREF(mit->ait);
10223
 
        Py_XDECREF(mit->subspace);
10224
 
        for (i=0; i<mit->numiter; i++)
10225
 
                Py_XDECREF(mit->iters[i]);
10226
 
        _pya_free(mit);
 
10690
    int i;
 
10691
    Py_XDECREF(mit->indexobj);
 
10692
    Py_XDECREF(mit->ait);
 
10693
    Py_XDECREF(mit->subspace);
 
10694
    for(i=0; i<mit->numiter; i++)
 
10695
        Py_XDECREF(mit->iters[i]);
 
10696
    _pya_free(mit);
10227
10697
}
10228
10698
 
10229
10699
/* The mapiter object must be created new each time.  It does not work
10238
10708
*/
10239
10709
 
10240
10710
static PyTypeObject PyArrayMapIter_Type = {
10241
 
        PyObject_HEAD_INIT(NULL)
10242
 
        0,                                       /* ob_size */
10243
 
        "numpy.mapiter",                        /* tp_name */
10244
 
        sizeof(PyArrayIterObject),               /* tp_basicsize */
10245
 
        0,                                       /* tp_itemsize */
10246
 
        /* methods */
10247
 
        (destructor)arraymapiter_dealloc,       /* tp_dealloc */
10248
 
        0,                                      /* tp_print */
10249
 
        0,                                      /* tp_getattr */
10250
 
        0,                                      /* tp_setattr */
10251
 
        0,                                      /* tp_compare */
10252
 
        0,                                      /* tp_repr */
10253
 
        0,                                      /* tp_as_number */
10254
 
        0,                                      /* tp_as_sequence */
10255
 
        0,                                      /* tp_as_mapping */
10256
 
        0,                                      /* tp_hash */
10257
 
        0,                                      /* tp_call */
10258
 
        0,                                      /* tp_str */
10259
 
        0,              /* tp_getattro */
10260
 
        0,                                      /* tp_setattro */
10261
 
        0,                                      /* tp_as_buffer */
10262
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
10263
 
        0,                                      /* tp_doc */
10264
 
        (traverseproc)0,                        /* tp_traverse */
10265
 
        0,                                      /* tp_clear */
10266
 
        0,                                      /* tp_richcompare */
10267
 
        0,                                      /* tp_weaklistoffset */
10268
 
        0,                                      /* tp_iter */
10269
 
        (iternextfunc)0,                        /* tp_iternext */
10270
 
        0,                              /* tp_methods */
10271
 
        0,                                        /* tp_members */
10272
 
        0,                                        /* tp_getset */
10273
 
        0,                                        /* tp_base */
10274
 
        0,                                        /* tp_dict */
10275
 
        0,                                        /* tp_descr_get */
10276
 
        0,                                        /* tp_descr_set */
10277
 
        0,                                        /* tp_dictoffset */
10278
 
        (initproc)0,                              /* tp_init */
10279
 
        0,                                        /* tp_alloc */
10280
 
        0,                                        /* tp_new */
10281
 
        0,                                        /* tp_free */
10282
 
        0,                                        /* tp_is_gc */
10283
 
        0,                                        /* tp_bases */
10284
 
        0,                                        /* tp_mro */
10285
 
        0,                                        /* tp_cache */
10286
 
        0,                                        /* tp_subclasses */
10287
 
        0                                         /* tp_weaklist */
 
10711
    PyObject_HEAD_INIT(NULL)
 
10712
    0,                                       /* ob_size */
 
10713
    "numpy.mapiter",                        /* tp_name */
 
10714
    sizeof(PyArrayIterObject),               /* tp_basicsize */
 
10715
    0,                                       /* tp_itemsize */
 
10716
    /* methods */
 
10717
    (destructor)arraymapiter_dealloc,       /* tp_dealloc */
 
10718
    0,                                      /* tp_print */
 
10719
    0,                                      /* tp_getattr */
 
10720
    0,                                      /* tp_setattr */
 
10721
    0,                                      /* tp_compare */
 
10722
    0,                                      /* tp_repr */
 
10723
    0,                                      /* tp_as_number */
 
10724
    0,                                      /* tp_as_sequence */
 
10725
    0,                                      /* tp_as_mapping */
 
10726
    0,                                      /* tp_hash */
 
10727
    0,                                      /* tp_call */
 
10728
    0,                                      /* tp_str */
 
10729
    0,              /* tp_getattro */
 
10730
    0,                                      /* tp_setattro */
 
10731
    0,                                      /* tp_as_buffer */
 
10732
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
10733
    0,                                      /* tp_doc */
 
10734
    (traverseproc)0,                        /* tp_traverse */
 
10735
    0,                                      /* tp_clear */
 
10736
    0,                                      /* tp_richcompare */
 
10737
    0,                                      /* tp_weaklistoffset */
 
10738
    0,                                      /* tp_iter */
 
10739
    (iternextfunc)0,                        /* tp_iternext */
 
10740
    0,                              /* tp_methods */
 
10741
    0,                                        /* tp_members */
 
10742
    0,                                        /* tp_getset */
 
10743
    0,                                        /* tp_base */
 
10744
    0,                                        /* tp_dict */
 
10745
    0,                                        /* tp_descr_get */
 
10746
    0,                                        /* tp_descr_set */
 
10747
    0,                                        /* tp_dictoffset */
 
10748
    (initproc)0,                              /* tp_init */
 
10749
    0,                                        /* tp_alloc */
 
10750
    0,                                        /* tp_new */
 
10751
    0,                                        /* tp_free */
 
10752
    0,                                        /* tp_is_gc */
 
10753
    0,                                        /* tp_bases */
 
10754
    0,                                        /* tp_mro */
 
10755
    0,                                        /* tp_cache */
 
10756
    0,                                        /* tp_subclasses */
 
10757
    0                                         /* tp_weaklist */
10288
10758
 
10289
10759
};
10290
10760
 
10292
10762
 
10293
10763
 
10294
10764
/*OBJECT_API
10295
 
 Get MultiIterator,
 
10765
  Get MultiIterator,
10296
10766
*/
10297
10767
static PyObject *
10298
10768
PyArray_MultiIterNew(int n, ...)
10299
10769
{
10300
 
        va_list va;
10301
 
        PyArrayMultiIterObject *multi;
10302
 
        PyObject *current;
10303
 
        PyObject *arr;
10304
 
 
10305
 
        int i, err=0;
10306
 
 
10307
 
        if (n < 2 || n > NPY_MAXARGS) {
10308
 
                PyErr_Format(PyExc_ValueError,
10309
 
                             "Need between 2 and (%d) "                 \
10310
 
                             "array objects (inclusive).", NPY_MAXARGS);
10311
 
        }
10312
 
 
10313
 
        /* fprintf(stderr, "multi new...");*/
10314
 
 
10315
 
        multi = _pya_malloc(sizeof(PyArrayMultiIterObject));
10316
 
        if (multi == NULL) return PyErr_NoMemory();
10317
 
        PyObject_Init((PyObject *)multi, &PyArrayMultiIter_Type);
10318
 
 
10319
 
        for (i=0; i<n; i++) multi->iters[i] = NULL;
10320
 
        multi->numiter = n;
10321
 
        multi->index = 0;
10322
 
 
10323
 
        va_start(va, n);
10324
 
        for (i=0; i<n; i++) {
10325
 
                current = va_arg(va, PyObject *);
10326
 
                arr = PyArray_FROM_O(current);
10327
 
                if (arr==NULL) {
10328
 
                        err=1; break;
10329
 
                }
10330
 
                else {
10331
 
                        multi->iters[i] = (PyArrayIterObject *)PyArray_IterNew(arr);
10332
 
                        Py_DECREF(arr);
10333
 
                }
10334
 
        }
10335
 
 
10336
 
        va_end(va);
10337
 
 
10338
 
        if (!err && PyArray_Broadcast(multi) < 0) err=1;
10339
 
 
10340
 
        if (err) {
10341
 
                Py_DECREF(multi);
10342
 
                return NULL;
10343
 
        }
10344
 
 
10345
 
        PyArray_MultiIter_RESET(multi);
10346
 
 
10347
 
        return (PyObject *)multi;
 
10770
    va_list va;
 
10771
    PyArrayMultiIterObject *multi;
 
10772
    PyObject *current;
 
10773
    PyObject *arr;
 
10774
 
 
10775
    int i, err=0;
 
10776
 
 
10777
    if (n < 2 || n > NPY_MAXARGS) {
 
10778
        PyErr_Format(PyExc_ValueError,
 
10779
                     "Need between 2 and (%d) "                 \
 
10780
                     "array objects (inclusive).", NPY_MAXARGS);
 
10781
        return NULL;
 
10782
    }
 
10783
 
 
10784
    /* fprintf(stderr, "multi new...");*/
 
10785
 
 
10786
    multi = _pya_malloc(sizeof(PyArrayMultiIterObject));
 
10787
    if (multi == NULL) return PyErr_NoMemory();
 
10788
    PyObject_Init((PyObject *)multi, &PyArrayMultiIter_Type);
 
10789
 
 
10790
    for(i=0; i<n; i++) multi->iters[i] = NULL;
 
10791
    multi->numiter = n;
 
10792
    multi->index = 0;
 
10793
 
 
10794
    va_start(va, n);
 
10795
    for(i=0; i<n; i++) {
 
10796
        current = va_arg(va, PyObject *);
 
10797
        arr = PyArray_FROM_O(current);
 
10798
        if (arr==NULL) {
 
10799
            err=1; break;
 
10800
        }
 
10801
        else {
 
10802
            multi->iters[i] = (PyArrayIterObject *)PyArray_IterNew(arr);
 
10803
            Py_DECREF(arr);
 
10804
        }
 
10805
    }
 
10806
 
 
10807
    va_end(va);
 
10808
 
 
10809
    if (!err && PyArray_Broadcast(multi) < 0) err=1;
 
10810
 
 
10811
    if (err) {
 
10812
        Py_DECREF(multi);
 
10813
        return NULL;
 
10814
    }
 
10815
 
 
10816
    PyArray_MultiIter_RESET(multi);
 
10817
 
 
10818
    return (PyObject *)multi;
10348
10819
}
10349
10820
 
10350
10821
static PyObject *
10351
10822
arraymultiter_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
10352
10823
{
10353
10824
 
10354
 
        int n, i;
10355
 
        PyArrayMultiIterObject *multi;
10356
 
        PyObject *arr;
10357
 
 
10358
 
        if (kwds != NULL) {
10359
 
                PyErr_SetString(PyExc_ValueError,
10360
 
                                "keyword arguments not accepted.");
10361
 
                return NULL;
10362
 
        }
10363
 
 
10364
 
        n = PyTuple_Size(args);
10365
 
        if (n < 2 || n > NPY_MAXARGS) {
10366
 
                if (PyErr_Occurred()) return NULL;
10367
 
                PyErr_Format(PyExc_ValueError,
10368
 
                             "Need at least two and fewer than (%d) "   \
10369
 
                             "array objects.", NPY_MAXARGS);
10370
 
                return NULL;
10371
 
        }
10372
 
 
10373
 
        multi = _pya_malloc(sizeof(PyArrayMultiIterObject));
10374
 
        if (multi == NULL) return PyErr_NoMemory();
10375
 
        PyObject_Init((PyObject *)multi, &PyArrayMultiIter_Type);
10376
 
 
10377
 
        multi->numiter = n;
10378
 
        multi->index = 0;
10379
 
        for (i=0; i<n; i++) multi->iters[i] = NULL;
10380
 
        for (i=0; i<n; i++) {
10381
 
                arr = PyArray_FromAny(PyTuple_GET_ITEM(args, i), NULL, 0, 0, 0, NULL);
10382
 
                if (arr == NULL) goto fail;
10383
 
                if ((multi->iters[i] =                                  \
10384
 
                     (PyArrayIterObject *)PyArray_IterNew(arr))==NULL)
10385
 
                        goto fail;
10386
 
                Py_DECREF(arr);
10387
 
        }
10388
 
        if (PyArray_Broadcast(multi) < 0) goto fail;
10389
 
        PyArray_MultiIter_RESET(multi);
10390
 
 
10391
 
        return (PyObject *)multi;
 
10825
    int n, i;
 
10826
    PyArrayMultiIterObject *multi;
 
10827
    PyObject *arr;
 
10828
 
 
10829
    if (kwds != NULL) {
 
10830
        PyErr_SetString(PyExc_ValueError,
 
10831
                        "keyword arguments not accepted.");
 
10832
        return NULL;
 
10833
    }
 
10834
 
 
10835
    n = PyTuple_Size(args);
 
10836
    if (n < 2 || n > NPY_MAXARGS) {
 
10837
        if (PyErr_Occurred()) return NULL;
 
10838
        PyErr_Format(PyExc_ValueError,
 
10839
                     "Need at least two and fewer than (%d) "   \
 
10840
                     "array objects.", NPY_MAXARGS);
 
10841
        return NULL;
 
10842
    }
 
10843
 
 
10844
    multi = _pya_malloc(sizeof(PyArrayMultiIterObject));
 
10845
    if (multi == NULL) return PyErr_NoMemory();
 
10846
    PyObject_Init((PyObject *)multi, &PyArrayMultiIter_Type);
 
10847
 
 
10848
    multi->numiter = n;
 
10849
    multi->index = 0;
 
10850
    for(i=0; i<n; i++) multi->iters[i] = NULL;
 
10851
    for(i=0; i<n; i++) {
 
10852
        arr = PyArray_FromAny(PyTuple_GET_ITEM(args, i), NULL, 0, 0, 0, NULL);
 
10853
        if (arr == NULL) goto fail;
 
10854
        if ((multi->iters[i] =                                  \
 
10855
             (PyArrayIterObject *)PyArray_IterNew(arr))==NULL)
 
10856
            goto fail;
 
10857
        Py_DECREF(arr);
 
10858
    }
 
10859
    if (PyArray_Broadcast(multi) < 0) goto fail;
 
10860
    PyArray_MultiIter_RESET(multi);
 
10861
 
 
10862
    return (PyObject *)multi;
10392
10863
 
10393
10864
 fail:
10394
 
        Py_DECREF(multi);
10395
 
        return NULL;
 
10865
    Py_DECREF(multi);
 
10866
    return NULL;
10396
10867
}
10397
10868
 
10398
10869
static PyObject *
10399
10870
arraymultiter_next(PyArrayMultiIterObject *multi)
10400
10871
{
10401
 
        PyObject *ret;
10402
 
        int i, n;
 
10872
    PyObject *ret;
 
10873
    int i, n;
10403
10874
 
10404
 
        n = multi->numiter;
10405
 
        ret = PyTuple_New(n);
10406
 
        if (ret == NULL) return NULL;
10407
 
        if (multi->index < multi->size) {
10408
 
                for (i=0; i < n; i++) {
10409
 
                        PyArrayIterObject *it=multi->iters[i];
10410
 
                        PyTuple_SET_ITEM(ret, i,
10411
 
                                         PyArray_ToScalar(it->dataptr, it->ao));
10412
 
                        PyArray_ITER_NEXT(it);
10413
 
                }
10414
 
                multi->index++;
10415
 
                return ret;
 
10875
    n = multi->numiter;
 
10876
    ret = PyTuple_New(n);
 
10877
    if (ret == NULL) return NULL;
 
10878
    if (multi->index < multi->size) {
 
10879
        for(i=0; i < n; i++) {
 
10880
            PyArrayIterObject *it=multi->iters[i];
 
10881
            PyTuple_SET_ITEM(ret, i,
 
10882
                             PyArray_ToScalar(it->dataptr, it->ao));
 
10883
            PyArray_ITER_NEXT(it);
10416
10884
        }
10417
 
        return NULL;
 
10885
        multi->index++;
 
10886
        return ret;
 
10887
    }
 
10888
    return NULL;
10418
10889
}
10419
10890
 
10420
10891
static void
10421
10892
arraymultiter_dealloc(PyArrayMultiIterObject *multi)
10422
10893
{
10423
 
        int i;
 
10894
    int i;
10424
10895
 
10425
 
        for (i=0; i<multi->numiter; i++)
10426
 
                Py_XDECREF(multi->iters[i]);
10427
 
        multi->ob_type->tp_free((PyObject *)multi);
 
10896
    for(i=0; i<multi->numiter; i++)
 
10897
        Py_XDECREF(multi->iters[i]);
 
10898
    multi->ob_type->tp_free((PyObject *)multi);
10428
10899
}
10429
10900
 
10430
10901
static PyObject *
10431
10902
arraymultiter_size_get(PyArrayMultiIterObject *self)
10432
10903
{
10433
10904
#if SIZEOF_INTP <= SIZEOF_LONG
 
10905
    return PyInt_FromLong((long) self->size);
 
10906
#else
 
10907
    if (self->size < MAX_LONG)
10434
10908
        return PyInt_FromLong((long) self->size);
10435
 
#else
10436
 
        if (self->size < MAX_LONG)
10437
 
                return PyInt_FromLong((long) self->size);
10438
 
        else
10439
 
                return PyLong_FromLongLong((longlong) self->size);
 
10909
    else
 
10910
        return PyLong_FromLongLong((longlong) self->size);
10440
10911
#endif
10441
10912
}
10442
10913
 
10444
10915
arraymultiter_index_get(PyArrayMultiIterObject *self)
10445
10916
{
10446
10917
#if SIZEOF_INTP <= SIZEOF_LONG
 
10918
    return PyInt_FromLong((long) self->index);
 
10919
#else
 
10920
    if (self->size < MAX_LONG)
10447
10921
        return PyInt_FromLong((long) self->index);
10448
 
#else
10449
 
        if (self->size < MAX_LONG)
10450
 
                return PyInt_FromLong((long) self->index);
10451
 
        else
10452
 
                return PyLong_FromLongLong((longlong) self->index);
 
10922
    else
 
10923
        return PyLong_FromLongLong((longlong) self->index);
10453
10924
#endif
10454
10925
}
10455
10926
 
10456
10927
static PyObject *
10457
10928
arraymultiter_shape_get(PyArrayMultiIterObject *self)
10458
10929
{
10459
 
        return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
 
10930
    return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
10460
10931
}
10461
10932
 
10462
10933
static PyObject *
10463
10934
arraymultiter_iters_get(PyArrayMultiIterObject *self)
10464
10935
{
10465
 
        PyObject *res;
10466
 
        int i, n;
10467
 
        n = self->numiter;
10468
 
        res = PyTuple_New(n);
10469
 
        if (res == NULL) return res;
10470
 
        for (i=0; i<n; i++) {
10471
 
                Py_INCREF(self->iters[i]);
10472
 
                PyTuple_SET_ITEM(res, i, (PyObject *)self->iters[i]);
10473
 
        }
10474
 
        return res;
 
10936
    PyObject *res;
 
10937
    int i, n;
 
10938
    n = self->numiter;
 
10939
    res = PyTuple_New(n);
 
10940
    if (res == NULL) return res;
 
10941
    for(i=0; i<n; i++) {
 
10942
        Py_INCREF(self->iters[i]);
 
10943
        PyTuple_SET_ITEM(res, i, (PyObject *)self->iters[i]);
 
10944
    }
 
10945
    return res;
10475
10946
}
10476
10947
 
10477
10948
static PyGetSetDef arraymultiter_getsetlist[] = {
10478
 
        {"size",
10479
 
         (getter)arraymultiter_size_get,
10480
 
         NULL, NULL},
10481
 
        {"index",
10482
 
         (getter)arraymultiter_index_get,
10483
 
         NULL, NULL},
10484
 
        {"shape",
10485
 
         (getter)arraymultiter_shape_get,
10486
 
         NULL, NULL},
10487
 
        {"iters",
10488
 
         (getter)arraymultiter_iters_get,
10489
 
         NULL, NULL},
10490
 
        {NULL, NULL, NULL, NULL},
 
10949
    {"size",
 
10950
     (getter)arraymultiter_size_get,
 
10951
     NULL, NULL},
 
10952
    {"index",
 
10953
     (getter)arraymultiter_index_get,
 
10954
     NULL, NULL},
 
10955
    {"shape",
 
10956
     (getter)arraymultiter_shape_get,
 
10957
     NULL, NULL},
 
10958
    {"iters",
 
10959
     (getter)arraymultiter_iters_get,
 
10960
     NULL, NULL},
 
10961
    {NULL, NULL, NULL, NULL},
10491
10962
};
10492
10963
 
10493
10964
static PyMemberDef arraymultiter_members[] = {
10494
 
        {"numiter", T_INT, offsetof(PyArrayMultiIterObject, numiter),
10495
 
         RO, NULL},
10496
 
        {"nd", T_INT, offsetof(PyArrayMultiIterObject, nd), RO, NULL},
10497
 
        {NULL},
 
10965
    {"numiter", T_INT, offsetof(PyArrayMultiIterObject, numiter),
 
10966
     RO, NULL},
 
10967
    {"nd", T_INT, offsetof(PyArrayMultiIterObject, nd), RO, NULL},
 
10968
    {NULL},
10498
10969
};
10499
10970
 
10500
10971
static PyObject *
10501
10972
arraymultiter_reset(PyArrayMultiIterObject *self, PyObject *args)
10502
10973
{
10503
 
        if (!PyArg_ParseTuple(args, "")) return NULL;
 
10974
    if (!PyArg_ParseTuple(args, "")) return NULL;
10504
10975
 
10505
 
        PyArray_MultiIter_RESET(self);
10506
 
        Py_INCREF(Py_None);
10507
 
        return Py_None;
 
10976
    PyArray_MultiIter_RESET(self);
 
10977
    Py_INCREF(Py_None);
 
10978
    return Py_None;
10508
10979
}
10509
10980
 
10510
10981
static PyMethodDef arraymultiter_methods[] = {
10511
 
        {"reset", (PyCFunction) arraymultiter_reset, METH_VARARGS, NULL},
10512
 
        {NULL, NULL},
 
10982
    {"reset", (PyCFunction) arraymultiter_reset, METH_VARARGS, NULL},
 
10983
    {NULL, NULL},
10513
10984
};
10514
10985
 
10515
10986
static PyTypeObject PyArrayMultiIter_Type = {
10516
 
        PyObject_HEAD_INIT(NULL)
10517
 
        0,                                       /* ob_size */
10518
 
        "numpy.broadcast",                       /* tp_name */
10519
 
        sizeof(PyArrayMultiIterObject),          /* tp_basicsize */
10520
 
        0,                                       /* tp_itemsize */
10521
 
        /* methods */
10522
 
        (destructor)arraymultiter_dealloc,      /* tp_dealloc */
10523
 
        0,                                      /* tp_print */
10524
 
        0,                                      /* tp_getattr */
10525
 
        0,                                      /* tp_setattr */
10526
 
        0,                                      /* tp_compare */
10527
 
        0,                                      /* tp_repr */
10528
 
        0,                                      /* tp_as_number */
10529
 
        0,                                      /* tp_as_sequence */
10530
 
        0,                              /* tp_as_mapping */
10531
 
        0,                                      /* tp_hash */
10532
 
        0,                                      /* tp_call */
10533
 
        0,                                      /* tp_str */
10534
 
        0,              /* tp_getattro */
10535
 
        0,                                      /* tp_setattro */
10536
 
        0,                                      /* tp_as_buffer */
10537
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
10538
 
        0,                                      /* tp_doc */
10539
 
        0,                              /* tp_traverse */
10540
 
        0,                                      /* tp_clear */
10541
 
        0,                                      /* tp_richcompare */
10542
 
        0,                                      /* tp_weaklistoffset */
10543
 
        0,                              /* tp_iter */
10544
 
        (iternextfunc)arraymultiter_next,       /* tp_iternext */
10545
 
        arraymultiter_methods,          /* tp_methods */
10546
 
        arraymultiter_members,                  /* tp_members */
10547
 
        arraymultiter_getsetlist,               /* tp_getset */
10548
 
        0,                                        /* tp_base */
10549
 
        0,                                        /* tp_dict */
10550
 
        0,                                        /* tp_descr_get */
10551
 
        0,                                        /* tp_descr_set */
10552
 
        0,                                        /* tp_dictoffset */
10553
 
        (initproc)0,                              /* tp_init */
10554
 
        0,                                        /* tp_alloc */
10555
 
        arraymultiter_new,                        /* tp_new */
10556
 
        0,                                        /* tp_free */
10557
 
        0,                                        /* tp_is_gc */
10558
 
        0,                                        /* tp_bases */
10559
 
        0,                                        /* tp_mro */
10560
 
        0,                                        /* tp_cache */
10561
 
        0,                                        /* tp_subclasses */
10562
 
        0                                         /* tp_weaklist */
 
10987
    PyObject_HEAD_INIT(NULL)
 
10988
    0,                                       /* ob_size */
 
10989
    "numpy.broadcast",                       /* tp_name */
 
10990
    sizeof(PyArrayMultiIterObject),          /* tp_basicsize */
 
10991
    0,                                       /* tp_itemsize */
 
10992
    /* methods */
 
10993
    (destructor)arraymultiter_dealloc,      /* tp_dealloc */
 
10994
    0,                                      /* tp_print */
 
10995
    0,                                      /* tp_getattr */
 
10996
    0,                                      /* tp_setattr */
 
10997
    0,                                      /* tp_compare */
 
10998
    0,                                      /* tp_repr */
 
10999
    0,                                      /* tp_as_number */
 
11000
    0,                                      /* tp_as_sequence */
 
11001
    0,                              /* tp_as_mapping */
 
11002
    0,                                      /* tp_hash */
 
11003
    0,                                      /* tp_call */
 
11004
    0,                                      /* tp_str */
 
11005
    0,              /* tp_getattro */
 
11006
    0,                                      /* tp_setattro */
 
11007
    0,                                      /* tp_as_buffer */
 
11008
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
11009
    0,                                      /* tp_doc */
 
11010
    0,                              /* tp_traverse */
 
11011
    0,                                      /* tp_clear */
 
11012
    0,                                      /* tp_richcompare */
 
11013
    0,                                      /* tp_weaklistoffset */
 
11014
    0,                              /* tp_iter */
 
11015
    (iternextfunc)arraymultiter_next,       /* tp_iternext */
 
11016
    arraymultiter_methods,          /* tp_methods */
 
11017
    arraymultiter_members,                  /* tp_members */
 
11018
    arraymultiter_getsetlist,               /* tp_getset */
 
11019
    0,                                        /* tp_base */
 
11020
    0,                                        /* tp_dict */
 
11021
    0,                                        /* tp_descr_get */
 
11022
    0,                                        /* tp_descr_set */
 
11023
    0,                                        /* tp_dictoffset */
 
11024
    (initproc)0,                              /* tp_init */
 
11025
    0,                                        /* tp_alloc */
 
11026
    arraymultiter_new,                        /* tp_new */
 
11027
    0,                                        /* tp_free */
 
11028
    0,                                        /* tp_is_gc */
 
11029
    0,                                        /* tp_bases */
 
11030
    0,                                        /* tp_mro */
 
11031
    0,                                        /* tp_cache */
 
11032
    0,                                        /* tp_subclasses */
 
11033
    0                                         /* tp_weaklist */
10563
11034
};
10564
11035
 
10565
11036
/*OBJECT_API*/
10566
11037
static PyArray_Descr *
10567
11038
PyArray_DescrNewFromType(int type_num)
10568
11039
{
10569
 
        PyArray_Descr *old;
10570
 
        PyArray_Descr *new;
 
11040
    PyArray_Descr *old;
 
11041
    PyArray_Descr *new;
10571
11042
 
10572
 
        old = PyArray_DescrFromType(type_num);
10573
 
        new = PyArray_DescrNew(old);
10574
 
        Py_DECREF(old);
10575
 
        return new;
 
11043
    old = PyArray_DescrFromType(type_num);
 
11044
    new = PyArray_DescrNew(old);
 
11045
    Py_DECREF(old);
 
11046
    return new;
10576
11047
}
10577
11048
 
10578
11049
/*** Array Descr Objects for dynamic types **/
10593
11064
static PyArray_Descr *
10594
11065
PyArray_DescrNew(PyArray_Descr *base)
10595
11066
{
10596
 
        PyArray_Descr *new;
10597
 
 
10598
 
        new = PyObject_New(PyArray_Descr, &PyArrayDescr_Type);
10599
 
        if (new == NULL) return NULL;
10600
 
        /* Don't copy PyObject_HEAD part */
10601
 
        memcpy((char *)new+sizeof(PyObject),
10602
 
               (char *)base+sizeof(PyObject),
10603
 
               sizeof(PyArray_Descr)-sizeof(PyObject));
10604
 
 
10605
 
        if (new->fields == Py_None) new->fields = NULL;
10606
 
        Py_XINCREF(new->fields);
10607
 
        Py_XINCREF(new->names);
10608
 
        if (new->subarray) {
10609
 
                new->subarray = _pya_malloc(sizeof(PyArray_ArrayDescr));
10610
 
                memcpy(new->subarray, base->subarray,
10611
 
                       sizeof(PyArray_ArrayDescr));
10612
 
                Py_INCREF(new->subarray->shape);
10613
 
                Py_INCREF(new->subarray->base);
10614
 
        }
10615
 
        Py_XINCREF(new->typeobj);
10616
 
        return new;
 
11067
    PyArray_Descr *new;
 
11068
 
 
11069
    new = PyObject_New(PyArray_Descr, &PyArrayDescr_Type);
 
11070
    if (new == NULL) return NULL;
 
11071
    /* Don't copy PyObject_HEAD part */
 
11072
    memcpy((char *)new+sizeof(PyObject),
 
11073
           (char *)base+sizeof(PyObject),
 
11074
           sizeof(PyArray_Descr)-sizeof(PyObject));
 
11075
 
 
11076
    if (new->fields == Py_None) new->fields = NULL;
 
11077
    Py_XINCREF(new->fields);
 
11078
    Py_XINCREF(new->names);
 
11079
    if (new->subarray) {
 
11080
        new->subarray = _pya_malloc(sizeof(PyArray_ArrayDescr));
 
11081
        memcpy(new->subarray, base->subarray,
 
11082
               sizeof(PyArray_ArrayDescr));
 
11083
        Py_INCREF(new->subarray->shape);
 
11084
        Py_INCREF(new->subarray->base);
 
11085
    }
 
11086
    Py_XINCREF(new->typeobj);
 
11087
    return new;
10617
11088
}
10618
11089
 
10619
11090
/* should never be called for builtin-types unless
10622
11093
static void
10623
11094
arraydescr_dealloc(PyArray_Descr *self)
10624
11095
{
10625
 
        if (self->fields == Py_None) {
10626
 
                fprintf(stderr, "*** Reference count error detected: \n" \
10627
 
                        "an attempt was made to deallocate %d (%c) ***\n", 
10628
 
                        self->type_num, self->type);
10629
 
                Py_INCREF(self);
10630
 
                Py_INCREF(self);
10631
 
                return;
10632
 
        }
10633
 
        Py_XDECREF(self->typeobj);
10634
 
        Py_XDECREF(self->names);
10635
 
        Py_XDECREF(self->fields);
10636
 
        if (self->subarray) {
10637
 
                Py_DECREF(self->subarray->shape);
10638
 
                Py_DECREF(self->subarray->base);
10639
 
                _pya_free(self->subarray);
10640
 
        }
10641
 
        self->ob_type->tp_free((PyObject *)self);
 
11096
    if (self->fields == Py_None) {
 
11097
        fprintf(stderr, "*** Reference count error detected: \n" \
 
11098
                "an attempt was made to deallocate %d (%c) ***\n",
 
11099
                self->type_num, self->type);
 
11100
        Py_INCREF(self);
 
11101
        Py_INCREF(self);
 
11102
        return;
 
11103
    }
 
11104
    Py_XDECREF(self->typeobj);
 
11105
    Py_XDECREF(self->names);
 
11106
    Py_XDECREF(self->fields);
 
11107
    if (self->subarray) {
 
11108
        Py_DECREF(self->subarray->shape);
 
11109
        Py_DECREF(self->subarray->base);
 
11110
        _pya_free(self->subarray);
 
11111
    }
 
11112
    self->ob_type->tp_free((PyObject *)self);
10642
11113
}
10643
11114
 
10644
11115
/* we need to be careful about setting attributes because these
10646
11117
   data.  Currently no attributes of dtype objects can be set.
10647
11118
*/
10648
11119
static PyMemberDef arraydescr_members[] = {
10649
 
        {"type", T_OBJECT, offsetof(PyArray_Descr, typeobj), RO, NULL},
10650
 
        {"kind", T_CHAR, offsetof(PyArray_Descr, kind), RO, NULL},
10651
 
        {"char", T_CHAR, offsetof(PyArray_Descr, type), RO, NULL},
10652
 
        {"num", T_INT, offsetof(PyArray_Descr, type_num), RO, NULL},
10653
 
        {"byteorder", T_CHAR, offsetof(PyArray_Descr, byteorder), RO, NULL},
10654
 
        {"itemsize", T_INT, offsetof(PyArray_Descr, elsize), RO, NULL},
10655
 
        {"alignment", T_INT, offsetof(PyArray_Descr, alignment), RO, NULL},
10656
 
        {"flags", T_UBYTE, offsetof(PyArray_Descr, hasobject), RO, NULL},
10657
 
        {"names", T_OBJECT, offsetof(PyArray_Descr, names), RO, NULL},
10658
 
        {NULL},
 
11120
    {"type", T_OBJECT, offsetof(PyArray_Descr, typeobj), RO, NULL},
 
11121
    {"kind", T_CHAR, offsetof(PyArray_Descr, kind), RO, NULL},
 
11122
    {"char", T_CHAR, offsetof(PyArray_Descr, type), RO, NULL},
 
11123
    {"num", T_INT, offsetof(PyArray_Descr, type_num), RO, NULL},
 
11124
    {"byteorder", T_CHAR, offsetof(PyArray_Descr, byteorder), RO, NULL},
 
11125
    {"itemsize", T_INT, offsetof(PyArray_Descr, elsize), RO, NULL},
 
11126
    {"alignment", T_INT, offsetof(PyArray_Descr, alignment), RO, NULL},
 
11127
    {"flags", T_UBYTE, offsetof(PyArray_Descr, hasobject), RO, NULL},
 
11128
    {NULL},
10659
11129
};
10660
11130
 
10661
11131
static PyObject *
10662
11132
arraydescr_subdescr_get(PyArray_Descr *self)
10663
11133
{
10664
 
        if (self->subarray == NULL) {
10665
 
                Py_INCREF(Py_None);
10666
 
                return Py_None;
10667
 
        }
10668
 
        return Py_BuildValue("OO", (PyObject *)self->subarray->base,
10669
 
                             self->subarray->shape);
 
11134
    if (self->subarray == NULL) {
 
11135
        Py_INCREF(Py_None);
 
11136
        return Py_None;
 
11137
    }
 
11138
    return Py_BuildValue("OO", (PyObject *)self->subarray->base,
 
11139
                         self->subarray->shape);
10670
11140
}
10671
11141
 
10672
11142
static PyObject *
10673
11143
arraydescr_protocol_typestr_get(PyArray_Descr *self)
10674
11144
{
10675
 
        char basic_=self->kind;
10676
 
        char endian = self->byteorder;
10677
 
        int size=self->elsize;
10678
 
 
10679
 
        if (endian == '=') {
10680
 
                endian = '<';
10681
 
                if (!PyArray_IsNativeByteOrder(endian)) endian = '>';
10682
 
        }
10683
 
 
10684
 
        if (self->type_num == PyArray_UNICODE) {
10685
 
                size >>= 2;
10686
 
        }
10687
 
        return PyString_FromFormat("%c%c%d", endian, basic_, size);
 
11145
    char basic_=self->kind;
 
11146
    char endian = self->byteorder;
 
11147
    int size=self->elsize;
 
11148
 
 
11149
    if (endian == '=') {
 
11150
        endian = '<';
 
11151
        if (!PyArray_IsNativeByteOrder(endian)) endian = '>';
 
11152
    }
 
11153
 
 
11154
    if (self->type_num == PyArray_UNICODE) {
 
11155
        size >>= 2;
 
11156
    }
 
11157
    return PyString_FromFormat("%c%c%d", endian, basic_, size);
10688
11158
}
10689
11159
 
10690
11160
static PyObject *
10691
11161
arraydescr_typename_get(PyArray_Descr *self)
10692
11162
{
10693
 
        int len;
10694
 
        PyTypeObject *typeobj = self->typeobj;
10695
 
        PyObject *res;
10696
 
        char *s;
10697
 
        static int prefix_len=0;
10698
 
        
10699
 
        if (PyTypeNum_ISUSERDEF(self->type_num)) {
10700
 
                s = strrchr(typeobj->tp_name, '.');
10701
 
                if (s == NULL) {
10702
 
                        res = PyString_FromString(typeobj->tp_name);
10703
 
                }
10704
 
                else {
10705
 
                        res = PyString_FromStringAndSize(s+1, strlen(s)-1);
10706
 
                }
10707
 
                return res;
 
11163
    int len;
 
11164
    PyTypeObject *typeobj = self->typeobj;
 
11165
    PyObject *res;
 
11166
    char *s;
 
11167
    static int prefix_len=0;
 
11168
 
 
11169
    if (PyTypeNum_ISUSERDEF(self->type_num)) {
 
11170
        s = strrchr(typeobj->tp_name, '.');
 
11171
        if (s == NULL) {
 
11172
            res = PyString_FromString(typeobj->tp_name);
10708
11173
        }
10709
11174
        else {
10710
 
                if (prefix_len == 0)
10711
 
                        prefix_len = strlen("numpy.");
10712
 
 
10713
 
                len = strlen(typeobj->tp_name);
10714
 
                if (*(typeobj->tp_name + (len-1)) == '_')
10715
 
                        len-=1;
10716
 
                len -= prefix_len;
10717
 
                res = PyString_FromStringAndSize(typeobj->tp_name+prefix_len, len);
10718
 
        }
10719
 
        if (PyTypeNum_ISFLEXIBLE(self->type_num) && self->elsize != 0) {
10720
 
                PyObject *p;
10721
 
                p = PyString_FromFormat("%d", self->elsize * 8);
10722
 
                PyString_ConcatAndDel(&res, p);
 
11175
            res = PyString_FromStringAndSize(s+1, strlen(s)-1);
10723
11176
        }
10724
11177
        return res;
 
11178
    }
 
11179
    else {
 
11180
        if (prefix_len == 0)
 
11181
            prefix_len = strlen("numpy.");
 
11182
 
 
11183
        len = strlen(typeobj->tp_name);
 
11184
        if (*(typeobj->tp_name + (len-1)) == '_')
 
11185
            len-=1;
 
11186
        len -= prefix_len;
 
11187
        res = PyString_FromStringAndSize(typeobj->tp_name+prefix_len, len);
 
11188
    }
 
11189
    if (PyTypeNum_ISFLEXIBLE(self->type_num) && self->elsize != 0) {
 
11190
        PyObject *p;
 
11191
        p = PyString_FromFormat("%d", self->elsize * 8);
 
11192
        PyString_ConcatAndDel(&res, p);
 
11193
    }
 
11194
    return res;
10725
11195
}
10726
11196
 
10727
11197
static PyObject *
10728
11198
arraydescr_base_get(PyArray_Descr *self)
10729
11199
{
10730
 
        if (self->subarray == NULL) {
10731
 
                Py_INCREF(self);
10732
 
                return (PyObject *)self;
10733
 
        }
10734
 
        Py_INCREF(self->subarray->base);
10735
 
        return (PyObject *)(self->subarray->base);
 
11200
    if (self->subarray == NULL) {
 
11201
        Py_INCREF(self);
 
11202
        return (PyObject *)self;
 
11203
    }
 
11204
    Py_INCREF(self->subarray->base);
 
11205
    return (PyObject *)(self->subarray->base);
10736
11206
}
10737
11207
 
10738
11208
static PyObject *
10739
11209
arraydescr_shape_get(PyArray_Descr *self)
10740
11210
{
10741
 
        if (self->subarray == NULL) {
10742
 
                return PyTuple_New(0);
10743
 
        }
10744
 
        if (PyTuple_Check(self->subarray->shape)) {
10745
 
                Py_INCREF(self->subarray->shape);
10746
 
                return (PyObject *)(self->subarray->shape);
10747
 
        }
10748
 
        return Py_BuildValue("(O)", self->subarray->shape);
 
11211
    if (self->subarray == NULL) {
 
11212
        return PyTuple_New(0);
 
11213
    }
 
11214
    if (PyTuple_Check(self->subarray->shape)) {
 
11215
        Py_INCREF(self->subarray->shape);
 
11216
        return (PyObject *)(self->subarray->shape);
 
11217
    }
 
11218
    return Py_BuildValue("(O)", self->subarray->shape);
10749
11219
}
10750
11220
 
10751
11221
static PyObject *
10752
11222
arraydescr_protocol_descr_get(PyArray_Descr *self)
10753
11223
{
10754
 
        PyObject *dobj, *res;
10755
 
 
10756
 
        if (self->names == NULL) {
10757
 
                /* get default */
10758
 
                dobj = PyTuple_New(2);
10759
 
                if (dobj == NULL) return NULL;
10760
 
                PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
10761
 
                PyTuple_SET_ITEM(dobj, 1, \
10762
 
                                 arraydescr_protocol_typestr_get(self));
10763
 
                res = PyList_New(1);
10764
 
                if (res == NULL) {Py_DECREF(dobj); return NULL;}
10765
 
                PyList_SET_ITEM(res, 0, dobj);
10766
 
                return res;
10767
 
        }
10768
 
 
10769
 
        return PyObject_CallMethod(_numpy_internal, "_array_descr",
10770
 
                                   "O", self);
 
11224
    PyObject *dobj, *res;
 
11225
    PyObject *_numpy_internal;
 
11226
 
 
11227
    if (self->names == NULL) {
 
11228
        /* get default */
 
11229
        dobj = PyTuple_New(2);
 
11230
        if (dobj == NULL) return NULL;
 
11231
        PyTuple_SET_ITEM(dobj, 0, PyString_FromString(""));
 
11232
        PyTuple_SET_ITEM(dobj, 1, \
 
11233
                         arraydescr_protocol_typestr_get(self));
 
11234
        res = PyList_New(1);
 
11235
        if (res == NULL) {Py_DECREF(dobj); return NULL;}
 
11236
        PyList_SET_ITEM(res, 0, dobj);
 
11237
        return res;
 
11238
    }
 
11239
 
 
11240
    _numpy_internal = PyImport_ImportModule("numpy.core._internal");
 
11241
    if (_numpy_internal == NULL) return NULL;
 
11242
    res = PyObject_CallMethod(_numpy_internal, "_array_descr",
 
11243
                              "O", self);
 
11244
    Py_DECREF(_numpy_internal);
 
11245
    return res;
10771
11246
}
10772
11247
 
10773
11248
/* returns 1 for a builtin type
10777
11252
static PyObject *
10778
11253
arraydescr_isbuiltin_get(PyArray_Descr *self)
10779
11254
{
10780
 
        long val;
10781
 
        val = 0;
10782
 
        if (self->fields == Py_None) val = 1;
10783
 
        if (PyTypeNum_ISUSERDEF(self->type_num)) val = 2;
10784
 
        return PyInt_FromLong(val);
 
11255
    long val;
 
11256
    val = 0;
 
11257
    if (self->fields == Py_None) val = 1;
 
11258
    if (PyTypeNum_ISUSERDEF(self->type_num)) val = 2;
 
11259
    return PyInt_FromLong(val);
10785
11260
}
10786
11261
 
10787
11262
static int
10788
11263
_arraydescr_isnative(PyArray_Descr *self)
10789
11264
{
10790
 
        if (self->names == NULL) {
10791
 
                return PyArray_ISNBO(self->byteorder);
10792
 
        }
10793
 
        else {
10794
 
                PyObject *key, *value, *title=NULL;
10795
 
                PyArray_Descr *new;
10796
 
                int offset;
10797
 
                Py_ssize_t pos=0;
10798
 
                while(PyDict_Next(self->fields, &pos, &key, &value)) {
10799
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
10800
 
                                              &title)) return -1;
10801
 
                        if (!_arraydescr_isnative(new)) return 0;
10802
 
                }
10803
 
        }
10804
 
        return 1;
 
11265
    if (self->names == NULL) {
 
11266
        return PyArray_ISNBO(self->byteorder);
 
11267
    }
 
11268
    else {
 
11269
        PyObject *key, *value, *title=NULL;
 
11270
        PyArray_Descr *new;
 
11271
        int offset;
 
11272
        Py_ssize_t pos=0;
 
11273
        while(PyDict_Next(self->fields, &pos, &key, &value)) {
 
11274
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
11275
                                  &title)) return -1;
 
11276
            if (!_arraydescr_isnative(new)) return 0;
 
11277
        }
 
11278
    }
 
11279
    return 1;
10805
11280
}
10806
11281
 
10807
11282
/* return Py_True if this data-type descriptor
10813
11288
static PyObject *
10814
11289
arraydescr_isnative_get(PyArray_Descr *self)
10815
11290
{
10816
 
        PyObject *ret;
10817
 
        int retval;
10818
 
        retval = _arraydescr_isnative(self);
10819
 
        if (retval == -1) return NULL;
10820
 
        ret = (retval ? Py_True : Py_False);
10821
 
        Py_INCREF(ret);
10822
 
        return ret;
 
11291
    PyObject *ret;
 
11292
    int retval;
 
11293
    retval = _arraydescr_isnative(self);
 
11294
    if (retval == -1) return NULL;
 
11295
    ret = (retval ? Py_True : Py_False);
 
11296
    Py_INCREF(ret);
 
11297
    return ret;
10823
11298
}
10824
11299
 
10825
11300
static PyObject *
10826
11301
arraydescr_fields_get(PyArray_Descr *self)
10827
11302
{
10828
 
        if (self->names == NULL) {
10829
 
                Py_INCREF(Py_None);
10830
 
                return Py_None;
10831
 
        }
10832
 
        return PyDictProxy_New(self->fields);
 
11303
    if (self->names == NULL) {
 
11304
        Py_INCREF(Py_None);
 
11305
        return Py_None;
 
11306
    }
 
11307
    return PyDictProxy_New(self->fields);
10833
11308
}
10834
11309
 
10835
11310
static PyObject *
10836
11311
arraydescr_hasobject_get(PyArray_Descr *self)
10837
11312
{
10838
 
        PyObject *res;
10839
 
        if (PyDataType_FLAGCHK(self, NPY_ITEM_HASOBJECT))
10840
 
                res = Py_True;
10841
 
        else
10842
 
                res = Py_False;
10843
 
        Py_INCREF(res);
10844
 
        return res;
 
11313
    PyObject *res;
 
11314
    if (PyDataType_FLAGCHK(self, NPY_ITEM_HASOBJECT))
 
11315
        res = Py_True;
 
11316
    else
 
11317
        res = Py_False;
 
11318
    Py_INCREF(res);
 
11319
    return res;
 
11320
}
 
11321
 
 
11322
static PyObject *
 
11323
arraydescr_names_get(PyArray_Descr *self)
 
11324
{
 
11325
    if (self->names == NULL) {
 
11326
        Py_INCREF(Py_None);
 
11327
        return Py_None;
 
11328
    }
 
11329
    Py_INCREF(self->names);
 
11330
    return self->names;
 
11331
}
 
11332
 
 
11333
static int
 
11334
arraydescr_names_set(PyArray_Descr *self, PyObject *val)
 
11335
{
 
11336
    int N = 0;
 
11337
    int i;
 
11338
    PyObject *new_names;
 
11339
    if (self->names == NULL) {
 
11340
        PyErr_SetString(PyExc_ValueError, "there are no fields defined");
 
11341
        return -1;
 
11342
    }
 
11343
 
 
11344
    N = PyTuple_GET_SIZE(self->names);
 
11345
    if (!PySequence_Check(val) || PyObject_Size((PyObject *)val) != N) {
 
11346
        PyErr_Format(PyExc_ValueError, "must replace all names at once" \
 
11347
                     " with a sequence of length %d", N);
 
11348
        return -1;
 
11349
    }
 
11350
    /* Make sure all entries are strings */
 
11351
    for(i=0; i<N; i++) {
 
11352
        PyObject *item;
 
11353
        int valid=1;
 
11354
        item = PySequence_GetItem(val, i);
 
11355
        valid = PyString_Check(item);
 
11356
        Py_DECREF(item);
 
11357
        if (!valid) {
 
11358
            PyErr_Format(PyExc_ValueError,
 
11359
                         "item #%d of names is of type %s and not string",
 
11360
                         i, item->ob_type->tp_name);
 
11361
            return -1;
 
11362
        }
 
11363
    }
 
11364
    /* Update dictionary keys in fields */
 
11365
    new_names = PySequence_Tuple(val);
 
11366
 
 
11367
    for(i=0; i<N; i++) {
 
11368
        PyObject *key;
 
11369
        PyObject *item;
 
11370
        PyObject *new_key;
 
11371
        key = PyTuple_GET_ITEM(self->names, i);
 
11372
        /* Borrowed reference to item */
 
11373
        item = PyDict_GetItem(self->fields, key);
 
11374
        new_key = PyTuple_GET_ITEM(new_names, i);
 
11375
        PyDict_SetItem(self->fields, new_key, item);
 
11376
        PyDict_DelItem(self->fields, key);
 
11377
    }
 
11378
 
 
11379
    /* Replace names */
 
11380
    Py_DECREF(self->names);
 
11381
    self->names = new_names;
 
11382
 
 
11383
    return 0;
10845
11384
}
10846
11385
 
10847
11386
static PyGetSetDef arraydescr_getsets[] = {
10848
 
        {"subdtype",
10849
 
         (getter)arraydescr_subdescr_get,
10850
 
         NULL, NULL},
10851
 
        {"descr",
10852
 
         (getter)arraydescr_protocol_descr_get,
10853
 
         NULL, NULL},
10854
 
        {"str",
10855
 
         (getter)arraydescr_protocol_typestr_get,
10856
 
         NULL, NULL},
10857
 
        {"name",
10858
 
         (getter)arraydescr_typename_get,
10859
 
         NULL, NULL},
10860
 
        {"base",
10861
 
         (getter)arraydescr_base_get,
10862
 
         NULL, NULL},
10863
 
        {"shape",
10864
 
         (getter)arraydescr_shape_get,
10865
 
         NULL, NULL},
10866
 
        {"isbuiltin",
10867
 
         (getter)arraydescr_isbuiltin_get,
10868
 
         NULL, NULL},
10869
 
        {"isnative",
10870
 
         (getter)arraydescr_isnative_get,
10871
 
         NULL, NULL},
10872
 
        {"fields",
10873
 
         (getter)arraydescr_fields_get,
10874
 
         NULL, NULL},
10875
 
        {"hasobject",
10876
 
         (getter)arraydescr_hasobject_get,
10877
 
         NULL, NULL},
10878
 
        {NULL, NULL, NULL, NULL},
 
11387
    {"subdtype",
 
11388
     (getter)arraydescr_subdescr_get,
 
11389
     NULL, NULL},
 
11390
    {"descr",
 
11391
     (getter)arraydescr_protocol_descr_get,
 
11392
     NULL, NULL},
 
11393
    {"str",
 
11394
     (getter)arraydescr_protocol_typestr_get,
 
11395
     NULL, NULL},
 
11396
    {"name",
 
11397
     (getter)arraydescr_typename_get,
 
11398
     NULL, NULL},
 
11399
    {"base",
 
11400
     (getter)arraydescr_base_get,
 
11401
     NULL, NULL},
 
11402
    {"shape",
 
11403
     (getter)arraydescr_shape_get,
 
11404
     NULL, NULL},
 
11405
    {"isbuiltin",
 
11406
     (getter)arraydescr_isbuiltin_get,
 
11407
     NULL, NULL},
 
11408
    {"isnative",
 
11409
     (getter)arraydescr_isnative_get,
 
11410
     NULL, NULL},
 
11411
    {"fields",
 
11412
     (getter)arraydescr_fields_get,
 
11413
     NULL, NULL},
 
11414
    {"names",
 
11415
     (getter)arraydescr_names_get,
 
11416
     (setter)arraydescr_names_set,
 
11417
     NULL},
 
11418
    {"hasobject",
 
11419
     (getter)arraydescr_hasobject_get,
 
11420
     NULL, NULL},
 
11421
    {NULL, NULL, NULL, NULL},
10879
11422
};
10880
11423
 
10881
11424
static PyObject *
10882
11425
arraydescr_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
10883
11426
{
10884
 
        PyObject *odescr;
10885
 
        PyArray_Descr *descr, *conv;
10886
 
        Bool align=FALSE;
10887
 
        Bool copy=FALSE;
10888
 
        static char *kwlist[] = {"dtype", "align", "copy", NULL};
10889
 
 
10890
 
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&O&",
10891
 
                                         kwlist, &odescr, 
10892
 
                                         PyArray_BoolConverter, &align,
10893
 
                                         PyArray_BoolConverter, &copy))
10894
 
                return NULL;
10895
 
 
10896
 
        if (align) {
10897
 
                if (!PyArray_DescrAlignConverter(odescr, &conv))
10898
 
                        return NULL;
10899
 
        }
10900
 
        else if (!PyArray_DescrConverter(odescr, &conv))
10901
 
                return NULL;
10902
 
        /* Get a new copy of it unless it's already a copy */
10903
 
        if (copy && conv->fields == Py_None) {
10904
 
                descr = PyArray_DescrNew(conv);
10905
 
                Py_DECREF(conv);
10906
 
                conv = descr;
10907
 
        }
10908
 
        return (PyObject *)conv;
 
11427
    PyObject *odescr;
 
11428
    PyArray_Descr *descr, *conv;
 
11429
    Bool align=FALSE;
 
11430
    Bool copy=FALSE;
 
11431
    static char *kwlist[] = {"dtype", "align", "copy", NULL};
 
11432
 
 
11433
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&O&",
 
11434
                                     kwlist, &odescr,
 
11435
                                     PyArray_BoolConverter, &align,
 
11436
                                     PyArray_BoolConverter, &copy))
 
11437
        return NULL;
 
11438
 
 
11439
    if (align) {
 
11440
        if (!PyArray_DescrAlignConverter(odescr, &conv))
 
11441
            return NULL;
 
11442
    }
 
11443
    else if (!PyArray_DescrConverter(odescr, &conv))
 
11444
        return NULL;
 
11445
    /* Get a new copy of it unless it's already a copy */
 
11446
    if (copy && conv->fields == Py_None) {
 
11447
        descr = PyArray_DescrNew(conv);
 
11448
        Py_DECREF(conv);
 
11449
        conv = descr;
 
11450
    }
 
11451
    return (PyObject *)conv;
10909
11452
}
10910
11453
 
10911
11454
 
10913
11456
static PyObject *
10914
11457
arraydescr_reduce(PyArray_Descr *self, PyObject *args)
10915
11458
{
10916
 
        /* version number of this pickle type. Increment if we need to
10917
 
           change the format. Be sure to handle the old versions in
10918
 
           arraydescr_setstate. */
10919
 
        const int version = 3;
10920
 
        PyObject *ret, *mod, *obj;
10921
 
        PyObject *state;
10922
 
        char endian;
10923
 
        int elsize, alignment;
10924
 
 
10925
 
        ret = PyTuple_New(3);
10926
 
        if (ret == NULL) return NULL;
10927
 
        mod = PyImport_ImportModule("numpy.core.multiarray");
10928
 
        if (mod == NULL) {Py_DECREF(ret); return NULL;}
10929
 
        obj = PyObject_GetAttrString(mod, "dtype");
10930
 
        Py_DECREF(mod);
10931
 
        if (obj == NULL) {Py_DECREF(ret); return NULL;}
10932
 
        PyTuple_SET_ITEM(ret, 0, obj);
10933
 
        if (PyTypeNum_ISUSERDEF(self->type_num) ||              \
10934
 
            ((self->type_num == PyArray_VOID &&                 \
10935
 
              self->typeobj != &PyVoidArrType_Type))) {
10936
 
                obj = (PyObject *)self->typeobj;
10937
 
                Py_INCREF(obj);
10938
 
        }
10939
 
        else {
10940
 
                elsize = self->elsize;
10941
 
                if (self->type_num == PyArray_UNICODE) {
10942
 
                        elsize >>= 2;
10943
 
                }
10944
 
                obj = PyString_FromFormat("%c%d",self->kind, elsize);
10945
 
        }
10946
 
        PyTuple_SET_ITEM(ret, 1, Py_BuildValue("(Nii)", obj, 0, 1));
10947
 
 
10948
 
        /* Now return the state which is at least
10949
 
           byteorder, subarray, and fields */
10950
 
        endian = self->byteorder;
10951
 
        if (endian == '=') {
10952
 
                endian = '<';
10953
 
                if (!PyArray_IsNativeByteOrder(endian)) endian = '>';
10954
 
        }
10955
 
        state = PyTuple_New(8);
10956
 
        PyTuple_SET_ITEM(state, 0, PyInt_FromLong(version));
10957
 
        PyTuple_SET_ITEM(state, 1, PyString_FromFormat("%c", endian));
10958
 
        PyTuple_SET_ITEM(state, 2, arraydescr_subdescr_get(self));
10959
 
        if (self->names) {
10960
 
                Py_INCREF(self->names);
10961
 
                Py_INCREF(self->fields);
10962
 
                PyTuple_SET_ITEM(state, 3, self->names);
10963
 
                PyTuple_SET_ITEM(state, 4, self->fields);
10964
 
        }
10965
 
        else {
10966
 
                PyTuple_SET_ITEM(state, 3, Py_None);
10967
 
                PyTuple_SET_ITEM(state, 4, Py_None);
10968
 
                Py_INCREF(Py_None);
10969
 
                Py_INCREF(Py_None);
10970
 
        }
10971
 
 
10972
 
        /* for extended types it also includes elsize and alignment */
10973
 
        if (PyTypeNum_ISEXTENDED(self->type_num)) {
10974
 
                elsize = self->elsize;
10975
 
                alignment = self->alignment;
10976
 
        }
10977
 
        else {elsize = -1; alignment = -1;}
10978
 
 
10979
 
        PyTuple_SET_ITEM(state, 5, PyInt_FromLong(elsize));
10980
 
        PyTuple_SET_ITEM(state, 6, PyInt_FromLong(alignment));
10981
 
        PyTuple_SET_ITEM(state, 7, PyInt_FromLong(self->hasobject));
10982
 
 
10983
 
        PyTuple_SET_ITEM(ret, 2, state);
10984
 
        return ret;
 
11459
    /* version number of this pickle type. Increment if we need to
 
11460
       change the format. Be sure to handle the old versions in
 
11461
       arraydescr_setstate. */
 
11462
    const int version = 3;
 
11463
    PyObject *ret, *mod, *obj;
 
11464
    PyObject *state;
 
11465
    char endian;
 
11466
    int elsize, alignment;
 
11467
 
 
11468
    ret = PyTuple_New(3);
 
11469
    if (ret == NULL) return NULL;
 
11470
    mod = PyImport_ImportModule("numpy.core.multiarray");
 
11471
    if (mod == NULL) {Py_DECREF(ret); return NULL;}
 
11472
    obj = PyObject_GetAttrString(mod, "dtype");
 
11473
    Py_DECREF(mod);
 
11474
    if (obj == NULL) {Py_DECREF(ret); return NULL;}
 
11475
    PyTuple_SET_ITEM(ret, 0, obj);
 
11476
    if (PyTypeNum_ISUSERDEF(self->type_num) ||              \
 
11477
        ((self->type_num == PyArray_VOID &&                 \
 
11478
          self->typeobj != &PyVoidArrType_Type))) {
 
11479
        obj = (PyObject *)self->typeobj;
 
11480
        Py_INCREF(obj);
 
11481
    }
 
11482
    else {
 
11483
        elsize = self->elsize;
 
11484
        if (self->type_num == PyArray_UNICODE) {
 
11485
            elsize >>= 2;
 
11486
        }
 
11487
        obj = PyString_FromFormat("%c%d",self->kind, elsize);
 
11488
    }
 
11489
    PyTuple_SET_ITEM(ret, 1, Py_BuildValue("(Nii)", obj, 0, 1));
 
11490
 
 
11491
    /* Now return the state which is at least
 
11492
       byteorder, subarray, and fields */
 
11493
    endian = self->byteorder;
 
11494
    if (endian == '=') {
 
11495
        endian = '<';
 
11496
        if (!PyArray_IsNativeByteOrder(endian)) endian = '>';
 
11497
    }
 
11498
    state = PyTuple_New(8);
 
11499
    PyTuple_SET_ITEM(state, 0, PyInt_FromLong(version));
 
11500
    PyTuple_SET_ITEM(state, 1, PyString_FromFormat("%c", endian));
 
11501
    PyTuple_SET_ITEM(state, 2, arraydescr_subdescr_get(self));
 
11502
    if (self->names) {
 
11503
        Py_INCREF(self->names);
 
11504
        Py_INCREF(self->fields);
 
11505
        PyTuple_SET_ITEM(state, 3, self->names);
 
11506
        PyTuple_SET_ITEM(state, 4, self->fields);
 
11507
    }
 
11508
    else {
 
11509
        PyTuple_SET_ITEM(state, 3, Py_None);
 
11510
        PyTuple_SET_ITEM(state, 4, Py_None);
 
11511
        Py_INCREF(Py_None);
 
11512
        Py_INCREF(Py_None);
 
11513
    }
 
11514
 
 
11515
    /* for extended types it also includes elsize and alignment */
 
11516
    if (PyTypeNum_ISEXTENDED(self->type_num)) {
 
11517
        elsize = self->elsize;
 
11518
        alignment = self->alignment;
 
11519
    }
 
11520
    else {elsize = -1; alignment = -1;}
 
11521
 
 
11522
    PyTuple_SET_ITEM(state, 5, PyInt_FromLong(elsize));
 
11523
    PyTuple_SET_ITEM(state, 6, PyInt_FromLong(alignment));
 
11524
    PyTuple_SET_ITEM(state, 7, PyInt_FromLong(self->hasobject));
 
11525
 
 
11526
    PyTuple_SET_ITEM(ret, 2, state);
 
11527
    return ret;
10985
11528
}
10986
11529
 
10987
11530
/* returns 1 if this data-type has an object portion
10988
11531
   used when setting the state because hasobject is not stored.
10989
 
 */
 
11532
*/
10990
11533
static int
10991
11534
_descr_find_object(PyArray_Descr *self)
10992
11535
{
10993
 
        if (self->hasobject || self->type_num == PyArray_OBJECT || 
10994
 
            self->kind == 'O')
 
11536
    if (self->hasobject || self->type_num == PyArray_OBJECT ||
 
11537
        self->kind == 'O')
 
11538
        return NPY_OBJECT_DTYPE_FLAGS;
 
11539
    if (PyDescr_HASFIELDS(self)) {
 
11540
        PyObject *key, *value, *title=NULL;
 
11541
        PyArray_Descr *new;
 
11542
        int offset;
 
11543
        Py_ssize_t pos=0;
 
11544
        while (PyDict_Next(self->fields, &pos, &key, &value)) {
 
11545
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
11546
                                  &title)) {
 
11547
                PyErr_Clear();
 
11548
                return 0;
 
11549
            }
 
11550
            if (_descr_find_object(new)) {
 
11551
                new->hasobject = NPY_OBJECT_DTYPE_FLAGS;
10995
11552
                return NPY_OBJECT_DTYPE_FLAGS;
10996
 
        if (PyDescr_HASFIELDS(self)) {
10997
 
                PyObject *key, *value, *title=NULL;
10998
 
                PyArray_Descr *new;
10999
 
                int offset;
11000
 
                Py_ssize_t pos=0;
11001
 
                while (PyDict_Next(self->fields, &pos, &key, &value)) {
11002
 
                        if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
11003
 
                                              &title)) {
11004
 
                                PyErr_Clear();
11005
 
                                return 0;
11006
 
                        }
11007
 
                        if (_descr_find_object(new)) {
11008
 
                                new->hasobject = NPY_OBJECT_DTYPE_FLAGS;
11009
 
                                return NPY_OBJECT_DTYPE_FLAGS;
11010
 
                        }
11011
 
                }
 
11553
            }
11012
11554
        }
11013
 
        return 0;
 
11555
    }
 
11556
    return 0;
11014
11557
}
11015
11558
 
11016
11559
/* state is at least byteorder, subarray, and fields but could include elsize
11020
11563
static PyObject *
11021
11564
arraydescr_setstate(PyArray_Descr *self, PyObject *args)
11022
11565
{
11023
 
        int elsize = -1, alignment = -1;
11024
 
        int version = 3;
11025
 
        char endian;
11026
 
        PyObject *subarray, *fields, *names=NULL;
11027
 
        int incref_names = 1;
11028
 
        int dtypeflags=0;
11029
 
 
11030
 
        if (self->fields == Py_None) {Py_INCREF(Py_None); return Py_None;}
11031
 
 
11032
 
        if (PyTuple_GET_SIZE(args) != 1 || 
11033
 
            !(PyTuple_Check(PyTuple_GET_ITEM(args, 0)))) {
11034
 
                PyErr_BadInternalCall();
11035
 
                return NULL;
11036
 
        }
11037
 
        switch (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))) {
11038
 
        case 8:
11039
 
                if (!PyArg_ParseTuple(args, "(icOOOiii)", &version, &endian, 
11040
 
                                      &subarray, &names, &fields, &elsize, 
11041
 
                                      &alignment, &dtypeflags)) {
11042
 
                        return NULL;
11043
 
                }
11044
 
                break;
11045
 
        case 7:
11046
 
                if (!PyArg_ParseTuple(args, "(icOOOii)", &version, &endian, 
11047
 
                                      &subarray, &names, &fields, &elsize, 
11048
 
                                      &alignment)) {
11049
 
                        return NULL;
11050
 
                }
11051
 
                break;
11052
 
        case 6:
11053
 
                if (!PyArg_ParseTuple(args, "(icOOii)", &version, 
11054
 
                                      &endian, &subarray, &fields, 
11055
 
                                      &elsize, &alignment)) {
11056
 
                        PyErr_Clear();
11057
 
                }
11058
 
                break;
11059
 
        case 5:
11060
 
                version = 0;
11061
 
                if (!PyArg_ParseTuple(args, "(cOOii)", 
11062
 
                                      &endian, &subarray, &fields, &elsize, 
11063
 
                                      &alignment)) {
11064
 
                        return NULL;
11065
 
                }
11066
 
                break;
11067
 
        default:
11068
 
                version = -1; /* raise an error */
11069
 
        }
11070
 
        
11071
 
        /* If we ever need another pickle format, increment the version
11072
 
           number. But we should still be able to handle the old versions.
11073
 
        */
11074
 
        if (version < 0 || version > 3) {
11075
 
            PyErr_Format(PyExc_ValueError,
11076
 
                         "can't handle version %d of numpy.dtype pickle",
11077
 
                         version);
11078
 
            return NULL;
11079
 
        }
11080
 
 
11081
 
        if (version == 1 || version == 0) {
11082
 
            if (fields != Py_None) {
11083
 
                PyObject *key, *list;
11084
 
                key = PyInt_FromLong(-1);
11085
 
                list = PyDict_GetItem(fields, key);
11086
 
                if (!list) return NULL;
11087
 
                    Py_INCREF(list);
11088
 
                    names = list;
11089
 
                    PyDict_DelItem(fields, key);
11090
 
                    incref_names = 0;
11091
 
            }
11092
 
            else {
11093
 
                names = Py_None;
11094
 
            }
11095
 
        }
11096
 
 
11097
 
 
11098
 
        if ((fields == Py_None && names != Py_None) ||  \
11099
 
            (names == Py_None && fields != Py_None)) {
11100
 
            PyErr_Format(PyExc_ValueError,
11101
 
                         "inconsistent fields and names");
11102
 
            return NULL;
11103
 
        }
11104
 
 
11105
 
        if (endian != '|' &&
11106
 
            PyArray_IsNativeByteOrder(endian)) endian = '=';
11107
 
 
11108
 
        self->byteorder = endian;
11109
 
        if (self->subarray) {
11110
 
                Py_XDECREF(self->subarray->base);
11111
 
                Py_XDECREF(self->subarray->shape);
11112
 
                _pya_free(self->subarray);
11113
 
        }
11114
 
        self->subarray = NULL;
11115
 
 
11116
 
        if (subarray != Py_None) {
11117
 
                self->subarray = _pya_malloc(sizeof(PyArray_ArrayDescr));
11118
 
                self->subarray->base = (PyArray_Descr *)PyTuple_GET_ITEM(subarray, 0);
11119
 
                Py_INCREF(self->subarray->base);
11120
 
                self->subarray->shape = PyTuple_GET_ITEM(subarray, 1);
11121
 
                Py_INCREF(self->subarray->shape);
11122
 
        }
11123
 
 
 
11566
    int elsize = -1, alignment = -1;
 
11567
    int version = 3;
 
11568
    char endian;
 
11569
    PyObject *subarray, *fields, *names=NULL;
 
11570
    int incref_names = 1;
 
11571
    int dtypeflags=0;
 
11572
 
 
11573
    if (self->fields == Py_None) {Py_INCREF(Py_None); return Py_None;}
 
11574
 
 
11575
    if (PyTuple_GET_SIZE(args) != 1 ||
 
11576
        !(PyTuple_Check(PyTuple_GET_ITEM(args, 0)))) {
 
11577
        PyErr_BadInternalCall();
 
11578
        return NULL;
 
11579
    }
 
11580
    switch (PyTuple_GET_SIZE(PyTuple_GET_ITEM(args,0))) {
 
11581
    case 8:
 
11582
        if (!PyArg_ParseTuple(args, "(icOOOiii)", &version, &endian,
 
11583
                              &subarray, &names, &fields, &elsize,
 
11584
                              &alignment, &dtypeflags)) {
 
11585
            return NULL;
 
11586
        }
 
11587
        break;
 
11588
    case 7:
 
11589
        if (!PyArg_ParseTuple(args, "(icOOOii)", &version, &endian,
 
11590
                              &subarray, &names, &fields, &elsize,
 
11591
                              &alignment)) {
 
11592
            return NULL;
 
11593
        }
 
11594
        break;
 
11595
    case 6:
 
11596
        if (!PyArg_ParseTuple(args, "(icOOii)", &version,
 
11597
                              &endian, &subarray, &fields,
 
11598
                              &elsize, &alignment)) {
 
11599
            PyErr_Clear();
 
11600
        }
 
11601
        break;
 
11602
    case 5:
 
11603
        version = 0;
 
11604
        if (!PyArg_ParseTuple(args, "(cOOii)",
 
11605
                              &endian, &subarray, &fields, &elsize,
 
11606
                              &alignment)) {
 
11607
            return NULL;
 
11608
        }
 
11609
        break;
 
11610
    default:
 
11611
        version = -1; /* raise an error */
 
11612
    }
 
11613
 
 
11614
    /* If we ever need another pickle format, increment the version
 
11615
       number. But we should still be able to handle the old versions.
 
11616
    */
 
11617
    if (version < 0 || version > 3) {
 
11618
        PyErr_Format(PyExc_ValueError,
 
11619
                     "can't handle version %d of numpy.dtype pickle",
 
11620
                     version);
 
11621
        return NULL;
 
11622
    }
 
11623
 
 
11624
    if (version == 1 || version == 0) {
11124
11625
        if (fields != Py_None) {
11125
 
                Py_XDECREF(self->fields);
11126
 
                self->fields = fields;
11127
 
                Py_INCREF(fields);
11128
 
                Py_XDECREF(self->names);
11129
 
                self->names = names;
11130
 
                if (incref_names)
11131
 
                    Py_INCREF(names);
11132
 
        }
11133
 
 
11134
 
        if (PyTypeNum_ISEXTENDED(self->type_num)) {
11135
 
                self->elsize = elsize;
11136
 
                self->alignment = alignment;
11137
 
        }
11138
 
 
11139
 
        self->hasobject = dtypeflags;
11140
 
        if (version < 3) {
11141
 
                self->hasobject = _descr_find_object(self);
11142
 
        }
11143
 
        Py_INCREF(Py_None);
11144
 
        return Py_None;
 
11626
            PyObject *key, *list;
 
11627
            key = PyInt_FromLong(-1);
 
11628
            list = PyDict_GetItem(fields, key);
 
11629
            if (!list) return NULL;
 
11630
            Py_INCREF(list);
 
11631
            names = list;
 
11632
            PyDict_DelItem(fields, key);
 
11633
            incref_names = 0;
 
11634
        }
 
11635
        else {
 
11636
            names = Py_None;
 
11637
        }
 
11638
    }
 
11639
 
 
11640
 
 
11641
    if ((fields == Py_None && names != Py_None) ||  \
 
11642
        (names == Py_None && fields != Py_None)) {
 
11643
        PyErr_Format(PyExc_ValueError,
 
11644
                     "inconsistent fields and names");
 
11645
        return NULL;
 
11646
    }
 
11647
 
 
11648
    if (endian != '|' &&
 
11649
        PyArray_IsNativeByteOrder(endian)) endian = '=';
 
11650
 
 
11651
    self->byteorder = endian;
 
11652
    if (self->subarray) {
 
11653
        Py_XDECREF(self->subarray->base);
 
11654
        Py_XDECREF(self->subarray->shape);
 
11655
        _pya_free(self->subarray);
 
11656
    }
 
11657
    self->subarray = NULL;
 
11658
 
 
11659
    if (subarray != Py_None) {
 
11660
        self->subarray = _pya_malloc(sizeof(PyArray_ArrayDescr));
 
11661
        self->subarray->base = (PyArray_Descr *)PyTuple_GET_ITEM(subarray, 0);
 
11662
        Py_INCREF(self->subarray->base);
 
11663
        self->subarray->shape = PyTuple_GET_ITEM(subarray, 1);
 
11664
        Py_INCREF(self->subarray->shape);
 
11665
    }
 
11666
 
 
11667
    if (fields != Py_None) {
 
11668
        Py_XDECREF(self->fields);
 
11669
        self->fields = fields;
 
11670
        Py_INCREF(fields);
 
11671
        Py_XDECREF(self->names);
 
11672
        self->names = names;
 
11673
        if (incref_names)
 
11674
            Py_INCREF(names);
 
11675
    }
 
11676
 
 
11677
    if (PyTypeNum_ISEXTENDED(self->type_num)) {
 
11678
        self->elsize = elsize;
 
11679
        self->alignment = alignment;
 
11680
    }
 
11681
 
 
11682
    self->hasobject = dtypeflags;
 
11683
    if (version < 3) {
 
11684
        self->hasobject = _descr_find_object(self);
 
11685
    }
 
11686
    Py_INCREF(Py_None);
 
11687
    return Py_None;
11145
11688
}
11146
11689
 
11147
11690
 
11148
11691
/* returns a copy of the PyArray_Descr structure with the byteorder
11149
11692
   altered:
11150
 
    no arguments:  The byteorder is swapped (in all subfields as well)
11151
 
    single argument:  The byteorder is forced to the given state
11152
 
                      (in all subfields as well)
11153
 
 
11154
 
                      Valid states:  ('big', '>') or ('little' or '<')
11155
 
                                     ('native', or '=')
11156
 
 
11157
 
                   If a descr structure with | is encountered it's own
11158
 
                   byte-order is not changed but any fields are:
 
11693
   no arguments:  The byteorder is swapped (in all subfields as well)
 
11694
   single argument:  The byteorder is forced to the given state
 
11695
   (in all subfields as well)
 
11696
 
 
11697
   Valid states:  ('big', '>') or ('little' or '<')
 
11698
   ('native', or '=')
 
11699
 
 
11700
   If a descr structure with | is encountered it's own
 
11701
   byte-order is not changed but any fields are:
11159
11702
*/
11160
11703
 
11161
11704
/*OBJECT_API
11162
11705
  Deep bytorder change of a data-type descriptor
11163
11706
  *** Leaves reference count of self unchanged --- does not DECREF self ***
11164
 
*/
 
11707
  */
11165
11708
static PyArray_Descr *
11166
11709
PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian)
11167
11710
{
11168
 
        PyArray_Descr *new;
11169
 
        char endian;
11170
 
 
11171
 
        new = PyArray_DescrNew(self);
11172
 
        endian = new->byteorder;
11173
 
        if (endian != PyArray_IGNORE) {
11174
 
                if (newendian == PyArray_SWAP) {  /* swap byteorder */
11175
 
                        if PyArray_ISNBO(endian) endian = PyArray_OPPBYTE;
11176
 
                        else endian = PyArray_NATBYTE;
11177
 
                        new->byteorder = endian;
11178
 
                }
11179
 
                else if (newendian != PyArray_IGNORE) {
11180
 
                        new->byteorder = newendian;
11181
 
                }
11182
 
        }
11183
 
        if (new->names) {
11184
 
                PyObject *newfields;
11185
 
                PyObject *key, *value;
11186
 
                PyObject *newvalue;
11187
 
                PyObject *old;
11188
 
                PyArray_Descr *newdescr;
11189
 
                Py_ssize_t pos = 0;
11190
 
                int len, i;
11191
 
                newfields = PyDict_New();
11192
 
                /* make new dictionary with replaced */
11193
 
                /* PyArray_Descr Objects */
11194
 
                while(PyDict_Next(self->fields, &pos, &key, &value)) {
11195
 
                        if (!PyString_Check(key) ||          \
11196
 
                            !PyTuple_Check(value) ||                    \
11197
 
                            ((len=PyTuple_GET_SIZE(value)) < 2))
11198
 
                                continue;
11199
 
 
11200
 
                        old = PyTuple_GET_ITEM(value, 0);
11201
 
                        if (!PyArray_DescrCheck(old)) continue;
11202
 
                        newdescr = PyArray_DescrNewByteorder            \
11203
 
                                ((PyArray_Descr *)old, newendian);
11204
 
                        if (newdescr == NULL) {
11205
 
                                Py_DECREF(newfields); Py_DECREF(new);
11206
 
                                return NULL;
11207
 
                        }
11208
 
                        newvalue = PyTuple_New(len);
11209
 
                        PyTuple_SET_ITEM(newvalue, 0,           \
11210
 
                                         (PyObject *)newdescr);
11211
 
                        for(i=1; i<len; i++) {
11212
 
                                old = PyTuple_GET_ITEM(value, i);
11213
 
                                Py_INCREF(old);
11214
 
                                PyTuple_SET_ITEM(newvalue, i, old);
11215
 
                        }
11216
 
                        PyDict_SetItem(newfields, key, newvalue);
11217
 
                        Py_DECREF(newvalue);
11218
 
                }
11219
 
                Py_DECREF(new->fields);
11220
 
                new->fields = newfields;
11221
 
        }
11222
 
        if (new->subarray) {
11223
 
                Py_DECREF(new->subarray->base);
11224
 
                new->subarray->base = PyArray_DescrNewByteorder \
11225
 
                        (self->subarray->base, newendian);
11226
 
        }
11227
 
        return new;
 
11711
    PyArray_Descr *new;
 
11712
    char endian;
 
11713
 
 
11714
    new = PyArray_DescrNew(self);
 
11715
    endian = new->byteorder;
 
11716
    if (endian != PyArray_IGNORE) {
 
11717
        if (newendian == PyArray_SWAP) {  /* swap byteorder */
 
11718
            if PyArray_ISNBO(endian) endian = PyArray_OPPBYTE;
 
11719
            else endian = PyArray_NATBYTE;
 
11720
            new->byteorder = endian;
 
11721
        }
 
11722
        else if (newendian != PyArray_IGNORE) {
 
11723
            new->byteorder = newendian;
 
11724
        }
 
11725
    }
 
11726
    if (new->names) {
 
11727
        PyObject *newfields;
 
11728
        PyObject *key, *value;
 
11729
        PyObject *newvalue;
 
11730
        PyObject *old;
 
11731
        PyArray_Descr *newdescr;
 
11732
        Py_ssize_t pos = 0;
 
11733
        int len, i;
 
11734
        newfields = PyDict_New();
 
11735
        /* make new dictionary with replaced */
 
11736
        /* PyArray_Descr Objects */
 
11737
        while(PyDict_Next(self->fields, &pos, &key, &value)) {
 
11738
            if (!PyString_Check(key) ||          \
 
11739
                !PyTuple_Check(value) ||                    \
 
11740
                ((len=PyTuple_GET_SIZE(value)) < 2))
 
11741
                continue;
 
11742
 
 
11743
            old = PyTuple_GET_ITEM(value, 0);
 
11744
            if (!PyArray_DescrCheck(old)) continue;
 
11745
            newdescr = PyArray_DescrNewByteorder            \
 
11746
                ((PyArray_Descr *)old, newendian);
 
11747
            if (newdescr == NULL) {
 
11748
                Py_DECREF(newfields); Py_DECREF(new);
 
11749
                return NULL;
 
11750
            }
 
11751
            newvalue = PyTuple_New(len);
 
11752
            PyTuple_SET_ITEM(newvalue, 0,           \
 
11753
                             (PyObject *)newdescr);
 
11754
            for(i=1; i<len; i++) {
 
11755
                old = PyTuple_GET_ITEM(value, i);
 
11756
                Py_INCREF(old);
 
11757
                PyTuple_SET_ITEM(newvalue, i, old);
 
11758
            }
 
11759
            PyDict_SetItem(newfields, key, newvalue);
 
11760
            Py_DECREF(newvalue);
 
11761
        }
 
11762
        Py_DECREF(new->fields);
 
11763
        new->fields = newfields;
 
11764
    }
 
11765
    if (new->subarray) {
 
11766
        Py_DECREF(new->subarray->base);
 
11767
        new->subarray->base = PyArray_DescrNewByteorder \
 
11768
            (self->subarray->base, newendian);
 
11769
    }
 
11770
    return new;
11228
11771
}
11229
11772
 
11230
11773
 
11231
11774
static PyObject *
11232
11775
arraydescr_newbyteorder(PyArray_Descr *self, PyObject *args)
11233
11776
{
11234
 
        char endian=PyArray_SWAP;
11235
 
 
11236
 
        if (!PyArg_ParseTuple(args, "|O&", PyArray_ByteorderConverter,
11237
 
                              &endian)) return NULL;
11238
 
 
11239
 
        return (PyObject *)PyArray_DescrNewByteorder(self, endian);
 
11777
    char endian=PyArray_SWAP;
 
11778
 
 
11779
    if (!PyArg_ParseTuple(args, "|O&", PyArray_ByteorderConverter,
 
11780
                          &endian)) return NULL;
 
11781
 
 
11782
    return (PyObject *)PyArray_DescrNewByteorder(self, endian);
11240
11783
}
11241
11784
 
11242
11785
static PyMethodDef arraydescr_methods[] = {
11243
 
        /* for pickling */
11244
 
        {"__reduce__", (PyCFunction)arraydescr_reduce, METH_VARARGS,
11245
 
         NULL},
11246
 
        {"__setstate__", (PyCFunction)arraydescr_setstate, METH_VARARGS,
11247
 
         NULL},
11248
 
        {"newbyteorder", (PyCFunction)arraydescr_newbyteorder, METH_VARARGS,
11249
 
         NULL},
11250
 
        {NULL,          NULL}           /* sentinel */
 
11786
    /* for pickling */
 
11787
    {"__reduce__", (PyCFunction)arraydescr_reduce, METH_VARARGS,
 
11788
     NULL},
 
11789
    {"__setstate__", (PyCFunction)arraydescr_setstate, METH_VARARGS,
 
11790
     NULL},
 
11791
    {"newbyteorder", (PyCFunction)arraydescr_newbyteorder, METH_VARARGS,
 
11792
     NULL},
 
11793
    {NULL,          NULL}           /* sentinel */
11251
11794
};
11252
11795
 
11253
11796
static PyObject *
11254
11797
arraydescr_str(PyArray_Descr *self)
11255
11798
{
11256
 
        PyObject *sub;
 
11799
    PyObject *sub;
11257
11800
 
11258
 
        if (self->names) {
11259
 
                PyObject *lst;
11260
 
                lst = arraydescr_protocol_descr_get(self);
11261
 
                if (!lst) {
11262
 
                        sub = PyString_FromString("<err>");
11263
 
                        PyErr_Clear();
11264
 
                }
11265
 
                else sub = PyObject_Str(lst);
11266
 
                Py_XDECREF(lst);
11267
 
                if (self->type_num != PyArray_VOID) {
11268
 
                        PyObject *p;
11269
 
                        PyObject *t=PyString_FromString("'");
11270
 
                        p = arraydescr_protocol_typestr_get(self);
11271
 
                        PyString_Concat(&p, t);
11272
 
                        PyString_ConcatAndDel(&t, p);
11273
 
                        p = PyString_FromString("(");
11274
 
                        PyString_ConcatAndDel(&p, t);
11275
 
                        PyString_ConcatAndDel(&p, PyString_FromString(", "));
11276
 
                        PyString_ConcatAndDel(&p, sub);
11277
 
                        PyString_ConcatAndDel(&p, PyString_FromString(")"));
11278
 
                        sub = p;
11279
 
                }
11280
 
        }
11281
 
        else if (self->subarray) {
11282
 
                PyObject *p;
11283
 
                PyObject *t = PyString_FromString("(");
11284
 
                PyObject *sh;
11285
 
                p = arraydescr_str(self->subarray->base);
11286
 
                if (!self->subarray->base->names && !self->subarray->base->subarray) {
11287
 
                        PyObject *t=PyString_FromString("'");
11288
 
                        PyString_Concat(&p, t);
11289
 
                        PyString_ConcatAndDel(&t, p);
11290
 
                        p = t;
11291
 
                }
11292
 
                PyString_ConcatAndDel(&t, p);
11293
 
                PyString_ConcatAndDel(&t, PyString_FromString(","));
11294
 
                if (!PyTuple_Check(self->subarray->shape)) {
11295
 
                        sh = Py_BuildValue("(O)", self->subarray->shape);
11296
 
                }
11297
 
                else {
11298
 
                        sh = self->subarray->shape;
11299
 
                        Py_INCREF(sh);
11300
 
                }
11301
 
                PyString_ConcatAndDel(&t, PyObject_Str(sh));
11302
 
                Py_DECREF(sh);
11303
 
                PyString_ConcatAndDel(&t, PyString_FromString(")"));
11304
 
                sub = t;
11305
 
        }
11306
 
        else if (PyDataType_ISFLEXIBLE(self) || !PyArray_ISNBO(self->byteorder)) {
11307
 
                sub = arraydescr_protocol_typestr_get(self);
 
11801
    if (self->names) {
 
11802
        PyObject *lst;
 
11803
        lst = arraydescr_protocol_descr_get(self);
 
11804
        if (!lst) {
 
11805
            sub = PyString_FromString("<err>");
 
11806
            PyErr_Clear();
 
11807
        }
 
11808
        else sub = PyObject_Str(lst);
 
11809
        Py_XDECREF(lst);
 
11810
        if (self->type_num != PyArray_VOID) {
 
11811
            PyObject *p;
 
11812
            PyObject *t=PyString_FromString("'");
 
11813
            p = arraydescr_protocol_typestr_get(self);
 
11814
            PyString_Concat(&p, t);
 
11815
            PyString_ConcatAndDel(&t, p);
 
11816
            p = PyString_FromString("(");
 
11817
            PyString_ConcatAndDel(&p, t);
 
11818
            PyString_ConcatAndDel(&p, PyString_FromString(", "));
 
11819
            PyString_ConcatAndDel(&p, sub);
 
11820
            PyString_ConcatAndDel(&p, PyString_FromString(")"));
 
11821
            sub = p;
 
11822
        }
 
11823
    }
 
11824
    else if (self->subarray) {
 
11825
        PyObject *p;
 
11826
        PyObject *t = PyString_FromString("(");
 
11827
        PyObject *sh;
 
11828
        p = arraydescr_str(self->subarray->base);
 
11829
        if (!self->subarray->base->names && !self->subarray->base->subarray) {
 
11830
            PyObject *t=PyString_FromString("'");
 
11831
            PyString_Concat(&p, t);
 
11832
            PyString_ConcatAndDel(&t, p);
 
11833
            p = t;
 
11834
        }
 
11835
        PyString_ConcatAndDel(&t, p);
 
11836
        PyString_ConcatAndDel(&t, PyString_FromString(","));
 
11837
        if (!PyTuple_Check(self->subarray->shape)) {
 
11838
            sh = Py_BuildValue("(O)", self->subarray->shape);
11308
11839
        }
11309
11840
        else {
11310
 
                sub = arraydescr_typename_get(self);
 
11841
            sh = self->subarray->shape;
 
11842
            Py_INCREF(sh);
11311
11843
        }
11312
 
        return sub;
 
11844
        PyString_ConcatAndDel(&t, PyObject_Str(sh));
 
11845
        Py_DECREF(sh);
 
11846
        PyString_ConcatAndDel(&t, PyString_FromString(")"));
 
11847
        sub = t;
 
11848
    }
 
11849
    else if (PyDataType_ISFLEXIBLE(self) || !PyArray_ISNBO(self->byteorder)) {
 
11850
        sub = arraydescr_protocol_typestr_get(self);
 
11851
    }
 
11852
    else {
 
11853
        sub = arraydescr_typename_get(self);
 
11854
    }
 
11855
    return sub;
11313
11856
}
11314
11857
 
11315
11858
static PyObject *
11316
11859
arraydescr_repr(PyArray_Descr *self)
11317
11860
{
11318
 
        PyObject *sub, *s;
11319
 
        s = PyString_FromString("dtype(");
11320
 
        sub = arraydescr_str(self);
11321
 
        if (!self->names && !self->subarray) {
11322
 
                PyObject *t=PyString_FromString("'");
11323
 
                PyString_Concat(&sub, t);
11324
 
                PyString_ConcatAndDel(&t, sub);
11325
 
                sub = t;
11326
 
        }
11327
 
        PyString_ConcatAndDel(&s, sub);
11328
 
        sub = PyString_FromString(")");
11329
 
        PyString_ConcatAndDel(&s, sub);
11330
 
        return s;
 
11861
    PyObject *sub, *s;
 
11862
    s = PyString_FromString("dtype(");
 
11863
    sub = arraydescr_str(self);
 
11864
    if (!self->names && !self->subarray) {
 
11865
        PyObject *t=PyString_FromString("'");
 
11866
        PyString_Concat(&sub, t);
 
11867
        PyString_ConcatAndDel(&t, sub);
 
11868
        sub = t;
 
11869
    }
 
11870
    PyString_ConcatAndDel(&s, sub);
 
11871
    sub = PyString_FromString(")");
 
11872
    PyString_ConcatAndDel(&s, sub);
 
11873
    return s;
11331
11874
}
11332
11875
 
11333
11876
static PyObject *
11334
11877
arraydescr_richcompare(PyArray_Descr *self, PyObject *other, int cmp_op)
11335
11878
{
11336
 
        PyArray_Descr *new=NULL;
11337
 
        PyObject *result = Py_NotImplemented;
11338
 
        if (!PyArray_DescrCheck(other)) {
11339
 
                if (PyArray_DescrConverter(other, &new) == PY_FAIL)
11340
 
                        return NULL;
11341
 
        }
11342
 
        else {
11343
 
                new = (PyArray_Descr *)other;
11344
 
                Py_INCREF(new);
11345
 
        }
11346
 
        switch (cmp_op) {
11347
 
        case Py_LT:
11348
 
                if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new))
11349
 
                        result = Py_True;
11350
 
                else
11351
 
                        result = Py_False;
11352
 
                break;
11353
 
        case Py_LE:
11354
 
                if (PyArray_CanCastTo(self, new))
11355
 
                        result = Py_True;
11356
 
                else
11357
 
                        result = Py_False;
11358
 
                break;
11359
 
        case Py_EQ:
11360
 
                if (PyArray_EquivTypes(self, new))
11361
 
                        result = Py_True;
11362
 
                else
11363
 
                        result = Py_False;
11364
 
                break;
11365
 
        case Py_NE:
11366
 
                if (PyArray_EquivTypes(self, new))
11367
 
                        result = Py_False;
11368
 
                else
11369
 
                        result = Py_True;
11370
 
                break;
11371
 
        case Py_GT:
11372
 
                if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(new, self))
11373
 
                        result = Py_True;
11374
 
                else
11375
 
                        result = Py_False;
11376
 
                break;
11377
 
        case Py_GE:
11378
 
                if (PyArray_CanCastTo(new, self))
11379
 
                        result = Py_True;
11380
 
                else
11381
 
                        result = Py_False;
11382
 
                break;
11383
 
        default:
11384
 
                result = Py_NotImplemented;
11385
 
        }
 
11879
    PyArray_Descr *new=NULL;
 
11880
    PyObject *result = Py_NotImplemented;
 
11881
    if (!PyArray_DescrCheck(other)) {
 
11882
        if (PyArray_DescrConverter(other, &new) == PY_FAIL)
 
11883
            return NULL;
 
11884
    }
 
11885
    else {
 
11886
        new = (PyArray_Descr *)other;
 
11887
        Py_INCREF(new);
 
11888
    }
 
11889
    switch (cmp_op) {
 
11890
    case Py_LT:
 
11891
        if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(self, new))
 
11892
            result = Py_True;
 
11893
        else
 
11894
            result = Py_False;
 
11895
        break;
 
11896
    case Py_LE:
 
11897
        if (PyArray_CanCastTo(self, new))
 
11898
            result = Py_True;
 
11899
        else
 
11900
            result = Py_False;
 
11901
        break;
 
11902
    case Py_EQ:
 
11903
        if (PyArray_EquivTypes(self, new))
 
11904
            result = Py_True;
 
11905
        else
 
11906
            result = Py_False;
 
11907
        break;
 
11908
    case Py_NE:
 
11909
        if (PyArray_EquivTypes(self, new))
 
11910
            result = Py_False;
 
11911
        else
 
11912
            result = Py_True;
 
11913
        break;
 
11914
    case Py_GT:
 
11915
        if (!PyArray_EquivTypes(self, new) && PyArray_CanCastTo(new, self))
 
11916
            result = Py_True;
 
11917
        else
 
11918
            result = Py_False;
 
11919
        break;
 
11920
    case Py_GE:
 
11921
        if (PyArray_CanCastTo(new, self))
 
11922
            result = Py_True;
 
11923
        else
 
11924
            result = Py_False;
 
11925
        break;
 
11926
    default:
 
11927
        result = Py_NotImplemented;
 
11928
    }
11386
11929
 
11387
 
        Py_XDECREF(new);
11388
 
        Py_INCREF(result);
11389
 
        return result;
 
11930
    Py_XDECREF(new);
 
11931
    Py_INCREF(result);
 
11932
    return result;
11390
11933
}
11391
11934
 
11392
11935
/*************************************************************************
11397
11940
descr_length(PyObject *self0)
11398
11941
{
11399
11942
 
11400
 
        PyArray_Descr *self = (PyArray_Descr *)self0;
 
11943
    PyArray_Descr *self = (PyArray_Descr *)self0;
11401
11944
 
11402
 
        if (self->names)
11403
 
                return PyDict_Size(self->fields);
11404
 
        else return 0;
 
11945
    if (self->names)
 
11946
        return PyTuple_GET_SIZE(self->names);
 
11947
    else return 0;
11405
11948
}
11406
11949
 
11407
11950
static PyObject *
11408
11951
descr_repeat(PyObject *self, Py_ssize_t length)
11409
11952
{
11410
 
        PyObject *tup;
11411
 
        PyArray_Descr *new;
11412
 
        if (length < 0)
11413
 
                return PyErr_Format(PyExc_ValueError,
 
11953
    PyObject *tup;
 
11954
    PyArray_Descr *new;
 
11955
    if (length < 0)
 
11956
        return PyErr_Format(PyExc_ValueError,
11414
11957
#if (PY_VERSION_HEX < 0x02050000)
11415
 
                                    "Array length must be >= 0, not %d",
 
11958
                            "Array length must be >= 0, not %d",
11416
11959
#else
11417
 
                                    "Array length must be >= 0, not %zd",
 
11960
                            "Array length must be >= 0, not %zd",
11418
11961
#endif
11419
 
                                    length);
11420
 
        tup = Py_BuildValue("O" NPY_SSIZE_T_PYFMT, self, length);
11421
 
        if (tup == NULL) return NULL;
11422
 
        PyArray_DescrConverter(tup, &new);
11423
 
        Py_DECREF(tup);
11424
 
        return (PyObject *)new;
 
11962
                            length);
 
11963
    tup = Py_BuildValue("O" NPY_SSIZE_T_PYFMT, self, length);
 
11964
    if (tup == NULL) return NULL;
 
11965
    PyArray_DescrConverter(tup, &new);
 
11966
    Py_DECREF(tup);
 
11967
    return (PyObject *)new;
11425
11968
}
11426
11969
 
11427
11970
static PyObject *
11428
11971
descr_subscript(PyArray_Descr *self, PyObject *op)
11429
11972
{
11430
11973
 
11431
 
        if (self->names) {
11432
 
                if (PyString_Check(op) || PyUnicode_Check(op)) {
11433
 
                        PyObject *obj;
11434
 
                        obj = PyDict_GetItem(self->fields, op);
11435
 
                        if (obj != NULL) {
11436
 
                                PyObject *descr;
11437
 
                                descr = PyTuple_GET_ITEM(obj, 0);
11438
 
                                Py_INCREF(descr);
11439
 
                                return descr;
11440
 
                        }
11441
 
                        else {
11442
 
                                PyErr_Format(PyExc_KeyError,
11443
 
                                             "field named \'%s\' not found.",
11444
 
                                             PyString_AsString(op));
11445
 
                        }
11446
 
                }
11447
 
                else {
11448
 
                        PyObject *name;
11449
 
                        int value;
11450
 
                        value = PyArray_PyIntAsInt(op);
11451
 
                        if (!PyErr_Occurred()) {
11452
 
                                int size;
11453
 
                                size = PyTuple_GET_SIZE(self->names);
11454
 
                                if (value < 0) value += size;
11455
 
                                if (value < 0 || value >= size) {
11456
 
                                        PyErr_Format(PyExc_IndexError,
11457
 
                                                     "0<=index<%d not %d",
11458
 
                                                     size, value);
11459
 
                                        return NULL;
11460
 
                                }
11461
 
                                name = PyTuple_GET_ITEM(self->names, value);
11462
 
                                return descr_subscript(self, name);
11463
 
                        }
11464
 
                }
11465
 
                PyErr_SetString(PyExc_ValueError,
11466
 
                                "only integers, strings or unicode values "
11467
 
                                "allowed for getting fields.");
11468
 
        }
11469
 
        else {
11470
 
                PyObject *astr;
11471
 
                astr = arraydescr_str(self);
 
11974
    if (self->names) {
 
11975
        if (PyString_Check(op) || PyUnicode_Check(op)) {
 
11976
            PyObject *obj;
 
11977
            obj = PyDict_GetItem(self->fields, op);
 
11978
            if (obj != NULL) {
 
11979
                PyObject *descr;
 
11980
                descr = PyTuple_GET_ITEM(obj, 0);
 
11981
                Py_INCREF(descr);
 
11982
                return descr;
 
11983
            }
 
11984
            else {
11472
11985
                PyErr_Format(PyExc_KeyError,
11473
 
                             "there are no fields in dtype %s.",
11474
 
                             PyString_AsString(astr));
11475
 
                Py_DECREF(astr);
11476
 
        }
11477
 
        return NULL;
 
11986
                             "field named \'%s\' not found.",
 
11987
                             PyString_AsString(op));
 
11988
            }
 
11989
        }
 
11990
        else {
 
11991
            PyObject *name;
 
11992
            int value;
 
11993
            value = PyArray_PyIntAsInt(op);
 
11994
            if (!PyErr_Occurred()) {
 
11995
                int size;
 
11996
                size = PyTuple_GET_SIZE(self->names);
 
11997
                if (value < 0) value += size;
 
11998
                if (value < 0 || value >= size) {
 
11999
                    PyErr_Format(PyExc_IndexError,
 
12000
                                 "0<=index<%d not %d",
 
12001
                                 size, value);
 
12002
                    return NULL;
 
12003
                }
 
12004
                name = PyTuple_GET_ITEM(self->names, value);
 
12005
                return descr_subscript(self, name);
 
12006
            }
 
12007
        }
 
12008
        PyErr_SetString(PyExc_ValueError,
 
12009
                        "only integers, strings or unicode values "
 
12010
                        "allowed for getting fields.");
 
12011
    }
 
12012
    else {
 
12013
        PyObject *astr;
 
12014
        astr = arraydescr_str(self);
 
12015
        PyErr_Format(PyExc_KeyError,
 
12016
                     "there are no fields in dtype %s.",
 
12017
                     PyString_AsString(astr));
 
12018
        Py_DECREF(astr);
 
12019
    }
 
12020
    return NULL;
11478
12021
}
11479
12022
 
11480
12023
static PySequenceMethods descr_as_sequence = {
11481
 
        descr_length,
11482
 
        (binaryfunc)NULL,
11483
 
        descr_repeat,
 
12024
    descr_length,
 
12025
    (binaryfunc)NULL,
 
12026
    descr_repeat,
11484
12027
};
11485
12028
 
11486
12029
static PyMappingMethods descr_as_mapping = {
11487
 
        descr_length,                       /*mp_length*/
11488
 
        (binaryfunc)descr_subscript,        /*mp_subscript*/
11489
 
        (objobjargproc)NULL,                /*mp_ass_subscript*/
 
12030
    descr_length,                       /*mp_length*/
 
12031
    (binaryfunc)descr_subscript,        /*mp_subscript*/
 
12032
    (objobjargproc)NULL,                /*mp_ass_subscript*/
11490
12033
};
11491
12034
 
11492
12035
/****************** End of Mapping Protocol ******************************/
11493
12036
 
11494
12037
 
11495
12038
static PyTypeObject PyArrayDescr_Type = {
11496
 
        PyObject_HEAD_INIT(NULL)
11497
 
        0,                                       /* ob_size */
11498
 
        "numpy.dtype",                           /* tp_name */
11499
 
        sizeof(PyArray_Descr),                   /* tp_basicsize */
11500
 
        0,                                       /* tp_itemsize */
11501
 
        /* methods */
11502
 
        (destructor)arraydescr_dealloc,         /* tp_dealloc */
11503
 
        0,                                      /* tp_print */
11504
 
        0,                                      /* tp_getattr */
11505
 
        0,                                      /* tp_setattr */
11506
 
        0,                                      /* tp_compare */
11507
 
        (reprfunc)arraydescr_repr,              /* tp_repr */
11508
 
        0,                                      /* tp_as_number */
11509
 
        &descr_as_sequence,                     /* tp_as_sequence */
11510
 
        &descr_as_mapping,                      /* tp_as_mapping */
11511
 
        0,                                      /* tp_hash */
11512
 
        0,                                      /* tp_call */
11513
 
        (reprfunc)arraydescr_str,               /* tp_str */
11514
 
        0,                                      /* tp_getattro */
11515
 
        0,                                      /* tp_setattro */
11516
 
        0,                                      /* tp_as_buffer */
11517
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
11518
 
        0,                                      /* tp_doc */
11519
 
        0,                                      /* tp_traverse */
11520
 
        0,                                      /* tp_clear */
11521
 
        (richcmpfunc)arraydescr_richcompare,    /* tp_richcompare */
11522
 
        0,                                      /* tp_weaklistoffset */
11523
 
        0,                                      /* tp_iter */
11524
 
        0,                                      /* tp_iternext */
11525
 
        arraydescr_methods,                     /* tp_methods */
11526
 
        arraydescr_members,                     /* tp_members */
11527
 
        arraydescr_getsets,                     /* tp_getset */
11528
 
        0,                                        /* tp_base */
11529
 
        0,                                        /* tp_dict */
11530
 
        0,                                        /* tp_descr_get */
11531
 
        0,                                        /* tp_descr_set */
11532
 
        0,                                        /* tp_dictoffset */
11533
 
        0,                                        /* tp_init */
11534
 
        0,                                        /* tp_alloc */
11535
 
        arraydescr_new,                           /* tp_new */
11536
 
        0,                                        /* tp_free */
11537
 
        0,                                        /* tp_is_gc */
11538
 
        0,                                        /* tp_bases */
11539
 
        0,                                        /* tp_mro */
11540
 
        0,                                        /* tp_cache */
11541
 
        0,                                        /* tp_subclasses */
11542
 
        0                                         /* tp_weaklist */
 
12039
    PyObject_HEAD_INIT(NULL)
 
12040
    0,                                       /* ob_size */
 
12041
    "numpy.dtype",                           /* tp_name */
 
12042
    sizeof(PyArray_Descr),                   /* tp_basicsize */
 
12043
    0,                                       /* tp_itemsize */
 
12044
    /* methods */
 
12045
    (destructor)arraydescr_dealloc,         /* tp_dealloc */
 
12046
    0,                                      /* tp_print */
 
12047
    0,                                      /* tp_getattr */
 
12048
    0,                                      /* tp_setattr */
 
12049
    0,                                      /* tp_compare */
 
12050
    (reprfunc)arraydescr_repr,              /* tp_repr */
 
12051
    0,                                      /* tp_as_number */
 
12052
    &descr_as_sequence,                     /* tp_as_sequence */
 
12053
    &descr_as_mapping,                      /* tp_as_mapping */
 
12054
    0,                                      /* tp_hash */
 
12055
    0,                                      /* tp_call */
 
12056
    (reprfunc)arraydescr_str,               /* tp_str */
 
12057
    0,                                      /* tp_getattro */
 
12058
    0,                                      /* tp_setattro */
 
12059
    0,                                      /* tp_as_buffer */
 
12060
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
12061
    0,                                      /* tp_doc */
 
12062
    0,                                      /* tp_traverse */
 
12063
    0,                                      /* tp_clear */
 
12064
    (richcmpfunc)arraydescr_richcompare,    /* tp_richcompare */
 
12065
    0,                                      /* tp_weaklistoffset */
 
12066
    0,                                      /* tp_iter */
 
12067
    0,                                      /* tp_iternext */
 
12068
    arraydescr_methods,                     /* tp_methods */
 
12069
    arraydescr_members,                     /* tp_members */
 
12070
    arraydescr_getsets,                     /* tp_getset */
 
12071
    0,                                        /* tp_base */
 
12072
    0,                                        /* tp_dict */
 
12073
    0,                                        /* tp_descr_get */
 
12074
    0,                                        /* tp_descr_set */
 
12075
    0,                                        /* tp_dictoffset */
 
12076
    0,                                        /* tp_init */
 
12077
    0,                                        /* tp_alloc */
 
12078
    arraydescr_new,                           /* tp_new */
 
12079
    0,                                        /* tp_free */
 
12080
    0,                                        /* tp_is_gc */
 
12081
    0,                                        /* tp_bases */
 
12082
    0,                                        /* tp_mro */
 
12083
    0,                                        /* tp_cache */
 
12084
    0,                                        /* tp_subclasses */
 
12085
    0                                         /* tp_weaklist */
11543
12086
};
11544
12087
 
11545
12088
 
11546
12089
/** Array Flags Object **/
11547
12090
 
11548
 
typedef struct PyArrayFlagsObject {
11549
 
        PyObject_HEAD
11550
 
        PyObject *arr;
11551
 
        int flags;
11552
 
} PyArrayFlagsObject;
11553
 
 
11554
12091
/*OBJECT_API
11555
 
 Get New ArrayFlagsObject
 
12092
  Get New ArrayFlagsObject
11556
12093
*/
11557
12094
static PyObject *
11558
12095
PyArray_NewFlagsObject(PyObject *obj)
11559
12096
{
11560
 
        PyObject *flagobj;
11561
 
        int flags;
11562
 
        if (obj == NULL) {
11563
 
                flags = CONTIGUOUS | OWNDATA | FORTRAN | ALIGNED;
11564
 
        }
11565
 
        else {
11566
 
                flags = PyArray_FLAGS(obj);
11567
 
        }
11568
 
        flagobj = PyArrayFlags_Type.tp_alloc(&PyArrayFlags_Type, 0);
11569
 
        if (flagobj == NULL) return NULL;
11570
 
        Py_XINCREF(obj);
11571
 
        ((PyArrayFlagsObject *)flagobj)->arr = obj;
11572
 
        ((PyArrayFlagsObject *)flagobj)->flags = flags;
 
12097
    PyObject *flagobj;
 
12098
    int flags;
 
12099
    if (obj == NULL) {
 
12100
        flags = CONTIGUOUS | OWNDATA | FORTRAN | ALIGNED;
 
12101
    }
 
12102
    else {
 
12103
        flags = PyArray_FLAGS(obj);
 
12104
    }
 
12105
    flagobj = PyArrayFlags_Type.tp_alloc(&PyArrayFlags_Type, 0);
 
12106
    if (flagobj == NULL) return NULL;
 
12107
    Py_XINCREF(obj);
 
12108
    ((PyArrayFlagsObject *)flagobj)->arr = obj;
 
12109
    ((PyArrayFlagsObject *)flagobj)->flags = flags;
11573
12110
 
11574
 
        return flagobj;
 
12111
    return flagobj;
11575
12112
}
11576
12113
 
11577
12114
static void
11578
12115
arrayflags_dealloc(PyArrayFlagsObject *self)
11579
12116
{
11580
 
        Py_XDECREF(self->arr);
11581
 
        self->ob_type->tp_free((PyObject *)self);
 
12117
    Py_XDECREF(self->arr);
 
12118
    self->ob_type->tp_free((PyObject *)self);
11582
12119
}
11583
12120
 
11584
12121
 
11585
 
#define _define_get(UPPER, lower)                 \
11586
 
static PyObject * \
11587
 
arrayflags_ ## lower ## _get(PyArrayFlagsObject *self) \
11588
 
{ \
11589
 
        PyObject *item; \
 
12122
#define _define_get(UPPER, lower)                                       \
 
12123
    static PyObject *                                                   \
 
12124
    arrayflags_ ## lower ## _get(PyArrayFlagsObject *self)              \
 
12125
    {                                                                   \
 
12126
        PyObject *item;                                                 \
11590
12127
        item = ((self->flags & (UPPER)) == (UPPER)) ? Py_True : Py_False; \
11591
 
        Py_INCREF(item); \
11592
 
        return item; \
11593
 
}
 
12128
        Py_INCREF(item);                                                \
 
12129
        return item;                                                    \
 
12130
    }
11594
12131
 
11595
12132
_define_get(CONTIGUOUS, contiguous)
11596
12133
_define_get(FORTRAN, fortran)
11605
12142
static PyObject *
11606
12143
arrayflags_forc_get(PyArrayFlagsObject *self)
11607
12144
{
11608
 
        PyObject *item;
11609
 
 
11610
 
        if (((self->flags & FORTRAN) == FORTRAN) ||
11611
 
            ((self->flags & CONTIGUOUS) == CONTIGUOUS))
11612
 
                item = Py_True;
11613
 
        else
11614
 
                item = Py_False;
11615
 
 
11616
 
        Py_INCREF(item);
11617
 
        return item;
 
12145
    PyObject *item;
 
12146
 
 
12147
    if (((self->flags & FORTRAN) == FORTRAN) ||
 
12148
        ((self->flags & CONTIGUOUS) == CONTIGUOUS))
 
12149
        item = Py_True;
 
12150
    else
 
12151
        item = Py_False;
 
12152
 
 
12153
    Py_INCREF(item);
 
12154
    return item;
11618
12155
}
11619
12156
 
11620
12157
static PyObject *
11621
12158
arrayflags_fnc_get(PyArrayFlagsObject *self)
11622
12159
{
11623
 
        PyObject *item;
11624
 
 
11625
 
        if (((self->flags & FORTRAN) == FORTRAN) &&
11626
 
            !((self->flags & CONTIGUOUS) == CONTIGUOUS))
11627
 
                item = Py_True;
11628
 
        else
11629
 
                item = Py_False;
11630
 
 
11631
 
        Py_INCREF(item);
11632
 
        return item;
 
12160
    PyObject *item;
 
12161
 
 
12162
    if (((self->flags & FORTRAN) == FORTRAN) &&
 
12163
        !((self->flags & CONTIGUOUS) == CONTIGUOUS))
 
12164
        item = Py_True;
 
12165
    else
 
12166
        item = Py_False;
 
12167
 
 
12168
    Py_INCREF(item);
 
12169
    return item;
11633
12170
}
11634
12171
 
11635
12172
static PyObject *
11636
12173
arrayflags_farray_get(PyArrayFlagsObject *self)
11637
12174
{
11638
 
        PyObject *item;
11639
 
 
11640
 
        if (((self->flags & (ALIGNED|WRITEABLE|FORTRAN)) ==     \
11641
 
             (ALIGNED|WRITEABLE|FORTRAN)) &&
11642
 
            !((self->flags & CONTIGUOUS) == CONTIGUOUS))
11643
 
                item = Py_True;
11644
 
        else
11645
 
                item = Py_False;
11646
 
 
11647
 
        Py_INCREF(item);
11648
 
        return item;
 
12175
    PyObject *item;
 
12176
 
 
12177
    if (((self->flags & (ALIGNED|WRITEABLE|FORTRAN)) ==     \
 
12178
         (ALIGNED|WRITEABLE|FORTRAN)) &&
 
12179
        !((self->flags & CONTIGUOUS) == CONTIGUOUS))
 
12180
        item = Py_True;
 
12181
    else
 
12182
        item = Py_False;
 
12183
 
 
12184
    Py_INCREF(item);
 
12185
    return item;
11649
12186
}
11650
12187
 
11651
12188
static PyObject *
11652
12189
arrayflags_num_get(PyArrayFlagsObject *self)
11653
12190
{
11654
 
        return PyInt_FromLong(self->flags);
 
12191
    return PyInt_FromLong(self->flags);
11655
12192
}
11656
12193
 
11657
12194
/* relies on setflags order being write, align, uic */
11658
12195
static int
11659
12196
arrayflags_updateifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
11660
12197
{
11661
 
        PyObject *res;
11662
 
        if (self->arr == NULL) {
11663
 
                PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
11664
 
                return -1;
11665
 
        }
11666
 
        res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None, Py_None,
11667
 
                                  (PyObject_IsTrue(obj) ? Py_True : Py_False));
11668
 
        if (res == NULL) return -1;
11669
 
        Py_DECREF(res);
11670
 
        return 0;
 
12198
    PyObject *res;
 
12199
    if (self->arr == NULL) {
 
12200
        PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
 
12201
        return -1;
 
12202
    }
 
12203
    res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None, Py_None,
 
12204
                              (PyObject_IsTrue(obj) ? Py_True : Py_False));
 
12205
    if (res == NULL) return -1;
 
12206
    Py_DECREF(res);
 
12207
    return 0;
11671
12208
}
11672
12209
 
11673
12210
static int
11674
12211
arrayflags_aligned_set(PyArrayFlagsObject *self, PyObject *obj)
11675
12212
{
11676
 
        PyObject *res;
11677
 
        if (self->arr == NULL) {
11678
 
                PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
11679
 
                return -1;
11680
 
        }
11681
 
        res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None,
11682
 
                                  (PyObject_IsTrue(obj) ? Py_True : Py_False),
11683
 
                                  Py_None);
11684
 
        if (res == NULL) return -1;
11685
 
        Py_DECREF(res);
11686
 
        return 0;
 
12213
    PyObject *res;
 
12214
    if (self->arr == NULL) {
 
12215
        PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
 
12216
        return -1;
 
12217
    }
 
12218
    res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None,
 
12219
                              (PyObject_IsTrue(obj) ? Py_True : Py_False),
 
12220
                              Py_None);
 
12221
    if (res == NULL) return -1;
 
12222
    Py_DECREF(res);
 
12223
    return 0;
11687
12224
}
11688
12225
 
11689
12226
static int
11690
12227
arrayflags_writeable_set(PyArrayFlagsObject *self, PyObject *obj)
11691
12228
{
11692
 
        PyObject *res;
11693
 
        if (self->arr == NULL) {
11694
 
                PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
11695
 
                return -1;
11696
 
        }
11697
 
        res = PyObject_CallMethod(self->arr, "setflags", "OOO",
11698
 
                                  (PyObject_IsTrue(obj) ? Py_True : Py_False),
11699
 
                                   Py_None, Py_None);
11700
 
        if (res == NULL) return -1;
11701
 
        Py_DECREF(res);
11702
 
        return 0;
 
12229
    PyObject *res;
 
12230
    if (self->arr == NULL) {
 
12231
        PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
 
12232
        return -1;
 
12233
    }
 
12234
    res = PyObject_CallMethod(self->arr, "setflags", "OOO",
 
12235
                              (PyObject_IsTrue(obj) ? Py_True : Py_False),
 
12236
                              Py_None, Py_None);
 
12237
    if (res == NULL) return -1;
 
12238
    Py_DECREF(res);
 
12239
    return 0;
11703
12240
}
11704
12241
 
11705
12242
 
11706
12243
static PyGetSetDef arrayflags_getsets[] = {
11707
 
        {"contiguous",
11708
 
         (getter)arrayflags_contiguous_get,
11709
 
         NULL,
11710
 
         ""},
11711
 
        {"c_contiguous",
11712
 
         (getter)arrayflags_contiguous_get,
11713
 
         NULL,
11714
 
         ""},
11715
 
        {"f_contiguous",
11716
 
         (getter)arrayflags_fortran_get,
11717
 
         NULL,
11718
 
         ""},
11719
 
        {"fortran",
11720
 
         (getter)arrayflags_fortran_get,
11721
 
         NULL,
11722
 
         ""},
11723
 
        {"updateifcopy",
11724
 
         (getter)arrayflags_updateifcopy_get,
11725
 
         (setter)arrayflags_updateifcopy_set,
11726
 
         ""},
11727
 
        {"owndata",
11728
 
         (getter)arrayflags_owndata_get,
11729
 
         NULL,
11730
 
         ""},
11731
 
        {"aligned",
11732
 
         (getter)arrayflags_aligned_get,
11733
 
         (setter)arrayflags_aligned_set,
11734
 
         ""},
11735
 
        {"writeable",
11736
 
         (getter)arrayflags_writeable_get,
11737
 
         (setter)arrayflags_writeable_set,
11738
 
         ""},
11739
 
        {"fnc",
11740
 
         (getter)arrayflags_fnc_get,
11741
 
         NULL,
11742
 
         ""},
11743
 
        {"forc",
11744
 
         (getter)arrayflags_forc_get,
11745
 
         NULL,
11746
 
         ""},
11747
 
        {"behaved",
11748
 
         (getter)arrayflags_behaved_get,
11749
 
         NULL,
11750
 
         ""},
11751
 
        {"carray",
11752
 
         (getter)arrayflags_carray_get,
11753
 
         NULL,
11754
 
         ""},
11755
 
        {"farray",
11756
 
         (getter)arrayflags_farray_get,
11757
 
         NULL,
11758
 
         ""},
11759
 
        {"num",
11760
 
         (getter)arrayflags_num_get,
11761
 
         NULL,
11762
 
         ""},
11763
 
        {NULL, NULL, NULL, NULL},
 
12244
    {"contiguous",
 
12245
     (getter)arrayflags_contiguous_get,
 
12246
     NULL,
 
12247
     ""},
 
12248
    {"c_contiguous",
 
12249
     (getter)arrayflags_contiguous_get,
 
12250
     NULL,
 
12251
     ""},
 
12252
    {"f_contiguous",
 
12253
     (getter)arrayflags_fortran_get,
 
12254
     NULL,
 
12255
     ""},
 
12256
    {"fortran",
 
12257
     (getter)arrayflags_fortran_get,
 
12258
     NULL,
 
12259
     ""},
 
12260
    {"updateifcopy",
 
12261
     (getter)arrayflags_updateifcopy_get,
 
12262
     (setter)arrayflags_updateifcopy_set,
 
12263
     ""},
 
12264
    {"owndata",
 
12265
     (getter)arrayflags_owndata_get,
 
12266
     NULL,
 
12267
     ""},
 
12268
    {"aligned",
 
12269
     (getter)arrayflags_aligned_get,
 
12270
     (setter)arrayflags_aligned_set,
 
12271
     ""},
 
12272
    {"writeable",
 
12273
     (getter)arrayflags_writeable_get,
 
12274
     (setter)arrayflags_writeable_set,
 
12275
     ""},
 
12276
    {"fnc",
 
12277
     (getter)arrayflags_fnc_get,
 
12278
     NULL,
 
12279
     ""},
 
12280
    {"forc",
 
12281
     (getter)arrayflags_forc_get,
 
12282
     NULL,
 
12283
     ""},
 
12284
    {"behaved",
 
12285
     (getter)arrayflags_behaved_get,
 
12286
     NULL,
 
12287
     ""},
 
12288
    {"carray",
 
12289
     (getter)arrayflags_carray_get,
 
12290
     NULL,
 
12291
     ""},
 
12292
    {"farray",
 
12293
     (getter)arrayflags_farray_get,
 
12294
     NULL,
 
12295
     ""},
 
12296
    {"num",
 
12297
     (getter)arrayflags_num_get,
 
12298
     NULL,
 
12299
     ""},
 
12300
    {NULL, NULL, NULL, NULL},
11764
12301
};
11765
12302
 
11766
12303
static PyObject *
11767
12304
arrayflags_getitem(PyArrayFlagsObject *self, PyObject *ind)
11768
12305
{
11769
 
        char *key;
11770
 
        int n;
11771
 
        if (!PyString_Check(ind)) goto fail;
11772
 
        key = PyString_AS_STRING(ind);
11773
 
        n = PyString_GET_SIZE(ind);
11774
 
        switch(n) {
11775
 
        case 1:
11776
 
                switch(key[0]) {
11777
 
                case 'C':
11778
 
                        return arrayflags_contiguous_get(self);
11779
 
                case 'F':
11780
 
                        return arrayflags_fortran_get(self);
11781
 
                case 'W':
11782
 
                        return arrayflags_writeable_get(self);
11783
 
                case 'B':
11784
 
                        return arrayflags_behaved_get(self);
11785
 
                case 'O':
11786
 
                        return arrayflags_owndata_get(self);
11787
 
                case 'A':
11788
 
                        return arrayflags_aligned_get(self);
11789
 
                case 'U':
11790
 
                        return arrayflags_updateifcopy_get(self);
11791
 
                default:
11792
 
                        goto fail;
11793
 
                }
11794
 
                break;
11795
 
        case 2:
11796
 
                if (strncmp(key, "CA", n)==0)
11797
 
                        return arrayflags_carray_get(self);
11798
 
                if (strncmp(key, "FA", n)==0)
11799
 
                        return arrayflags_farray_get(self);
11800
 
                break;
11801
 
        case 3:
11802
 
                if (strncmp(key, "FNC", n)==0)
11803
 
                        return arrayflags_fnc_get(self);
11804
 
                break;
11805
 
        case 4:
11806
 
                if (strncmp(key, "FORC", n)==0)
11807
 
                        return arrayflags_forc_get(self);
11808
 
                break;
11809
 
        case 6:
11810
 
                if (strncmp(key, "CARRAY", n)==0)
11811
 
                        return arrayflags_carray_get(self);
11812
 
                if (strncmp(key, "FARRAY", n)==0)
11813
 
                        return arrayflags_farray_get(self);
11814
 
                break;
11815
 
        case 7:
11816
 
                if (strncmp(key,"FORTRAN",n)==0)
11817
 
                        return arrayflags_fortran_get(self);
11818
 
                if (strncmp(key,"BEHAVED",n)==0)
11819
 
                        return arrayflags_behaved_get(self);
11820
 
                if (strncmp(key,"OWNDATA",n)==0)
11821
 
                        return arrayflags_owndata_get(self);
11822
 
                if (strncmp(key,"ALIGNED",n)==0)
11823
 
                        return arrayflags_aligned_get(self);
11824
 
                break;
11825
 
        case 9:
11826
 
                if (strncmp(key,"WRITEABLE",n)==0)
11827
 
                        return arrayflags_writeable_get(self);
11828
 
                break;
11829
 
        case 10:
11830
 
                if (strncmp(key,"CONTIGUOUS",n)==0)
11831
 
                        return arrayflags_contiguous_get(self);
11832
 
                break;
11833
 
        case 12:
11834
 
                if (strncmp(key, "UPDATEIFCOPY", n)==0)
11835
 
                        return arrayflags_updateifcopy_get(self);
11836
 
                if (strncmp(key, "C_CONTIGUOUS", n)==0)
11837
 
                        return arrayflags_contiguous_get(self);
11838
 
                if (strncmp(key, "F_CONTIGUOUS", n)==0)
11839
 
                        return arrayflags_fortran_get(self);
11840
 
                break;
 
12306
    char *key;
 
12307
    int n;
 
12308
    if (!PyString_Check(ind)) goto fail;
 
12309
    key = PyString_AS_STRING(ind);
 
12310
    n = PyString_GET_SIZE(ind);
 
12311
    switch(n) {
 
12312
    case 1:
 
12313
        switch(key[0]) {
 
12314
        case 'C':
 
12315
            return arrayflags_contiguous_get(self);
 
12316
        case 'F':
 
12317
            return arrayflags_fortran_get(self);
 
12318
        case 'W':
 
12319
            return arrayflags_writeable_get(self);
 
12320
        case 'B':
 
12321
            return arrayflags_behaved_get(self);
 
12322
        case 'O':
 
12323
            return arrayflags_owndata_get(self);
 
12324
        case 'A':
 
12325
            return arrayflags_aligned_get(self);
 
12326
        case 'U':
 
12327
            return arrayflags_updateifcopy_get(self);
 
12328
        default:
 
12329
            goto fail;
11841
12330
        }
 
12331
        break;
 
12332
    case 2:
 
12333
        if (strncmp(key, "CA", n)==0)
 
12334
            return arrayflags_carray_get(self);
 
12335
        if (strncmp(key, "FA", n)==0)
 
12336
            return arrayflags_farray_get(self);
 
12337
        break;
 
12338
    case 3:
 
12339
        if (strncmp(key, "FNC", n)==0)
 
12340
            return arrayflags_fnc_get(self);
 
12341
        break;
 
12342
    case 4:
 
12343
        if (strncmp(key, "FORC", n)==0)
 
12344
            return arrayflags_forc_get(self);
 
12345
        break;
 
12346
    case 6:
 
12347
        if (strncmp(key, "CARRAY", n)==0)
 
12348
            return arrayflags_carray_get(self);
 
12349
        if (strncmp(key, "FARRAY", n)==0)
 
12350
            return arrayflags_farray_get(self);
 
12351
        break;
 
12352
    case 7:
 
12353
        if (strncmp(key,"FORTRAN",n)==0)
 
12354
            return arrayflags_fortran_get(self);
 
12355
        if (strncmp(key,"BEHAVED",n)==0)
 
12356
            return arrayflags_behaved_get(self);
 
12357
        if (strncmp(key,"OWNDATA",n)==0)
 
12358
            return arrayflags_owndata_get(self);
 
12359
        if (strncmp(key,"ALIGNED",n)==0)
 
12360
            return arrayflags_aligned_get(self);
 
12361
        break;
 
12362
    case 9:
 
12363
        if (strncmp(key,"WRITEABLE",n)==0)
 
12364
            return arrayflags_writeable_get(self);
 
12365
        break;
 
12366
    case 10:
 
12367
        if (strncmp(key,"CONTIGUOUS",n)==0)
 
12368
            return arrayflags_contiguous_get(self);
 
12369
        break;
 
12370
    case 12:
 
12371
        if (strncmp(key, "UPDATEIFCOPY", n)==0)
 
12372
            return arrayflags_updateifcopy_get(self);
 
12373
        if (strncmp(key, "C_CONTIGUOUS", n)==0)
 
12374
            return arrayflags_contiguous_get(self);
 
12375
        if (strncmp(key, "F_CONTIGUOUS", n)==0)
 
12376
            return arrayflags_fortran_get(self);
 
12377
        break;
 
12378
    }
11842
12379
 
11843
12380
 fail:
11844
 
        PyErr_SetString(PyExc_KeyError, "Unknown flag");
11845
 
        return NULL;
 
12381
    PyErr_SetString(PyExc_KeyError, "Unknown flag");
 
12382
    return NULL;
11846
12383
}
11847
12384
 
11848
12385
static int
11849
12386
arrayflags_setitem(PyArrayFlagsObject *self, PyObject *ind, PyObject *item)
11850
12387
{
11851
 
        char *key;
11852
 
        int n;
11853
 
        if (!PyString_Check(ind)) goto fail;
11854
 
        key = PyString_AS_STRING(ind);
11855
 
        n = PyString_GET_SIZE(ind);
11856
 
        if (((n==9) && (strncmp(key, "WRITEABLE", n)==0)) ||
11857
 
            ((n==1) && (strncmp(key, "W", n)==0)))
11858
 
                return arrayflags_writeable_set(self, item);
11859
 
        else if (((n==7) && (strncmp(key, "ALIGNED", n)==0)) ||
11860
 
                 ((n==1) && (strncmp(key, "A", n)==0)))
11861
 
                return arrayflags_aligned_set(self, item);
11862
 
        else if (((n==12) && (strncmp(key, "UPDATEIFCOPY", n)==0)) ||
11863
 
                 ((n==1) && (strncmp(key, "U", n)==0)))
11864
 
                return arrayflags_updateifcopy_set(self, item);
 
12388
    char *key;
 
12389
    int n;
 
12390
    if (!PyString_Check(ind)) goto fail;
 
12391
    key = PyString_AS_STRING(ind);
 
12392
    n = PyString_GET_SIZE(ind);
 
12393
    if (((n==9) && (strncmp(key, "WRITEABLE", n)==0)) ||
 
12394
        ((n==1) && (strncmp(key, "W", n)==0)))
 
12395
        return arrayflags_writeable_set(self, item);
 
12396
    else if (((n==7) && (strncmp(key, "ALIGNED", n)==0)) ||
 
12397
             ((n==1) && (strncmp(key, "A", n)==0)))
 
12398
        return arrayflags_aligned_set(self, item);
 
12399
    else if (((n==12) && (strncmp(key, "UPDATEIFCOPY", n)==0)) ||
 
12400
             ((n==1) && (strncmp(key, "U", n)==0)))
 
12401
        return arrayflags_updateifcopy_set(self, item);
11865
12402
 
11866
 
fail:
11867
 
        PyErr_SetString(PyExc_KeyError, "Unknown flag");
11868
 
        return -1;
 
12403
 fail:
 
12404
    PyErr_SetString(PyExc_KeyError, "Unknown flag");
 
12405
    return -1;
11869
12406
}
11870
12407
 
11871
12408
static char *
11872
12409
_torf_(int flags, int val)
11873
12410
{
11874
 
        if ((flags & val) == val) return "True";
11875
 
        else return "False";
 
12411
    if ((flags & val) == val) return "True";
 
12412
    else return "False";
11876
12413
}
11877
12414
 
11878
12415
static PyObject *
11879
12416
arrayflags_print(PyArrayFlagsObject *self)
11880
12417
{
11881
 
        int fl = self->flags;
11882
 
 
11883
 
        return PyString_FromFormat("  %s : %s\n  %s : %s\n  %s : %s\n"\
11884
 
                                   "  %s : %s\n  %s : %s\n  %s : %s",
11885
 
                                   "C_CONTIGUOUS", _torf_(fl, CONTIGUOUS),
11886
 
                                   "F_CONTIGUOUS", _torf_(fl, FORTRAN),
11887
 
                                   "OWNDATA", _torf_(fl, OWNDATA),
11888
 
                                   "WRITEABLE", _torf_(fl, WRITEABLE),
11889
 
                                   "ALIGNED", _torf_(fl, ALIGNED),
11890
 
                                   "UPDATEIFCOPY", _torf_(fl, UPDATEIFCOPY));
11891
 
}
11892
 
 
 
12418
    int fl = self->flags;
 
12419
 
 
12420
    return PyString_FromFormat("  %s : %s\n  %s : %s\n  %s : %s\n"\
 
12421
                               "  %s : %s\n  %s : %s\n  %s : %s",
 
12422
                               "C_CONTIGUOUS", _torf_(fl, CONTIGUOUS),
 
12423
                               "F_CONTIGUOUS", _torf_(fl, FORTRAN),
 
12424
                               "OWNDATA", _torf_(fl, OWNDATA),
 
12425
                               "WRITEABLE", _torf_(fl, WRITEABLE),
 
12426
                               "ALIGNED", _torf_(fl, ALIGNED),
 
12427
                               "UPDATEIFCOPY", _torf_(fl, UPDATEIFCOPY));
 
12428
}
 
12429
 
 
12430
 
 
12431
static int
 
12432
arrayflags_compare(PyArrayFlagsObject *self, PyArrayFlagsObject *other)
 
12433
{
 
12434
    if (self->flags == other->flags)
 
12435
        return 0;
 
12436
    else if (self->flags < other->flags)
 
12437
        return -1;
 
12438
    else
 
12439
        return 1;
 
12440
}
11893
12441
 
11894
12442
static PyMappingMethods arrayflags_as_mapping = {
11895
12443
#if PY_VERSION_HEX >= 0x02050000
11896
 
        (lenfunc)NULL,                       /*mp_length*/
 
12444
    (lenfunc)NULL,                       /*mp_length*/
11897
12445
#else
11898
 
        (inquiry)NULL,                       /*mp_length*/
 
12446
    (inquiry)NULL,                       /*mp_length*/
11899
12447
#endif
11900
 
        (binaryfunc)arrayflags_getitem,      /*mp_subscript*/
11901
 
        (objobjargproc)arrayflags_setitem,   /*mp_ass_subscript*/
 
12448
    (binaryfunc)arrayflags_getitem,      /*mp_subscript*/
 
12449
    (objobjargproc)arrayflags_setitem,   /*mp_ass_subscript*/
11902
12450
};
11903
12451
 
11904
12452
 
11905
12453
static PyObject *
11906
12454
arrayflags_new(PyTypeObject *self, PyObject *args, PyObject *kwds)
11907
12455
{
11908
 
        PyObject *arg=NULL;
11909
 
        if (!PyArg_UnpackTuple(args, "flagsobj", 0, 1, &arg))
11910
 
                return NULL;
 
12456
    PyObject *arg=NULL;
 
12457
    if (!PyArg_UnpackTuple(args, "flagsobj", 0, 1, &arg))
 
12458
        return NULL;
11911
12459
 
11912
 
        if ((arg != NULL) && PyArray_Check(arg)) {
11913
 
                return PyArray_NewFlagsObject(arg);
11914
 
        }
11915
 
        else {
11916
 
                return PyArray_NewFlagsObject(NULL);
11917
 
        }
 
12460
    if ((arg != NULL) && PyArray_Check(arg)) {
 
12461
        return PyArray_NewFlagsObject(arg);
 
12462
    }
 
12463
    else {
 
12464
        return PyArray_NewFlagsObject(NULL);
 
12465
    }
11918
12466
}
11919
12467
 
11920
12468
static PyTypeObject PyArrayFlags_Type = {
11921
 
        PyObject_HEAD_INIT(NULL)
11922
 
        0,
11923
 
        "numpy.flagsobj",
11924
 
        sizeof(PyArrayFlagsObject),
11925
 
        0,                                       /* tp_itemsize */
11926
 
        /* methods */
11927
 
        (destructor)arrayflags_dealloc,         /* tp_dealloc */
11928
 
        0,                                      /* tp_print */
11929
 
        0,                                      /* tp_getattr */
11930
 
        0,                                      /* tp_setattr */
11931
 
        0,                                      /* tp_compare */
11932
 
        (reprfunc)arrayflags_print,             /* tp_repr */
11933
 
        0,                                      /* tp_as_number */
11934
 
        0,                                      /* tp_as_sequence */
11935
 
        &arrayflags_as_mapping,                 /* tp_as_mapping */
11936
 
        0,                                      /* tp_hash */
11937
 
        0,                                      /* tp_call */
11938
 
        (reprfunc)arrayflags_print,             /* tp_str */
11939
 
        0,                                      /* tp_getattro */
11940
 
        0,                                      /* tp_setattro */
11941
 
        0,                                      /* tp_as_buffer */
11942
 
        Py_TPFLAGS_DEFAULT,                     /* tp_flags */
11943
 
        0,                                      /* tp_doc */
11944
 
        0,                                      /* tp_traverse */
11945
 
        0,                                      /* tp_clear */
11946
 
        0,                                      /* tp_richcompare */
11947
 
        0,                                      /* tp_weaklistoffset */
11948
 
        0,                                      /* tp_iter */
11949
 
        0,                                      /* tp_iternext */
11950
 
        0,                                       /* tp_methods */
11951
 
        0,                                       /* tp_members */
11952
 
        arrayflags_getsets,                      /* tp_getset */
11953
 
        0,                                        /* tp_base */
11954
 
        0,                                        /* tp_dict */
11955
 
        0,                                        /* tp_descr_get */
11956
 
        0,                                        /* tp_descr_set */
11957
 
        0,                                        /* tp_dictoffset */
11958
 
        0,                                        /* tp_init */
11959
 
        0,                                        /* tp_alloc */
11960
 
        arrayflags_new,                           /* tp_new */
11961
 
        0,                                        /* tp_free */
11962
 
        0,                                        /* tp_is_gc */
11963
 
        0,                                        /* tp_bases */
11964
 
        0,                                        /* tp_mro */
11965
 
        0,                                        /* tp_cache */
11966
 
        0,                                        /* tp_subclasses */
11967
 
        0                                         /* tp_weaklist */
 
12469
    PyObject_HEAD_INIT(NULL)
 
12470
    0,
 
12471
    "numpy.flagsobj",
 
12472
    sizeof(PyArrayFlagsObject),
 
12473
    0,                                       /* tp_itemsize */
 
12474
    /* methods */
 
12475
    (destructor)arrayflags_dealloc,         /* tp_dealloc */
 
12476
    0,                                      /* tp_print */
 
12477
    0,                                      /* tp_getattr */
 
12478
    0,                                      /* tp_setattr */
 
12479
    (cmpfunc)arrayflags_compare,            /* tp_compare */
 
12480
    (reprfunc)arrayflags_print,             /* tp_repr */
 
12481
    0,                                      /* tp_as_number */
 
12482
    0,                                      /* tp_as_sequence */
 
12483
    &arrayflags_as_mapping,                 /* tp_as_mapping */
 
12484
    0,                                      /* tp_hash */
 
12485
    0,                                      /* tp_call */
 
12486
    (reprfunc)arrayflags_print,             /* tp_str */
 
12487
    0,                                      /* tp_getattro */
 
12488
    0,                                      /* tp_setattro */
 
12489
    0,                                      /* tp_as_buffer */
 
12490
    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
 
12491
    0,                                      /* tp_doc */
 
12492
    0,                                      /* tp_traverse */
 
12493
    0,                                      /* tp_clear */
 
12494
    0,                                      /* tp_richcompare */
 
12495
    0,                                      /* tp_weaklistoffset */
 
12496
    0,                                      /* tp_iter */
 
12497
    0,                                      /* tp_iternext */
 
12498
    0,                                       /* tp_methods */
 
12499
    0,                                       /* tp_members */
 
12500
    arrayflags_getsets,                      /* tp_getset */
 
12501
    0,                                        /* tp_base */
 
12502
    0,                                        /* tp_dict */
 
12503
    0,                                        /* tp_descr_get */
 
12504
    0,                                        /* tp_descr_set */
 
12505
    0,                                        /* tp_dictoffset */
 
12506
    0,                                        /* tp_init */
 
12507
    0,                                        /* tp_alloc */
 
12508
    arrayflags_new,                           /* tp_new */
 
12509
    0,                                        /* tp_free */
 
12510
    0,                                        /* tp_is_gc */
 
12511
    0,                                        /* tp_bases */
 
12512
    0,                                        /* tp_mro */
 
12513
    0,                                        /* tp_cache */
 
12514
    0,                                        /* tp_subclasses */
 
12515
    0                                         /* tp_weaklist */
11968
12516
};