summaryrefslogtreecommitdiff
path: root/base/include/scipy/arrayobject.h
blob: 7136f5c0bf1c797043f24a91f2c50066b37f44cd (plain)
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

/* This expects the following variables to be defined (besides
   the usual ones from pyconfig.h

   SIZEOF_LONG_DOUBLE -- sizeof(long double) or sizeof(double) if no
                         long double is present on platform.
   CHAR_BIT       --     number of bits in a char (usually 8)
                         (should be in limits.h)
*/

#ifndef Py_ARRAYOBJECT_H
#define Py_ARRAYOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif

#include "config.h"

/* There are several places in the code where an array of dimensions is */
/* allocated statically.  This is the size of that static allocation. */

#define MAX_DIMS 40

/* Used for Converter Functions "O&" code in ParseTuple */
#define PY_FAIL 0
#define PY_SUCCEED 1

#define NUMERIC_VERSION 0x0300

	/* Some platforms don't define bool, long long, or long double.
	   Handle that here.
	 */

#ifdef PY_LONG_LONG
typedef PY_LONG_LONG longlong;
typedef unsigned PY_LONG_LONG ulonglong;
#  ifdef _MSC_VER
#    define LONGLONG_FMT         "%I64d"
#    define ULONGLONG_FMT        "%I64u"
#    define LONGLONG_SUFFIX(x)   (x##i64)
#    define ULONGLONG_SUFFIX(x)  (x##Ui64)
#  else
	/* #define LONGLONG_FMT   "%lld"      Another possible variant
           #define ULONGLONG_FMT  "%llu"

	   #define LONGLONG_FMT   "%qd"   -- BSD perhaps?
	   #define ULONGLONG_FMT   "%qu"
	*/
#    define LONGLONG_FMT         "%Ld"
#    define ULONGLONG_FMT        "%Lu"
#    define LONGLONG_SUFFIX(x)   (x##LL)
#    define ULONGLONG_SUFFIX(x)  (x##ULL)
#  endif
#else
typedef long longlong;
typedef unsigned long ulonglong;
#  define LONGLONG_SUFFIX(x)  (x##L)
#  define ULONGLONG_SUFFIX(x) (x##UL)
#endif


typedef unsigned char bool;
#define false 0
#define true 1

#if SIZEOF_LONG_DOUBLE==SIZEOF_DOUBLE
	typedef double longdouble;
        #define LONGDOUBLE_FMT "g"
#else
	typedef long double longdouble;
        #define LONGDOUBLE_FMT "Lg"
#endif

#ifndef Py_USING_UNICODE
#define Py_UNICODE char
#endif


typedef signed char byte;
typedef unsigned char ubyte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;

typedef struct { float real, imag; } cfloat;
typedef struct { double real, imag; } cdouble;
typedef struct {longdouble real, imag;} clongdouble;

enum PyArray_TYPES {    PyArray_BOOL=0,
                        PyArray_BYTE, PyArray_UBYTE,
		        PyArray_SHORT, PyArray_USHORT,
		        PyArray_INT, PyArray_UINT,
			PyArray_LONG, PyArray_ULONG,
                        PyArray_LONGLONG, PyArray_ULONGLONG,
			PyArray_FLOAT, PyArray_DOUBLE, PyArray_LONGDOUBLE,
			PyArray_CFLOAT, PyArray_CDOUBLE, PyArray_CLONGDOUBLE,
			PyArray_OBJECT=17,
                        PyArray_STRING, PyArray_UNICODE,
			PyArray_VOID,
			PyArray_NTYPES,
			PyArray_NOTYPE,
};

	/* How many floating point types are there */
#define PyArray_NUM_FLOATTYPE 3


	/* We need to match intp to a signed integer of the same size as
	   a pointer variable. uintp to the equivalent unsigned integer
	*/


	/* These characters correspond to the array type and the
	   struct module */

	/*  except 'p' -- signed integer for pointer type */

enum PyArray_TYPECHAR { PyArray_BOOLLTR = '?',
			PyArray_BYTELTR = 'b',
			PyArray_UBYTELTR = 'B',
			PyArray_SHORTLTR = 'h',
			PyArray_USHORTLTR = 'H',
			PyArray_INTLTR = 'i',
			PyArray_UINTLTR = 'I',
			PyArray_LONGLTR = 'l',
			PyArray_ULONGLTR = 'L',  
			PyArray_LONGLONGLTR = 'q',   
			PyArray_ULONGLONGLTR = 'Q',
			PyArray_FLOATLTR = 'f',
			PyArray_DOUBLELTR = 'd',
			PyArray_LONGDOUBLELTR = 'g',
			PyArray_CFLOATLTR = 'F',
			PyArray_CDOUBLELTR = 'D',
			PyArray_CLONGDOUBLELTR = 'G',
			PyArray_OBJECTLTR = 'O',
			PyArray_STRINGLTR = 'S',
			PyArray_UNICODELTR = 'U',
		        PyArray_VOIDLTR = 'V',

			/* No Descriptor, just a define -- this let's
			 Python users specify an array of integers
			 large enough to hold a pointer on the platform*/
			PyArray_INTPLTR = 'p',
			PyArray_UINTPLTR = 'P',

			PyArray_GENSIGNED = 'i',
			PyArray_GENUNSIGNED = 'u',
			PyArray_GENFLOAT = 'f',
			PyArray_GENCOMPLEX = 'c'
};

	/* Define bit-width array types and typedefs */

#define MAKEFLOAT(x) x.

#define MAX_INT8 127
#define MIN_INT8 -128
#define MAX_UINT8 255
#define MAX_INT16 32767
#define MIN_INT16 -32768
#define MAX_UINT16 65535
#define MAX_INT32 2147483647
#define MIN_INT32 (-MAX_INT32 - 1)
#define MAX_UINT32 4294967295U
#define MAX_INT64 LONGLONG_SUFFIX(9223372036854775807)
#define MIN_INT64 (-MAX_INT64 - LONGLONG_SUFFIX(1))
#define MAX_UINT64 ULONGLONG_SUFFIX(18446744073709551615)
#define MAX_INT128 LONGLONG_SUFFIX(85070591730234615865843651857942052864)
#define MIN_INT128 (-MAX_INT128 - LONGLONG_SUFFIX(1))
#define MAX_UINT128 ULONGLONG_SUFFIX(170141183460469231731687303715884105728)
#define MAX_INT256 LONGLONG_SUFFIX(57896044618658097711785492504343953926634992332820282019728792003956564819967)
#define MIN_INT256 (-MAX_INT256 - LONGLONG_SUFFIX(1))
#define MAX_UINT256 ULONGLONG_SUFFIX(115792089237316195423570985008687907853269984665640564039457584007913129639935)

