File: types-and-structures.rst

package info (click to toggle)
numpy 1%3A1.24.2-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 44,720 kB
  • sloc: ansic: 188,931; python: 156,261; asm: 111,405; javascript: 32,693; cpp: 14,210; f90: 755; sh: 638; fortran: 478; makefile: 292; sed: 140; perl: 34
file content (1491 lines) | stat: -rw-r--r-- 57,772 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491

*****************************
Python Types and C-Structures
*****************************

.. sectionauthor:: Travis E. Oliphant

Several new types are defined in the C-code. Most of these are
accessible from Python, but a few are not exposed due to their limited
use. Every new Python type has an associated :c:expr:`PyObject *` with an
internal structure that includes a pointer to a "method table" that
defines how the new object behaves in Python. When you receive a
Python object into C code, you always get a pointer to a
:c:type:`PyObject` structure. Because a :c:type:`PyObject` structure is
very generic and defines only :c:macro:`PyObject_HEAD`, by itself it
is not very interesting. However, different objects contain more
details after the :c:macro:`PyObject_HEAD` (but you have to cast to the
correct type to access them --- or use accessor functions or macros).


New Python Types Defined
========================

Python types are the functional equivalent in C of classes in Python.
By constructing a new Python type you make available a new object for
Python. The ndarray object is an example of a new type defined in C.
New types are defined in C by two basic steps:

1. creating a C-structure (usually named ``Py{Name}Object``) that is
   binary- compatible with the :c:type:`PyObject` structure itself but holds
   the additional information needed for that particular object;

2. populating the :c:type:`PyTypeObject` table (pointed to by the ob_type
   member of the :c:type:`PyObject` structure) with pointers to functions
   that implement the desired behavior for the type.

Instead of special method names which define behavior for Python
classes, there are "function tables" which point to functions that
implement the desired results. Since Python 2.2, the PyTypeObject
itself has become dynamic which allows C types that can be "sub-typed
"from other C-types in C, and sub-classed in Python. The children
types inherit the attributes and methods from their parent(s).

There are two major new types: the ndarray ( :c:data:`PyArray_Type` )
and the ufunc ( :c:data:`PyUFunc_Type` ). Additional types play a
supportive role: the :c:data:`PyArrayIter_Type`, the
:c:data:`PyArrayMultiIter_Type`, and the :c:data:`PyArrayDescr_Type`
. The :c:data:`PyArrayIter_Type` is the type for a flat iterator for an
ndarray (the object that is returned when getting the flat
attribute). The :c:data:`PyArrayMultiIter_Type` is the type of the
object returned when calling ``broadcast`` (). It handles iteration
and broadcasting over a collection of nested sequences. Also, the
:c:data:`PyArrayDescr_Type` is the data-type-descriptor type whose
instances describe the data.  Finally, there are 21 new scalar-array
types which are new Python scalars corresponding to each of the
fundamental data types available for arrays. An additional 10 other
types are place holders that allow the array scalars to fit into a
hierarchy of actual Python types.


PyArray_Type and PyArrayObject
------------------------------

.. c:var:: PyTypeObject PyArray_Type

   The Python type of the ndarray is :c:data:`PyArray_Type`. In C, every
   ndarray is a pointer to a :c:type:`PyArrayObject` structure. The ob_type
   member of this structure contains a pointer to the :c:data:`PyArray_Type`
   typeobject.

.. c:type:: PyArrayObject
            NPY_AO

   The :c:type:`PyArrayObject` C-structure contains all of the required
   information for an array. All instances of an ndarray (and its
   subclasses) will have this structure.  For future compatibility,
   these structure members should normally be accessed using the
   provided macros. If you need a shorter name, then you can make use
   of :c:type:`NPY_AO` (deprecated) which is defined to be equivalent to
   :c:type:`PyArrayObject`. Direct access to the struct fields are
   deprecated. Use the ``PyArray_*(arr)`` form instead.
   As of NumPy 1.20, the size of this struct is not considered part of
   the NumPy ABI (see note at the end of the member list).

   .. code-block:: c

      typedef struct PyArrayObject {
          PyObject_HEAD
          char *data;
          int nd;
          npy_intp *dimensions;
          npy_intp *strides;
          PyObject *base;
          PyArray_Descr *descr;
          int flags;
          PyObject *weakreflist;
          /* version dependent private members */
      } PyArrayObject;

   .. c:macro:: PyObject_HEAD

       This is needed by all Python objects. It consists of (at least)
       a reference count member ( ``ob_refcnt`` ) and a pointer to the
       typeobject ( ``ob_type`` ). (Other elements may also be present
       if Python was compiled with special options see
       Include/object.h in the Python source tree for more
       information). The ob_type member points to a Python type
       object.

   .. c:member:: char *data

       Accessible via :c:data:`PyArray_DATA`, this data member is a
       pointer to the first element of the array. This pointer can
       (and normally should) be recast to the data type of the array.

   .. c:member:: int nd

       An integer providing the number of dimensions for this
       array. When nd is 0, the array is sometimes called a rank-0
       array. Such arrays have undefined dimensions and strides and
       cannot be accessed. Macro :c:data:`PyArray_NDIM` defined in
       ``ndarraytypes.h`` points to this data member. :c:data:`NPY_MAXDIMS`
       is the largest number of dimensions for any array.

   .. c:member:: npy_intp dimensions

       An array of integers providing the shape in each dimension as
       long as nd :math:`\geq` 1. The integer is always large enough
       to hold a pointer on the platform, so the dimension size is
       only limited by memory. :c:data:`PyArray_DIMS` is the macro
       associated with this data member.

   .. c:member:: npy_intp *strides

       An array of integers providing for each dimension the number of
       bytes that must be skipped to get to the next element in that
       dimension. Associated with macro :c:data:`PyArray_STRIDES`.

   .. c:member:: PyObject *base

       Pointed to by :c:data:`PyArray_BASE`, this member is used to hold a
       pointer to another Python object that is related to this array.
       There are two use cases:

       - If this array does not own its own memory, then base points to the
         Python object that owns it (perhaps another array object)
       - If this array has the :c:data:`NPY_ARRAY_WRITEBACKIFCOPY` flag set,
         then this array is a working copy of a "misbehaved" array.

       When ``PyArray_ResolveWritebackIfCopy`` is called, the array pointed to
       by base will be updated with the contents of this array.

   .. c:member:: PyArray_Descr *descr

       A pointer to a data-type descriptor object (see below). The
       data-type descriptor object is an instance of a new built-in
       type which allows a generic description of memory. There is a
       descriptor structure for each data type supported. This
       descriptor structure contains useful information about the type
       as well as a pointer to a table of function pointers to
       implement specific functionality. As the name suggests, it is
       associated with the macro :c:data:`PyArray_DESCR`.

   .. c:member:: int flags

       Pointed to by the macro :c:data:`PyArray_FLAGS`, this data member represents
       the flags indicating how the memory pointed to by data is to be
       interpreted. Possible flags are :c:data:`NPY_ARRAY_C_CONTIGUOUS`,
       :c:data:`NPY_ARRAY_F_CONTIGUOUS`, :c:data:`NPY_ARRAY_OWNDATA`,
       :c:data:`NPY_ARRAY_ALIGNED`, :c:data:`NPY_ARRAY_WRITEABLE`,
       :c:data:`NPY_ARRAY_WRITEBACKIFCOPY`.

   .. c:member:: PyObject *weakreflist

       This member allows array objects to have weak references (using the
       weakref module).

   .. note::

      Further members are considered private and version dependent. If the size
      of the struct is important for your code, special care must be taken.
      A possible use-case when this is relevant is subclassing in C.
      If your code relies on ``sizeof(PyArrayObject)`` to be constant,
      you must add the following check at import time:

      .. code-block:: c

         if (sizeof(PyArrayObject) < PyArray_Type.tp_basicsize) {
             PyErr_SetString(PyExc_ImportError,
                "Binary incompatibility with NumPy, must recompile/update X.");
             return NULL;
         }

      To ensure that your code does not have to be compiled for a specific
      NumPy version, you may add a constant, leaving room for changes in NumPy.
      A solution guaranteed to be compatible with any future NumPy version
      requires the use of a runtime calculate offset and allocation size.


