/* Copyright (C) 1995 by Thomas Glen Smith. All Rights Reserved. */
/* grade2 APL2 V1.0.0 **************************************************
* Called by gradedn2 and gradeup2. *
* Obtains indices that sort an APL variable of character type in *
* ascending or descending sequence. *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb grade2(left,rite,up)
Aplcb left;
Aplcb rite;
int up;
{
Aplcopy; Cat; Endoper; Errstop; Getcb; Grade2a; Formati; Indexof;
Indxsub; Perm; Reshape; Temp; Transpos;
extern int indxorg;
Aplcb dimcb,out1=NULL,out2=NULL,out3=NULL;
int axis=1+indxorg,cols,div,i,j,rows;
out1 = rite; /* So it'll get freed if premature break from for(;;) */
for(;;) {
out3 = transpos(NULL,temp(formati(left,&dimcb)));
/* If left was 2 3R'abcABC', it w/b 3 2 R'aAbBcC' */
if (dimcb == NULL) break; /* Error? */
div = (dimcb->aplcount < 2) ? 1 : *(dimcb->aplptr.aplint);
endoper(temp(dimcb));
if (rite->aplrank > 0) {
for(i = cols = 1, j = rite->aplrank; i < j; i++)
cols *= *(rite->apldim + i); /* cols = X/1URrite. */
rows = *(rite->apldim); /* rows = 1YRrite. */
}
else rows = cols = 1;
dimcb = getcb(NULL,2,APLINT+APLTEMP,1,NULL);
if (dimcb == NULL) break;
*(dimcb->aplptr.aplint) = rows; /* 1YRrite */
*(dimcb->aplptr.aplint + 1) = cols; /* X/1URrite */
out2 = perm(indxsub(rows)); /* 1 2 ... rows */
if (out2 == NULL) break; /* Error. */
out1 = perm(cat(cat(
indexof(out3,reshape(dimcb,rite)),out2,axis),out2,axis));
/* Rite is reshaped to a matrix, with the final two */
/* rows consisting of 1 2 ... rows. */
endoper(temp(out2));
dimcb = NULL; /* Freed already. */
if (out1 == NULL) break; /* Error. */
out2 = aplcopy(out1); /* Make a copy. */
if (out2 == NULL) break; /* Error. */
out3 = grade2a(out1,out2,up,rows,cols+2,div);
break; /* final break from for(;;) */
} /* end for(;;) */
return(errstop(0,temp(out1),temp(out2),out3));
}