#define Bool bool;

	/* Need to find the number of bits for each type and 
	   make definitions accordingly. 

	   C states that sizeof(char) == 1 by definition 
	   
	   So, just using the sizeof keyword won't help.  

	   It also looks like Python itself uses sizeof(char) quite a
	   bit, which by definition should be 1 all the time.

	   Idea: Make Use of CHAR_BIT which should tell us how many
	   BITS per CHARACTER
	*/

	/* Include platform definitions -- These are in the C89/90 standard */
#include <limits.h>  
#define MAX_BYTE SCHAR_MAX
#define MIN_BYTE SCHAR_MIN
#define MAX_UBYTE UCHAR_MAX
#define MAX_SHORT SHRT_MAX
#define MIN_SHORT SHRT_MIN
#define MAX_USHORT USHRT_MAX
#define MAX_INT   INT_MAX
#ifndef INT_MIN
#define INT_MIN (-INT_MAX - 1)
#endif
#define MIN_INT   INT_MIN
#define MAX_UINT  UINT_MAX
#define MAX_LONG  LONG_MAX
#define MIN_LONG  LONG_MIN
#define MAX_ULONG  ULONG_MAX

#define SIZEOF_LONGDOUBLE SIZEOF_LONG_DOUBLE
#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
#define BITSOF_BOOL sizeof(bool)*CHAR_BIT
#define BITSOF_CHAR CHAR_BIT
#define BITSOF_SHORT (SIZEOF_SHORT*CHAR_BIT)
#define BITSOF_INT (SIZEOF_INT*CHAR_BIT)
#define BITSOF_LONG (SIZEOF_LONG*CHAR_BIT)
#define BITSOF_LONGLONG (SIZEOF_LONGLONG*CHAR_BIT)
#define BITSOF_FLOAT (SIZEOF_FLOAT*CHAR_BIT)
#define BITSOF_DOUBLE (SIZEOF_DOUBLE*CHAR_BIT)
#define BITSOF_LONGDOUBLE (SIZEOF_LONGDOUBLE*CHAR_BIT)


#if BITSOF_LONG == 8
#define PyArray_INT8 PyArray_LONG
#define PyArray_UINT8 PyArray_ULONG
	typedef long Int8;
	typedef unsigned long UInt8;
#define STRBITSOF_LONG "8"
#elif BITSOF_LONG == 16
#define PyArray_INT16 PyArray_LONG
#define PyArray_UINT16 PyArray_ULONG
	typedef long Int16;
	typedef unsigned long UInt16;
#define STRBITSOF_LONG "16"
#elif BITSOF_LONG == 32
#define PyArray_INT32 PyArray_LONG
#define PyArray_UINT32 PyArray_ULONG
	typedef long Int32;
	typedef unsigned long UInt32;
#define STRBITSOF_LONG "32"
#elif BITSOF_LONG == 64
#define PyArray_INT64 PyArray_LONG
#define PyArray_UINT64 PyArray_ULONG
	typedef long Int64;
	typedef unsigned long UInt64;
#define STRBITSOF_LONG "64"
#elif BITSOF_LONG == 128
#define PyArray_INT128 PyArray_LONG
#define PyArray_UINT128 PyArray_ULONG
	typedef long Int128;
	typedef unsigned long UInt128;
#define STRBITSOF_LONG "128"
#endif

#if BITSOF_LONGLONG == 8
#  ifndef PyArray_INT8
#    define PyArray_INT8 PyArray_LONGLONG
#    define PyArray_UINT8 PyArray_ULONGLONG
	typedef longlong Int8;
	typedef ulonglong UInt8;
#  endif
#  define MAX_LONGLONG MAX_INT8
#  define MIN_LONGLONG MIN_INT8
#  define MAX_ULONGLONG MAX_UINT8
#define STRBITSOF_LONGLONG "8"
#elif BITSOF_LONGLONG == 16
#  ifndef PyArray_INT16
#    define PyArray_INT16 PyArray_LONGLONG
#    define PyArray_UINT16 PyArray_ULONGLONG
	typedef longlong Int16;
	typedef ulonglong UInt16;
#  endif
#  define MAX_LONGLONG MAX_INT16
#  define MIN_LONGLONG MIN_INT16
#  define MAX_ULONGLONG MAX_UINT16
#define STRBITSOF_LONGLONG "16"
#elif BITSOF_LONGLONG == 32
#  ifndef PyArray_INT32
#    define PyArray_INT32 PyArray_LONGLONG
#    define PyArray_UINT32 PyArray_ULONGLONG
	typedef longlong Int32;
	typedef ulonglong UInt32;
#  endif
#  define MAX_LONGLONG MAX_INT32
#  define MIN_LONGLONG MIN_INT32
#  define MAX_ULONGLONG MAX_UINT32
#define STRBITSOF_LONGLONG "32"
#elif BITSOF_LONGLONG == 64
#  ifndef PyArray_INT64
#    define PyArray_INT64 PyArray_LONGLONG
#    define PyArray_UINT64 PyArray_ULONGLONG
	typedef longlong Int64;
	typedef ulonglong UInt64;
#  endif
#  define MAX_LONGLONG MAX_INT64
#  define MIN_LONGLONG MIN_INT64
#  define MAX_ULONGLONG MAX_UINT64
#define STRBITSOF_LONGLONG "64"
#elif BITSOF_LONGLONG == 128
#  ifndef PyArray_INT128
#    define PyArray_INT128 PyArray_LONGLONG
#    define PyArray_UINT128 PyArray_ULONGLONG
	typedef longlong Int128;
	typedef ulonglong UInt128;