PyArrayDescr_Type and PyArray_Descr
-----------------------------------

.. c:var:: PyTypeObject PyArrayDescr_Type

   The :c:data:`PyArrayDescr_Type` is the built-in type of the
   data-type-descriptor objects used to describe how the bytes comprising
   the array are to be interpreted.  There are 21 statically-defined
   :c:type:`PyArray_Descr` objects for the built-in data-types. While these
   participate in reference counting, their reference count should never
   reach zero.  There is also a dynamic table of user-defined
   :c:type:`PyArray_Descr` objects that is also maintained. Once a
   data-type-descriptor object is "registered" it should never be
   deallocated either. The function :c:func:`PyArray_DescrFromType` (...) can
   be used to retrieve a :c:type:`PyArray_Descr` object from an enumerated
   type-number (either built-in or user- defined).

.. c:type:: PyArray_Descr

   The :c:type:`PyArray_Descr` structure lies at the heart of the
   :c:data:`PyArrayDescr_Type`. While it is described here for
   completeness, it should be considered internal to NumPy and manipulated via
   ``PyArrayDescr_*`` or ``PyDataType*`` functions and macros. The size of this
   structure is subject to change across versions of NumPy. To ensure
   compatibility:

   - Never declare a non-pointer instance of the struct
   - Never perform pointer arithmetic
   - Never use ``sizof(PyArray_Descr)``

   It has the following structure:

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          PyTypeObject *typeobj;
          char kind;
          char type;
          char byteorder;
          char flags;
          int type_num;
          int elsize;
          int alignment;
          PyArray_ArrayDescr *subarray;
          PyObject *fields;
          PyObject *names;
          PyArray_ArrFuncs *f;
          PyObject *metadata;
          NpyAuxData *c_metadata;
          npy_hash_t hash;
      } PyArray_Descr;

   .. c:member:: PyTypeObject *typeobj

       Pointer to a typeobject that is the corresponding Python type for
       the elements of this array. For the builtin types, this points to
       the corresponding array scalar. For user-defined types, this
       should point to a user-defined typeobject. This typeobject can
       either inherit from array scalars or not. If it does not inherit
       from array scalars, then the :c:data:`NPY_USE_GETITEM` and
       :c:data:`NPY_USE_SETITEM` flags should be set in the ``flags`` member.

   .. c:member:: char kind

       A character code indicating the kind of array (using the array
       interface typestring notation). A 'b' represents Boolean, a 'i'
       represents signed integer, a 'u' represents unsigned integer, 'f'
       represents floating point, 'c' represents complex floating point, 'S'
       represents 8-bit zero-terminated bytes, 'U' represents 32-bit/character
       unicode string, and 'V' represents arbitrary.

   .. c:member:: char type

       A traditional character code indicating the data type.

   .. c:member:: char byteorder

       A character indicating the byte-order: '>' (big-endian), '<' (little-
       endian), '=' (native), '\|' (irrelevant, ignore). All builtin data-
       types have byteorder '='.

   .. c:member:: char flags

       A data-type bit-flag that determines if the data-type exhibits object-
       array like behavior. Each bit in this member is a flag which are named
       as:

   .. c:member:: int alignment

       Non-NULL if this type is an array (C-contiguous) of some other type


..
  dedented to allow internal linking, pending a refactoring

.. c:macro:: NPY_ITEM_REFCOUNT

    Indicates that items of this data-type must be reference
    counted (using :c:func:`Py_INCREF` and :c:func:`Py_DECREF` ).

       .. c:macro:: NPY_ITEM_HASOBJECT

           Same as :c:data:`NPY_ITEM_REFCOUNT`.

..
  dedented to allow internal linking, pending a refactoring

.. c:macro:: NPY_LIST_PICKLE

    Indicates arrays of this data-type must be converted to a list
    before pickling.

.. c:macro:: NPY_ITEM_IS_POINTER

    Indicates the item is a pointer to some other data-type

.. c:macro:: NPY_NEEDS_INIT

    Indicates memory for this data-type must be initialized (set
    to 0) on creation.

.. c:macro:: NPY_NEEDS_PYAPI

    Indicates this data-type requires the Python C-API during
    access (so don't give up the GIL if array access is going to
    be needed).

.. c:macro:: NPY_USE_GETITEM

    On array access use the ``f->getitem`` function pointer
    instead of the standard conversion to an array scalar. Must
    use if you don't define an array scalar to go along with
    the data-type.

