/*Copyright (C) 1992, 1994 by Thomas Glen Smith. All Rights Reserved.*/
/* outrprdp APL2 V1.0.0 ************************************************
* Called by execjota, execjotc, and execjotd. Differs from outrprd in *
* that it expects oper to be a procedure call rather than a function. *
* Does outer product for all matching data types, or of mixed data *
* types where one is convertible to the other, i.e. outrprd will never *
* be invoked with either left or rite of type APLCHAR, and the other *
* something else. If left is of type APLCHAR, rite will be also. *
***********************************************************************/
#define INCLUDES APLCB
#include "includes.h"
Aplcb outrprdp(oper,left,rite)
void (*oper)();
Aplcb left,rite;
{
Chrcopy; Dyadrup; Errstop; Getcb; Intcopy; Matchok;
int cnt,datacnt,datatyp,iw,*ip,jw,otype,rank;
Aplcb out=NULL;
char *ldata,*odata,*rdata;
double wrkd[2];
if (!matchok(&left,&rite,APLMASK))
return(NULL);
datacnt=left->aplcount*rite->aplcount;
datatyp=left->aplflags & APLMASK;
otype = (APLCHAR == datatyp) ? APLINT : datatyp;
rank = left->aplrank + rite->aplrank;
out = getcb(NULL, datacnt, otype + APLTEMP, rank, NULL);
if (rank > 1) { /* set dimensions */
ip = intcopy(out->apldim, left->apldim, left->aplrank, 1);
ip = intcopy(ip, rite->apldim, rite->aplrank, 1);
}
if (datacnt) {
cnt = 0; /* Count of output elements finished. */
odata = out->aplptr.aplchar;
ldata = left->aplptr.aplchar;
iw = left->aplcount;
while(0 < iw--) {
rdata = rite->aplptr.aplchar;
jw = rite->aplcount;
while(0 < jw--) {
*(wrkd+1) = 0e0; /* Initialize. */
(*oper)(ldata,rdata,(char*)wrkd);
rdata += rite->aplsize;
if (*(wrkd+1) != 0e0 && otype != APLCPLX) {
otype = APLCPLX;
out = dyadrup(out,cnt); /* Convert to complex. */
odata = out->aplptr.aplchar + cnt * out->aplsize;
}
odata = chrcopy(odata,(char*)wrkd,out->aplsize,1);
cnt++; /* Bump count of elements finished. */
}
ldata += left->aplsize;
}
}
return(errstop(0,left,rite,out));
}