/* -*- c -*- */ #include "Python.h" #include "numpy/arrayobject.h" #define _UMATHMODULE #include "numpy/ufuncobject.h" #include "abstract.h" #include /* A whole slew of basic math functions are provided originally by Konrad Hinsen. */ #if !defined(__STDC__) && !defined(_MSC_VER) extern double fmod (double, double); extern double frexp (double, int *); extern double ldexp (double, int); extern double modf (double, double *); #endif #ifndef M_PI #define M_PI 3.14159265358979323846264338328 #endif #ifndef HAVE_INVERSE_HYPERBOLIC static double acosh(double x) { return log(x + sqrt((x-1.0)*(x+1.0))); } static double asinh(double xx) { double x; int sign; if (xx < 0.0) { sign = -1; x = -xx; } else { sign = 1; x = xx; } return sign*log(x + sqrt(x*x+1.0)); } static double atanh(double x) { return 0.5*log((1.0+x)/(1.0-x)); } #endif #ifdef HAVE_HYPOT #if !defined(NeXT) && !defined(_MSC_VER) extern double hypot(double, double); #endif #else double hypot(double x, double y) { double yx; x = fabs(x); y = fabs(y); if (x < y) { double temp = x; x = y; y = temp; } if (x == 0.) return 0.; else { yx = y/x; return x*sqrt(1.+yx*yx); } } #endif /* Define isnan, isinf, isfinite, signbit if needed */ /* Use fpclassify if possible */ /* isnan, isinf -- these will use macros and then fpclassify if available before defaulting to a dumb convert-to-double version... isfinite -- define a macro if not already available signbit -- if macro available use it, otherwise define a function and a dumb convert-to-double version for other types. */ #if defined(fpclassify) #if !defined(isnan) #define isnan(x) (fpclassify(x) == FP_NAN) #endif #if !defined(isinf) #define isinf(x) (fpclassify(x) == FP_INFINITE) #endif #else /* check to see if already have a function like this */ #if !defined(HAVE_ISNAN) #if !defined(isnan) #include "_isnan.c" #endif #endif /* HAVE_ISNAN */ #if !defined(HAVE_ISINF) #if !defined(isinf) #define isinf(x) (!isnan((x)) && isnan((x)-(x))) #endif #endif /* HAVE_ISINF */ #endif /* defined(fpclassify) */ /* Define signbit if needed */ #if !defined(signbit) #include "_signbit.c" #endif /* Now defined the extended type macros */ #if !defined(isnan) #if !defined(HAVE_LONGDOUBLE_FUNCS) || !defined(HAVE_ISNAN) #define isnanl(x) isnan((double)(x)) #endif #if !defined(HAVE_FLOAT_FUNCS) || !defined(HAVE_ISNAN) #define isnanf(x) isnan((double)(x)) #endif #else /* !defined(isnan) */ #define isnanl(x) isnan((x)) #define isnanf(x) isnan((x)) #endif /* !defined(isnan) */ #if !defined(isinf) #if !defined(HAVE_LONGDOUBLE_FUNCS) || !defined(HAVE_ISINF) #define isinfl(x) (!isnanl((x)) && isnanl((x)-(x))) #endif #if !defined(HAVE_FLOAT_FUNCS) || !defined(HAVE_ISINF) #define isinff(x) (!isnanf((x)) && isnanf((x)-(x))) #endif #else /* !defined(isinf) */ #define isinfl(x) isinf((x)) #define isinff(x) isinf((x)) #endif /* !defined(isinf) */ #if !defined(signbit) #define signbitl(x) ((longdouble) signbit((double)(x))) #define signbitf(x) ((float) signbit((double) (x))) #else #define signbitl(x) signbit((x)) #define signbitf(x) signbit((x)) #endif #if !defined(isfinite) #define isfinite(x) (!(isinf((x)) || isnan((x)))) #endif #define isfinitef(x) (!(isinff((x)) || isnanf((x)))) #define isfinitel(x) (!(isinfl((x)) || isnanl((x)))) /* First, the C functions that do the real work */ /* if C99 extensions not availble then define dummy functions that use the double versions for sin, cos, tan sinh, cosh, tanh, fabs, floor, ceil, fmod, sqrt, log10, log, exp, fabs asin, acos, atan, asinh, acosh, atanh hypot, atan2, pow */ /**begin repeat #kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan)*2# #typ=longdouble*16, float*16# #c=l*16,f*16# #TYPE=LONGDOUBLE*16, FLOAT*16# */ #ifndef HAVE_@TYPE@_FUNCS @typ@ @kind@@c@(@typ@ x) { return (@typ@) @kind@((double)x); } #endif /**end repeat**/ /**begin repeat #kind=(atan2,hypot,pow,fmod)*2# #typ=longdouble*4, float*4# #c=l*4,f*4# #TYPE=LONGDOUBLE*4,FLOAT*4# */ #ifndef HAVE_@TYPE@_FUNCS @typ@ @kind@@c@(@typ@ x, @typ@ y) { return (@typ@) @kind@((double)x, (double) y); } #endif /**end repeat**/ /**begin repeat #kind=modf*2# #typ=longdouble, float# #c=l,f# #TYPE=LONGDOUBLE, FLOAT# */ #ifndef HAVE_@TYPE@_FUNCS @typ@ modf@c@(@typ@ x, @typ@ *iptr) { double nx, niptr, y; nx = (double) x; y = modf(nx, &niptr); *iptr = (@typ@) niptr; return (@typ@) y; } #endif /**end repeat**/ #if !defined(HAVE_INVERSE_HYPERBOLIC_FLOAT) #ifdef HAVE_FLOAT_FUNCS static float acoshf(float x) { return logf(x + sqrtf((x-1.0)*(x+1.0))); } static float asinhf(float xx) { float x; int sign; if (xx < 0.0) { sign = -1; x = -xx; } else { sign = 1; x = xx; } return sign*logf(x + sqrtf(x*x+1.0)); } static float atanhf(float x) { return 0.5*logf((1.0+x)/(1.0-x)); } #else static float acoshf(float x) { return (float)acosh((double)(x)); } static float asinhf(float x) { return (float)asinh((double)(x)); } static float atanhf(float x) { return (float)atanh((double)(x)); } #endif #endif #if !defined(HAVE_INVERSE_HYPERBOLIC_LONGDOUBLE) #ifdef HAVE_LONGDOUBLE_FUNCS static longdouble acoshl(longdouble x) { return logl(x + sqrtl((x-1.0)*(x+1.0))); } static longdouble asinhl(longdouble xx) { longdouble x; int sign; if (xx < 0.0) { sign = -1; x = -xx; } else { sign = 1; x = xx; } return sign*logl(x + sqrtl(x*x+1.0)); } static longdouble atanhl(longdouble x) { return 0.5*logl((1.0+x)/(1.0-x)); } #else static longdouble acoshl(longdouble x) { return (longdouble)acosh((double)(x)); } static longdouble asinhl(longdouble x) { return (longdouble)asinh((double)(x)); } static longdouble atanhl(longdouble x) { return (longdouble)atanh((double)(x)); } #endif #endif /* Don't pass structures between functions (only pointers) because how structures are passed is compiler dependent and could cause segfaults if ufuncobject.c is compiled with a different compiler than an extension that makes use of the UFUNC API */ /**begin repeat #typ=float, double, longdouble# #c=f,,l# */ /* constants */ static c@typ@ nc_1@c@ = {1., 0.}; static c@typ@ nc_half@c@ = {0.5, 0.}; static c@typ@ nc_i@c@ = {0., 1.}; static c@typ@ nc_i2@c@ = {0., 0.5}; /* static c@typ@ nc_mi@c@ = {0., -1.}; static c@typ@ nc_pi2@c@ = {M_PI/2., 0.}; */ static void nc_sum@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { r->real = a->real + b->real; r->imag = a->imag + b->imag; return; } static void nc_diff@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { r->real = a->real - b->real; r->imag = a->imag - b->imag; return; } static void nc_neg@c@(c@typ@ *a, c@typ@ *r) { r->real = -a->real; r->imag = -a->imag; return; } static void nc_prod@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { @typ@ ar=a->real, br=b->real, ai=a->imag, bi=b->imag; r->real = ar*br - ai*bi; r->imag = ar*bi + ai*br; return; } static void nc_quot@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { @typ@ ar=a->real, br=b->real, ai=a->imag, bi=b->imag; @typ@ d = br*br + bi*bi; r->real = (ar*br + ai*bi)/d; r->imag = (ai*br - ar*bi)/d; return; } static void nc_floor_quot@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { @typ@ ar=a->real, br=b->real, ai=a->imag, bi=b->imag; @typ@ d = br*br + bi*bi; r->real = floor@c@((ar*br + ai*bi)/d); r->imag = 0; return; } static void nc_sqrt@c@(c@typ@ *x, c@typ@ *r) { @typ@ s,d; if (x->real == 0. && x->imag == 0.) *r = *x; else { s = sqrt@c@(0.5*(fabs@c@(x->real) + hypot@c@(x->real,x->imag))); d = 0.5*x->imag/s; if (x->real > 0.) { r->real = s; r->imag = d; } else if (x->imag >= 0.) { r->real = d; r->imag = s; } else { r->real = -d; r->imag = -s; } } return; } static void nc_log@c@(c@typ@ *x, c@typ@ *r) { @typ@ l = hypot@c@(x->real,x->imag); r->imag = atan2@c@(x->imag, x->real); r->real = log@c@(l); return; } static void nc_exp@c@(c@typ@ *x, c@typ@ *r) { @typ@ a = exp@c@(x->real); r->real = a*cos@c@(x->imag); r->imag = a*sin@c@(x->imag); return; } static void nc_pow@c@(c@typ@ *a, c@typ@ *b, c@typ@ *r) { @typ@ ar=a->real, br=b->real, ai=a->imag, bi=b->imag; if (br == 0. && bi == 0.) { r->real = 1.; r->imag = 0.; } else if (ar == 0. && ai == 0.) { r->real = 0.; r->imag = 0.; } else { nc_log@c@(a, r); nc_prod@c@(r, b, r); nc_exp@c@(r, r); } return; } static void nc_prodi@c@(c@typ@ *x, c@typ@ *r) { r->real = -x->imag; r->imag = x->real; return; } static void nc_acos@c@(c@typ@ *x, c@typ@ *r) { nc_prod@c@(x,x,r); nc_diff@c@(&nc_1@c@, r, r); nc_sqrt@c@(r, r); nc_prodi@c@(r, r); nc_sum@c@(x, r, r); nc_log@c@(r, r); nc_prodi@c@(r, r); nc_neg@c@(r, r); return; /* return nc_neg(nc_prodi(nc_log(nc_sum(x,nc_prod(nc_i, nc_sqrt(nc_diff(nc_1,nc_prod(x,x)))))))); */ } static void nc_acosh@c@(c@typ@ *x, c@typ@ *r) { nc_prod@c@(x, x, r); nc_diff@c@(&nc_1@c@, r, r); nc_sqrt@c@(r, r); nc_prodi@c@(r, r); nc_sum@c@(x, r, r); nc_log@c@(r, r); return; /* return nc_log(nc_sum(x,nc_prod(nc_i, nc_sqrt(nc_diff(nc_1,nc_prod(x,x)))))); */ } static void nc_asin@c@(c@typ@ *x, c@typ@ *r) { c@typ@ a, *pa=&a; nc_prod@c@(x, x, r); nc_diff@c@(&nc_1@c@, r, r); nc_sqrt@c@(r, r); nc_prodi@c@(x, pa); nc_sum@c@(pa, r, r); nc_log@c@(r, r); nc_prodi@c@(r, r); nc_neg@c@(r, r); return; /* return nc_neg(nc_prodi(nc_log(nc_sum(nc_prod(nc_i,x), nc_sqrt(nc_diff(nc_1,nc_prod(x,x))))))); */ } static void nc_asinh@c@(c@typ@ *x, c@typ@ *r) { nc_prod@c@(x, x, r); nc_sum@c@(&nc_1@c@, r, r); nc_sqrt@c@(r, r); nc_diff@c@(r, x, r); nc_log@c@(r, r); nc_neg@c@(r, r); return; /* return nc_neg(nc_log(nc_diff(nc_sqrt(nc_sum(nc_1,nc_prod(x,x))),x))); */ } static void nc_atan@c@(c@typ@ *x, c@typ@ *r) { c@typ@ a, *pa=&a; nc_diff@c@(&nc_i@c@, x, pa); nc_sum@c@(&nc_i@c@, x, r); nc_quot@c@(r, pa, r); nc_log@c@(r,r); nc_prod@c@(&nc_i2@c@, r, r); return; /* return nc_prod(nc_i2,nc_log(nc_quot(nc_sum(nc_i,x),nc_diff(nc_i,x)))); */ } static void nc_atanh@c@(c@typ@ *x, c@typ@ *r) { c@typ@ a, *pa=&a; nc_diff@c@(&nc_1@c@, x, r); nc_sum@c@(&nc_1@c@, x, pa); nc_quot@c@(pa, r, r); nc_log@c@(r, r); nc_prod@c@(&nc_half@c@, r, r); return; /* return nc_prod(nc_half,nc_log(nc_quot(nc_sum(nc_1,x),nc_diff(nc_1,x)))); */ } static void nc_cos@c@(c@typ@ *x, c@typ@ *r) { @typ@ xr=x->real, xi=x->imag; r->real = cos@c@(xr)*cosh@c@(xi); r->imag = -sin@c@(xr)*sinh@c@(xi); return; } static void nc_cosh@c@(c@typ@ *x, c@typ@ *r) { @typ@ xr=x->real, xi=x->imag; r->real = cos(xi)*cosh(xr); r->imag = sin(xi)*sinh(xr); return; } #define M_LOG10_E 0.434294481903251827651128918916605082294397 static void nc_log10@c@(c@typ@ *x, c@typ@ *r) { nc_log@c@(x, r); r->real *= M_LOG10_E; r->imag *= M_LOG10_E; return; } static void nc_sin@c@(c@typ@ *x, c@typ@ *r) { @typ@ xr=x->real, xi=x->imag; r->real = sin@c@(xr)*cosh@c@(xi); r->imag = cos@c@(xr)*sinh@c@(xi); return; } static void nc_sinh@c@(c@typ@ *x, c@typ@ *r) { @typ@ xr=x->real, xi=x->imag; r->real = cos@c@(xi)*sinh@c@(xr); r->imag = sin@c@(xi)*cosh@c@(xr); return; } static void nc_tan@c@(c@typ@ *x, c@typ@ *r) { @typ@ sr,cr,shi,chi; @typ@ rs,is,rc,ic; @typ@ d; @typ@ xr=x->real, xi=x->imag; sr = sin@c@(xr); cr = cos@c@(xr); shi = sinh(xi); chi = cosh(xi); rs = sr*chi; is = cr*shi; rc = cr*chi; ic = -sr*shi; d = rc*rc + ic*ic; r->real = (rs*rc+is*ic)/d; r->imag = (is*rc-rs*ic)/d; return; } static void nc_tanh@c@(c@typ@ *x, c@typ@ *r) { @typ@ si,ci,shr,chr; @typ@ rs,is,rc,ic; @typ@ d; @typ@ xr=x->real, xi=x->imag; si = sin@c@(xi); ci = cos@c@(xi); shr = sinh@c@(xr); chr = cosh@c@(xr); rs = ci*shr; is = si*chr; rc = ci*chr; ic = si*shr; d = rc*rc + ic*ic; r->real = (rs*rc+is*ic)/d; r->imag = (is*rc-rs*ic)/d; return; } /**end repeat**/ /**begin repeat #TYPE=(BOOL, BYTE,UBYTE,SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE)*2# #OP=||, +*13, ^, -*13# #kind=add*14, subtract*14# #typ=(Bool, byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble)*2# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; i> 32); al = (a & 0xFFFFFFFFL); bh = (b >> 32); bl = (b & 0xFFFFFFFFL); #elif SIZEOF_LONGLONG == 128 ah = (a >> 64); al = (a & 0xFFFFFFFFFFFFFFFFL); bh = (b >> 64); bl = (b & 0xFFFFFFFFFFFFFFFFL); #else ah = al = bh = bl = 0; #endif /* 128-bit product: z*2**64 + (x+y)*2**32 + w */ w = al*bl; x = bh*al; y = ah*bl; z = ah*bh; /* *c = ((x + y)<<32) + w; */ #if SIZEOF_LONGLONG == 64 return z || (x>>32) || (y>>32) || (((x & 0xFFFFFFFFL) + (y & 0xFFFFFFFFL) + (w >> 32)) >> 32); #elif SIZEOF_LONGLONG == 128 return z || (x>>64) || (y>>64) || (((x & 0xFFFFFFFFFFFFFFFFL) + (y & 0xFFFFFFFFFFFFFFFFL) + (w >> 64)) >> 64); #else return 0; #endif } static int slonglong_overflow(longlong a0, longlong b0) { ulonglong a, b; ulonglong ah, al, bh, bl, w, x, y, z; /* Convert to non-negative quantities */ if (a0 < 0) { a = -a0; } else { a = a0; } if (b0 < 0) { b = -b0; } else { b = b0; } #if SIZEOF_LONGLONG == 64 ah = (a >> 32); al = (a & 0xFFFFFFFFL); bh = (b >> 32); bl = (b & 0xFFFFFFFFL); #elif SIZEOF_LONGLONG == 128 ah = (a >> 64); al = (a & 0xFFFFFFFFFFFFFFFFL); bh = (b >> 64); bl = (b & 0xFFFFFFFFFFFFFFFFL); #else ah = al = bh = bl = 0; #endif w = al*bl; x = bh*al; y = ah*bl; z = ah*bh; /* ulonglong c = ((x + y)<<32) + w; if ((a0 < 0) ^ (b0 < 0)) *c = -c; else *c = c */ #if SIZEOF_LONGLONG == 64 return z || (x>>31) || (y>>31) || (((x & 0xFFFFFFFFL) + (y & 0xFFFFFFFFL) + (w >> 32)) >> 31); #elif SIZEOF_LONGLONG == 128 return z || (x>>63) || (y>>63) || (((x & 0xFFFFFFFFFFFFFFFFL) + (y & 0xFFFFFFFFFFFFFFFFL) + (w >> 64)) >> 63); #else return 0; #endif } /** end direct numarray code **/ static void BOOL_multiply(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0], is2=steps[1], os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for (i=0; i MAX_@TYP@) generate_overflow_error(); *((@typ@ *)op) = temp; } } /**end repeat**/ static void ULONGLONG_multiply(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0], is2=steps[1], os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; ulonglong temp; for (i=0; i MAX_@TYP@) generate_overflow_error(); else if (temp < MIN_@TYP@) generate_overflow_error(); *((@typ@ *)op) = temp; } } /**end repeat**/ static void LONGLONG_multiply(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0], is2=steps[1], os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; longlong temp; for (i=0; i, >=, <, <=, ==, !=, &&, ||, &, |, ^# **/ static void BOOL_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; Bool in1, in2; for(i=0; i*13, >=*13, <*13, <=*13# #typ=(byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble)*4# #kind= greater*13, greater_equal*13, less*13, less_equal*13# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; i*3, >=*3, <*3, <=*3# #typ=(cfloat, cdouble, clongdouble)*4# #kind= greater*3, greater_equal*3, less*3, less_equal*3# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; ireal == ((@typ@ *)i2)->real) *((Bool *)op)=((@typ@ *)i1)->imag @OP@ \ ((@typ@ *)i2)->imag; else *((Bool *)op)=((@typ@ *)i1)->real @OP@ \ ((@typ@ *)i2)->real; } } /**end repeat**/ /**begin repeat #TYPE=(BYTE,UBYTE,SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE)*4# #typ=(byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble)*4# #OP= ==*13, !=*13, &&*13, ||*13# #kind=equal*13, not_equal*13, logical_and*13, logical_or*13# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; i 0 ? 1 : ((x) < 0 ? -1 : 0)) #define _SIGN2(x) ((x) == 0 ? 0 : 1) #define _SIGNC(x) (((x).real > 0) ? 1 : ((x).real < 0 ? -1 : ((x).imag > 0 ? 1 : ((x).imag < 0) ? -1 : 0))) /**begin repeat #TYPE=BYTE,SHORT,INT,LONG,LONGLONG,FLOAT,DOUBLE,LONGDOUBLE,UBYTE,USHORT,UINT,ULONG,ULONGLONG# #typ=byte,short,int,long,longlong,float,double,longdouble,ubyte,ushort,uint,ulong,ulonglong# #func=_SIGN1*8,_SIGN2*5# */ static void @TYPE@_sign(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],os=steps[1], n=dimensions[0]; char *i1=args[0], *op=args[1]; @typ@ t1; for(i=0; ireal || \ ((@typ@ *)i1)->imag); } } /**end repeat**/ /**begin repeat #TYPE=BYTE,SHORT,INT,LONG,LONGLONG# #typ=byte, short, int, long, longlong# #ftyp=float*2,double*2,longdouble*1# #c=f*2,,,l*1# */ static void @TYPE@_remainder(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; register @typ@ ix,iy, tmp; for(i=0; i 0) == (iy > 0)) { *((@typ@ *)op) = ix % iy; } else { /* handle mixed case the way Python does */ tmp = ix % iy; if (tmp) tmp += iy; *((@typ@ *)op)= tmp; } } } /**end repeat**/ /**begin repeat #TYPE=UBYTE,USHORT,UINT,ULONG,ULONGLONG# #typ=ubyte, ushort, uint, ulong, ulonglong# */ static void @TYPE@_remainder(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; register @typ@ ix,iy; for(i=0; i>*10# #kind=fmod*10, bitwise_and*10, bitwise_or*10, bitwise_xor*10, left_shift*10, right_shift*10# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; ireal || ((@typ@ *)i1)->imag; p2 = ((@typ@ *)i2)->real || ((@typ@ *)i2)->imag; *((Bool *)op)= (p1 || p2) && !(p1 && p2); } } /**end repeat**/ /**begin repeat #TYPE=(BOOL,BYTE,UBYTE,SHORT,USHORT,INT,UINT,LONG,ULONG,LONGLONG,ULONGLONG,FLOAT,DOUBLE,LONGDOUBLE)*2# #OP= >*14, <*14# #typ=(Bool, byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble)*2# #kind= maximum*14, minimum*14# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; for(i=0; i*3, <*3# #typ=(cfloat, cdouble, clongdouble)*2# #kind= maximum*3, minimum*3# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is1=steps[0],is2=steps[1],os=steps[2], n=dimensions[0]; char *i1=args[0], *i2=args[1], *op=args[2]; @typ@ *i1c, *i2c; for(i=0; ireal @OP@ i2c->real) || \ ((i1c->real==i2c->real) && (i1c->imag @OP@ i2c->imag))) memcpy(op, i1, sizeof(@typ@)); else memcpy(op, i2, sizeof(@typ@)); } } /**end repeat**/ /*** isinf, isinf, isfinite, signbit ***/ /**begin repeat #kind=isnan*3, isinf*3, isfinite*3, signbit*3# #TYPE=(FLOAT, DOUBLE, LONGDOUBLE)*4# #typ=(float, double, longdouble)*4# #c=(f,,l)*4# */ static void @TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func) { register intp i; intp is=steps[0], os=steps[1], n=dimensions[0]; char *ip=args[0], *op=args[1]; for(i=0; i