.. c:macro:: NPY_USE_SETITEM

    When creating a 0-d array from an array scalar use
    ``f->setitem`` instead of the standard copy from an array
    scalar. Must use if you don't define an array scalar to go
    along with the data-type.

       .. c:macro:: NPY_FROM_FIELDS

           The bits that are inherited for the parent data-type if these
           bits are set in any field of the data-type. Currently (
           :c:data:`NPY_NEEDS_INIT` \| :c:data:`NPY_LIST_PICKLE` \|
           :c:data:`NPY_ITEM_REFCOUNT` \| :c:data:`NPY_NEEDS_PYAPI` ).

       .. c:macro:: NPY_OBJECT_DTYPE_FLAGS

           Bits set for the object data-type: ( :c:data:`NPY_LIST_PICKLE`
           \| :c:data:`NPY_USE_GETITEM` \| :c:data:`NPY_ITEM_IS_POINTER` \|
           :c:data:`NPY_ITEM_REFCOUNT` \| :c:data:`NPY_NEEDS_INIT` \|
           :c:data:`NPY_NEEDS_PYAPI`).

       .. c:function:: int PyDataType_FLAGCHK(PyArray_Descr *dtype, int flags)

           Return true if all the given flags are set for the data-type
           object.

       .. c:function:: int PyDataType_REFCHK(PyArray_Descr *dtype)

           Equivalent to :c:func:`PyDataType_FLAGCHK` (*dtype*,
           :c:data:`NPY_ITEM_REFCOUNT`).

   .. c:member:: int type_num

       A number that uniquely identifies the data type. For new data-types,
       this number is assigned when the data-type is registered.

   .. c:member:: int elsize

       For data types that are always the same size (such as long), this
       holds the size of the data type. For flexible data types where
       different arrays can have a different elementsize, this should be
       0.

   .. c:member:: int alignment

       A number providing alignment information for this data type.
       Specifically, it shows how far from the start of a 2-element
       structure (whose first element is a ``char`` ), the compiler
       places an item of this type: ``offsetof(struct {char c; type v;},
       v)``

   .. c:member:: PyArray_ArrayDescr *subarray

       If this is non- ``NULL``, then this data-type descriptor is a
       C-style contiguous array of another data-type descriptor. In
       other-words, each element that this descriptor describes is
       actually an array of some other base descriptor. This is most
       useful as the data-type descriptor for a field in another
       data-type descriptor. The fields member should be ``NULL`` if this
       is non- ``NULL`` (the fields member of the base descriptor can be
       non- ``NULL`` however).

       .. c:type:: PyArray_ArrayDescr

           .. code-block:: c

              typedef struct {
                  PyArray_Descr *base;
                  PyObject *shape;
              } PyArray_ArrayDescr;

           .. c:member:: PyArray_Descr *base

               The data-type-descriptor object of the base-type.

           .. c:member:: PyObject *shape

               The shape (always C-style contiguous) of the sub-array as a Python
               tuple.

   .. c:member:: PyObject *fields

       If this is non-NULL, then this data-type-descriptor has fields
       described by a Python dictionary whose keys are names (and also
       titles if given) and whose values are tuples that describe the
       fields. Recall that a data-type-descriptor always describes a
       fixed-length set of bytes. A field is a named sub-region of that
       total, fixed-length collection. A field is described by a tuple
       composed of another data- type-descriptor and a byte
       offset. Optionally, the tuple may contain a title which is
       normally a Python string. These tuples are placed in this
       dictionary keyed by name (and also title if given).

   .. c:member:: PyObject *names

       An ordered tuple of field names. It is NULL if no field is
       defined.

   .. c:member:: PyArray_ArrFuncs *f

       A pointer to a structure containing functions that the type needs
       to implement internal features. These functions are not the same
       thing as the universal functions (ufuncs) described later. Their
       signatures can vary arbitrarily.

   .. c:member:: PyObject *metadata

       Metadata about this dtype.

   .. c:member:: NpyAuxData *c_metadata

       Metadata specific to the C implementation
       of the particular dtype. Added for NumPy 1.7.0.

   .. c:type:: npy_hash_t
   .. c:member:: npy_hash_t *hash

       Currently unused. Reserved for future use in caching
       hash values.