#  endif
#  define MAX_LONGLONG MAX_INT128
#  define MIN_LONGLONG MIN_INT128
#  define MAX_ULONGLONG MAX_UINT128
#define STRBITSOF_LONGLONG "128"
#elif BITSOF_LONGLONG == 256
#  define PyArray_INT256 PyArray_LONGLONG
#  define PyArray_UINT256 PyArray_ULONGLONG
	typedef longlong Int256;
	typedef ulonglong UInt256;
#  define MAX_LONGLONG MAX_INT256
#  define MIN_LONGLONG MIN_INT256
#  define MAX_ULONGLONG MAX_UINT256
#define STRBITSOF_LONGLONG "256"
#endif

#if BITSOF_INT == 8
#ifndef PyArray_INT8
#define PyArray_INT8 PyArray_INT
#define PyArray_UINT8 PyArray_UINT
	typedef int Int8;
	typedef unsigned int UInt8;
#endif
#define STRBITSOF_INT "8"
#elif BITSOF_INT == 16
#ifndef PyArray_INT16
#define PyArray_INT16 PyArray_INT
#define PyArray_UINT16 PyArray_UINT
	typedef int Int16;
	typedef unsigned int UInt16;
#endif
#define STRBITSOF_INT "16"
#elif BITSOF_INT == 32
#ifndef PyArray_INT32
#define PyArray_INT32 PyArray_INT
#define PyArray_UINT32 PyArray_UINT
	typedef int Int32;
	typedef unsigned int UInt32;
#endif
#define STRBITSOF_INT "32"
#elif BITSOF_INT == 64
#ifndef PyArray_INT64
#define PyArray_INT64 PyArray_INT
#define PyArray_UINT64 PyArray_UINT
	typedef int Int64;
	typedef unsigned int UInt64;
#endif
#define STRBITSOF_INT "64"
#elif BITSOF_INT == 128
#ifndef PyArray_INT128
#define PyArray_INT128 PyArray_INT
#define PyArray_UINT128 PyArray_UINT
	typedef int Int128;
	typedef unsigned int UInt128;
#endif
#define STRBITSOF_INT "128"
#endif

#if BITSOF_SHORT == 8
#ifndef PyArray_INT8
#define PyArray_INT8 PyArray_SHORT
#define PyArray_UINT8 PyArray_USHORT
	typedef short Int8;
	typedef unsigned short UInt8;
#endif
#define STRBITSOF_SHORT "8"
#elif BITSOF_SHORT == 16
#ifndef PyArray_INT16
#define PyArray_INT16 PyArray_SHORT
#define PyArray_UINT16 PyArray_USHORT
	typedef short Int16;
	typedef unsigned short UInt16;
#endif
#define STRBITSOF_SHORT "16"
#elif BITSOF_SHORT == 32
#ifndef PyArray_INT32
#define PyArray_INT32 PyArray_SHORT
#define PyArray_UINT32 PyArray_USHORT
	typedef short Int32;
	typedef unsigned short UInt32;
#endif
#define STRBITSOF_SHORT "32"
#elif BITSOF_SHORT == 64
#ifndef PyArray_INT64
#define PyArray_INT64 PyArray_SHORT
#define PyArray_UINT64 PyArray_USHORT
	typedef short Int64;
	typedef unsigned short UInt64;
#endif
#define STRBITSOF_SHORT "64"
#elif BITSOF_SHORT == 128
#ifndef PyArray_INT128
#define PyArray_INT128 PyArray_SHORT
#define PyArray_UINT128 PyArray_USHORT
	typedef short Int128;
	typedef unsigned short UInt128;
#endif
#define STRBITSOF_SHORT "128"
#endif


#if BITSOF_CHAR == 8
#ifndef PyArray_INT8
#define PyArray_INT8 PyArray_BYTE
#define PyArray_UINT8 PyArray_UBYTE
	typedef signed char Int8;
	typedef unsigned char UInt8;
#endif
#define STRBITSOF_CHAR "8"
#elif BITSOF_CHAR == 16
#ifndef PyArray_INT16
#define PyArray_INT16 PyArray_BYTE
#define PyArray_UINT16 PyArray_UBYTE
	typedef signed char Int16;
	typedef unsigned char UInt16;
#endif
#define STRBITSOF_CHAR "16"
#elif BITSOF_CHAR == 32
#ifndef PyArray_INT32
#define PyArray_INT32 PyArray_BYTE
#define PyArray_UINT32 PyArray_UBYTE
	typedef signed char Int32;
	typedef unsigned char UInt32;
#endif
#define STRBITSOF_CHAR "32"
#elif BITSOF_CHAR == 64
#ifndef PyArray_INT64
#define PyArray_INT64 PyArray_BYTE
#define PyArray_UINT64 PyArray_UBYTE
	typedef signed char Int64;
	typedef unsigned char UInt64;
#endif
#define STRBITSOF_CHAR "64"
#elif BITSOF_CHAR == 128
#ifndef PyArray_INT128
#define PyArray_INT128 PyArray_BYTE
#define PyArray_UINT128 PyArray_UBYTE
	typedef signed char Int128;
	typedef unsigned char UInt128;
#endif
#define STRBITSOF_CHAR "128"
#endif



#if BITSOF_DOUBLE == 16
#define STRBITSOF_DOUBLE "16"
#define STRBITSOF_CDOUBLE "32"
#ifndef PyArray_FLOAT16
#define PyArray_FLOAT16 PyArray_DOUBLE
#define PyArray_COMPLEX32 PyArray_CDOUBLE
	typedef  double Float16;
	typedef cdouble Complex32;
#endif
#elif BITSOF_DOUBLE == 32
#define STRBITSOF_DOUBLE "32"
#define STRBITSOF_CDOUBLE "64"
#ifndef PyArray_FLOAT32
#define PyArray_FLOAT32 PyArray_DOUBLE
#define PyArray_COMPLEX64 PyArray_CDOUBLE
	typedef double Float32;
	typedef cdouble Complex64;
