Metropoli BBS
VIEWER: reducecm.c MODE: TEXT (ASCII)
/* Copyright (C) 1993 by Thomas Glen Smith.  All Rights Reserved. */
/* reducecm APL2 V1.0.0 ************************************************
* Called by ireduces and nreduces.                                     *
* Builds the necessary output APLCB for a reduce or scan operation,    *
* but expects the caller to perform the reduce or scan.                *
***********************************************************************/
#define INCLUDES APLCB+APLMEM
#include "includes.h"
Aplcb reducecm(id,identity,rite,axis,axicnt,botcnt,topcnt,type)
int id; /* 1=reduce, 0=scan */
double *identity; /* identity value */
Aplcb rite; /* operand */
int *axis; /* axis of reduction */
int *axicnt,*botcnt,*topcnt; /* processing variables */
int type; /* data type of output */
{
	Axispre; Errinit; Errstop; Getcb; Imax;
	extern int indxorg;
	int datacnt,*dimin,*dimout,i,j,k,rank;
	Aplcb out=NULL;

	if (errinit())
		return(errstop(0,NULL,rite,NULL));
	if (*axis < 0) /* does caller want the default axis? */
		*axis = rite->aplrank;
	else
 		*axis += (indxorg == 0);
	if (OK!=axispre(rite,*axis,axicnt,botcnt,topcnt))
		return(errstop(0,NULL,rite,NULL));
	if (id)
		datacnt=*topcnt**botcnt; /* reduce */
	else
		datacnt=rite->aplcount; /* scan */
	rank=imax(0,rite->aplrank-id);
     if (datacnt && type == APLCHAR && *axicnt > 1) type = APLINT;
	out=getcb(NULL,datacnt,type+APLTEMP,rank,NULL);
	if (rank > 1) { /* output isn't scalar or vector */
		dimout=out->apldim;
		dimin=rite->apldim;
		for (i=1; i<=rite->aplrank; i++) {
			if (!(id && i==*axis))
				*dimout++=*dimin;
			dimin++;
		}
	}
	if (!datacnt) /* result empty? */
		return(out);
	/* 1 or more elements of output */
	if (rite->aplcount==0 && identity==NULL)
		return(errstop(13,NULL,rite,out)); /* no identity */
	return(out);
}
[ RETURN TO DIRECTORY ]