.. c:type:: PyArray_ArrFuncs

    Functions implementing internal features. Not all of these
    function pointers must be defined for a given type. The required
    members are ``nonzero``, ``copyswap``, ``copyswapn``, ``setitem``,
    ``getitem``, and ``cast``. These are assumed to be non- ``NULL``
    and ``NULL`` entries will cause a program crash. The other
    functions may be ``NULL`` which will just mean reduced
    functionality for that data-type. (Also, the nonzero function will
    be filled in with a default function if it is ``NULL`` when you
    register a user-defined data-type).

    .. code-block:: c

       typedef struct {
           PyArray_VectorUnaryFunc *cast[NPY_NTYPES];
           PyArray_GetItemFunc *getitem;
           PyArray_SetItemFunc *setitem;
           PyArray_CopySwapNFunc *copyswapn;
           PyArray_CopySwapFunc *copyswap;
           PyArray_CompareFunc *compare;
           PyArray_ArgFunc *argmax;
           PyArray_DotFunc *dotfunc;
           PyArray_ScanFunc *scanfunc;
           PyArray_FromStrFunc *fromstr;
           PyArray_NonzeroFunc *nonzero;
           PyArray_FillFunc *fill;
           PyArray_FillWithScalarFunc *fillwithscalar;
           PyArray_SortFunc *sort[NPY_NSORTS];
           PyArray_ArgSortFunc *argsort[NPY_NSORTS];
           PyObject *castdict;
           PyArray_ScalarKindFunc *scalarkind;
           int **cancastscalarkindto;
           int *cancastto;
           PyArray_FastClipFunc *fastclip;  /* deprecated */
           PyArray_FastPutmaskFunc *fastputmask;  /* deprecated */
           PyArray_FastTakeFunc *fasttake;  /* deprecated */
           PyArray_ArgFunc *argmin;
       } PyArray_ArrFuncs;

    The concept of a behaved segment is used in the description of the
    function pointers. A behaved segment is one that is aligned and in
    native machine byte-order for the data-type. The ``nonzero``,
    ``copyswap``, ``copyswapn``, ``getitem``, and ``setitem``
    functions can (and must) deal with mis-behaved arrays. The other
    functions require behaved memory segments.

    .. c:member:: void cast( \
            void *from, void *to, npy_intp n, void *fromarr, void *toarr)

        An array of function pointers to cast from the current type to
        all of the other builtin types. Each function casts a
        contiguous, aligned, and notswapped buffer pointed at by
        *from* to a contiguous, aligned, and notswapped buffer pointed
        at by *to* The number of items to cast is given by *n*, and
        the arguments *fromarr* and *toarr* are interpreted as
        PyArrayObjects for flexible arrays to get itemsize
        information.

    .. c:member:: PyObject *getitem(void *data, void *arr)

        A pointer to a function that returns a standard Python object
        from a single element of the array object *arr* pointed to by
        *data*. This function must be able to deal with "misbehaved
        "(misaligned and/or swapped) arrays correctly.

    .. c:member:: int setitem(PyObject *item, void *data, void *arr)

        A pointer to a function that sets the Python object *item*
        into the array, *arr*, at the position pointed to by *data*
        . This function deals with "misbehaved" arrays. If successful,
        a zero is returned, otherwise, a negative one is returned (and
        a Python error set).

    .. c:member:: void copyswapn( \
            void *dest, npy_intp dstride, void *src, npy_intp sstride, \
            npy_intp n, int swap, void *arr)

    .. c:member:: void copyswap(void *dest, void *src, int swap, void *arr)

        These members are both pointers to functions to copy data from
        *src* to *dest* and *swap* if indicated. The value of arr is
        only used for flexible ( :c:data:`NPY_STRING`, :c:data:`NPY_UNICODE`,
        and :c:data:`NPY_VOID` ) arrays (and is obtained from
        ``arr->descr->elsize`` ). The second function copies a single
        value, while the first loops over n values with the provided
        strides. These functions can deal with misbehaved *src*
        data. If *src* is NULL then no copy is performed. If *swap* is
        0, then no byteswapping occurs. It is assumed that *dest* and
        *src* do not overlap. If they overlap, then use ``memmove``
        (...) first followed by ``copyswap(n)`` with NULL valued
        ``src``.

    .. c:member:: int compare(const void* d1, const void* d2, void* arr)

        A pointer to a function that compares two elements of the
        array, ``arr``, pointed to by ``d1`` and ``d2``. This
        function requires behaved (aligned and not swapped) arrays.
        The return value is 1 if * ``d1`` > * ``d2``, 0 if * ``d1`` == *
        ``d2``, and -1 if * ``d1`` < * ``d2``. The array object ``arr`` is
        used to retrieve itemsize and field information for flexible arrays.

    .. c:member:: int argmax( \
            void* data, npy_intp n, npy_intp* max_ind, void* arr)

        A pointer to a function that retrieves the index of the
        largest of ``n`` elements in ``arr`` beginning at the element
        pointed to by ``data``. This function requires that the
        memory segment be contiguous and behaved. The return value is
        always 0. The index of the largest element is returned in
        ``max_ind``.

    .. c:member:: void dotfunc( \
            void* ip1, npy_intp is1, void* ip2, npy_intp is2, void* op, \
            npy_intp n, void* arr)

        A pointer to a function that multiplies two ``n`` -length
        sequences together, adds them, and places the result in
        element pointed to by ``op`` of ``arr``. The start of the two
        sequences are pointed to by ``ip1`` and ``ip2``. To get to
        the next element in each sequence requires a jump of ``is1``
        and ``is2`` *bytes*, respectively. This function requires
        behaved (though not necessarily contiguous) memory.

    .. c:member:: int scanfunc(FILE* fd, void* ip, void* arr)

        A pointer to a function that scans (scanf style) one element
        of the corresponding type from the file descriptor ``fd`` into
        the array memory pointed to by ``ip``. The array is assumed
        to be behaved. 
        The last argument ``arr`` is the array to be scanned into.
        Returns number of receiving arguments successfully assigned (which
        may be zero in case a matching failure occurred before the first
        receiving argument was assigned), or EOF if input failure occurs 
        before the first receiving argument was assigned.
        This function should be called without holding the Python GIL, and
        has to grab it for error reporting.

    .. c:member:: int fromstr(char* str, void* ip, char** endptr, void* arr)

        A pointer to a function that converts the string pointed to by
        ``str`` to one element of the corresponding type and places it
        in the memory location pointed to by ``ip``. After the
        conversion is completed, ``*endptr`` points to the rest of the
        string. The last argument ``arr`` is the array into which ip
        points (needed for variable-size data- types). Returns 0 on
        success or -1 on failure. Requires a behaved array.
        This function should be called without holding the Python GIL, and
        has to grab it for error reporting.

    .. c:member:: npy_bool nonzero(void* data, void* arr)

        A pointer to a function that returns TRUE if the item of
        ``arr`` pointed to by ``data`` is nonzero. This function can
        deal with misbehaved arrays.

    .. c:member:: void fill(void* data, npy_intp length, void* arr)

        A pointer to a function that fills a contiguous array of given
        length with data. The first two elements of the array must
        already be filled- in. From these two values, a delta will be
        computed and the values from item 3 to the end will be
        computed by repeatedly adding this computed delta. The data
        buffer must be well-behaved.

    .. c:member:: void fillwithscalar( \
            void* buffer, npy_intp length, void* value, void* arr)

        A pointer to a function that fills a contiguous ``buffer`` of
        the given ``length`` with a single scalar ``value`` whose
        address is given. The final argument is the array which is
        needed to get the itemsize for variable-length arrays.

    .. c:member:: int sort(void* start, npy_intp length, void* arr)

        An array of function pointers to a particular sorting
        algorithms. A particular sorting algorithm is obtained using a
        key (so far :c:data:`NPY_QUICKSORT`, :c:data:`NPY_HEAPSORT`,
        and :c:data:`NPY_MERGESORT` are defined). These sorts are done
        in-place assuming contiguous and aligned data.

    .. c:member:: int argsort( \
            void* start, npy_intp* result, npy_intp length, void *arr)

        An array of function pointers to sorting algorithms for this
        data type. The same sorting algorithms as for sort are
        available. The indices producing the sort are returned in
        ``result`` (which must be initialized with indices 0 to
        ``length-1`` inclusive).

    .. c:member:: PyObject *castdict

        Either ``NULL`` or a dictionary containing low-level casting
        functions for user- defined data-types. Each function is
        wrapped in a :c:expr:`PyCapsule *` and keyed by
        the data-type number.

    .. c:member:: NPY_SCALARKIND scalarkind(PyArrayObject* arr)

        A function to determine how scalars of this type should be
        interpreted. The argument is ``NULL`` or a 0-dimensional array
        containing the data (if that is needed to determine the kind
        of scalar). The return value must be of type
        :c:type:`NPY_SCALARKIND`.

    .. c:member:: int **cancastscalarkindto

        Either ``NULL`` or an array of :c:type:`NPY_NSCALARKINDS`
        pointers. These pointers should each be either ``NULL`` or a
        pointer to an array of integers (terminated by
        :c:data:`NPY_NOTYPE`) indicating data-types that a scalar of
        this data-type of the specified kind can be cast to safely
        (this usually means without losing precision).

    .. c:member:: int *cancastto

        Either ``NULL`` or an array of integers (terminated by
        :c:data:`NPY_NOTYPE` ) indicated data-types that this data-type
        can be cast to safely (this usually means without losing
        precision).

    .. c:member:: void fastclip( \
            void *in, npy_intp n_in, void *min, void *max, void *out)

        .. deprecated:: 1.17
            The use of this function will give a deprecation warning when
            ``np.clip``. Instead of this function, the datatype must
            instead use ``PyUFunc_RegisterLoopForDescr`` to attach a custom
            loop to ``np.core.umath.clip``, ``np.minimum``, and ``np.maximum``.

        .. deprecated:: 1.19
            Setting this function is deprecated and should always be ``NULL``,
            if set, it will be ignored.

        A function that reads ``n_in`` items from ``in``, and writes to
        ``out`` the read value if it is within the limits pointed to by
        ``min`` and ``max``, or the corresponding limit if outside. The
        memory segments must be contiguous and behaved, and either
        ``min`` or ``max`` may be ``NULL``, but not both.

    .. c:member:: void fastputmask( \
            void *in, void *mask, npy_intp n_in, void *values, npy_intp nv)

        .. deprecated:: 1.19
            Setting this function is deprecated and should always be ``NULL``,
            if set, it will be ignored.

        A function that takes a pointer ``in`` to an array of ``n_in``
        items, a pointer ``mask`` to an array of ``n_in`` boolean
        values, and a pointer ``vals`` to an array of ``nv`` items.
        Items from ``vals`` are copied into ``in`` wherever the value
        in ``mask`` is non-zero, tiling ``vals`` as needed if
        ``nv < n_in``. All arrays must be contiguous and behaved.

    .. c:member:: void fasttake( \
            void *dest, void *src, npy_intp *indarray, npy_intp nindarray, \
            npy_intp n_outer, npy_intp m_middle, npy_intp nelem, \
            NPY_CLIPMODE clipmode)

        .. deprecated:: 1.19
            Setting this function is deprecated and should always be ``NULL``,
            if set, it will be ignored.

        A function that takes a pointer ``src`` to a C contiguous,
        behaved segment, interpreted as a 3-dimensional array of shape
        ``(n_outer, nindarray, nelem)``, a pointer ``indarray`` to a
        contiguous, behaved segment of ``m_middle`` integer indices,
        and a pointer ``dest`` to a C contiguous, behaved segment,
        interpreted as a 3-dimensional array of shape
        ``(n_outer, m_middle, nelem)``. The indices in ``indarray`` are
        used to index ``src`` along the second dimension, and copy the
        corresponding chunks of ``nelem`` items into ``dest``.
        ``clipmode`` (which can take on the values :c:data:`NPY_RAISE`,
        :c:data:`NPY_WRAP` or :c:data:`NPY_CLIP`) determines how will
        indices smaller than 0 or larger than ``nindarray`` will be
        handled.

    .. c:member:: int argmin( \
            void* data, npy_intp n, npy_intp* min_ind, void* arr)

        A pointer to a function that retrieves the index of the
        smallest of ``n`` elements in ``arr`` beginning at the element
        pointed to by ``data``. This function requires that the
        memory segment be contiguous and behaved. The return value is
        always 0. The index of the smallest element is returned in
        ``min_ind``.


