use Array: all; use SimplePrint: all; use SimpleFibre: all; use Math: all; use String:{tochar}; import Char:all; use Bits:all; /* % This is the APEX stdlib.sis include file. % Standard equates and constants for APL compiler % Also standard coercion functions */ #define toB(x) tob((x)) #define toI(x) toi((x)) #define toD(x) tod((x)) #define toC(x) (x) #define toc(x) ((x)) void APEXERROR(char[.] msg) { /* Error function. This needs work, as it should kill * the running task, too. */ /*print(msg); */ return(); } /* Structural function utility functions */ /* Ravel utility */ #define APEXRavel(y) (reshape([prod(shape(y))],y)) 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); } #define APEXRESHAPE(TYPE) \ inline TYPE[*] APEXReshape(int[.] x, TYPE[*] y) \ { /* APEX vector x reshape, with item reuse */ \ ry = APEXRavel(y); \ zxrho = prod(x); /* THIS NEEDS XRHO FOR CODE SAFETY!! */ \ yxrho = shape(ry)[0]; \ if( zxrho <= yxrho) { /* No element resuse case */ \ z = take([zxrho],ry); \ } else { \ ncopies = zxrho/yxrho; /* # complete copies of y. */ \ /* FIXME: y empty case !*/ \ z = with(. <= [i] <= .) \ genarray( [ncopies], y,y); \ /* Now append the leftover bits */ \ z = APEXRavel(z) ++ take([zxrho-(ncopies*yxrho)],ry); \ } \ return(reshape(x,z)); \ } APEXRESHAPE(bool) APEXRESHAPE(int) APEXRESHAPE(double) APEXRESHAPE(char) inline bool SameShape(int[*] x, int[*] y) { /* Predicate for two shape vectors having same shape */ if (dim(x) != dim(y)) z = false; else z = with ([0] <= i < [dim(y)]) fold(&, true, (shape(x))[i] == (shape(y))[i]); return(z); } #define APEXmiota(N) with (. <= [iv] <= .) genarray([N], iv) #define APEXPI 3.1415926535897932d #define APEXE 2.718281828d /* APEXPINFINITYI largest integer */ #define APEXPINFINITYD 1.7976931348623156D308 /* APEXMINFINITYI smallest integer */ #define APEXMINFINITYD -1.7976931348623156D308 /* % 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! */ inline int Dsignum(double y) { /* signum double */ if (0.0 == y) z = 0; else if (0.0 > y) z = -1; else z = 1; return(z); } inline int Isignum(int y) { /* signum int */ if (0 == y) z = 0; else if (0 > y) z = -1; else z = 1; return(z); } inline double Dresidue(double x, double y, double QUADct) { /* Double residue double */ /* See Iresidue for definition */ if (0.0 == x) nx = 1.0; else nx = x; z = y - x * tod(Dfloor(y/nx, QUADct)); return(z); } inline int Iresidue(int x, int y, double ignoreme) { /* Integer residue integer */ /* Third argument is ignored - QUADct for Dresidue */ /* This definition is taken from SHARP APL Refman May 1991, p.6-26. * It extends the definition of residue to fractional right arguments * and to zero, negative and fractional left arguments. * r= y-x times floor y divide x+0=x */ if (0 == x) nx = 1; else nx = x; z = y - x * (y/nx); return(z); } inline int DfloorNoFuzz(double y) { /* Exact floor (no fuzz) */ return(toi(floor(y))); } inline int Dfloor(double y, double QUADct) { /* Fuzzy floor */ /* Definition taken from SHARP APL Refman May 1991, p.6-23 * floor: n <- (signum y) times nofuzzfloor 0.5+abs y) * z <- n-(QUADct times 1 max abs y)<(n-y) * * If you want a double result, write: "y - 1| y". * */ n = tod(DfloorNoFuzz(0.5+fabs(y))); if (y < 0.0) n = -n; else if (0.0 == y) n = 0.0; range = fabs(y); if (1.0 > range) range = 1.0; fuzzlim = QUADct*range; ny = n-y; if (fuzzlim < ny) z = n - 1.0; else z = n; return(toi(z)); } inline bool APEXFUZZEQ(double x, double y, double QUADct) { /* ISO APL Tolerant equality predicate */ absx = abs(x); absy = abs(y); tolerance = QUADct * max(absx,absy); z = abs(x-y) <= tolerance; return(z); } /* % 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, */ #define FindFirst(x,y,cfn,QUADct) \ sx = shape(x)[0]; \ z = sx; /* if not found */ \ for(i=0; iy[i]; i=shp; } return(z); } inline bool comparatorfnb(bool x, bool y,double QUADct) { /* Boolean comparator */ z = (x == y); return(z); } inline bool comparatorfni(int x, int y, double QUADct) { /* integer comparator */ z = (x == y); return(z); } inline bool comparatorfnd(double x, double y, double QUADct) { /* double comparator with fuzz */ L = _abs_(x-y); /* Tolerant equality */ R = QUADct*max(_abs_(x),_abs_(y)); z = (L <= R); return(z); } inline bool comparatorfnc(char x, char y,double QUADct) { /* char comparator */ z = (x == y); return(z); } inline bool comparatorfndnf(double x,double y, double QUADct) { /* double comparator, no fuzz */ z = (x == y); return(z); } /* Lehmer's random number generator */ #define lehmer(qrl) mod(qrl*16807,2147483647) /* Transposes */ #define APEXTRANSPOSE(TYPE,OTFILL) \ inline TYPE[*] APEXTranspose(TYPE[*] y) \ { \ z = with(iv) \ ( . <= iv <= .) : y[reverse( iv)]; \ genarray( reverse( shape(y)), OTFILL); \ return(z); \ } APEXTRANSPOSE(bool,false) APEXTRANSPOSE(int,0) APEXTRANSPOSE(double,0.0) APEXTRANSPOSE(char,' ') /* End of transposes */ /* End of boilerplate */ inline bool[+] notXBB(bool[+] y) { /* Monadic scalar functions on array */ z = with( . <= iv <= .) genarray(shape(y), notXBB(toB(y[iv])),false); return(z); } inline bool notXBB(bool y) { return(!tob(y)); } inline bool eqBIB(bool x, int y) { return(toI(x) == toI(y)); } inline int mpyIII(int x, int y) { return(toI(x)*toI(y)); } inline int plusIII(int x, int y) { return(toI(x)+toI(y)); } inline double divDID(double x, int y) { dx = tod(x); dy = tod(y); if (dx == dy) z = 1.0d; else z = dx/dy; return(z); } inline double modIDD(int x, double y, double QUADct) { return(Dresidue(toD(x),toD(y),QUADct)); } inline double mpyDID(double x, int y) { return(toD(x)*toD(y)); } inline double barDDD(double x, double y) { return(toD(x)-toD(y)); } inline double divDBD(double x, bool y) { dx = tod(x); dy = tod(y); if (dx == dy) z = 1.0d; else z = dx/dy; return(z); } inline double modBDD(bool x, double y, double QUADct) { return(Dresidue(toD(x),toD(y),QUADct)); } inline double mpyDBD(double x, bool y) { return(toD(x)*toD(y)); } inline int plusBBI(bool x, bool y) { return(toI(x)+toI(y)); } inline int[.] comaXII(int y) { return([y]); } inline int[.] rotrXII(int[.] y) { /* Vector reverse */ n = shape(y); cell = 0; z = with( . <= iv <= .) genarray(n, y[(n[0]-1)-iv],cell); return(z); } inline int[.] comaXII(int[.] y) { return(y); } inline int[.] comaXII(int[+] y) { /* Ravel of anything of rank>1 */ z = reshape([prod(shape(y))],y); return(z); } inline double[.] comaXDD(double y) { return([y]); } inline bool[.] comaXBB(bool[.] y) { return(y); } inline bool[.] rotrXBB(bool[.] y) { /* Vector reverse */ n = shape(y); cell = false; z = with( . <= iv <= .) genarray(n, y[(n[0]-1)-iv],cell); return(z); } inline int[+] rhoIII(int[.] x, int y) { /* Vector reshape scalar to matrix) */ zxrho = prod(toi(x)); /* Result element count */ z = genarray([zxrho], y); /* allocate result */ z = reshape(toi(x),z); 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) { z = APEXReshape(toi(x),y); return(z); } inline int[*] rhoIII(int[.] x, int[*] y) { z = APEXReshape(toi(x),y); return(z); } inline int[*] iotaCCI(char[.] x, char[*] y,int QUADio) { /* Character vector iota character non-scalar */ table = genarray([256],shape(x)[0]); /* Not found */ for(i=shape(x)[0]-1; i<=0; i--) table[toi(x[i])] = i; z = with(. <= iv <= .) genarray(shape(y), table[toi(y[iv])],0); return(z+QUADio); } inline int[.] takeBII(bool x, int[.] y) /* LOTS of missing code here. (x0<0 for example */ { /* Scalar take vector */ z = with( . <= iv <= .) genarray([abs(toi(x))], y[iv]); return(z); } inline int[*] dropBII(bool x, int[*] y) { /* Scalar drop non-scalar */ res = drop([toi(x)], y); return( res); } inline bool[*] dropBBB(bool x, bool[*] y) { /* Scalar drop non-scalar */ res = drop([toi(x)], y); return( res); } inline int[0] rhoXII(int y) { /* Shape of scalar */ return(shape(y)); } inline int[1] rhoXBI(bool[.] y) { /* Shape of vector */ return(shape(y)); } inline int[1] rhoXII(int[.] y) { /* Shape of vector */ return(shape(y)); } 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 int[.] iotaXII(int[1] shp, int QUADio) { /* Index generator on 1-element vector */ /* HELP! Needs length error check */ /* HELP! Needs domain check for negative shp */ res = with( . <= i <= .) genarray( toI(shp), i[0]+QUADio); return( res); } inline int[.] iotaXIINonNegsy(int[1] shp, int QUADio) { /* Index generator on 1-element vector, known to be non-negative integer */ res = with( . <= [i] <= .) genarray( [toI(shp[0])], i+QUADio); return( res); } inline int[.] rhoXII(int[+] y) { /* Shape of rank-3 or higher */ return(shape(y)); } inline int[0] rhoXDI(double y) { /* Shape of scalar */ return(shape(y)); } int quadXBB(bool[*] y, int QUADpp, int QUADpw) { /* {quad}{<-} anything */ r=display(y); /* KLUDGE!!! print doesn't support booleans! */ /* MORE kludges - sac tends to evaporate side effects, so we'll help things along abit until that is repaired. */ return(r); } int quadXII(int[*] y, int QUADpp, int QUADpw) { /* {quad}{<-} anything */ r=display(y); /* KLUDGE!!! print doesn't support booleans! */ /* MORE kludges - sac tends to evaporate side effects, so we'll help things along abit until that is repaired. */ return(r); } inline int[.] comaIII(int[.] x, int[.] y) { /* VxV last-axis catenate */ return(toI(x)++toI(y)); } inline int[.] comaIBI(int[.] x, bool y) {/* VxS catenate first (or last) axis */ return(toI(x)++[toI(y)]); } inline bool[.] comaBBB(bool[.] x, bool y) {/* VxS catenate first (or last) axis */ return(toB(x)++[toB(y)]); } inline bool[2] comaBBB(bool x, bool y) {/* SxS catenate first (or last) axis */ return([toB(x)]++[toB(y)]); } inline int[*] dtakIBI(int x, bool[+] y) { /* Scalar basevalue rank>1 */ yt = APEXTranspose(y); /* Dumb, but easy */ ycols = (shape(y))[dim(y)-1]; cellshape=take([1],shape(y)); cell = 0; frameshape = drop([1],shape(y)); weights = genarray(cellshape, toI(1)); for (i=ycols-2; i>=0; i--) weights[i]= weights[i+1]*toI(x); z = with(. <= iv <= .) genarray(frameshape, with([0] <= jv < cellshape) fold(+, 0, weights[jv] * toI(yt[iv++jv])),cell); return(z); } inline bool sameIIB(int x, int y) { /* Scalar match scalar */ if (toI(x) == toI(y)) z = true; else z = false; return(z); } inline int[+] utakIII(int[.] x, int[+] y) { /* Vector represent non-scalar */ yt = APEXTranspose(y); cell = genarray(shape(x),0); z = with (. <= iv <= .) genarray(shape(yt),utakIII(x,yt[iv]),cell); return(z); } inline int[.] utakIII(int[.] x, int y) { /* Vector represent scalar */ /* Taken from ISO Extended APL standard Draft N93.03, page 155 */ wts = genarray(shape(x),toI(1)); for(i=shape(x)[0]-2; i>=0; i--) wts[i] = wts[i+1] * toI(x[i+1]); z = genarray(shape(x),0); cy = toI(y); for(i=shape(x)[0]-1; i>=0; i--){ z[i] = Iresidue(toI(x[i]),cy/wts[i],0.0); /* Represent is NOT fuzzy (SAPL Ref Man p.6-47, 1991 */ cy = cy - z[i] * wts[i]; } return(z); } inline bool sameIDB(int[+] x, double[+] y,double QUADct) { /* Non-scalar match non-scalar */ if (dim(x) != dim(y)) z = false; else if (! SameShape(shape(x),shape(y))) z = false; else z = with(_mul_SxA_(0,shape(y)) <= iv < shape(y)) fold(&, true, eqDDB(toD(x[iv]), toD(y[iv]), QUADct)); return(z); } inline bool eqIDB(int x, double y, double QUADct) { return((toD(x) == toD(y)) || APEXFUZZEQ(toD(x),toD(y),QUADct)); } inline int dtakIII(int x, int y) { /* Scalar basevalue Scalar */ return(y); } inline int[*] dtakIII(int x, int[+] y) { /* Scalar basevalue rank>1 */ yt = APEXTranspose(y); /* Dumb, but easy */ ycols = (shape(y))[dim(y)-1]; cellshape=take([1],shape(y)); cell = 0; frameshape = drop([1],shape(y)); weights = genarray(cellshape, toI(1)); for (i=ycols-2; i>=0; i--) weights[i]= weights[i+1]*toI(x); z = with(. <= iv <= .) genarray(frameshape, with([0] <= jv < cellshape) fold(+, 0, weights[jv] * toI(yt[iv++jv])),cell); return(z); } inline int dtakIII(int[.] x, int[.] y) { /* Vector basevalue vector */ /* 3 cases - all give 22200: * 10 10 10 basevalue 200 200 200 * 10 10 10 basevalue 200 * (,10) basevalue 200 200 200 */ ycols = (shape(y))[0]; if (1 == ycols){ /* Maybe extend y */ ycols = shape(x)[0]; y = genarray([ycols],y[0]); } if (1 == shape(x)[0]){ /* Maybe extend x */ x = genarray([ycols], x[0]); } weights = genarray([ycols], toI(1)); for (i=ycols-2; i>=0; i--) weights[i]= weights[i+1]*toI(x[i]); z = with([0] <= iv < [ycols]) fold(+, 0, weights[iv] * toI(y[iv])); return(z); } inline int[*] dtakIII(int[.] x, int[+] y) { /* Vector basevalue rank>1 */ yt = APEXTranspose(y); /* Dumb, but easy */ ycols = (shape(y))[dim(y)-1]; cellshape=take([1],shape(y)); cell=genarray(cellshape,0); frameshape = drop([1],shape(y)); weights = genarray(cellshape, toI(1)); for (i=ycols-2; i>=0; i--) weights[i]= weights[i+1]*toI(x); z = with(. <= iv <= .) genarray(frameshape, with([0] <= jv < cellshape) fold(+, 0, weights[jv] * toI(yt[iv++jv])),cell); return(z); } inline bool sameIIB(int[+] x, int[+] y) { /* Non-scalar match non-scalar */ if (dim(x) != dim(y)) z = false; else if (! SameShape(shape(x),shape(y))) z = false; else z = with(_mul_SxA_(0,shape(y)) <= iv < shape(y)) fold(&, true, eqIIB(toI(x[iv]), toI(y[iv]))); return(z); } inline bool eqIIB(int x, int y) { return(toI(x) == toI(y)); } inline int[.] utakIII(int[.] x, int y) { /* Vector represent scalar */ /* Taken from ISO Extended APL standard Draft N93.03, page 155 */ wts = genarray(shape(x),toI(1)); for(i=shape(x)[0]-2; i>=0; i--) wts[i] = wts[i+1] * toI(x[i+1]); z = genarray(shape(x),0); cy = toI(y); for(i=shape(x)[0]-1; i>=0; i--){ z[i] = Iresidue(toI(x[i]),cy/wts[i],0.0); /* Represent is NOT fuzzy (SAPL Ref Man p.6-47, 1991 */ cy = cy - z[i] * wts[i]; } return(z); } inline bool sameIDB(int[.] x, double[.] y,double QUADct) { /* vector-vector match */ if (dim(x) != dim(y)) z = false; else z = with(_mul_SxA_(0,shape(y)) <= iv < shape(y)) fold(&, true, eqDDB(toD(x[iv]), toD(y[iv]), QUADct)); return(z); } inline bool eqIDB(int x, double y, double QUADct) { return((toD(x) == toD(y)) || APEXFUZZEQ(toD(x),toD(y),QUADct)); } inline double[.] utakIDD(int[.] x, double y) { /* Vector represent scalar */ /* Taken from ISO Extended APL standard Draft N93.03, page 155 */ wts = genarray(shape(x),toD(1)); for(i=shape(x)[0]-2; i>=0; i--) wts[i] = wts[i+1] * toD(x[i+1]); z = genarray(shape(x),0.0d); cy = toD(y); for(i=shape(x)[0]-1; i>=0; i--){ z[i] = Dresidue(toD(x[i]),cy/wts[i],0.0); /* Represent is NOT fuzzy (SAPL Ref Man p.6-47, 1991 */ cy = cy - z[i] * wts[i]; } return(z); } inline bool sameDDB(double[.] x, double[.] y,double QUADct) { /* vector-vector match */ if (dim(x) != dim(y)) z = false; else z = with(_mul_SxA_(0,shape(y)) <= iv < shape(y)) fold(&, true, eqDDB(toD(x[iv]), toD(y[iv]), QUADct)); return(z); } inline bool eqDDB(double x, double y, double QUADct) { return((toD(x) == toD(y)) || APEXFUZZEQ(toD(x),toD(y),QUADct)); } inline double[.] utakBDD(bool[.] x, double y) { /* Vector represent scalar */ /* Taken from ISO Extended APL standard Draft N93.03, page 155 */ wts = genarray(shape(x),toD(1)); for(i=shape(x)[0]-2; i>=0; i--) wts[i] = wts[i+1] * toD(x[i+1]); z = genarray(shape(x),0.0d); cy = toD(y); for(i=shape(x)[0]-1; i>=0; i--){ z[i] = Dresidue(toD(x[i]),cy/wts[i],0.0); /* Represent is NOT fuzzy (SAPL Ref Man p.6-47, 1991 */ cy = cy - z[i] * wts[i]; } return(z); } inline int[*] indrfr(int fr, int i, int[+] X) { /* X[;;;scalari;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = drop([fr+1], shape(X)); cell = genarray(cellshape,0); z = with (. <= iv <= .) genarray(frameshape,(X[iv])[i], cell); return(z); } inline int[*] indrfr(int fr, int[+] i, int[+] X) { /* X[;;;i;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = shape(i)++drop([fr+1],shape(X)); cell = genarray(cellshape,0); /* not used, but SAC needs help */ z = with (. <= iv <= .) genarray(frameshape,indrfr0(i,X[iv]),cell); return(z); } inline int[*] indrfr0(int i, int[*] X) { /* X[i;;;] i is scalar */ z = X[[i]]; return(z); } inline int[*] indrfr0(int[+] i, int[*] X) { /* X[im;;;] im is array */ cellshape = drop([1],shape(X)); cell = genarray(cellshape, 0); z = with (. <= iv <= .) genarray(shape(i), X[i[iv]],cell); return(z); } inline double[*] indrfr(int fr, int i, double[+] X) { /* X[;;;scalari;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = drop([fr+1], shape(X)); cell = genarray(cellshape,0.0d); z = with (. <= iv <= .) genarray(frameshape,(X[iv])[i], cell); return(z); } inline double[*] indrfr(int fr, int[+] i, double[+] X) { /* X[;;;i;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = shape(i)++drop([fr+1],shape(X)); cell = genarray(cellshape,0.0d); /* not used, but SAC needs help */ z = with (. <= iv <= .) genarray(frameshape,indrfr0(i,X[iv]),cell); return(z); } inline double[*] indrfr0(int i, double[*] X) { /* X[i;;;] i is scalar */ z = X[[i]]; return(z); } inline double[*] indrfr0(int[+] i, double[*] X) { /* X[im;;;] im is array */ cellshape = drop([1],shape(X)); cell = genarray(cellshape, 0.0d); z = with (. <= iv <= .) genarray(shape(i), X[i[iv]],cell); return(z); } inline bool[*] indrfr(int fr, int i, bool[+] X) { /* X[;;;scalari;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = drop([fr+1], shape(X)); cell = genarray(cellshape,false); z = with (. <= iv <= .) genarray(frameshape,(X[iv])[i], cell); return(z); } inline bool[*] indrfr(int fr, int[+] i, bool[+] X) { /* X[;;;i;;;], where i has fr semicolons to its left */ /* Indexing is origin-0. Caller will correct this */ /* This could stand some optimization, perhaps, for boolean i, * unless SAC avoids building an array-valued temp of toI(i). */ frameshape = take([fr],shape(X)); cellshape = shape(i)++drop([fr+1],shape(X)); cell = genarray(cellshape,false); /* not used, but SAC needs help */ z = with (. <= iv <= .) genarray(frameshape,indrfr0(i,X[iv]),cell); return(z); } inline bool[*] indrfr0(int i, bool[*] X) { /* X[i;;;] i is scalar */ z = X[[i]]; return(z); } inline bool[*] indrfr0(int[+] i, bool[*] X) { /* X[im;;;] im is array */ cellshape = drop([1],shape(X)); cell = genarray(cellshape, false); z = with (. <= iv <= .) genarray(shape(i), X[i[iv]],cell); return(z); } inline double[+] indsfr(int fr, int[*] i, double[+] X, double[+] Y) { /* X[;;;i;;;]<- nonscalar Y, where i has fr semicolons to its left */ cellshape = shape(i)++drop([fr],shape(X)); cell = genarray(cellshape,0.0d); /* not used, but SAC needs help */ frameshape = take([fr],shape(X)); z = with (. <= iv <= .) genarray(frameshape,indsfr0(i,X[iv], Y[iv]),cell); zshape = frameshape++cellshape; return(reshape(zshape,z)); } inline double[+] indsfr(int fr, int[+] i, double[+] X, double Y) { /* X[;;;i;;;]<- scalar Y, where i has fr semicolons to its left */ cellshape = drop([fr+1],shape(X)); cell = genarray(cellshape,0.0d); /* not used, but SAC needs help */ frameshape = take([fr],shape(X)); z = with (. <= iv <= .) genarray(frameshape,indsfr0(i,X[iv], Y),cell); return(z); } inline double[+] indsfr(int fr, int i, double[+] X, double Y) { /* X[;;;i;;;]<- scalar Y, where i has fr semicolons to its left */ cellshape = drop([fr+1],shape(X)); cell = genarray(cellshape,0.0d); frameshape = take([fr],shape(X)); z = with (. <= iv <= .) genarray(frameshape,indsfr0(i,X[iv], Y),cell); zshape = frameshape++cellshape; return(z); } inline double[+] indsfr0(int i, double[+] X, double Y) { /* Case 1. X[scalarI;;]<- scalarY NB. Leading axis */ cell = genarray(drop([1],shape(X)),tod(Y)); z = tod(X); z[[i]] = cell; return(z); } inline double[+] indsfr0(int i, double[+] X, double[+] Y) { /* Case 1. X[scalarI;;]<- non-scalarY NB. Leading axis */ /* This has to match on shape. FIXME! */ z = tod(X); z[[i]] = tod(Y); return(z); } inline double[+] indsfr0(int[.] iv, double[+] X, double Y) { /* 2. X[non-scalarIV;;]<- scalarY NB. Leading axis */ /* This would almost work under a with-loop, but the potential * for duplicates in iv scuppers that. Ergo, FOR loop. */ z = tod(X); cellshape = drop([1],shape(X)); cell = genarray (cellshape, tod(Y)); raveli = APEXRavel(iv); for(i=0; i