	SUBROUTINE FOUR2 (XDATA,N,NDIM,ISGN,IFORM,IER)

C	COOLEY-TUKEY FAST FOURIER TRANSFORM IN ANSI BASIC FORTRAN.
C	MULTI-DIMENSIONAL TRANSFORM, EACH DIMENSION A POWER OF TWO,
C	COMPLEX OR REAL DATA.  THE TRANSFORM DONE IS
C	DIMENSION XDATA(N(1),N(2),...,N(NDIM)),TRAN(N(1),...,N(NDIM))
C	TRAN(K1,K2,...) = 1/SQRT(NTOT) * SUM(XDATA(J1,J2,...)*EXP(ISGN*2*
C	PI*I*((J1-1)*(K1-1)/N(1)+(J2-1)*(K2-1)/N(2)+...))), SUMMED FOR ALL
C	J1 AND K1 FROM 1 TO N(1), J2 AND K2 FROM 1 TO N(2), ETC. FOR ALL
C	NDIM SUBSCRIPTS.  NDIM MUST BE POSITIVE AND ALL N(IDIMX) POWERS OF
C	TWO.  NTOT = N(1)*N(2)*...*N(NDIM).  ISGN = +1 OR -1, FOR A
C	FORWARD OR AN INVERSE TRANSFORM.  IFORM = +1, 0, OR -1, AS DATA IS
C	COMPLEX, REAL OR THE FIRST HALF OF A COMPLEX ARRAY.  TRANSFORM
C	VALUES ARE RETURNED TO ARRAY XDATA.  THEY ARE COMPLEX, REAL OR
C	THE FIRST HALF OF A COMPLEX ARRAY, AS IFORM = 1, -1 OR 0.
C	THE TRANSFORM OF A REAL ARRAY (IFORM = 0) DIMENSIONED N(1) BY N(2)
C	BY ... WILL BE RETURNED IN THE SAME ARRAY, NOW CONSIDERED TO
C	BE COMPLEX OF DIMENSIONS N(1)/2+1 BY N(2) BY ....  NOTE THAT IF
C	IFORM = 0 OR -1, N(1) MUST BE EVEN, AND ENOUGH ROOM MUST BE
C	RESERVED.  THE MISSING VALUES MAY BE OBTAINED BY COMPLEX CONJUGA-
C	TION.  THE REVERSE TRANSFORMATION, OF A HALF COMPLEX ARRAY DIMEN-
C	SIONED N(1)/2+1 BY N(2) BY ..., IS ACCOMPLISHED BY SETTING IFORM
C	TO -1 AND REVERSING ISGN.  N(1) MUST BE THE TRUE N(1), NOT N(1)/2
C	+1.  THE TRANSFORM WILL BE REAL AND RETURNED TO THE INPUT ARRAY.
C	RUNNING TIME IS PROPORTIONAL TO NTOT*LOG2(NTOT), RATHER THAN
C	THE NAIVE NTOT**2.
C	WRITTEN BY NORMAN BRENNER, MIT, JUNE 1968.  SEE-- IEEE AUDIO
C	TRANSACTIONS, JUNE 1967 AND JUNE 1969, SPECIAL FFT ISSUES.

	DIMENSION XDATA(1), N(1)
	IF (IABS(NDIM-1)-NDIM+1+IABS(IABS(ISGN)-1)+IABS(IFORM)/2) 5,5,110
5	NTOT=1

	DO 10 IDIMX=1,NDIM
	IF (N(IDIMX)) 130,130,8
8	IF (N(IDIMX)-2**IFIX(ALOG(FLOAT(N(IDIMX)))/ALOG(2.)+.5)) 130,10,130
10	NTOT=NTOT*N(IDIMX)

	IF (IFORM) 70,20,20
20	NREM=NTOT

	DO 60 IDIMX=1,NDIM
	NREM=NREM/N(IDIMX)
	NPREV=NTOT/(N(IDIMX)*NREM)
	NCURR=N(IDIMX)
	IF (IDIMX-1+IFORM) 30,30,40
30	NCURR=NCURR/2
40	CALL BITRV (XDATA,NPREV,NCURR,NREM,N(IDIMX))
	CALL DFT2 (XDATA,NPREV,NCURR,NREM,ISGN)
	IF (IDIMX-1+IFORM) 50,50,60
50	CALL FIXRL (XDATA,N,NREM,ISGN,IFORM)
	NTOT=(NTOT/N(1))*(N(1)/2+1)
60	CONTINUE
	GO TO 105

70	NTOT=(NTOT/N(1))*(N(1)/2+1)
	NREM=1

	DO 100 JDIM=1,NDIM
	IDIMX=NDIM+1-JDIM
	NCURR=N(IDIMX)
	IF (IDIMX-1) 80,80,90
80	NCURR=NCURR/2
	CALL FIXRL (XDATA,N,NREM,ISGN,IFORM)
	NTOT=NTOT/(N(1)/2+1)*N(1)
90	NPREV=NTOT/(N(IDIMX)*NREM)
	CALL BITRV (XDATA,NPREV,NCURR,NREM,N(IDIMX))
	CALL DFT2 (XDATA,NPREV,NCURR,NREM,ISGN)
100	NREM=NREM*N(IDIMX)

105	IER=0
	RETURN

110	IER=1
	RETURN

130	IER=2
	RETURN

	END
