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);
}