Newsgroups: comp.lang.apl
Path: watmath!watserv2.uwaterloo.ca!mach1!torn!howland.reston.ans.net!usc!sdd.hp.com!decwrl!decwrl!csus.edu!sfsuvax1.sfsu.edu!vpcsc4
From: vpcsc4@sfsuvax1.sfsu.edu (Emmett McLean)
Subject: Fortran style data types 
Message-ID: <1993May15.232906.19573@csus.edu>
Sender: news@csus.edu
Organization: San Francisco State University
References: <1993May15.231328.18776@csus.edu>
Date: Sat, 15 May 1993 23:29:06 GMT
Lines: 122

Below is a message to Roger which may be of general interest to those who
may be interested in interfacing J with some numerical Fortran code. 

Emmett
 
> Roger, I made some modification to J to make calling Fortran routines easier.  Since Fortran
> arrays are stored transposed relative to C, I added a parallel tower of numeric types that
> are stored transposed relative to the usual arrays.  I'm using the modifications to ease
> calling standard Fortran numerical packages like LAPACK.  I was hoping to get you opinion
> on the modifications.  -David Gurr
> 
> gurr@phase.mcg.edu
> 
> 
> =================================================================
> ===========================================================
> Added to jt.h
> =======================
> typedef long  FI;
> typedef double FD;
> typedef struct {FD re,im;} FZ;
> 
> #define FBOOL           262144          /* FB  Fortran boolian                */
> #define FINT            524288L         /* FI  Fortran integer                */
> #define FDBL            1048576L        /* FD  Fortran floatingpoint double   */
> #define FCMPX           2097152L        /* FZ  Fortran complex double         */
> 
> #define FORTRAN         (FBOOL+FINT+FDBL+FCMPX)
> #define NOUN            (NUMERIC+CHAR+BOX+BOXK+FORTRAN)
> 
> 
> Added to the definition of bp in u.c
> ===============================
>   case FBOOL:    R sixeof(FB);   /*   Fortran boolian               */
>   case FINT:     R sizeof(FI);   /*   Fortran integer               */
>   case FDBL:     R sizeof(FD);   /*   Fortran floatingpoint double  */
>   case FCMPX:    R sizeof(FZ);   /*   Fortran complex double        */
> 
> 
> Added to k.c
> ================================
> /* Transpose between C style representation and Fortran style */
> void transrep(w)A w; {A temp; 
>   temp=cant1(w); 
>   MC(AV(w),AV(temp),AN(temp)*bp(AT(temp)));}
> 
> 
> 
> Added cases to the definition of ccvt in k.c
> ======================================
> static B ccvt(t,w,y)I t;A w,*y;{I n,wt,*wv,*yv, fort; B flg;
> RZ(w);
>  n=AN(w); wt=AT(w); wv=AV(w);
> /* if no Fortran types are involved, do the usual */
>  if (!(FORTRAN&(t|wt))){
>   if(t>=wt||!n){
>    if(t==wt)RZ(*y=ca(w))
>    else{GA(*y,t,n,AR(w),AS(w)); yv=AV(*y); 
> if(t&CMPX+BOXK)fillv(t,n,yv);}
>   if(t==wt||!n)R 1;
> }
> switch(CVCASE(t,wt)){
>   case BxI: R BfromI(w,y);
>   case BxD: R BfromD(w,y);
>   case IxD: R IfromD(w,y);
>   case BxZ: R BfromZ(w,y);
>   case IxZ: R IfromZ(w,y);
>   case DxZ: R DfromZ(w,y);
>   case IxB: {I*x=    yv;B*v=(B*)wv; DO(n,*x++=*v++;);} R 1;
>   case DxB: {D*x=(D*)yv;B*v=(B*)wv; DO(n,*x++=*v++;);} R 1;
>   case DxI: {D*x=(D*)yv;I*v=    wv; DO(n,*x++=*v++;);} R 1;
>   case ZxB: {Z*x=(Z*)yv;B*v=(B*)wv; DO(n,x++->re=*v++;);} R 1;
>   case ZxI: {Z*x=(Z*)yv;I*v=    wv; DO(n,x++->re=*v++;);} R 1;
>   case ZxD: {Z*x=(Z*)yv;D*v=(D*)wv; DO(n,x++->re=*v++;);} R 1;
>   case KxA: {K*x=(K*)yv;A*v=(A*)wv; DO(n,x++->v=ca(*v++););} R 1;
>   default:  ASSERT(0,EVDOMAIN);
> }}
> /* If Fortran types are involved convert to & from Fortran */
> /* types and then do the usuall ccvt                       */
>  if  ((FORTRAN&(t|wt))){
>     if ((NUMERIC&t)&&(FORTRAN&wt)){
>          wt=wt>>17; AT(w)=wt; transrep(w); R ccvt(wt,w,y);}
>      if ((FORTRAN&t)&&(NUMERIC&wt)){
>         flg = ccvt((t>>17),w,y); 
>         transrep(*y);    
>         AT(*y)=t; 
>         R flg;}
>      if ((FORTRAN&t)&&(FORTRAN&wt))  {
>          wt=wt>>17;  AT(w)=wt; flg = ccvt((t>>17),w,y); AT(*y)=t; R flg;}
>     ASSERT(0,EVDOMAIN);}
> }
> 
> 
> Added cases in coerce1 in u.c
> ========================================
>  I coerce1(w,mt)A*w;I mt;{I t,wt;
>   RZ(*w);
>   if(!AN(*w))R mt;
>   wt=AT(*w);
> /* if Fortran types are not involved */
>   if (!(FORTRAN&(mt|wt))){t=MAX(wt,mt);}
> /* and the cases that do involve Fortran types */
>   if  ((FORTRAN&(mt|wt))){
>      if ((NUMERIC&mt)&&(FORTRAN&wt)){t=MAX((wt>>17),mt);}
>      if ((FORTRAN&mt)&&(NUMERIC&wt)){t=MAX((wt<<17),mt);}
>      if ((FORTRAN&mt)&&(FORTRAN&wt)){t=MAX(wt,mt);}
>    }
>    ASSERT((wt&(NUMERIC|FORTRAN)),EVDOMAIN);
>    if(t!=wt)RZ(*w=cvt(t,*w));
>    R t; }
> 
> coerce2 needs to be modified as well.
> 
> 
> Added cases to thorn1 in f.c
> ===================================
>   case FBOOL: R th(cant1(w),WB,fmtB);
>   case FINT:  R th(cant1(w),WD,fmtI);
>   case FDBL:  R th(cant1(w),WD,fmtD);
>   case FCMPX: R th(cant1(w),WZ,fmtZ);
> 
> 