The :c:data:`PyArray_Type` typeobject implements many of the features of
:c:type:`Python objects <PyTypeObject>` including the :c:member:`tp_as_number
<PyTypeObject.tp_as_number>`, :c:member:`tp_as_sequence
<PyTypeObject.tp_as_sequence>`, :c:member:`tp_as_mapping
<PyTypeObject.tp_as_mapping>`, and :c:member:`tp_as_buffer
<PyTypeObject.tp_as_buffer>` interfaces. The :c:type:`rich comparison
<richcmpfunc>`) is also used along with new-style attribute lookup for
member (:c:member:`tp_members <PyTypeObject.tp_members>`) and properties
(:c:member:`tp_getset <PyTypeObject.tp_getset>`).
The :c:data:`PyArray_Type` can also be sub-typed.

.. tip::

    The ``tp_as_number`` methods use a generic approach to call whatever
    function has been registered for handling the operation.  When the
    ``_multiarray_umath module`` is imported, it sets the numeric operations
    for all arrays to the corresponding ufuncs. This choice can be changed with
    :c:func:`PyUFunc_ReplaceLoopBySignature` The ``tp_str`` and ``tp_repr``
    methods can also be altered using :c:func:`PyArray_SetStringFunction`.


PyUFunc_Type and PyUFuncObject
------------------------------

.. c:var:: PyTypeObject PyUFunc_Type

   The ufunc object is implemented by creation of the
   :c:data:`PyUFunc_Type`. It is a very simple type that implements only
   basic getattribute behavior, printing behavior, and has call
   behavior which allows these objects to act like functions. The
   basic idea behind the ufunc is to hold a reference to fast
   1-dimensional (vector) loops for each data type that supports the
   operation. These one-dimensional loops all have the same signature
   and are the key to creating a new ufunc. They are called by the
   generic looping code as appropriate to implement the N-dimensional
   function. There are also some generic 1-d loops defined for
   floating and complexfloating arrays that allow you to define a
   ufunc using a single scalar function (*e.g.* atanh).


