Metropoli BBS
VIEWER: laminate.c MODE: TEXT (ASCII)
/* 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));
}
[ RETURN TO DIRECTORY ]