#endif
#elif BITSOF_DOUBLE == 64
#define STRBITSOF_DOUBLE "64"
#define STRBITSOF_CDOUBLE "128"
#ifndef PyArray_FLOAT64
#define PyArray_FLOAT64 PyArray_DOUBLE
#define PyArray_COMPLEX128 PyArray_CDOUBLE
	typedef double Float64;
	typedef cdouble Complex128;
#endif
#elif BITSOF_DOUBLE == 80
#define STRBITSOF_DOUBLE "80"
#define STRBITSOF_CDOUBLE "160"
#ifndef PyArray_FLOAT80
#define PyArray_FLOAT80 PyArray_DOUBLE
#define PyArray_COMPLEX160 PyArray_CDOUBLE
	typedef double Float80
	typedef cdouble Complex160
#endif
#elif BITSOF_DOUBLE == 96
#define STRBITSOF_DOUBLE "96"
#define STRBITSOF_CDOUBLE "192"
#ifndef PyArray_FLOAT96
#define PyArray_FLOAT96 PyArray_DOUBLE
#define PyArray_COMPLEX192 PyArray_CDOUBLE
	typedef double Float96;
	typedef cdouble Complex192;
#endif
#elif BITSOF_DOUBLE == 128
#define STRBITSOF_DOUBLE "128"
#define STRBITSOF_CDOUBLE "256"
#ifndef PyArray_FLOAT128
#define PyArray_FLOAT128 PyArray_DOUBLE
#define PyArray_COMPLEX256 PyArray_CDOUBLE
	typedef double Float128;
	typedef cdouble Complex256;
#endif
#endif



#if BITSOF_FLOAT == 16
#define STRBITSOF_FLOAT "16"
#define STRBITSOF_CFLOAT "32"
#ifndef PyArray_FLOAT16
#define PyArray_FLOAT16 PyArray_FLOAT
#define PyArray_COMPLEX32 PyArray_CFLOAT
	typedef float Float16;
	typedef cfloat Complex32;
#endif
#elif BITSOF_FLOAT == 32
#define STRBITSOF_FLOAT "32"
#define STRBITSOF_CFLOAT "64"
#ifndef PyArray_FLOAT32
#define PyArray_FLOAT32 PyArray_FLOAT
#define PyArray_COMPLEX64 PyArray_CFLOAT
	typedef float Float32;
	typedef cfloat Complex64;
#endif
#elif BITSOF_FLOAT == 64
#define STRBITSOF_FLOAT "64"
#define STRBITSOF_CFLOAT "128"
#ifndef PyArray_FLOAT64
#define PyArray_FLOAT64 PyArray_FLOAT
#define PyArray_COMPLEX128 PyArray_CFLOAT
	typedef float Float64;
	typedef cfloat Complex128;
#endif
#elif BITSOF_FLOAT == 80
#define STRBITSOF_FLOAT "80"
#define STRBITSOF_CFLOAT "160"
#ifndef PyArray_FLOAT80
#define PyArray_FLOAT80 PyArray_FLOAT
#define PyArray_COMPLEX160 PyArray_CFLOAT
	typedef float Float80
	typedef cfloat Complex160
#endif
#elif BITSOF_FLOAT == 96
#define STRBITSOF_FLOAT "96"
#define STRBITSOF_CFLOAT "192"
#ifndef PyArray_FLOAT96
#define PyArray_FLOAT96 PyArray_FLOAT
#define PyArray_COMPLEX192 PyArray_CFLOAT
	typedef float Float96;
	typedef cfloat Complex192;
#endif
#elif BITSOF_FLOAT == 128
#define STRBITSOF_FLOAT "128"
#define STRBITSOF_CFLOAT "256"
#ifndef PyArray_FLOAT128
#define PyArray_FLOAT128 PyArray_FLOAT
#define PyArray_COMPLEX256 PyArray_CFLOAT
	typedef float Float128;
	typedef cfloat Complex256;
#endif
#endif


#if BITSOF_LONGDOUBLE == 16
#define STRBITSOF_LONGDOUBLE "16"
#define STRBITSOF_CLONGDOUBLE "32"
#ifndef PyArray_FLOAT16
#define PyArray_FLOAT16 PyArray_LONGDOUBLE
#define PyArray_COMPLEX32 PyArray_CLONGDOUBLE
	typedef  longdouble Float16;
	typedef clongdouble Complex32;
#endif
#elif BITSOF_LONGDOUBLE == 32
#define STRBITSOF_LONGDOUBLE "32"
#define STRBITSOF_CLONGDOUBLE "64"
#ifndef PyArray_FLOAT32
#define PyArray_FLOAT32 PyArray_LONGDOUBLE
#define PyArray_COMPLEX64 PyArray_CLONGDOUBLE
	typedef longdouble Float32;
	typedef clongdouble Complex64;
#endif
#elif BITSOF_LONGDOUBLE == 64
#define STRBITSOF_LONGDOUBLE "64"
#define STRBITSOF_CLONGDOUBLE "128"
#ifndef PyArray_FLOAT64
#define PyArray_FLOAT64 PyArray_LONGDOUBLE
#define PyArray_COMPLEX128 PyArray_CLONGDOUBLE
	typedef longdouble Float64;
	typedef clongdouble Complex128;
#endif
#elif BITSOF_LONGDOUBLE == 80
#define STRBITSOF_LONGDOUBLE "80"
#define STRBITSOF_CLONGDOUBLE "160" 
#ifndef PyArray_FLOAT80
#define PyArray_FLOAT80 PyArray_LONGDOUBLE
#define PyArray_COMPLEX160 PyArray_CLONGDOUBLE
	typedef longdouble Float80
	typedef clongdouble Complex160
#endif
#elif BITSOF_LONGDOUBLE == 96
#define STRBITSOF_LONGDOUBLE "96"
#define STRBITSOF_CLONGDOUBLE "192"
#ifndef PyArray_FLOAT96
#define PyArray_FLOAT96 PyArray_LONGDOUBLE
#define PyArray_COMPLEX192 PyArray_CLONGDOUBLE
	typedef longdouble Float96;
	typedef clongdouble Complex192;