.. c:type:: PyUFuncObject

   The core of the ufunc is the :c:type:`PyUFuncObject` which contains all
   the information needed to call the underlying C-code loops that
   perform the actual work. While it is described here for completeness, it
   should be considered internal to NumPy and manipulated via ``PyUFunc_*``
   functions. The size of this structure is subject to change across versions
   of NumPy. To ensure compatibility:

   - Never declare a non-pointer instance of the struct
   - Never perform pointer arithmetic
   - Never use ``sizeof(PyUFuncObject)``

   It has the following structure:

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          int nin;
          int nout;
          int nargs;
          int identity;
          PyUFuncGenericFunction *functions;
          void **data;
          int ntypes;
          int reserved1;
          const char *name;
          char *types;
          const char *doc;
          void *ptr;
          PyObject *obj;
          PyObject *userloops;
          int core_enabled;
          int core_num_dim_ix;
          int *core_num_dims;
          int *core_dim_ixs;
          int *core_offsets;
          char *core_signature;
          PyUFunc_TypeResolutionFunc *type_resolver;
          PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
          void *reserved2;
          npy_uint32 *op_flags;
          npy_uint32 *iter_flags;
          /* new in API version 0x0000000D */
          npy_intp *core_dim_sizes;
          npy_uint32 *core_dim_flags;
          PyObject *identity_value;
          /* Further private slots (size depends on the NumPy version) */
      } PyUFuncObject;

   .. c:macro: PyObject_HEAD

       required for all Python objects.

   .. c:member:: int nin

       The number of input arguments.

   .. c:member:: int nout

       The number of output arguments.

   .. c:member:: int nargs

       The total number of arguments (*nin* + *nout*). This must be
       less than :c:data:`NPY_MAXARGS`.

   .. c:member:: int identity

       Either :c:data:`PyUFunc_One`, :c:data:`PyUFunc_Zero`,
       :c:data:`PyUFunc_MinusOne`, :c:data:`PyUFunc_None`,
       :c:data:`PyUFunc_ReorderableNone`, or
       :c:data:`PyUFunc_IdentityValue` to indicate
       the identity for this operation. It is only used for a
       reduce-like call on an empty array.

   .. c:member:: void functions( \
          char** args, npy_intp* dims, npy_intp* steps, void* extradata)

       An array of function pointers --- one for each data type
       supported by the ufunc. This is the vector loop that is called
       to implement the underlying function *dims* [0] times. The
       first argument, *args*, is an array of *nargs* pointers to
       behaved memory. Pointers to the data for the input arguments
       are first, followed by the pointers to the data for the output
       arguments. How many bytes must be skipped to get to the next
       element in the sequence is specified by the corresponding entry
       in the *steps* array. The last argument allows the loop to
       receive extra information.  This is commonly used so that a
       single, generic vector loop can be used for multiple
       functions. In this case, the actual scalar function to call is
       passed in as *extradata*. The size of this function pointer
       array is ntypes.

   .. c:member:: void **data

       Extra data to be passed to the 1-d vector loops or ``NULL`` if
       no extra-data is needed. This C-array must be the same size (
       *i.e.* ntypes) as the functions array. ``NULL`` is used if
       extra_data is not needed. Several C-API calls for UFuncs are
       just 1-d vector loops that make use of this extra data to
       receive a pointer to the actual function to call.

   .. c:member:: int ntypes

       The number of supported data types for the ufunc. This number
       specifies how many different 1-d loops (of the builtin data
       types) are available.

   .. c:member:: int reserved1

       Unused.

   .. c:member:: char *name

       A string name for the ufunc. This is used dynamically to build
       the __doc\__ attribute of ufuncs.

   .. c:member:: char *types

       An array of :math:`nargs \times ntypes` 8-bit type_numbers
       which contains the type signature for the function for each of
       the supported (builtin) data types. For each of the *ntypes*
       functions, the corresponding set of type numbers in this array
       shows how the *args* argument should be interpreted in the 1-d
       vector loop. These type numbers do not have to be the same type
       and mixed-type ufuncs are supported.

   .. c:member:: char *doc

       Documentation for the ufunc. Should not contain the function
       signature as this is generated dynamically when __doc\__ is
       retrieved.

   .. c:member:: void *ptr

       Any dynamically allocated memory. Currently, this is used for
       dynamic ufuncs created from a python function to store room for
       the types, data, and name members.

   .. c:member:: PyObject *obj

       For ufuncs dynamically created from python functions, this member
       holds a reference to the underlying Python function.

   .. c:member:: PyObject *userloops

       A dictionary of user-defined 1-d vector loops (stored as CObject
       ptrs) for user-defined types. A loop may be registered by the
       user for any user-defined type. It is retrieved by type number.
       User defined type numbers are always larger than
       :c:data:`NPY_USERDEF`.

   .. c:member:: int core_enabled

       0 for scalar ufuncs; 1 for generalized ufuncs

   .. c:member:: int core_num_dim_ix

       Number of distinct core dimension names in the signature

   .. c:member:: int *core_num_dims

       Number of core dimensions of each argument

   .. c:member:: int *core_dim_ixs

       Dimension indices in a flattened form; indices of argument ``k`` are
       stored in ``core_dim_ixs[core_offsets[k] : core_offsets[k] +
       core_numdims[k]]``

   .. c:member:: int *core_offsets

       Position of 1st core dimension of each argument in ``core_dim_ixs``,
       equivalent to cumsum(``core_num_dims``)

   .. c:member:: char *core_signature

       Core signature string

   .. c:member:: PyUFunc_TypeResolutionFunc *type_resolver

       A function which resolves the types and fills an array with the dtypes
       for the inputs and outputs

   .. c:member:: PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector

       .. deprecated:: 1.22

            Some fallback support for this slot exists, but will be removed
            eventually.  A universal function that relied on this will
            have to be ported eventually.
            See ref:`NEP 41 <NEP41>` and ref:`NEP 43 <NEP43>`

   .. c:member:: void *reserved2

       For a possible future loop selector with a different signature.

   .. c:member:: npy_uint32 op_flags

       Override the default operand flags for each ufunc operand.

   .. c:member:: npy_uint32 iter_flags

       Override the default nditer flags for the ufunc.

   Added in API version 0x0000000D

   .. c:member:: npy_intp *core_dim_sizes

       For each distinct core dimension, the possible
       :ref:`frozen <frozen>` size if
       :c:data:`UFUNC_CORE_DIM_SIZE_INFERRED` is ``0``

   .. c:member:: npy_uint32 *core_dim_flags

       For each distinct core dimension, a set of ``UFUNC_CORE_DIM*`` flags

..
  dedented to allow internal linking, pending a refactoring

.. c:macro:: UFUNC_CORE_DIM_CAN_IGNORE

    if the dim name ends in ``?``

.. c:macro:: UFUNC_CORE_DIM_SIZE_INFERRED

    if the dim size will be determined from the operands
    and not from a :ref:`frozen <frozen>` signature

   .. c:member:: PyObject *identity_value

       Identity for reduction, when :c:member:`PyUFuncObject.identity`
       is equal to :c:data:`PyUFunc_IdentityValue`.

PyArrayIter_Type and PyArrayIterObject
--------------------------------------

.. c:var:: PyTypeObject PyArrayIter_Type

   This is an iterator object that makes it easy to loop over an
   N-dimensional array. It is the object returned from the flat
   attribute of an ndarray. It is also used extensively throughout the
   implementation internals to loop over an N-dimensional array. The
   tp_as_mapping interface is implemented so that the iterator object
   can be indexed (using 1-d indexing), and a few methods are
   implemented through the tp_methods table. This object implements the
   next method and can be used anywhere an iterator can be used in
   Python.

