use Array: all; use SimplePrint: all; use SimpleFibre: all; use Math: all; use String:{tochar}; /* % Start of boilerplate % This is used to generate the APEX stdlib.sis include file. % Standard equates and constants for APL compiler % Also standard coercion functions % For SAC, we map names of system variables, system functions, % quad, and quote-quadfrom APL symbols to legal SAC names % by replacing the quad/quote-quad with QUAD or QUOTEQUAD. % This happens in the syntax analyzer, for lack of a better % place. We also map quad/quote-quad to function calls, % removing the assignment. R. Bernecky 2004-06-11 */ /* Empty vectors */ #define EMPTYBOOL _drop_SxV_(1, [true]) #define EMPTYINT _drop_SxV_(1, [0]) #define EMPTYDOUBLE _drop_SxV_(1, [0d]) #define EMPTYCHAR _drop_SxV_(1, [' ']) /* end of empty array jokes */ void APEXERROR(char[.] msg) { /* Error function. This needs work, as it should kill * the running task, too. */ /*print(msg); */ return(); } /* Structural function utility functions */ inline int VectorRotateAmount(int x, int y) { /* Normalize x rotate for array of shape y on selected axis */ /* normalize rotation count */ if (x>0) z = _mod_(x,y); else z = y - _mod_(_abs_(x),y); return(z); } /* First-axis catenate, stolen from NTCtemplates_array.mac */ /** * * @fn [*] psel( int[.] idx, [*] Array) * * @brief selects the subarray of Array at position idx, provided * shape( idx)[[0]] <= dim( Array) holds. * ******************************************************************************/ #define PSEL( a) \ inline \ a[*] psel( int[.] idx, a[*] array) \ { \ new_shape = _drop_SxV_( _sel_( [0], _shape_(idx)), _shape_(array)); \ res = with( . <= iv <= .) { \ new_idx = _cat_VxV_( idx, iv); \ } genarray( new_shape, _sel_(new_idx, array), zero( array)); \ return( res); \ } #define BUILT_IN( fun) \ fun( int) \ fun( float) \ fun( double) \ fun( bool) \ fun( char) BUILT_IN( PSEL) #define CAT( a) \ inline \ a[*] (++)( a[+] arr_a, a[+] arr_b) \ { \ new_shp = _modarray_( _shape_( arr_a), \ [0], \ _add_SxS_( _sel_([0], _shape_( arr_a)), \ _sel_([0], _shape_( arr_b)) ) ); \ res = with( . <= iv < _shape_( arr_a)) \ genarray( new_shp, _sel_( iv, arr_a)); \ offset = _modarray_( _mul_SxA_( 0, new_shp), \ [0], \ _sel_([0], _shape_( arr_a)) ); \ res = with( offset <= iv <= .) \ modarray( res, iv, _sel_( _sub_AxA_( iv, offset), arr_b)); \ return( res); \ } /* scalar take matrix, adapted from NTCtemplates_array.mac */ #define APLTAKE(a) \ inline \ a[*] take( int v, a[*] array) \ { \ v2 = _shape_(array); \ v2 = modarray(v2,[0],v); \ return( take(v2,array)); \ } #define APEXPI 3.1415926535897932d #define APEXE 2.718281828d /* APEXPINFINITYI largest integer */ #define APEXPINFINITYD 1.7976931348623156D308 /* APEXMINFINITYI smallest integer */ #define APEXMINFINITYD -1.7976931348623156D308 /* % Various coercion functions */ #define toB(y) (tob(y)) #define toI(y) (toi(y)) #define toD(y) (tod(y)) #define toC(y) (y) inline bool[+] tob (bool[+] x) { z = with (. <= iv <= .) genarray(_shape_(x),tob(_sel_(iv,x))); return(z); } inline bool[+] tob (int[+] x) { z = with (. <= iv <= .) genarray(_shape_(x),tob(_sel_(iv,x))); return(z); } inline bool[+] tob (double[+] x) { z = with (. <= iv <= .) genarray(_shape_(x),tob(_sel_(iv,x))); return(z); } inline bool tob(bool x) { return(x); } inline bool tob(int x) { if (1 == _toi_S_(x)) z = true; else z = false; return(z); } inline bool tob(double x) { if (1 == _toi_S_(x)) z = true; else z = false; return(z); } inline int BtoI(bool x) { if (x) z = 1; else z = 0; return(z); } inline double BtoD(bool x) { if (x) z = 1.0d; else z = 0d; return(z); } #define BtoC(x) error[character] inline bool ItoB0(int x) { if (1 == x) z = true; else if (0 == x) z = false; else { /* error("domain error on BtoC\n"); stupid string vs array*/ z = false; } return(z); } #define ItoD(x) double(x) #define ItoC(x) error[character] inline bool DtoB(double x) { z = true; if (0d == x) z = false; /* stupid string vs array else error("domain error in DtoB\n"); */ return(z); } /* this is BROKEN 2004-08-24 rbe inline int DtoI(double x) { stupid string vs array if (x != trunc(x)) error("domain error in DtoI\n"); return(x); } * BROKEN */ #define DtoC(x) error[character] #define CtoB(x) error[boolean] #define CtoI(x) error[integer] #define CtoD(x) error[double_real] /* end of scalar coercions */ /* % Floating-point utilities % This taken from page 93 of the 1993-01-06 version % of Committee Draft 1 of the Extended ISO APL Standard % NO {quad}ct support yet! */ #define Dsignum(p) (if p = 0.0d0 then 0 elseif p<0.0d0 then -1 else 1 end if) #define Isignum(p) (if p = 0 then 0 elseif p<0 then -1 else 1 end if) #define Dmod(p,q) fmod(tod(p),tod(q)) #define Imod(p,q) _mod_(p,q) /* % 1996-12-07 Pearl Harbor Day. Try to fix bug in DBank infdivm % benchmark. (4 5 rho 6) + rank 1 (4 1 rho 7) introduces singleton % vectors into scalar fn calls. % Hence, we need support for singletons within scalar fns. % There is an similar, but independent, bug in rank support for % the extension case. */ /* vector-scalar simple search loops * This is origin-0 x1 iota y0 * cfn is comparator function type suffix to use, e.g, b,i,d,c, */ #ifdef BROKEN #define FindFirst(x,y,cfn,QUADct) \ sx = _shape_(x)[0]; \ z = sx; /* if not found */ \ for(i=0; i y[[j,i]]}); \ } \ inline TYPE[.,.,.] APEXTranspose(TYPE[.,.,.] y) \ { /* Rank-3 transpose */ \ return({[i,j,k] -> y[[k,j,i]]}); \ } \ inline TYPE[.,.,.,.] APEXTranspose(TYPE[.,.,.,.] y) \ { /* Rank-4 transpose */ \ return({[i,j,k,l] -> y[[l,k,j,i]]}); \ } \ inline TYPE[.,.,.,.,.] APEXTranspose(TYPE[.,.,.,.,.] y) \ { /* Rank-5 transpose */ \ return({[i,j,k,l,m] -> y[[m,l,k,j,i]]}); \ } \ inline TYPE[.,.,.,.,.,.] APEXTranspose(TYPE[.,.,.,.,.,.] y) \ { /* Rank-6 transpose */ \ return({[i,j,k,l,m,n] -> y[[n,m,l,k,j,i]]}); \ } \ inline TYPE[.,.,.,.,.,.,.] APEXTranspose(TYPE[.,.,.,.,.,.,.] y) \ { /* Rank-7 transpose */ \ return({[i,j,k,l,m,n,o] -> y[[o,n,m,l,k,j,i]]}); \ } APEXTRANSPOSE(bool) APEXTRANSPOSE(int) APEXTRANSPOSE(double) APEXTRANSPOSE(char) /* End of transpose utilities */ /* modulus functions */ inline int Dmodulo(int x, int y, double QUADct) { if (0 == x) z = 0; else z = Imod(y,x); return(z); } inline double Dmodulo(double x, double y, double QUADct) { /* See page 93 of the 1993-01-06 version of Committee Draft 1 of the Extended ISO APL Standard THIS NEEDS WORK TO SUPPORT QUADct!!!! */ if (0.0d == x) z = 0.0d; else z = Dmod(y,x); return(z); } /* End of boilerplate */ /* * Monadic scalar function code fragments * rbe 2004-03-29 */ /* Floor: Identity if not floating */ #define mminXBB(YV) (YV) #define mminXII(YV) (YV) #define mminXDD(YV) (floor(YV) /* Ceiling: Identity if not floating */ #define mmaxXBB(YV) (YV) #define mmaxXII(YV) (YV) #define mmaxXDD(YV) (-floor-(YV) /* Signum */ #define mmpyXBB(YV) (YV) #define mmpyXII(YV) (Isignum(YV)) #define mmpyXDD(YV) (Dsignum(YV)) /* Reciprocal */ #define mdivXBD(YV) (1.0d/$YT##toD(YV)) #define mdivXID(YV) (1.0d/$YT##toD(YV)) #define mdivXDD(YV) (1.0d/$YT##toD(YV)) /* Not */ #define mnotXBB(YV) (~YV) #define mnotXIB(YV) (~ItoB(YV)) #define mnotXDB(YV) (~DtoB(YV)) /* Exponential */ #define mexpXBD(YV) (exp(BtoD(YV)) #define mexpXID(YV) (exp(ItoD(YV)) #define mexpXDD(YV) (exp(YV)) /* Logarithm */ #define mlogXBD(YV) (log(BtoD(YV)) #define mlogXID(YV) (log(ItoD(YV)) #define mlogXDD(YV) (log(DtoD(YV)) /* Pi-times */ #define mcircXBD(YV) (PI*BtoD(YV)) #define mcircXID(YV) (PI*ItoD(YV)) #define mcircXDD(YV) (PI*YV) /* % Dyadic Scalar Function kernel macro definitions % Function names are defined as: % {valence, jsymbol, compute type, result type} % Having result type available will let us support things like % int*int where we know result will be integer, rather than being % required to support double_real result. 1996-05-05 */ /* x plus y */ #define dplusBBI(XV,YV) (toi(XV)+toi(YV)) #define dplusBII(XV,YV) (toi(XV)+YV) #define dplusIBI(XV,YV) (XV+toi(YV)) #define dplusIII(XV,YV) (XV+YV) #define dplusDDD(XV,YV) (XV+YV) #define dplusBDD(XV,YV) (tod(XV)+YV) #define dplusDBD(XV,YV) (XV+tod(YV)) #define dplusIDD(XY,YV) (tod(XV)+YV) #define dplusDID(XV,YV) (XV+tod(YV)) /* x minus y */ #define dbarBBI(XV,YV) (toi(XV)-toi(YV)) #define dbarIBI(XV,YV) (XV-toi(YV)) #define dbarBII(XV,YV) (XV-YV) #define dbarIII(XV,YV) (XV-YV) #define dbarIDD(XV,YV) (tod(XV)-YV) #define dbarDID(XV,YV) (XV-tod(YV)) #define dbarDDD(XV,YV) (XV-YV) #define dbarBDD(XV,YV) (tod(XV)-YV) #define dbarDBD(XV,YV) (XV-tod(YV)) /* x times y */ #define dmpyBBB(XV,YV) (XV&YV) #define dmpyIII(XV,YV) (XV*YV) #define dmpyDDD(XV,YV) (XV*YV) #define dmpyBII(XV,YV) (toi(XV)*YV) #define dmpyIBI(XV,YV) (XV*toi(YV)) #define dmpyBDD(XV,YV) (tod(XV)*YV) #define dmpyDBD(XV,YV) (XV*tod(YV)) #define dmpyDID(XV,YV) (XV*tod(YV)) #define dmpyIDD(XV,YV) (tod(XV)*YV) /* x divided by y */ inline double APEX_DIVIDEDD (double X, double Y) { if (X == Y) z = 1.0d; else z = X/Y; return(z); } #define ddivBDD(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivIDD(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivDDD(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivBID(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivIID(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivDID(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivBBD(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivIBD(XV,YV) (APEX_DIVIDEDD(XV,YV)) #define ddivDBD(XV,YV) (APEX_DIVIDEDD(XV,YV)) /* x min y */ inline int APEX_MINII (int x, int y) { if (x <= y) z = x; else z = y; return (z); } inline char APEX_MINCC (char x, char y) { if (x <= y) z = x; else z = y; return (z); } inline double APEX_MINDD (double x, double y) { if (x <= y) z = x; else z = y; return (z); } #define dminBBB(XV,YV) (XV&YV) #define dminIII(XV,YV) (APEX_MINII(XV,YV)) #define dminDDD(XV,YV) (APEX_MINDD(XV,YV)) #define dminCCC(XV,YV) (APEX_MINCC(XV,YV)) #define dminBII(XV,YV) (APEX_MINII(toi(XV),YV)) #define dminIBI(XV,YV) (APEX_MINII(XV,toi(YV))) #define dminBDD(XV,YV) (APEX_MINDD(tod(XV),YV)) #define dminDBD(XV,YV) (APEX_MINDD(XV,tod(YV))) #define dminIDD(XV,YV) (APEX_MINDD(tod(XV),YV)) #define dminDID(XV,YV) (APEX_MINDD(XV,tod(YV))) /* NB. max and min extended to characters */ inline int APEX_MAXII (int x, int y) { if (x >= y) z = x; else z = y; return (z); } inline char APEX_MAXCC (char x, char y) { if (x >= y) z = x; else z = y; return (z); } inline double APEX_MAXDD (double x, double y) { if (x >= y) z = x; else z = y; return (z); } /* x max y */ #define dmaxBBB(XV,YV) (XV|YV) #define dmaxIII(XV,YV) (APEX_MAXII(XV,YV)) #define dmaxDDD(XV,YV) (APEX_MAXDD(XV,YV)) #define dmaxCCC(XV,YV) (APEX_MAXCC(XV,YV)) #define dmaxBII(XV,YV) (APEX_MAXII(toi(XV),YV)) #define dmaxIBI(XV,YV) (APEX_MAXII(XV,toi(YV))) #define dmaxBDD(XV,YV) (APEX_MAXDD(tod(XV),YV)) #define dmaxDBD(XV,YV) (APEX_MAXDD(XV,tod(YV))) #define dmaxIDD(XV,YV) (APEX_MAXDD(tod(XV),YV)) #define dmaxDID(XV,YV) (APEX_MAXDD(XV,tod(YV))) /* x mod y */ #define dmodBBB(XV,YV,QUADct) ((~XV)&YV) #define dmodIII(XV,YV,QUADct) (Dmodulo(XV,YV)) #define dmodDDD(XV,YV,QUADct) (Dmodulo(XV,YV)) /* x star y */ #define dstarBBB(XV,YV) (XV|~YV) #define dstarIDD(XV,YV) (exp(XV,YV)) #define dstarDDD(XV,YV) (exp(XV,YV)) /* The dstari fragment will not work in integer type because EmitDyadicScalarFns % (and everyone else!) uses lhtype,rhtype to compute fragment % type. This fails for general star because we do not know that % the result type is going to be double_real, as we can not % ascertain that the right argument is positive. % Do it the slow way for now... 1995-11-18 % Actually, now that we have predicates, we can do better! 1996-04-30 */ #define dlogBDD(XV,YV) (log(YV)/log(XV)) #define dlogIDD(XV,YV) (log(YV)/log(XV)) #define dlogDDD(XV,YV) (log(YV)/log(XV)) /* NB. Extension of ISO APL to allow comparison of characters */ /* relationals */ #define dltBBB(XV,YV,QUADct) ((~XV)&YV) #define dltIBB(XV,YV,QUADct) (XVYV) #define dgtDDB(XV,YV,QUADct) (XV>YV) #define dgtCCB(XV,YV,QUADct) (XV>YV) #define dgeBBB(XV,YV,QUADct) (XV|~YV) #define dgeIIB(XV,YV,QUADct) (XV>=YV) #define dgeDDB(XV,YV,QUADct) (XV>=YV) #define dgeCCB(XV,YV,QUADct) (XV>=YV) /* As of 2004-09-16, we don't support lcm/gcd. Needs work in code generator and dfa to support side effects in scan, etc. rbe */ #define dandBBB(XV,YV) (XV&YV) /* Euclids algorithm for lcm */ #define dandII(XV,YV) (for initial ax := abs(XV); ay := abs(YV); \ u = min(ax,ay); v := max (ax,ay); \ while (v ~= 0) repeat \ v := mod(old u,old v); \ u := old v; \ returns value of (ax*ay)/u \ end for) /* Euclids algorithm for lcm */ #define dandDD(XV,YV) (for initial ax := abs(XV); ay := abs(YV); \ u = min(ax,ay); v := max (ax,ay); \ while (v ~= 0) repeat \ v := mod(old u,old v); \ u := old v; \ returns value of (ax*ay)/u \ end for) #define dorBBB(XV,YV) (XV||YV) /* Euclids algorithm for gcd */ #define dorII(XV,YV) (for initial \ ax := abs(XV); ay := abs(YV); \ u = min(ax,ay); v := max (ax,ay); \ while (v ~= 0) repeat \ v := mod(old u,old v); \ u := old v; \ returns value of u \ end for) /* Euclids algorithm for gcd */ #define dorDDD(XV,YV) (for initial \ ax := abs(XV); ay := abs(YV); \ u = min(ax,ay); v := max (ax,ay); \ while (v ~= 0) repeat \ v := mod(old u,old v); \ u := old v; \ returns value of u \ end for) #define dnandBBB(XV,YV) (~XV&YV) #define dnorBBB(XV,YV) (~XV|YV) #define dcircDDD(XV,YV) (if (XV = 1.0d) then sin(YV) \ elseif (XV = 2.0d) then cos(YV) \ elseif (XV = 3.0d) then tan(YV) \ elseif (XV = 4.0d) then exp((1.0d+YV*YV),0.5d) \ else error[double_real] end if) /* domain error check above */ /* 1 circle */ #define dcirc1DDD(XV,YV) (sin(YV)) /* 2 circle */ #define dcirc2DDD(XV,YV) (cos(YV)) /* 3 circle */ #define dcirc3DDD(XV,YV) (tan(YV)) /* 3 circle */ #define dcirc4DDD(XV,YV) (exp((1.0d+YV*YV),0.5d)) inline int mpyIIIsl(int x, int y ) { /* SxS dyadic scalar fn, shapes match */ z = dmpyIII(toI(x),toI(y)); return(z); } inline double[+] plusDIDsx(double x, int[+] y ) { /* SxA scalar function */ xel = toD(x); z = with( . <= iv <= .) { yel = toD(_sel_(iv,y)); } genarray( _shape_(y), dplusDID(xel,yel)); return(z); } inline double[+] tranXDD(double[+] y) { z = { [i,j] -> y[j,i] }; return(z); } inline int[.] rhoIII(int x, int y) { /* Scalar reshape scalar (to vector) */ zxrho = prod(toi(x)); /* Result element count */ z = genarray([zxrho], y); /* allocate result */ return(z); } inline double[*] rhoIDD(int[.] x, double[*] y) { rx = APEXRAVEL(x); ry = APEXRAVEL(y); rhxrho = prod(x); /* THIS NEEDS XRHO FOR CODE SAFETY!! */ zxrho = _shape_(ry)[0]; if( zxrho <= rhxrho) { /* No element resuse case */ z = with(. <= [iv] <= .) genarray([rhxrho], _sel_([iv],ry)); } else { z = with(. <= [i] <= .) genarray( [zxrho], _sel_([i%rhxrho],ry)); /* i%len above fishy. Needed last iteration only? */ } return( _reshape_(rx, z)); } inline int[.] iotaXII(int shp, int QUADio) { /* Index generator on scalar */ /* HELP! Needs domain check for negative shp */ res = with( . <= [i] <= .) genarray( [toI(shp)], i+QUADio); return( res); } inline int[.] iotaXIINonNegsy(int shp, int QUADio) { /* Index generator on ScalarN when N is non-negative integer */ res = with( . <= [i] <= .) genarray( [toI(shp)], i+QUADio); return( res); } inline double[*] plusdotmpyDDD(double[*] x, double[*] y) { /* Transpose case of inner product z = x f.g y */ yt = APEXTranspose(y); ls = _drop_SxV_(_neg_(1),_shape_(x)); rs = _drop_SxV_( 1,_shape_(y)); cell = genarray([_shape_(y)[0]],0.0d); z = with(. <= [i,j] <= .) genarray(ls++rs, plusslXDD( dmpyDDD(tod(x[[i]]),tod(yt[[j]])) ), cell); return(z); } inline double[+] plusslXDD(double[+] y) { /* last axis reduce rank-2 or greater matrix */ sy = _shape_(y); zrho = _drop_SxV_(_neg_(1), sy); z = with (. <= iv <= .) genarray(zrho, plusslXDD(psel(iv,y)),0.0d); /* Not quite recursive */ return(z); } inline double plusslXDD(double[.] y) { /* Last axis reduction of vector */ z = with (_mul_SxA_(0,_shape_(y)) <= iv < _shape_(y)) fold( plusDDD, toD(0), toD(_sel_(iv, y))); return(z); } inline double plusDDD(double x, double y ) { /* SxS dyadic scalar fn, shapes match */ z = dplusDDD(toD(x),toD(y)); return(z); } inline bool eqDDBsl(double x, double y , double QUADct) { /* SxS dyadic scalar fn, shapes match */ z = deqDDB(toD(x),toD(y), QUADct); return(z); } inline int plusBBIsl(bool x, bool y ) { /* SxS dyadic scalar fn, shapes match */ z = dplusBBI(toI(x),toI(y)); return(z); } int quadXDD(double[*] y, int QUADpp, int QUADpw) { /* {quad}{<-} anything */ r=print(y); /* KLUDGE!!! print doesn't support booleans! */ return(r); } double ipddXID(int siz,int QUADio) { /* Start of function ipdd 2005-10-26 19:25:56.000 */ TMP_25=mpyIIIsl(siz ,siz ); TMP_27=iotaXII( TMP_25 ,QUADio) ; TMP_28=plusDIDsx( 0.5 ,TMP_27 ); TMP_29=rhoIII(2 ,siz ) ; m_0=rhoIDD(TMP_29 ,TMP_28 ) ; TMP_31=tranXDD( m_0 ) ; TMP_32=plusdotmpyDDD(m_0 ,TMP_31 ) ; TMP_39=plusslXDD( TMP_32 ) ; r_0=plusslXDD( TMP_39 ) ; r=r_0; return(r_0); } int main() { /* Start of function main 2005-10-26 19:25:56.000 */ QUADio_0=toi(( false ) ); QUADct_0=( 1.0e-13 ) ; QUADpp_0=( 10 ) ; QUADpw_0=( 80 ) ; QUADrl_0=( 16807 ) ; QUADio_1=toi(( false ) ); n_0=( 100 ) ; QUADrl_1=( 16807 ) ; QUADpp_1=( 10 ) ; QUADpw_1=( 80 ) ; r_0=ipddXID( n_0 ,QUADio_1) ; TMP_67=quadXDD( r_0 ,QUADpp_1,QUADpw_1) ; TMP_69=eqDDBsl(r_0 , 2.500083325e13 ,QUADct_0); r_1=toi(TMP_67)+plusBBIsl(true ,TMP_69 ); r=r_1; return(r_1); }