Metropoli BBS
VIEWER: conform.c MODE: TEXT (ASCII)
/*Copyright (C) 1992, 1994 by Thomas Glen Smith.  All Rights Reserved.*/
/* conform APL2 V1.0.0 *************************************************
* Called by cat, laminate, and rotate to see if left and rite conform. *
* If either argument is scalar or a one-element vector, returns OK.    *
* If ranks are equal, left and rite must agree in shape except in the  *
* axis dimension (axis may be 0 to force complete agreement).          *
* If ranks differ, all dimensions must agree after dropping the axis   *
* dimension from the higher ranking.  Big and lit are set appropiately.*
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
int conform(left,rite,axis,big,lit)
Aplcb left,rite,big[],lit[];
int axis;
{
	int *dimbig,*dimleft,*dimlit,*dimrite,i,j;

	*lit = left; /* default */
	*big = rite; /* default */
     if (left->aplrank == 0) return(OK); /* left is scalar */
     if (rite->aplrank == 0) { /* rite is scalar */
     	*lit = rite;
          *big = left;
          return(OK);
     }
	if (left->aplrank==1 && left->aplcount==1) /* one-item vector */
		return(OK);
	if (rite->aplrank==1 && rite->aplcount==1) { /* one-item vector */
		*lit=rite;
		*big=left;
		return(OK);
	}
	dimleft=left->apldim;
	dimrite=rite->apldim;
	if (left->aplrank == rite->aplrank) {
		for(i=1; i<=left->aplrank; i++)
			if (*dimleft++ != *dimrite++ && i != axis)
				return(NOTOK);
		return(OK);
	}
	/* neither is a scalar or one-element vector, and ranks differ */
	if (iabs(left->aplrank-rite->aplrank)-1) /* ranks differ by more than one */
		return(NOTOK);
	if (left->aplrank > rite->aplrank) {
		*lit=rite;
		*big=left;
	}
	dimlit=(*lit)->apldim;
	dimbig=(*big)->apldim;
	j=imax(left->aplrank,rite->aplrank);
	for (i=1; i<=j; i++) {
		if (i != axis)
			if (*dimbig != *dimlit++)
				return(NOTOK);
		dimbig++;
	}
	return(OK);
}
[ RETURN TO DIRECTORY ]