#endif
#elif BITSOF_LONGDOUBLE == 128
#define STRBITSOF_LONGDOUBLE "128"
#define STRBITSOF_CLONGDOUBLE "256"
#ifndef PyArray_FLOAT128
#define PyArray_FLOAT128 PyArray_LONGDOUBLE
#define PyArray_COMPLEX256 PyArray_CLONGDOUBLE
	typedef longdouble Float128;
	typedef clongdouble Complex256;
#endif
#elif BITSOF_LONGDOUBLE == 256
#define STRBITSOF_LONGDOUBLE "256"
#define STRBITSOF_CLONGDOUBLE "512"
#define PyArray_FLOAT256 PyArray_LONGDOUBLE
#define PyArray_COMPLEX512 PyArray_CLONGDOUBLE
	typedef longdouble Float256;
	typedef clongdouble Complex512;
#endif


	/* End of typedefs for numarray style bit-width names */

/* This is to typedef Intp to the appropriate pointer size for this platform.
 * Py_intptr_t, Py_uintptr_t are defined in pyport.h. */
typedef Py_intptr_t intp;
typedef Py_uintptr_t uintp;

#if SIZEOF_PY_INTPTR_T == SIZEOF_INT  
	#define PyArray_INTP PyArray_INT
	#define PyArray_UINTP PyArray_UINT
        #define PyIntpArrType_Type PyIntArrType_Type
        #define PyUIntpArrType_Type PyUIntArrType_Type
	#define MAX_INTP MAX_INT
	#define MIN_INTP MIN_INT
	#define MAX_UINTP MAX_UINT
#elif SIZEOF_PY_INTPTR_T == SIZEOF_LONG
	#define PyArray_INTP PyArray_LONG
	#define PyArray_UINTP PyArray_ULONG
        #define PyIntpArrType_Type PyLongArrType_Type
        #define PyUIntpArrType_Type PyULongArrType_Type
	#define MAX_INTP MAX_LONG
	#define MIN_INTP MIN_LONG
	#define MAX_UINTP MAX_ULONG
#elif defined(PY_LONG_LONG) && (SIZEOF_PY_INTPTR_T == SIZEOF_LONG_LONG)
	#define PyArray_INTP PyArray_LONGLONG
	#define PyArray_UINTP PyArray_ULONGLONG
        #define PyIntpArrType_Type PyLongLongArrType_Type
        #define PyUIntpArrType_Type PyULongLongArrType_Type
	#define MAX_INTP MAX_LONGLONG
	#define MIN_INTP MIN_LONGLONG
	#define MAX_UINTP MAX_ULONGLONG
#endif

#define ERR(str) fprintf(stderr, #str); fflush(stderr);
#define ERR2(str) fprintf(stderr, str); fflush(stderr);

  /* Macros to define how array, and dimension/strides data is
     allocated. 
  */

  /* Data buffer */
#define PyDataMem_NEW(size) ((char *)malloc(size))
  /* #define PyArrayMem_NEW(size) PyMem_NEW(char, size)*/
#define PyDataMem_FREE(ptr)  free(ptr)
#define PyDataMem_XFREE(ptr) if (ptr) free(ptr)
  /* #define PyArrayMem_FREE(ptr) PyMem_Free(ptr) */
#define PyDataMem_RENEW(ptr,size) ((char *)realloc(ptr,size))

  /* Dimensions and strides */
#define PyDimMem_NEW(size) ((intp *)malloc(size*sizeof(intp)))
#define PyDimMem_FREE(ptr) free(ptr)
#define PyDimMem_XFREE(ptr) if (ptr) free(ptr)
#define PyDimMem_RENEW(ptr,size) ((intp *)realloc(ptr,size*sizeof(intp)))


struct PyArrayObject;   /* Forward */

typedef PyObject *(PyArray_UnaryFunc)(struct PyArrayObject *, PyObject *);
typedef PyObject *(PyArray_BinaryFunc)(struct PyArrayObject *, PyObject *, \
					 PyObject *);

  /* These must deal with unaligned and unbyteswapped data if necessary */
typedef PyObject * (PyArray_GetItemFunc) (char *, struct PyArrayObject *);
typedef int (PyArray_SetItemFunc)(PyObject *, char *, struct PyArrayObject *);

typedef int (PyArray_CompareFunc)(const void *, const void *,
				  struct PyArrayObject *);
typedef int (PyArray_CopySwapNFunc)(void *, void *, intp, int, int);
typedef int (PyArray_CopySwapFunc)(void *, void *, int, int);
typedef int (PyArray_NonzeroFunc)(void *, struct PyArrayObject *);


  /* These assume aligned and byteswapped data -- a buffer will be
      used before or contiguous data will be obtained
  */
typedef int (PyArray_ArgFunc)(void*, intp, intp*, struct PyArrayObject *);
typedef int (PyArray_DotFunc)(char *, int, char *, int,
			      char *, int, struct PyArrayObject *);
typedef int (PyArray_VectorUnaryFunc)(void *, void *, intp,
				      struct PyArrayObject *,
				      struct PyArrayObject *);
typedef int (PyArray_ScanFunc)(FILE *, void *, int, char *);


typedef struct {
	/* Functions to cast to all other standard types*/
	PyArray_VectorUnaryFunc *cast[PyArray_NTYPES];

	/* Functions to get and set items with standard
	   Python types -- not array scalars */
	PyArray_GetItemFunc *getitem;
	PyArray_SetItemFunc *setitem;

	/* Function to compare items */
	PyArray_CompareFunc *compare;

  	/* Function to select largest */
	PyArray_ArgFunc *argmax;

	/* Function to compute dot product */
	PyArray_DotFunc	*dotfunc;	   
	
	/* Function to scan an ASCII file and 
	   place a single value plus possible separator */
	PyArray_ScanFunc *scanfunc;

	/* Copy and/or swap data.  Memory areas may not overlap */
	/*  Use memmove first if they might */
	PyArray_CopySwapNFunc *copyswapn;
        PyArray_CopySwapFunc *copyswap;
	
	/* Function to determine if data is zero or not */
	PyArray_NonzeroFunc *nonzero;

 	PyTypeObject *typeobj;  /* the type object for this type */
	int type_num;           /* number representing this type */
	int elsize;             /* element size for this type -- 
				   or 0 if variable */
       	int alignment;          /* alignment needed for this type */
	char type;              /* character representing this type */

} PyArray_Descr;


