      SUBROUTINE CXFFT3N(C,MX,MY,MZ,ISIGN)

C Parameters:

      INTEGER MXTRIG
      PARAMETER(MXTRIG=1000)

C Arguments:

      INTEGER ISIGN,MX,MY,MZ
      REAL C(*)

C Local scalars:

      INTEGER INC,IND,JUMP,K,LOT,MXOLD,MYOLD,MZOLD

C Local arrays:

      REAL TRIG1(MXTRIG),TRIG2(MXTRIG),TRIG3(MXTRIG)
      SAVE TRIG1,TRIG2,TRIG3,MXOLD,MYOLD,MZOLD
C***********************************************************************
C Subroutine CXFFT3N

c Interface routine for "Generalized Prime Factor Algorithm" FFT code
c of Temperton for computation of 3 dimensional FFTs

c Calling program should have call of form

c    CALL CXFFT3N(CX,MX,MY,MZ,ISIGN)

c where
c    CX(I,J,K,L)= complex array of 3-vectors at locations (I,J,K), with
c                  I = 1,...,MX
c                  J = 1,...,MY
c                  K = 1,...,MZ
c                  L = 1-3
c
c Upon return,
c    CX(I,J,K,L)= complex array of discrete fourier transform of original
c                 array CX, defined to be

c    CXout(I,J,K,L)=

c    Mx-1 My-1 Mz-1
c    sum  sum  sum CXin(u,v,w,L)*exp[ISIGN*2*pi*i*(u*I/Mx+v*J/My+w*K/Mz)]
c    u=0  v=0  w=0

c Note that here C is defined as a real array C(*) 
c C(1) = Re[CX(1,1,1,1)]
c C(2) = Im[CX(1,1,1,1)]
c C(3) = Re[CX(2,1,1,1)]
c C(4) = Re[CX(2,1,1,1)]
 
c or, in general:

c C(1+2*((I-1)+(J-1)*MY+(K-1)*MY*MZ+(L-1)*(MX+MY+MZ)) = Re[CX(I,J,K,L]
c C(2+2*((I-1)+(J-1)*MY+(K-1)*MY*MZ+(L-1)*(MX+MY+MZ)) = Im[CX(I,J,K,L]

c
C Interface written by P.J.Flatau
C
C History:
C
C***********************************************************************
      data mxold, myold, mzold/0,0,0/
      if(mx.ne.mxold .or. my.ne.myold .or. mz.ne.mzold) then
        mxold=mx
        myold=my
        mzold=mz
        CALL SETGPFA(trig1,mX)
        CALL SETGPFA(trig2,mY)
        CALL SETGPFA(trig3,mZ)
      endif
C --- first dimension
      INC=2
      JUMP=2*MX
      LOT=MY*MZ
      CALL GPFA(C(1),c(2),TRIG1,INC,JUMP,MX,LOT,ISIGN)
C --- second dimension
      INC=MX*2
      JUMP=2
      LOT=MX
C --- one plane at a time
      DO K=1,MZ
         IND=1+2*MX*MY*(K-1)
         CALL GPFA(C(IND),C(IND+1),TRIG2,INC,JUMP,
     &               MY,LOT,ISIGN)
      ENDDO
C --- third dimension
      INC=MX*MY*2
      JUMP=2
      LOT=MX*MY
      CALL GPFA(C(1),C(2),TRIG3,INC,JUMP,MZ,LOT,
     &          ISIGN)
      RETURN
      END
