/* Copyright (C) 1993 by Thomas Glen Smith. All Rights Reserved. */
/* laminate APL2 V1.0.0 ************************************************
* Called by eachdyad. *
* Joins two APL variables of identical shape and rank along a new axis *
* indicated by a fractional number. A number between 0 and 1 *
* indicates the new axis is to be first. A number between the last *
* present axis and one greater means the new axis is to be last. The *
* result will have rank 1 greater than the arguments, and the same *
* shape except for the new axis, is always 2. *
***********************************************************************/
#define INCLUDES APLCB+APLMEM
#include "includes.h"
Aplcb laminate(left,rite,paxis)
Aplcb left, rite;
double paxis;
{
Catlamcm; Conform; Errstop; Getcb; Imax; Matchok;
Aplcb big, lit, out=NULL;
int axicnt,axis,botcnt,datacnt,datatyp,*dimptr,i,*ip,j,leftcnt,*op,
rank,ritecnt,topcnt;
if (!matchok(&left,&rite,APLMASK+APLAPL))
return(NULL); /* data types must match */
if (OK != conform(left,rite,0,&big,&lit))
return(errstop(50,left,rite,NULL)); /* shapes must match */
if (paxis < 0.0)
return(errstop(51,left,rite,NULL)); /* axis m/b positive */
rank=imax(1,big->aplrank)+1;
if (rank < (axis = 1 + paxis))
return(errstop(52,left,rite,NULL)); /* axis too big */
dimptr = op = malloc(rank*sizeof(int));
if (big->aplrank) { /* copy dimensions */
ip = big->apldim;
datacnt = 1;
for(i=1; i<=rank; i++) {
if (i != axis)
*op++ = j = *ip++;
else
*op++ = j = 2; /* axis dimension is always 2 */
datacnt *= j;
}
}
else { /* laminating two scalars */
datacnt = 2;
*(op+axis%2) = 1; /* non-axis dimension is 1 */
*(op+axis-1) = 2; /* make axis dimension 2 */
}
out = getcb(NULL,datacnt,
(datatyp=left->aplflags & (APLMASK+APLAPL))+APLTEMP,
rank,dimptr);
if ((out->aplcount == 0) ||
(OK != axispre(out,axis,&axicnt,&botcnt,&topcnt)))
return(errstop(0,left,rite,out));
leftcnt=ritecnt=botcnt;
return(catlamcm(left,rite,out,axis,
axicnt,botcnt,topcnt,leftcnt,ritecnt));
}