typedef struct PyArrayObject {
	PyObject_HEAD
	char *data;             /* pointer to raw data buffer */
	int nd;                 /* number of dimensions, also called ndim */ 
	intp *dimensions;       /* size in each dimension */
        intp *strides;          /* bytes to jump to get to the 
				   next element in each dimension */
	PyObject *base;         /* This object should be decref'd
				   upon deletion of array */
	                        /* For views it points to the original array */
	                        /* For creation from buffer object it points 
				   to an object that shold be decref'd on 
				   deletion */
	                        /* For UPDATEIFCOPY flag this is an array 
				   to-be-updated upon deletion of this one */
	PyArray_Descr *descr;   /* Pointer to type structure */
	int flags;              /* Flags describing array -- see below*/
	int itemsize;           /* needed for Flexible size arrays:
                                   CHAR, UNICODE, and VOID arrays
 			         */ 
	PyObject *weakreflist;  /* For weakreferences */

} PyArrayObject;

#define fortran fortran_  /* For some compilers */

typedef struct {   /* Just the type_num and itemsize variables 
		      for use in the TypeNum Converter function */
	int type_num;
	int itemsize;
	int fortran;  /* Set to 1 if fortran-defined strides is desired */
} PyArray_Typecode;

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


/* Mirrors buffer object to ptr */

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

/* Array flags */
#define CONTIGUOUS     1      /* means c-style contiguous (last index
			       varies the fastest) data elements right
			      after each other. */

	                      /* All 0-d arrays are CONTIGUOUS and FORTRAN
				 contiguous.  If a 1-d array is CONTIGUOUS
				 it is also FORTRAN contiguous 
			      */

	/* Not used -- always assumed 
#define OWN_DIMENSIONS 2  
#define OWN_STRIDES    4  
	*/

#define OWN_DATA       8

#define FORTRAN    0x020    /* set if array is a contiguous Fortran array */
	                    /*  first index varies the fastest in memory
			        (strides array is reverse of C-contiguous
			           array)*/

	/* array never has these two set -- FromAny flags only */
#define FORCECAST     0x040    
#define ENSURECOPY    0x080 	

#define ALIGNED       0x100
#define NOTSWAPPED    0x200
#define WRITEABLE     0x400

  /* Flag used in creating a new array, not set in the array */

	/* If this flags is set, then base contains a pointer to 
	   an array of the same size that should be updated with the 
	   current contents of this array when this array is deallocated
	*/
#define UPDATEIFCOPY  0x1000


/* Size of internal buffers used for alignment */
#define PyArray_BUFSIZE 10000*sizeof(double)
#define PyArray_MIN_BUFSIZE 5
#define PyArray_MAX_BUFSIZE MAX_INT32
#define MAXBUFNUM 1024


#define BEHAVED_FLAGS ALIGNED | NOTSWAPPED | WRITEABLE
#define BEHAVED_FLAGS_RO ALIGNED | NOTSWAPPED
#define CARRAY_FLAGS CONTIGUOUS | BEHAVED_FLAGS
#define FARRAY_FLAGS FORTRAN | BEHAVED_FLAGS
#define DEFAULT_FLAGS CARRAY_FLAGS

#define UPDATE_ALL_FLAGS CONTIGUOUS | FORTRAN | ALIGNED


/*
 * C API:  consists of Macros and functions.  The MACROS are defined here. 
 */


#define PyArray_CHKFLAGS(m, FLAGS) \
	((((PyArrayObject *)(m))->flags & (FLAGS)) == (FLAGS))
#define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, CONTIGUOUS)
#define PyArray_ISONESEGMENT(m) (PyArray_CHKFLAGS(m, CONTIGUOUS) ||	\
				 PyArray_CHKFLAGS(m, FORTRAN))
#define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, WRITEABLE)

#define PyArray_ISCARRAY(m) PyArray_CHKFLAGS(m, CARRAY_FLAGS)
#define PyArray_ISFARRAY(m) PyArray_CHKFLAGS(m, FARRAY_FLAGS)
#define PyArray_ISBEHAVED(m) PyArray_CHKFLAGS(m, BEHAVED_FLAGS)
#define PyArray_ISBEHAVED_RO(m) PyArray_CHKFLAGS(m, BEHAVED_FLAGS_RO)


#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif

        /* Useful if a and b have to be evaluated.  */

#define tMAX(a,b,typ) {typ _x_=(a); typ _y_=(b); _x_>_y_ ? _x_ : _y_}
#define tMIN(a,b,typ) {typ _x_=(a); typ _y_=(b); _x_<_y_ ? _x_ : _y_}

#if defined(ALLOW_THREADS)
#define BEGIN_THREADS Py_BEGIN_ALLOW_THREADS
#define END_THREADS   Py_END_ALLOW_THREADS
#define END_THREADS_FAIL Py_UNBLOCK_THREADS
#define ALLOW_C_API_DEF  PyGILState_STATE __save__;
#define ALLOW_C_API      __save__ = PyGILState_Ensure();
#define DISABLE_C_API    PyGILState_Release(__save__);
#else
#define BEGIN_THREADS
#define END_THREADS
#define END_THREADS_FAIL
#define ALLOW_C_API_DEF
#define	ALLOW_C_API    
#define	DISABLE_C_API  
#endif

typedef struct {
        PyObject_HEAD
	int                     nd_m1;            /* number of dimensions - 1 */
        intp		        index, size;
	intp                    coordinates[MAX_DIMS];/* N-dimensional loop */
        intp                    dims_m1[MAX_DIMS];    /* ao->dimensions - 1 */
	intp                    strides[MAX_DIMS];    /* ao->strides or fake */
	intp                    backstrides[MAX_DIMS];/* how far to jump back */
	intp                    factors[MAX_DIMS];     /* shape factors */
	PyArrayObject           *ao;
	char                    *dataptr;        /* pointer to current item*/
        unsigned char           contiguous;
} PyArrayIterObject;


/* Iterator API */ 
#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
	