.. c:type:: PyArrayIterObject

   The C-structure corresponding to an object of :c:data:`PyArrayIter_Type` is
   the :c:type:`PyArrayIterObject`. The :c:type:`PyArrayIterObject` is used to
   keep track of a pointer into an N-dimensional array. It contains associated
   information used to quickly march through the array. The pointer can
   be adjusted in three basic ways: 1) advance to the "next" position in
   the array in a C-style contiguous fashion, 2) advance to an arbitrary
   N-dimensional coordinate in the array, and 3) advance to an arbitrary
   one-dimensional index into the array. The members of the
   :c:type:`PyArrayIterObject` structure are used in these
   calculations. Iterator objects keep their own dimension and strides
   information about an array. This can be adjusted as needed for
   "broadcasting," or to loop over only specific dimensions.

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          int   nd_m1;
          npy_intp  index;
          npy_intp  size;
          npy_intp  coordinates[NPY_MAXDIMS];
          npy_intp  dims_m1[NPY_MAXDIMS];
          npy_intp  strides[NPY_MAXDIMS];
          npy_intp  backstrides[NPY_MAXDIMS];
          npy_intp  factors[NPY_MAXDIMS];
          PyArrayObject *ao;
          char  *dataptr;
          npy_bool  contiguous;
      } PyArrayIterObject;

   .. c:member:: int nd_m1

       :math:`N-1` where :math:`N` is the number of dimensions in the
       underlying array.

   .. c:member:: npy_intp index

       The current 1-d index into the array.

   .. c:member:: npy_intp size

       The total size of the underlying array.

   .. c:member:: npy_intp *coordinates

       An :math:`N` -dimensional index into the array.

   .. c:member:: npy_intp *dims_m1

       The size of the array minus 1 in each dimension.

   .. c:member:: npy_intp *strides

       The strides of the array. How many bytes needed to jump to the next
       element in each dimension.

   .. c:member:: npy_intp *backstrides

       How many bytes needed to jump from the end of a dimension back
       to its beginning. Note that ``backstrides[k] == strides[k] *
       dims_m1[k]``, but it is stored here as an optimization.

   .. c:member:: npy_intp *factors

       This array is used in computing an N-d index from a 1-d index. It
       contains needed products of the dimensions.

   .. c:member:: PyArrayObject *ao

       A pointer to the underlying ndarray this iterator was created to
       represent.

   .. c:member:: char *dataptr

       This member points to an element in the ndarray indicated by the
       index.

   .. c:member:: npy_bool contiguous

       This flag is true if the underlying array is
       :c:data:`NPY_ARRAY_C_CONTIGUOUS`. It is used to simplify
       calculations when possible.


How to use an array iterator on a C-level is explained more fully in
later sections. Typically, you do not need to concern yourself with
the internal structure of the iterator object, and merely interact
with it through the use of the macros :c:func:`PyArray_ITER_NEXT` (it),
:c:func:`PyArray_ITER_GOTO` (it, dest), or :c:func:`PyArray_ITER_GOTO1D`
(it, index). All of these macros require the argument *it* to be a
:c:expr:`PyArrayIterObject *`.


PyArrayMultiIter_Type and PyArrayMultiIterObject
------------------------------------------------

.. c:var:: PyTypeObject PyArrayMultiIter_Type

   This type provides an iterator that encapsulates the concept of
   broadcasting. It allows :math:`N` arrays to be broadcast together
   so that the loop progresses in C-style contiguous fashion over the
   broadcasted array. The corresponding C-structure is the
   :c:type:`PyArrayMultiIterObject` whose memory layout must begin any
   object, *obj*, passed in to the :c:func:`PyArray_Broadcast` (obj)
   function. Broadcasting is performed by adjusting array iterators so
   that each iterator represents the broadcasted shape and size, but
   has its strides adjusted so that the correct element from the array
   is used at each iteration.


.. c:type:: PyArrayMultiIterObject

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          int numiter;
          npy_intp size;
          npy_intp index;
          int nd;
          npy_intp dimensions[NPY_MAXDIMS];
          PyArrayIterObject *iters[NPY_MAXDIMS];
      } PyArrayMultiIterObject;

   .. c:macro: PyObject_HEAD

       Needed at the start of every Python object (holds reference count
       and type identification).

   .. c:member:: int numiter

       The number of arrays that need to be broadcast to the same shape.

   .. c:member:: npy_intp size

       The total broadcasted size.

   .. c:member:: npy_intp index

       The current (1-d) index into the broadcasted result.

   .. c:member:: int nd

       The number of dimensions in the broadcasted result.

   .. c:member:: npy_intp *dimensions

       The shape of the broadcasted result (only ``nd`` slots are used).

   .. c:member:: PyArrayIterObject **iters

       An array of iterator objects that holds the iterators for the
       arrays to be broadcast together. On return, the iterators are
       adjusted for broadcasting.

PyArrayNeighborhoodIter_Type and PyArrayNeighborhoodIterObject
--------------------------------------------------------------

.. c:var:: PyTypeObject PyArrayNeighborhoodIter_Type

   This is an iterator object that makes it easy to loop over an
   N-dimensional neighborhood.

.. c:type:: PyArrayNeighborhoodIterObject

   The C-structure corresponding to an object of
   :c:data:`PyArrayNeighborhoodIter_Type` is the
   :c:type:`PyArrayNeighborhoodIterObject`.

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          int nd_m1;
          npy_intp index, size;
          npy_intp coordinates[NPY_MAXDIMS]
          npy_intp dims_m1[NPY_MAXDIMS];
          npy_intp strides[NPY_MAXDIMS];
          npy_intp backstrides[NPY_MAXDIMS];
          npy_intp factors[NPY_MAXDIMS];
          PyArrayObject *ao;
          char *dataptr;
          npy_bool contiguous;
          npy_intp bounds[NPY_MAXDIMS][2];
          npy_intp limits[NPY_MAXDIMS][2];
          npy_intp limits_sizes[NPY_MAXDIMS];
          npy_iter_get_dataptr_t translate;
          npy_intp nd;
          npy_intp dimensions[NPY_MAXDIMS];
          PyArrayIterObject* _internal_iter;
          char* constant;
          int mode;
      } PyArrayNeighborhoodIterObject;

PyArrayFlags_Type and PyArrayFlagsObject
----------------------------------------

.. c:var:: PyTypeObject PyArrayFlags_Type

   When the flags attribute is retrieved from Python, a special
   builtin object of this type is constructed. This special type makes
   it easier to work with the different flags by accessing them as
   attributes or by accessing them as if the object were a dictionary
   with the flag names as entries.

.. c:type:: PyArrayFlagsObject

   .. code-block:: c

      typedef struct PyArrayFlagsObject {
              PyObject_HEAD
              PyObject *arr;
              int flags;
      } PyArrayFlagsObject;


ScalarArrayTypes
----------------

There is a Python type for each of the different built-in data types
that can be present in the array Most of these are simple wrappers
around the corresponding data type in C. The C-names for these types
are ``Py{TYPE}ArrType_Type`` where ``{TYPE}`` can be

    **Bool**, **Byte**, **Short**, **Int**, **Long**, **LongLong**,
    **UByte**, **UShort**, **UInt**, **ULong**, **ULongLong**,
    **Half**, **Float**, **Double**, **LongDouble**, **CFloat**,
    **CDouble**, **CLongDouble**, **String**, **Unicode**, **Void**, and
    **Object**.

These type names are part of the C-API and can therefore be created in
extension C-code. There is also a ``PyIntpArrType_Type`` and a
``PyUIntpArrType_Type`` that are simple substitutes for one of the
integer types that can hold a pointer on the platform. The structure
of these scalar objects is not exposed to C-code. The function
:c:func:`PyArray_ScalarAsCtype` (..) can be used to extract the C-type
value from the array scalar and the function :c:func:`PyArray_Scalar`
(...) can be used to construct an array scalar from a C-value.


Other C-Structures
==================

