1
#define PY_SSIZE_T_CLEAN
3
#include "structmember.h"
5
#define _MULTIARRAYMODULE
7
#include "numpy/arrayobject.h"
8
#include "numpy/arrayscalars.h"
10
#include "npy_config.h"
13
#include "scalartypes.h"
16
#include "convert_datatype.h"
19
* For backward compatibility
21
* Cast an array using typecode structure.
22
* steals reference to at --- cannot be NULL
24
NPY_NO_EXPORT PyObject *
25
PyArray_CastToType(PyArrayObject *mp, PyArray_Descr *at, int fortran)
34
((mpd->type_num == at->type_num) &&
35
PyArray_EquivByteorders(mpd->byteorder, at->byteorder) &&
36
((mpd->elsize == at->elsize) || (at->elsize==0)))) &&
37
PyArray_ISBEHAVED_RO(mp)) {
40
return (PyObject *)mp;
43
if (at->elsize == 0) {
44
PyArray_DESCR_REPLACE(at);
48
if (mpd->type_num == PyArray_STRING &&
49
at->type_num == PyArray_UNICODE) {
50
at->elsize = mpd->elsize << 2;
52
if (mpd->type_num == PyArray_UNICODE &&
53
at->type_num == PyArray_STRING) {
54
at->elsize = mpd->elsize >> 2;
56
if (at->type_num == PyArray_VOID) {
57
at->elsize = mpd->elsize;
61
out = PyArray_NewFromDescr(mp->ob_type, at,
71
ret = PyArray_CastTo((PyArrayObject *)out, mp);
82
* Get a cast function to cast from the input descriptor to the
83
* output type_number (must be a registered data-type).
84
* Returns NULL if un-successful.
86
NPY_NO_EXPORT PyArray_VectorUnaryFunc *
87
PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
89
PyArray_VectorUnaryFunc *castfunc = NULL;
91
if (type_num < PyArray_NTYPES) {
92
castfunc = descr->f->cast[type_num];
94
if (castfunc == NULL) {
95
PyObject *obj = descr->f->castdict;
96
if (obj && PyDict_Check(obj)) {
100
key = PyInt_FromLong(type_num);
101
cobj = PyDict_GetItem(obj, key);
103
if (PyCObject_Check(cobj)) {
104
castfunc = PyCObject_AsVoidPtr(cobj);
115
PyErr_SetString(PyExc_ValueError, "No cast function available.");
121
* copyswapn is used which increases and decreases reference counts for OBJECT arrays.
122
* All that needs to happen is for any reference counts in the buffers to be
123
* decreased when completely finished with the buffers.
125
* buffers[0] is the destination
126
* buffers[1] is the source
129
_strided_buffered_cast(char *dptr, intp dstride, int delsize, int dswap,
130
PyArray_CopySwapNFunc *dcopyfunc,
131
char *sptr, intp sstride, int selsize, int sswap,
132
PyArray_CopySwapNFunc *scopyfunc,
133
intp N, char **buffers, int bufsize,
134
PyArray_VectorUnaryFunc *castfunc,
135
PyArrayObject *dest, PyArrayObject *src)
140
* 1. copy input to buffer and swap
141
* 2. cast input to output
142
* 3. swap output if necessary and copy from output buffer
144
scopyfunc(buffers[1], selsize, sptr, sstride, N, sswap, src);
145
castfunc(buffers[1], buffers[0], N, src, dest);
146
dcopyfunc(dptr, dstride, buffers[0], delsize, N, dswap, dest);
150
/* otherwise we need to divide up into bufsize pieces */
153
int newN = MIN(N, bufsize);
155
_strided_buffered_cast(dptr+i*dstride, dstride, delsize,
157
sptr+i*sstride, sstride, selsize,
159
newN, buffers, bufsize, castfunc, dest, src);
167
_broadcast_cast(PyArrayObject *out, PyArrayObject *in,
168
PyArray_VectorUnaryFunc *castfunc, int iswap, int oswap)
170
int delsize, selsize, maxaxis, i, N;
171
PyArrayMultiIterObject *multi;
172
intp maxdim, ostrides, istrides;
174
PyArray_CopySwapNFunc *ocopyfunc, *icopyfunc;
176
NPY_BEGIN_THREADS_DEF;
178
delsize = PyArray_ITEMSIZE(out);
179
selsize = PyArray_ITEMSIZE(in);
180
multi = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, out, in);
185
if (multi->size != PyArray_SIZE(out)) {
186
PyErr_SetString(PyExc_ValueError,
187
"array dimensions are not "\
188
"compatible for copy");
193
icopyfunc = in->descr->f->copyswapn;
194
ocopyfunc = out->descr->f->copyswapn;
195
maxaxis = PyArray_RemoveSmallest(multi);
197
/* cast 1 0-d array to another */
204
maxdim = multi->dimensions[maxaxis];
205
N = (int) (MIN(maxdim, PyArray_BUFSIZE));
206
ostrides = multi->iters[0]->strides[maxaxis];
207
istrides = multi->iters[1]->strides[maxaxis];
210
buffers[0] = _pya_malloc(N*delsize);
211
if (buffers[0] == NULL) {
215
buffers[1] = _pya_malloc(N*selsize);
216
if (buffers[1] == NULL) {
217
_pya_free(buffers[0]);
221
if (PyDataType_FLAGCHK(out->descr, NPY_NEEDS_INIT)) {
222
memset(buffers[0], 0, N*delsize);
224
if (PyDataType_FLAGCHK(in->descr, NPY_NEEDS_INIT)) {
225
memset(buffers[1], 0, N*selsize);
228
#if NPY_ALLOW_THREADS
229
if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
234
while (multi->index < multi->size) {
235
_strided_buffered_cast(multi->iters[0]->dataptr,
237
delsize, oswap, ocopyfunc,
238
multi->iters[1]->dataptr,
240
selsize, iswap, icopyfunc,
243
PyArray_MultiIter_NEXT(multi);
245
#if NPY_ALLOW_THREADS
246
if (PyArray_ISNUMBER(in) && PyArray_ISNUMBER(out)) {
251
if (PyDataType_REFCHK(in->descr)) {
253
for (i = 0; i < N; i++, obptr+=selsize) {
254
PyArray_Item_XDECREF(obptr, out->descr);
257
if (PyDataType_REFCHK(out->descr)) {
259
for (i = 0; i < N; i++, obptr+=delsize) {
260
PyArray_Item_XDECREF(obptr, out->descr);
263
_pya_free(buffers[0]);
264
_pya_free(buffers[1]);
265
if (PyErr_Occurred()) {
275
* Must be broadcastable.
276
* This code is very similar to PyArray_CopyInto/PyArray_MoveInto
277
* except casting is done --- PyArray_BUFSIZE is used
278
* as the size of the casting buffer.
282
* Cast to an already created array.
285
PyArray_CastTo(PyArrayObject *out, PyArrayObject *mp)
289
PyArray_VectorUnaryFunc *castfunc = NULL;
290
intp mpsize = PyArray_SIZE(mp);
292
NPY_BEGIN_THREADS_DEF;
297
if (!PyArray_ISWRITEABLE(out)) {
298
PyErr_SetString(PyExc_ValueError, "output array is not writeable");
302
castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
303
if (castfunc == NULL) {
307
same = PyArray_SAMESHAPE(out, mp);
308
simple = same && ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
309
(PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
311
#if NPY_ALLOW_THREADS
312
if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
316
castfunc(mp->data, out->data, mpsize, mp, out);
318
#if NPY_ALLOW_THREADS
319
if (PyArray_ISNUMBER(mp) && PyArray_ISNUMBER(out)) {
323
if (PyErr_Occurred()) {
330
* If the input or output is OBJECT, STRING, UNICODE, or VOID
331
* then getitem and setitem are used for the cast
332
* and byteswapping is handled by those methods
334
if (PyArray_ISFLEXIBLE(mp) || PyArray_ISOBJECT(mp) || PyArray_ISOBJECT(out) ||
335
PyArray_ISFLEXIBLE(out)) {
339
iswap = PyArray_ISBYTESWAPPED(mp);
340
oswap = PyArray_ISBYTESWAPPED(out);
343
return _broadcast_cast(out, mp, castfunc, iswap, oswap);
348
_bufferedcast(PyArrayObject *out, PyArrayObject *in,
349
PyArray_VectorUnaryFunc *castfunc)
351
char *inbuffer, *bptr, *optr;
352
char *outbuffer=NULL;
353
PyArrayIterObject *it_in = NULL, *it_out = NULL;
355
intp ncopies = PyArray_SIZE(out) / PyArray_SIZE(in);
356
int elsize=in->descr->elsize;
357
int nels = PyArray_BUFSIZE;
359
int inswap, outswap = 0;
360
int obuf=!PyArray_ISCARRAY(out);
361
int oelsize = out->descr->elsize;
362
PyArray_CopySwapFunc *in_csn;
363
PyArray_CopySwapFunc *out_csn;
366
in_csn = in->descr->f->copyswap;
367
out_csn = out->descr->f->copyswap;
370
* If the input or output is STRING, UNICODE, or VOID
371
* then getitem and setitem are used for the cast
372
* and byteswapping is handled by those methods
375
inswap = !(PyArray_ISFLEXIBLE(in) || PyArray_ISNOTSWAPPED(in));
377
inbuffer = PyDataMem_NEW(PyArray_BUFSIZE*elsize);
378
if (inbuffer == NULL) {
381
if (PyArray_ISOBJECT(in)) {
382
memset(inbuffer, 0, PyArray_BUFSIZE*elsize);
384
it_in = (PyArrayIterObject *)PyArray_IterNew((PyObject *)in);
389
outswap = !(PyArray_ISFLEXIBLE(out) ||
390
PyArray_ISNOTSWAPPED(out));
391
outbuffer = PyDataMem_NEW(PyArray_BUFSIZE*oelsize);
392
if (outbuffer == NULL) {
395
if (PyArray_ISOBJECT(out)) {
396
memset(outbuffer, 0, PyArray_BUFSIZE*oelsize);
398
it_out = (PyArrayIterObject *)PyArray_IterNew((PyObject *)out);
399
if (it_out == NULL) {
402
nels = MIN(nels, PyArray_BUFSIZE);
405
optr = (obuf) ? outbuffer: out->data;
410
PyArray_ITER_RESET(it_in);
412
in_csn(bptr, it_in->dataptr, inswap, in);
414
PyArray_ITER_NEXT(it_in);
416
if ((el == nels) || (index == 0)) {
417
/* buffer filled, do cast */
418
castfunc(inbuffer, optr, el, in, out);
420
/* Copy from outbuffer to array */
421
for (i = 0; i < el; i++) {
422
out_csn(it_out->dataptr,
426
PyArray_ITER_NEXT(it_out);
431
optr += out->descr->elsize * nels;
442
PyDataMem_FREE(inbuffer);
443
PyDataMem_FREE(outbuffer);
451
* Cast to an already created array. Arrays don't have to be "broadcastable"
452
* Only requirement is they have the same number of elements.
455
PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
458
PyArray_VectorUnaryFunc *castfunc = NULL;
459
npy_intp mpsize = PyArray_SIZE(mp);
464
if (!PyArray_ISWRITEABLE(out)) {
465
PyErr_SetString(PyExc_ValueError, "output array is not writeable");
469
if (!(mpsize == PyArray_SIZE(out))) {
470
PyErr_SetString(PyExc_ValueError,
471
"arrays must have the same number of"
472
" elements for the cast.");
476
castfunc = PyArray_GetCastFunc(mp->descr, out->descr->type_num);
477
if (castfunc == NULL) {
480
simple = ((PyArray_ISCARRAY_RO(mp) && PyArray_ISCARRAY(out)) ||
481
(PyArray_ISFARRAY_RO(mp) && PyArray_ISFARRAY(out)));
483
castfunc(mp->data, out->data, mpsize, mp, out);
486
if (PyArray_SAMESHAPE(out, mp)) {
488
iswap = PyArray_ISBYTESWAPPED(mp) && !PyArray_ISFLEXIBLE(mp);
489
oswap = PyArray_ISBYTESWAPPED(out) && !PyArray_ISFLEXIBLE(out);
490
return _broadcast_cast(out, mp, castfunc, iswap, oswap);
492
return _bufferedcast(out, mp, castfunc);
496
*Check the type coercion rules.
499
PyArray_CanCastSafely(int fromtype, int totype)
501
PyArray_Descr *from, *to;
502
int felsize, telsize;
504
if (fromtype == totype) {
507
if (fromtype == PyArray_BOOL) {
510
if (totype == PyArray_BOOL) {
513
if (totype == PyArray_OBJECT || totype == PyArray_VOID) {
516
if (fromtype == PyArray_OBJECT || fromtype == PyArray_VOID) {
519
from = PyArray_DescrFromType(fromtype);
521
* cancastto is a PyArray_NOTYPE terminated C-int-array of types that
522
* the data-type can be cast to safely.
524
if (from->f->cancastto) {
526
curtype = from->f->cancastto;
527
while (*curtype != PyArray_NOTYPE) {
528
if (*curtype++ == totype) {
533
if (PyTypeNum_ISUSERDEF(totype)) {
536
to = PyArray_DescrFromType(totype);
537
telsize = to->elsize;
538
felsize = from->elsize;
547
case PyArray_LONGLONG:
548
if (PyTypeNum_ISINTEGER(totype)) {
549
if (PyTypeNum_ISUNSIGNED(totype)) {
553
return telsize >= felsize;
556
else if (PyTypeNum_ISFLOAT(totype)) {
558
return telsize > felsize;
561
return telsize >= felsize;
564
else if (PyTypeNum_ISCOMPLEX(totype)) {
566
return (telsize >> 1) > felsize;
569
return (telsize >> 1) >= felsize;
573
return totype > fromtype;
579
case PyArray_ULONGLONG:
580
if (PyTypeNum_ISINTEGER(totype)) {
581
if (PyTypeNum_ISSIGNED(totype)) {
582
return telsize > felsize;
585
return telsize >= felsize;
588
else if (PyTypeNum_ISFLOAT(totype)) {
590
return telsize > felsize;
593
return telsize >= felsize;
596
else if (PyTypeNum_ISCOMPLEX(totype)) {
598
return (telsize >> 1) > felsize;
601
return (telsize >> 1) >= felsize;
605
return totype > fromtype;
609
case PyArray_LONGDOUBLE:
610
if (PyTypeNum_ISCOMPLEX(totype)) {
611
return (telsize >> 1) >= felsize;
614
return totype > fromtype;
617
case PyArray_CDOUBLE:
618
case PyArray_CLONGDOUBLE:
619
return totype > fromtype;
621
case PyArray_UNICODE:
622
return totype > fromtype;
629
* leaves reference count alone --- cannot be NULL
632
PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
634
int fromtype=from->type_num;
635
int totype=to->type_num;
638
ret = (Bool) PyArray_CanCastSafely(fromtype, totype);
640
/* Check String and Unicode more closely */
641
if (fromtype == PyArray_STRING) {
642
if (totype == PyArray_STRING) {
643
ret = (from->elsize <= to->elsize);
645
else if (totype == PyArray_UNICODE) {
646
ret = (from->elsize << 2 <= to->elsize);
649
else if (fromtype == PyArray_UNICODE) {
650
if (totype == PyArray_UNICODE) {
651
ret = (from->elsize <= to->elsize);
655
* TODO: If totype is STRING or unicode
656
* see if the length is long enough to hold the
657
* stringified value of the object.
664
* See if array scalars can be cast.
667
PyArray_CanCastScalar(PyTypeObject *from, PyTypeObject *to)
672
fromtype = _typenum_fromtypeobj((PyObject *)from, 0);
673
totype = _typenum_fromtypeobj((PyObject *)to, 0);
674
if (fromtype == PyArray_NOTYPE || totype == PyArray_NOTYPE) {
677
return (Bool) PyArray_CanCastSafely(fromtype, totype);
681
* Is the typenum valid?
684
PyArray_ValidType(int type)
686
PyArray_Descr *descr;
689
descr = PyArray_DescrFromType(type);
697
/* Backward compatibility only */
698
/* In both Zero and One
700
***You must free the memory once you are done with it
701
using PyDataMem_FREE(ptr) or you create a memory leak***
703
If arr is an Object array you are getting a
704
BORROWED reference to Zero or One.
706
Please INCREF if you will be hanging on to it.
708
The memory for the ptr still must be freed in any case;
712
_check_object_rec(PyArray_Descr *descr)
714
if (PyDataType_HASFIELDS(descr) && PyDataType_REFCHK(descr)) {
715
PyErr_SetString(PyExc_TypeError, "Not supported for this data-type.");
722
Get pointer to zero of correct type for array.
725
PyArray_Zero(PyArrayObject *arr)
731
if (_check_object_rec(arr->descr) < 0) {
734
zeroval = PyDataMem_NEW(arr->descr->elsize);
735
if (zeroval == NULL) {
736
PyErr_SetNone(PyExc_MemoryError);
740
obj=PyInt_FromLong((long) 0);
741
if (PyArray_ISOBJECT(arr)) {
742
memcpy(zeroval, &obj, sizeof(PyObject *));
746
storeflags = arr->flags;
747
arr->flags |= BEHAVED;
748
ret = arr->descr->f->setitem(obj, zeroval, arr);
749
arr->flags = storeflags;
752
PyDataMem_FREE(zeroval);
759
Get pointer to one of correct type for array
762
PyArray_One(PyArrayObject *arr)
768
if (_check_object_rec(arr->descr) < 0) {
771
oneval = PyDataMem_NEW(arr->descr->elsize);
772
if (oneval == NULL) {
773
PyErr_SetNone(PyExc_MemoryError);
777
obj = PyInt_FromLong((long) 1);
778
if (PyArray_ISOBJECT(arr)) {
779
memcpy(oneval, &obj, sizeof(PyObject *));
784
storeflags = arr->flags;
785
arr->flags |= BEHAVED;
786
ret = arr->descr->f->setitem(obj, oneval, arr);
787
arr->flags = storeflags;
790
PyDataMem_FREE(oneval);
799
* Return the typecode of the array a Python object would be converted to
802
PyArray_ObjectType(PyObject *op, int minimum_type)
804
PyArray_Descr *intype;
805
PyArray_Descr *outtype;
808
intype = PyArray_DescrFromType(minimum_type);
809
if (intype == NULL) {
812
outtype = _array_find_type(op, intype, MAX_DIMS);
813
ret = outtype->type_num;
819
/* Raises error when len(op) == 0 */
822
NPY_NO_EXPORT PyArrayObject **
823
PyArray_ConvertToCommonType(PyObject *op, int *retn)
825
int i, n, allscalars = 0;
826
PyArrayObject **mps = NULL;
828
PyArray_Descr *intype = NULL, *stype = NULL;
829
PyArray_Descr *newtype = NULL;
830
NPY_SCALARKIND scalarkind = NPY_NOSCALAR, intypekind = NPY_NOSCALAR;
832
*retn = n = PySequence_Length(op);
834
PyErr_SetString(PyExc_ValueError, "0-length sequence.");
836
if (PyErr_Occurred()) {
840
mps = (PyArrayObject **)PyDataMem_NEW(n*sizeof(PyArrayObject *));
843
return (void*)PyErr_NoMemory();
846
if (PyArray_Check(op)) {
847
for (i = 0; i < n; i++) {
848
mps[i] = (PyArrayObject *) array_big_item((PyArrayObject *)op, i);
850
if (!PyArray_ISCARRAY(op)) {
851
for (i = 0; i < n; i++) {
853
obj = PyArray_NewCopy(mps[i], NPY_CORDER);
855
mps[i] = (PyArrayObject *)obj;
861
for (i = 0; i < n; i++) {
862
otmp = PySequence_GetItem(op, i);
863
if (!PyArray_CheckAnyScalar(otmp)) {
864
newtype = PyArray_DescrFromObject(otmp, intype);
868
intypekind = PyArray_ScalarKind(intype->type_num, NULL);
871
newtype = PyArray_DescrFromObject(otmp, stype);
874
scalarkind = PyArray_ScalarKind(newtype->type_num, NULL);
875
mps[i] = (PyArrayObject *)Py_None;
885
for (i = 0; i < n; i++) {
890
else if ((stype != NULL) && (intypekind != scalarkind)) {
892
* we need to upconvert to type that
893
* handles both intype and stype
894
* also don't forcecast the scalars.
896
if (!PyArray_CanCoerceScalar(stype->type_num,
899
newtype = _array_small_type(intype, stype);
903
for (i = 0; i < n; i++) {
910
/* Make sure all arrays are actual array objects. */
911
for (i = 0; i < n; i++) {
914
if ((otmp = PySequence_GetItem(op, i)) == NULL) {
917
if (!allscalars && ((PyObject *)(mps[i]) == Py_None)) {
918
/* forcecast scalars */
923
mps[i] = (PyArrayObject*)
924
PyArray_FromAny(otmp, intype, 0, 0, flags, NULL);
926
if (mps[i] == NULL) {
938
for (i = 0; i < n; i++) {