#define PyArray_ITER_RESET(it) {					\
	it->index = 0;						        \
	it->dataptr = it->ao->data;					\
	memset(it->coordinates, 0, (it->nd_m1+1)*sizeof(intp));		\
}


#define PyArray_ITER_NEXT(it) {				\
	it->index++;					\
	if (it->contiguous)  it->dataptr += it->ao->itemsize;	       \
	else {								\
		int _i_;						\
		for (_i_ = it->nd_m1; _i_ >= 0; _i_--) {		\
			if (it->coordinates[_i_] <			\
			    it->dims_m1[_i_]) {				\
				it->coordinates[_i_]++;			\
				it->dataptr += it->strides[_i_];	\
				break;					\
			}						\
			else {						\
				it->coordinates[_i_] = 0;		\
				it->dataptr -= it->backstrides[_i_];	\
			}						\
		}							\
	}								\
}

#define PyArray_ITER_GOTO(it, destination) {				\
		int _i_;						\
		it->index = 0;						\
		it->dataptr = it->ao->data;				\
		for (_i_ = it->nd_m1; _i_>=0; _i_--) {			\
			it->dataptr += destination[_i_] *		\
				it->strides[_i_];			\
			it->coordinates[_i_] = destination[_i_];	\
			it->index += destination[_i_] *			\
				( _i_==it->nd_m1 ? 1 :			\
				  it->dims_m1[i+1]+1) ;	  	        \
		}							\
	} 

#define PyArray_ITER_GOTO1D(it, ind) {                                  \
		int _i_;						\
		intp _lind_ = (intp) (ind);				\
		it->index = _lind_;					\
		if (it->contiguous)					\
			it->dataptr = it->ao->data + (ind) *		\
				it->ao->itemsize;			\
		else {							\
			it->dataptr = it->ao->data;			\
			for (_i_ = it->nd_m1; _i_>=0; _i_--) {		\
				it->dataptr += (_lind_ / it->factors[_i_]) \
					* it->strides[_i_];		\
				_lind_ %= it->factors[_i_];		\
			}						\
		}							\
}

/* Not constructed anywhere.  Just serves as a standard type that
   PyArray_Broadcast expects.

   Any object passed to PyArray_Broadcast must be binary compatible with 
   this structure.    
*/


typedef struct {
	PyObject_HEAD

	int                     numiter;               /* number of iters */
	intp                    size;                  /* broadcasted size */
	intp                    index;                 /* current index */
	int                     nd;                    /* number of dims */
	intp                    dimensions[MAX_DIMS];  /* dimensions */
	PyArrayIterObject       *iters[MAX_DIMS];      /* iterators */
} PyArrayMultiIterObject;  
	

/* Store the information needed for fancy-indexing over an array */

typedef struct {
	PyObject_HEAD
	/* Multi-iterator portion --- needs to be present in this order to 
	   work with PyArray_Broadcast */

	int                     numiter;               /* number of index-array
							  iterators */
	intp                    size;                  /* size of broadcasted 
							  result */
	intp                    index;                 /* current index */
	int                     nd;                    /* number of dims */
	intp                    dimensions[MAX_DIMS];  /* dimensions */
	PyArrayIterObject       *iters[MAX_DIMS];      /* index object 
							  iterators */
	PyArrayIterObject       *ait;                   /* flat Iterator for 
							  underlying array */

	/* flat iterator for subspace (when numiter < nd) */
	PyArrayIterObject       *subspace;

	/* if subspace iteration, then this is the array of 
	   axes in the underlying array represented by the
	   index objects */
	int                     iteraxes[MAX_DIMS];
	/* if subspace iteration, the these are the coordinates
	   to the start of the subspace.
	*/
	intp                    bscoord[MAX_DIMS];

	
	PyObject                *indexobj;             /* reference to 
							  creating obj */
	int                     view;
	int                     consec;
	char                    *dataptr;

} PyArrayMapIterObject;


/* Map Iterator API */ 
#define PyArrayMapIter_Check(op) PyObject_TypeCheck(op, &PyArrayMapIter_Type)


#define PyArray_NDIM(obj) (((PyArrayObject *)(obj))->nd)
#define PyArray_ISFORTRAN(m) (PyArray_CHKFLAGS(m, FORTRAN) && (PyArray_NDIM(m) > 1))
#define PyArray_DATA(obj) (((PyArrayObject *)(obj))->data)
#define PyArray_DIMS(obj) (((PyArrayObject *)(obj))->dimensions)
#define PyArray_STRIDES(obj) (((PyArrayObject *)(obj))->strides)
#define PyArray_DIM(obj,n) (((PyArrayObject *)(obj))->dimensions[n])
#define PyArray_STRIDE(obj,n) (((PyArrayObject *)(obj))->strides[n])
#define PyArray_BASE(obj) (((PyArrayObject *)(obj))->base)
#define PyArray_DESCR(obj) (((PyArrayObject *)(obj))->descr)
#define PyArray_FLAGS(obj) (((PyArrayObject *)(obj))->flags)
#define PyArray_ITEMSIZE(obj) (((PyArrayObject *)(obj))->itemsize)
#define PyArray_TYPE(obj) (((PyArrayObject *)(obj))->descr->type_num)
#define PyArray_GETITEM(obj,itemptr)			\
	((PyArrayObject *)(obj))->descr->getitem((char *)itemptr,	\
						 (PyArrayObject *)obj);
#define PyArray_SETITEM(obj,itemptr,v)					\
	(obj)->descr->setitem((PyObject *)v,(char *)(itemptr),		\
			      (PyArrayObject *)(obj));


#define PyTypeNum_ISBOOL(type) (type == PyArray_BOOL)
#define PyTypeNum_ISUNSIGNED(type) ((type == PyArray_UBYTE) || \
				 (type == PyArray_USHORT) || \
				 (type == PyArray_UINT) ||	\
				 (type == PyArray_ULONG) || \
				 (type == PyArray_ULONGLONG))

#define PyTypeNum_ISSIGNED(type) ((type == PyArray_BYTE) ||	\
			       (type == PyArray_SHORT) ||	\
			       (type == PyArray_INT) ||	\
			       (type == PyArray_LONG) ||	\
			       (type == PyArray_LONGLONG))