A few new C-structures were found to be useful in the development of
NumPy. These C-structures are used in at least one C-API call and are
therefore documented here. The main reason these structures were
defined is to make it easy to use the Python ParseTuple C-API to
convert from Python objects to a useful C-Object.


PyArray_Dims
------------

.. c:type:: PyArray_Dims

   This structure is very useful when shape and/or strides information
   is supposed to be interpreted. The structure is:

   .. code-block:: c

      typedef struct {
          npy_intp *ptr;
          int len;
      } PyArray_Dims;

   The members of this structure are

   .. c:member:: npy_intp *ptr

       A pointer to a list of (:c:type:`npy_intp`) integers which
       usually represent array shape or array strides.

   .. c:member:: int len

       The length of the list of integers. It is assumed safe to
       access *ptr* [0] to *ptr* [len-1].


PyArray_Chunk
-------------

.. c:type:: PyArray_Chunk

   This is equivalent to the buffer object structure in Python up to
   the ptr member. On 32-bit platforms (*i.e.* if :c:data:`NPY_SIZEOF_INT`
   == :c:data:`NPY_SIZEOF_INTP`), the len member also matches an equivalent
   member of the buffer object. It is useful to represent a generic
   single-segment chunk of memory.

   .. code-block:: c

      typedef struct {
          PyObject_HEAD
          PyObject *base;
          void *ptr;
          npy_intp len;
          int flags;
      } PyArray_Chunk;

   The members are

   .. c:macro: PyObject_HEAD

       Necessary for all Python objects. Included here so that the
       :c:type:`PyArray_Chunk` structure matches that of the buffer object
       (at least to the len member).

   .. c:member:: PyObject *base

       The Python object this chunk of memory comes from. Needed so that
       memory can be accounted for properly.

   .. c:member:: void *ptr

       A pointer to the start of the single-segment chunk of memory.

   .. c:member:: npy_intp len

       The length of the segment in bytes.

   .. c:member:: int flags

       Any data flags (*e.g.* :c:data:`NPY_ARRAY_WRITEABLE` ) that should
       be used to interpret the memory.


PyArrayInterface
----------------

.. seealso:: :ref:`arrays.interface`

.. c:type:: PyArrayInterface

   The :c:type:`PyArrayInterface` structure is defined so that NumPy and
   other extension modules can use the rapid array interface
   protocol. The :obj:`~object.__array_struct__` method of an object that
   supports the rapid array interface protocol should return a
   :c:type:`PyCapsule` that contains a pointer to a :c:type:`PyArrayInterface`
   structure with the relevant details of the array. After the new
   array is created, the attribute should be ``DECREF``'d which will
   free the :c:type:`PyArrayInterface` structure. Remember to ``INCREF`` the
   object (whose :obj:`~object.__array_struct__` attribute was retrieved) and
   point the base member of the new :c:type:`PyArrayObject` to this same
   object. In this way the memory for the array will be managed
   correctly.

   .. code-block:: c

      typedef struct {
          int two;
          int nd;
          char typekind;
          int itemsize;
          int flags;
          npy_intp *shape;
          npy_intp *strides;
          void *data;
          PyObject *descr;
      } PyArrayInterface;

   .. c:member:: int two

       the integer 2 as a sanity check.

   .. c:member:: int nd

       the number of dimensions in the array.

   .. c:member:: char typekind

       A character indicating what kind of array is present according to the
       typestring convention with 't' -> bitfield, 'b' -> Boolean, 'i' ->
       signed integer, 'u' -> unsigned integer, 'f' -> floating point, 'c' ->
       complex floating point, 'O' -> object, 'S' -> (byte-)string, 'U' ->
       unicode, 'V' -> void.

   .. c:member:: int itemsize

       The number of bytes each item in the array requires.

   .. c:member:: int flags

       Any of the bits :c:data:`NPY_ARRAY_C_CONTIGUOUS` (1),
       :c:data:`NPY_ARRAY_F_CONTIGUOUS` (2), :c:data:`NPY_ARRAY_ALIGNED` (0x100),
       :c:data:`NPY_ARRAY_NOTSWAPPED` (0x200), or :c:data:`NPY_ARRAY_WRITEABLE`
       (0x400) to indicate something about the data. The
       :c:data:`NPY_ARRAY_ALIGNED`, :c:data:`NPY_ARRAY_C_CONTIGUOUS`, and
       :c:data:`NPY_ARRAY_F_CONTIGUOUS` flags can actually be determined from
       the other parameters. The flag :c:data:`NPY_ARR_HAS_DESCR`
       (0x800) can also be set to indicate to objects consuming the
       version 3 array interface that the descr member of the
       structure is present (it will be ignored by objects consuming
       version 2 of the array interface).

   .. c:member:: npy_intp *shape

       An array containing the size of the array in each dimension.

   .. c:member:: npy_intp *strides

       An array containing the number of bytes to jump to get to the next
       element in each dimension.

   .. c:member:: void *data

       A pointer *to* the first element of the array.

   .. c:member:: PyObject *descr

       A Python object describing the data-type in more detail (same
       as the *descr* key in :obj:`~object.__array_interface__`). This can be
       ``NULL`` if *typekind* and *itemsize* provide enough
       information. This field is also ignored unless
       :c:data:`NPY_ARR_HAS_DESCR` flag is on in *flags*.


Internally used structures
--------------------------

Internally, the code uses some additional Python objects primarily for
memory management. These types are not accessible directly from
Python, and are not exposed to the C-API. They are included here only
for completeness and assistance in understanding the code.


.. c:type:: PyUFuncLoopObject

   A loose wrapper for a C-structure that contains the information
   needed for looping. This is useful if you are trying to understand
   the ufunc looping code. The :c:type:`PyUFuncLoopObject` is the associated
   C-structure. It is defined in the ``ufuncobject.h`` header.

.. c:type:: PyUFuncReduceObject

   A loose wrapper for the C-structure that contains the information
   needed for reduce-like methods of ufuncs. This is useful if you are
   trying to understand the reduce, accumulate, and reduce-at
   code. The :c:type:`PyUFuncReduceObject` is the associated C-structure. It
   is defined in the ``ufuncobject.h`` header.

.. c:type:: PyUFunc_Loop1d

   A simple linked-list of C-structures containing the information needed
   to define a 1-d loop for a ufunc for every defined signature of a
   user-defined data-type.

.. c:var:: PyTypeObject PyArrayMapIter_Type

   Advanced indexing is handled with this Python type. It is simply a
   loose wrapper around the C-structure containing the variables
   needed for advanced array indexing. The associated C-structure,
   ``PyArrayMapIterObject``, is useful if you are trying to
   understand the advanced-index mapping code. It is defined in the
   ``arrayobject.h`` header. This type is not exposed to Python and
   could be replaced with a C-structure. As a Python type it takes
   advantage of reference- counted memory management.