/* Copyright (C) 1994 by Thomas Glen Smith. All Rights Reserved. */
/* rotate APL2 V1.0.0 **************************************************
* First consider the simple case where the left argument, k, is a *
* scalar, and the right, x, is a vector. Then if indxorg=0, the *
* result equals - *
* indexv(x,dyadic(mod,shape(x),imonadic(iplus,k,indxgen(shape(x)))), *
* NULL); *
* E.g. rotate(iscalar(2),litvect("2 3 5 7 11"),1) produces 5 7 11 2 3. *
* If the rank of x exceeds 1, then the third argument, j, is the axis *
* along which rotation is to occur. The shape of k must equal the *
* remaining dimensions of x, and each vector along the jth axis of x is*
* rotated as specified by the corresponding element of k. A scalar or *
* one-element vector k is extended to conform as required. *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb rotate(left,rite,axis)
Aplcb left,rite;
int axis; /* axis of reversal */
{
Errstop; Integer; Revrot; Rotatesb;
extern int aplerr, indxorg;
int axicnt,botcnt,topcnt;
int i,imax(),*lp,*rp,lincr;
Aplcb out=NULL;
axis += (indxorg == 0); /* make axis relative 1 */
if (NULL == (out=revrot(rite,axis,&axicnt,&botcnt,&topcnt)))
return(errstop(0,left,rite,NULL));
if (left->aplcount == 1) lincr = 0;
else {
if (rite->aplrank > 1 &&
1 != rite->aplrank-imax(1,left->aplrank))
return(errstop(48,left,rite,out)); /* rite in bad shape */
lincr = 1;
if (left->aplrank) lp = left->apldim; /* left isn't a scalar */
else lp = &lincr; /* treat scalars as one-element vectors */
rp=rite->apldim;
for (i=1; i<rite->aplrank; i++) {
if (i == axis) rp++;
else if (*lp++ != *rp++)
return(errstop(49,left,rite,out));
}
}
if (APLINT != (left->aplflags & APLMASK))
left = integer(left); /* convert to integer */
if (aplerr)
return(errstop(0,left,rite,out));
if (0 == out->aplcount)
return(errstop(0,left,rite,out));
return(rotatesb(left,rite,out,axis,axicnt,botcnt,topcnt,lincr));
}