#define PyTypeNum_ISINTEGER(type) ((type >= PyArray_BYTE) &&	\
				(type <= PyArray_ULONGLONG))
       
#define PyTypeNum_ISFLOAT(type) ((type >= PyArray_FLOAT) &&  \
			      (type <= PyArray_LONGDOUBLE))

#define PyTypeNum_ISNUMBER(type) (type <= PyArray_CLONGDOUBLE)

#define PyTypeNum_ISSTRING(type) ((type == PyArray_UCHAR) || \
			       (type == PyArray_UNICODE))

#define PyTypeNum_ISCOMPLEX(type) ((type >= PyArray_CFLOAT) && \
				(type <= PyArray_CLONGDOUBLE))
	
#define PyTypeNum_ISPYTHON(type) ((type == PyArray_LONG) || \
				  (type == PyArray_DOUBLE) ||	\
				  (type == PyArray_CDOUBLE) ||	\
				  (type == PyArray_OBJECT ))

#define PyTypeNum_ISFLEXIBLE(type) ((type==PyArray_STRING) || \
				    (type==PyArray_UNICODE) ||	\
				    (type==PyArray_VOID))

#define PyTypeNum_ISOBJECT(type) ((type) == PyArray_OBJECT)

#define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
#define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))
#define PyArray_ISSIGNED(obj) PyTypeNum_ISSIGNED(PyArray_TYPE(obj))
#define PyArray_ISINTEGER(obj) PyTypeNum_ISINTEGER(PyArray_TYPE(obj))
#define PyArray_ISFLOAT(obj) PyTypeNum_ISFLOAT(PyArray_TYPE(obj))
#define PyArray_ISNUMBER(obj) PyTypeNum_ISNUMBER(PyArray_TYPE(obj))
#define PyArray_ISSTRING(obj) PyTypeNum_ISSTRING(PyArray_TYPE(obj))
#define PyArray_ISCOMPLEX(obj) PyTypeNum_ISCOMPLEX(PyArray_TYPE(obj))
#define PyArray_ISPYTHONTYPE(obj) PyTypeNum_ISPYTHONTYPE(PyArray_TYPE(obj))
#define PyArray_ISFLEXIBLE(obj) PyTypeNum_ISFLEXIBLE(PyArray_TYPE(obj))
#define PyArray_ISOBJECT(obj) PyTypeNum_ISOBJECT(PyArray_TYPE(obj))

/* Object arrays ignore notswapped flag */
#define PyArray_ISNOTSWAPPED(m) (PyArray_CHKFLAGS(m, NOTSWAPPED) || \
				 PyArray_ISOBJECT(m))


  /*  Often, rather than always convert to an array, 
      we may want to delegate behavior for other objects passed in
  */

	/* 

#define Py_DELEGATE(op, name)                                     \
	if (PyObject_HasAttrString(op, #name)) {                  \
		PyObject *ret=NULL;				  \
		PyObject *meth=PyObject_GetAttrString(op, #name); \
		if (PyCallable_Check(meth)) {			  \
			ret = PyObject_CallObject(meth, NULL);	  \
		}						  \
		Py_XDECREF(meth);				  \
		return ret;					  \
	}

#define Py_DELEGATE_ARGS(op, name, args)			  \
	if (PyObject_HasAttrString(op, #name)) {                  \
		PyObject *ret=NULL;				  \
		PyObject *meth=PyObject_GetAttrString(op, #name); \
		if (PyCallable_Check(meth)) {			  \
			ret = PyObject_CallObject(meth, args);	  \
		}						  \
                Py_XDECREF(args);                                 \
		Py_XDECREF(meth);				  \
		return ret;					  \
	}

#define Py_DELEGATE_ARGS_KWDS(op, name, args, kwds)	          \
	if (PyObject_HasAttrString(op, #name)) {                  \
		PyObject *ret=NULL;				  \
		PyObject *meth=PyObject_GetAttrString(op, #name); \
		if (PyCallable_Check(meth)) {			  \
			ret = PyObject_Call(meth, args, kwds);	  \
		}						  \
                Py_XDECREF(args);                                 \
		Py_XDECREF(meth);				  \
		return ret;					  \
	}
	*/


        /* Includes the "function" C-API -- these are all stored in a 
	   list of pointers --- one for each file
	   The two lists are concatenated into one in multiarray.
	   
	   They are available as import_array()
         */

#include "__multiarray_api.h"


        /* C-API that requries previous API to be defined */

#define PyArray_Check(op) (PyObject_TypeCheck((op), &PyArray_Type))
#define PyArray_CheckExact(op) ((op)->ob_type == &PyArray_Type)

#define PyArray_CheckScalar(m) (PyObject_TypeCheck((m),			\
						   &PyGenericArrType_Type) \
				|| ((PyArray_Check((m))) &&		\
				    (((PyArrayObject *)(m))->nd == 0)))
#define PyArray_IsScalar(obj, cls)				\
	(PyObject_TypeCheck((obj), &Py##cls##ArrType_Type))
#define PyArray_GETCONTIGUOUS(m) (PyArray_ISCONTIGUOUS(m) ? Py_INCREF(m), m : \
	  (PyArrayObject *)(PyArray_ContiguousFromObject((PyObject *)(m), \
		                      PyArray_TYPE(m), 0, 0))) 

#define PyArray_SIZE(m) PyArray_MultiplyList(PyArray_DIMS(m), PyArray_NDIM(m))
#define PyArray_NBYTES(m) (PyArray_ITEMSIZE(m) * PyArray_SIZE(m))
#define PyArray_FROM_O(m) PyArray_FromAny(m, NULL, 0, 0, 0)
#define PyArray_FROM_OF(m,flags) PyArray_FromAny(m, NULL, 0, 0, flags)
#define REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
#define MAX_ELSIZE 2*SIZEOF_LONGDOUBLE

        /*Compatibility with old Numeric stuff -- don't use in new code */

#define PyArray_UNSIGNED_TYPES
#define PyArray_SBYTE PyArray_BYTE
#define PyArray_CHAR PyArray_BYTE


#ifdef __cplusplus
}
#endif

#endif /* !Py_ARRAYOBJECT_H */