SUBROUTINE fft99(a,work,trigs,ifax,inc,jump,n,lot,ISIGN),4
!
! PURPOSE      PERFORMS MULTIPLE FAST FOURIER TRANSFORMS.  THIS PACKAGE
!           WILL PERFORM A NUMBER OF SIMULTANEOUS REAL/HALF-COMPLEX
!           PERIODIC FOURIER TRANSFORMS OR CORRESPONDING INVERSE
!           TRANSFORMS, I.E.  GIVEN A SET OF REAL DATA VECTORS, THE
!           PACKAGE RETURNS A SET OF 'HALF-COMPLEX' FOURIER
!           COEFFICIENT VECTORS, OR VICE VERSA.  THE LENGTH OF THE
!           TRANSFORMS MUST BE AN EVEN NUMBER GREATER THAN 4 THAT HAS
!           NO OTHER FACTORS EXCEPT POSSIBLY POWERS OF 2, 3, AND 5.
!           THIS IS AN ALL FORTRAN VERSION OF THE CRAYLIB PACKAGE
!           THAT IS MOSTLY WRITTEN IN CAL.
!
!           THE PACKAGE FFT99F CONTAINS SEVERAL USER-LEVEL ROUTINES:
!
!         SUBROUTINE SET99
!             AN INITIALIZATION ROUTINE THAT MUST BE CALLED ONCE
!             BEFORE A SEQUENCE OF CALLS TO THE FFT ROUTINES
!             (PROVIDED THAT N IS NOT CHANGED).
!
!         SUBROUTINES FFT99 AND FFT991
!             TWO FFT ROUTINES THAT RETURN SLIGHTLY DIFFERENT
!             ARRANGEMENTS OF THE DATA IN GRIDPOINT SPACE.
!
!
! ACCESS       THIS FORTRAN VERSION MAY BE ACCESSED WITH
!
!                *FORTRAN,P=XLIB,SN=FFT99F
!
!           TO ACCESS THE CRAY OBJECT CODE, CALLING THE USER ENTRY
!           POINTS FROM A CRAY PROGRAM IS SUFFICIENT.  THE SOURCE
!           FORTRAN AND CAL CODE FOR THE CRAYLIB VERSION MAY BE
!           ACCESSED USING
!
!                FETCH P=CRAYLIB,SN=FFT99
!                FETCH P=CRAYLIB,SN=CAL99
!
! USAGE        LET N BE OF THE FORM 2**P * 3**Q * 5**R, WHERE P .GE. 1,
!           Q .GE. 0, AND R .GE. 0.  THEN A TYPICAL SEQUENCE OF
!           CALLS TO TRANSFORM A GIVEN SET OF REAL VECTORS OF LENGTH
!           N TO A SET OF 'HALF-COMPLEX' FOURIER COEFFICIENT VECTORS
!           OF LENGTH N IS
!
!                DIMENSION IFAX(13),TRIGS(3*N/2+1),A(M*(N+2)),
!               +          WORK(M*(N+1))
!
!                CALL SET99 (TRIGS, IFAX, N)
!                CALL FFT99 (A,WORK,TRIGS,IFAX,INC,JUMP,N,M,ISIGN)
!
!           SEE THE INDIVIDUAL WRITE-UPS FOR SET99, FFT99, AND
!           FFT991 BELOW, FOR A DETAILED DESCRIPTION OF THE
!           ARGUMENTS.
!
! HISTORY      THE PACKAGE WAS WRITTEN BY CLIVE TEMPERTON AT ECMWF IN
!           NOVEMBER, 1978.  IT WAS MODIFIED, DOCUMENTED, AND TESTED
!           FOR NCAR BY RUSS REW IN SEPTEMBER, 1980.
!
!-----------------------------------------------------------------------
!
! SUBROUTINE SET99 (TRIGS, IFAX, N)
!
! PURPOSE      A SET-UP ROUTINE FOR FFT99 AND FFT991.  IT NEED ONLY BE
!           CALLED ONCE BEFORE A SEQUENCE OF CALLS TO THE FFT
!           ROUTINES (PROVIDED THAT N IS NOT CHANGED).
!
! ARGUMENT     IFAX(13),TRIGS(3*N/2+1)
! DIMENSIONS
!
! ARGUMENTS
!
! ON INPUT     TRIGS
!            A FLOATING POINT ARRAY OF DIMENSION 3*N/2 IF N/2 IS
!            EVEN, OR 3*N/2+1 IF N/2 IS ODD.
!
!           IFAX
!            AN INTEGER ARRAY.  THE NUMBER OF ELEMENTS ACTUALLY USED
!            WILL DEPEND ON THE FACTORIZATION OF N.  DIMENSIONING
!            IFAX FOR 13 SUFFICES FOR ALL N LESS THAN A MILLION.
!
!           N
!            AN EVEN NUMBER GREATER THAN 4 THAT HAS NO PRIME FACTOR
!            GREATER THAN 5.  N IS THE LENGTH OF THE TRANSFORMS (SEE
!            THE DOCUMENTATION FOR FFT99 AND FFT991 FOR THE
!            DEFINITIONS OF THE TRANSFORMS).
!
! ON OUTPUT    IFAX
!            CONTAINS THE FACTORIZATION OF N/2.  IFAX(1) IS THE
!            NUMBER OF FACTORS, AND THE FACTORS THEMSELVES ARE STORED
!            IN IFAX(2),IFAX(3),...  IF SET99 IS CALLED WITH N ODD,
!            OR IF N HAS ANY PRIME FACTORS GREATER THAN 5, IFAX(1)
!            IS SET TO -99.
!
!           TRIGS
!            AN ARRAY OF TRIGNOMENTRIC FUNCTION VALUES SUBSEQUENTLY
!            USED BY THE FFT ROUTINES.
!
!-----------------------------------------------------------------------
!
! SUBROUTINE FFT991 (A,WORK,TRIGS,IFAX,INC,JUMP,N,M,ISIGN)
!                    AND
! SUBROUTINE FFT99 (A,WORK,TRIGS,IFAX,INC,JUMP,N,M,ISIGN)
!
! PURPOSE      PERFORM A NUMBER OF SIMULTANEOUS REAL/HALF-COMPLEX
!           PERIODIC FOURIER TRANSFORMS OR CORRESPONDING INVERSE
!           TRANSFORMS, USING ORDINARY SPATIAL ORDER OF GRIDPOINT
!           VALUES (FFT991) OR EXPLICIT CYCLIC CONTINUITY IN THE
!           GRIDPOINT VALUES (FFT99).  GIVEN A SET
!           OF REAL DATA VECTORS, THE PACKAGE RETURNS A SET OF
!           'HALF-COMPLEX' FOURIER COEFFICIENT VECTORS, OR VICE
!           VERSA.  THE LENGTH OF THE TRANSFORMS MUST BE AN EVEN
!           NUMBER THAT HAS NO OTHER FACTORS EXCEPT POSSIBLY POWERS
!           OF 2, 3, AND 5.  THESE VERSION OF FFT991 AND FFT99 ARE
!           OPTIMIZED FOR USE ON THE CRAY-1.
!
! ARGUMENT     A(M*(N+2)), WORK(M*(N+1)), TRIGS(3*N/2+1), IFAX(13)
! DIMENSIONS
!
! ARGUMENTS
!
! ON INPUT     A
!            AN ARRAY OF LENGTH M*(N+2) CONTAINING THE INPUT DATA
!            OR COEFFICIENT VECTORS.  THIS ARRAY IS OVERWRITTEN BY
!            THE RESULTS.
!
!           WORK
!            A WORK ARRAY OF DIMENSION M*(N+1)
!
!           TRIGS
!            AN ARRAY SET UP BY SET99, WHICH MUST BE CALLED FIRST.
!
!           IFAX
!            AN ARRAY SET UP BY SET99, WHICH MUST BE CALLED FIRST.
!
!           INC
!            THE INCREMENT (IN WORDS) BETWEEN SUCCESSIVE ELEMENTS OF
!            EACH DATA OR COEFFICIENT VECTOR (E.G.  INC=1 FOR
!            CONSECUTIVELY STORED DATA).
!
!           JUMP
!            THE INCREMENT (IN WORDS) BETWEEN THE FIRST ELEMENTS OF
!            SUCCESSIVE DATA OR COEFFICIENT VECTORS.  ON THE CRAY-1,
!            TRY TO ARRANGE DATA SO THAT JUMP IS NOT A MULTIPLE OF 8
!            (TO AVOID MEMORY BANK CONFLICTS).  FOR CLARIFICATION OF
!            INC AND JUMP, SEE THE EXAMPLES BELOW.
!
!           N
!            THE LENGTH OF EACH TRANSFORM (SEE DEFINITION OF
!            TRANSFORMS, BELOW).
!
!           M
!            THE NUMBER OF TRANSFORMS TO BE DONE SIMULTANEOUSLY.
!
!           ISIGN
!            = +1 FOR A TRANSFORM FROM FOURIER COEFFICIENTS TO
!                 GRIDPOINT VALUES.
!            = -1 FOR A TRANSFORM FROM GRIDPOINT VALUES TO FOURIER
!                 COEFFICIENTS.
!
! ON OUTPUT    A
!            IF ISIGN = +1, AND M COEFFICIENT VECTORS ARE SUPPLIED
!            EACH CONTAINING THE SEQUENCE:
!
!            A(0),B(0),A(1),B(1),...,A(N/2),B(N/2)  (N+2 VALUES)
!
!            THEN THE RESULT CONSISTS OF M DATA VECTORS EACH
!            CONTAINING THE CORRESPONDING N+2 GRIDPOINT VALUES:
!
!            FOR FFT991, X(0), X(1), X(2),...,X(N-1),0,0.
!            FOR FFT99, X(N-1),X(0),X(1),X(2),...,X(N-1),X(0).
!                (EXPLICIT CYCLIC CONTINUITY)
!
!            WHEN ISIGN = +1, THE TRANSFORM IS DEFINED BY:
!              X(J)=SUM(K=0,...,N-1)(C(K)*EXP(2*I*J*K*PI/N))
!              WHERE C(K)=A(K)+I*B(K) AND C(N-K)=A(K)-I*B(K)
!              AND I=SQRT (-1)
!
!            IF ISIGN = -1, AND M DATA VECTORS ARE SUPPLIED EACH
!            CONTAINING A SEQUENCE OF GRIDPOINT VALUES X(J) AS
!            DEFINED ABOVE, THEN THE RESULT CONSISTS OF M VECTORS
!            EACH CONTAINING THE CORRESPONDING FOURIER COFFICIENTS
!            A(K), B(K), 0 .LE. K .LE N/2.
!
!            WHEN ISIGN = -1, THE INVERSE TRANSFORM IS DEFINED BY:
!              C(K)=(1/N)*SUM(J=0,...,N-1)(X(J)*EXP(-2*I*J*K*PI/N))
!              WHERE C(K)=A(K)+I*B(K) AND I=SQRT(-1)
!
!            A CALL WITH ISIGN=+1 FOLLOWED BY A CALL WITH ISIGN=-1
!            (OR VICE VERSA) RETURNS THE ORIGINAL DATA.
!
!            NOTE: THE FACT THAT THE GRIDPOINT VALUES X(J) ARE REAL
!            IMPLIES THAT B(0)=B(N/2)=0.  FOR A CALL WITH ISIGN=+1,
!            IT IS NOT ACTUALLY NECESSARY TO SUPPLY THESE ZEROS.
!
! EXAMPLES      GIVEN 19 DATA VECTORS EACH OF LENGTH 64 (+2 FOR EXPLICIT
!            CYCLIC CONTINUITY), COMPUTE THE CORRESPONDING VECTORS OF
!            FOURIER COEFFICIENTS.  THE DATA MAY, FOR EXAMPLE, BE
!            ARRANGED LIKE THIS:
!
! FIRST DATA   A(1)=    . . .                A(66)=             A(70)
! VECTOR       X(63) X(0) X(1) X(2) ... X(63) X(0)  (4 EMPTY LOCATIONS)
!
! SECOND DATA  A(71)=   . . .                                  A(140)
! VECTOR       X(63) X(0) X(1) X(2) ... X(63) X(0)  (4 EMPTY LOCATIONS)
!
!            AND SO ON.  HERE INC=1, JUMP=70, N=64, M=19, ISIGN=-1,
!            AND FFT99 SHOULD BE USED (BECAUSE OF THE EXPLICIT CYCLIC
!            CONTINUITY).
!
!            ALTERNATIVELY THE DATA MAY BE ARRANGED LIKE THIS:
!
!             FIRST         SECOND                          LAST
!             DATA          DATA                            DATA
!             VECTOR        VECTOR                          VECTOR
!
!              A(1)=         A(2)=                           A(19)=
!
!              X(63)         X(63)       . . .               X(63)
!     A(20)=   X(0)          X(0)        . . .               X(0)
!     A(39)=   X(1)          X(1)        . . .               X(1)
!               .             .                               .
!               .             .                               .
!               .             .                               .
!
!            IN WHICH CASE WE HAVE INC=19, JUMP=1, AND THE REMAINING
!            PARAMETERS ARE THE SAME AS BEFORE.  IN EITHER CASE, EACH
!            COEFFICIENT VECTOR OVERWRITES THE CORRESPONDING INPUT
!            DATA VECTOR.
!
!-----------------------------------------------------------------------
  DIMENSION a((n+2)*lot),work((n+1)*lot),trigs(3*n/2+1),ifax(13)
!
!  SUBROUTINE "FFT99" - MULTIPLE FAST REAL PERIODIC TRANSFORM
!  CORRESPONDING TO OLD SCALAR ROUTINE FFT9
!  PROCEDURE USED TO CONVERT TO HALF-LENGTH COMPLEX TRANSFORM
!  IS GIVEN BY COOLEY, LEWIS AND WELCH (J. SOUND VIB., VOL. 12
!  (1970), 315-337)
!
!  A IS THE ARRAY CONTAINING INPUT AND OUTPUT DATA
!  WORK IS AN AREA OF SIZE (N+1)*LOT
!  TRIGS IS A PREVIOUSLY PREPARED LIST OF TRIG FUNCTION VALUES
!  IFAX IS A PREVIOUSLY PREPARED LIST OF FACTORS OF N/2
!  INC IS THE INCREMENT WITHIN EACH DATA 'VECTOR'
!      (E.G. INC=1 FOR CONSECUTIVELY STORED DATA)
!  JUMP IS THE INCREMENT BETWEEN THE START OF EACH DATA VECTOR
!  N IS THE LENGTH OF THE DATA VECTORS
!  LOT IS THE NUMBER OF DATA VECTORS
!  ISIGN = +1 FOR TRANSFORM FROM SPECTRAL TO GRIDPOINT
!        = -1 FOR TRANSFORM FROM GRIDPOINT TO SPECTRAL
!
!  ORDERING OF COEFFICIENTS:
!      A(0),B(0),A(1),B(1),A(2),B(2),...,A(N/2),B(N/2)
!      WHERE B(0)=B(N/2)=0; (N+2) LOCATIONS REQUIRED
!
!  ORDERING OF DATA:
!      X(N-1),X(0),X(1),X(2),...,X(N),X(0)
!      I.E. EXPLICIT CYCLIC CONTINUITY; (N+2) LOCATIONS REQUIRED
!
!  VECTORIZATION IS ACHIEVED ON CRAY BY DOING THE TRANSFORMS IN
!  PARALLEL
!
!  *** N.B. N IS ASSUMED TO BE AN EVEN NUMBER
!
!  DEFINITION OF TRANSFORMS:
!  -------------------------
!
!  ISIGN=+1: X(J)=SUM(K=0,...,N-1)(C(K)*EXP(2*I*J*K*PI/N))
!      WHERE C(K)=A(K)+I*B(K) AND C(N-K)=A(K)-I*B(K)
!
!  ISIGN=-1: A(K)=(1/N)*SUM(J=0,...,N-1)(X(J)*COS(2*J*K*PI/N))
!            B(K)=-(1/N)*SUM(J=0,...,N-1)(X(J)*SIN(2*J*K*PI/N))
!
!
!
!
  nfax=ifax(1)
  nx=n+1
  nh=n/2
  ink=inc+inc
  IF (ISIGN == +1) GO TO 30
!
!  IF NECESSARY, TRANSFER DATA TO WORK AREA
  igo=50
  IF (MOD(nfax,2) == 1) GO TO 40
  ibase=inc+1
  jbase=1
  DO l=1,lot
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO m=1,n
      work(j)=a(i)
      i=i+inc
      j=j+1
    END DO
    ibase=ibase+jump
    jbase=jbase+nx
  END DO
!
  igo=60
  GO TO 40
!
!  PREPROCESSING (ISIGN=+1)
!  ------------------------
!
  30 CONTINUE
  CALL fft99a(a,work,trigs,inc,jump,n,lot)
  igo=60
!
!  COMPLEX TRANSFORM
!  -----------------
!
  40 CONTINUE
  ia=inc+1
  la=1
  DO k=1,nfax
    IF (igo == 60) GO TO 60
!    50 CONTINUE
    CALL vpassm(a(ia),a(ia+inc),work(1),work(2),trigs,                  &
        ink,2,jump,nx,lot,nh,ifax(k+1),la)
    igo=60
    GO TO 70
    60 CONTINUE
    CALL vpassm(work(1),work(2),a(ia),a(ia+inc),trigs,                  &
        2,ink,nx,jump,lot,nh,ifax(k+1),la)
    igo=50
    70 CONTINUE
    la=la*ifax(k+1)
  END DO
!
  IF (ISIGN == -1) GO TO 130
!
!  IF NECESSARY, TRANSFER DATA FROM WORK AREA
  IF (MOD(nfax,2) == 1) GO TO 110
  ibase=1
  jbase=ia
  DO l=1,lot
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO m=1,n
      a(j)=work(i)
      i=i+1
      j=j+inc
    END DO
    ibase=ibase+nx
    jbase=jbase+jump
  END DO
!
!  FILL IN CYCLIC BOUNDARY POINTS
  110 CONTINUE
  ia=1
  ib=n*inc+1
!DIR$ IVDEP
  DO l=1,lot
    a(ia)=a(ib)
    a(ib+inc)=a(ia+inc)
    ia=ia+jump
    ib=ib+jump
  END DO
  GO TO 140
!
!  POSTPROCESSING (ISIGN=-1):
!  --------------------------
!
  130 CONTINUE
  CALL fft99b(work,a,trigs,inc,jump,n,lot)
!
  140 CONTINUE
  RETURN
END SUBROUTINE fft99


SUBROUTINE fft99a(a,work,trigs,inc,jump,n,lot) 2
  DIMENSION a(n),work(n),trigs(n)
!
!  SUBROUTINE FFT99A - PREPROCESSING STEP FOR FFT99, ISIGN=+1
!  (SPECTRAL TO GRIDPOINT TRANSFORM)
!
  nh=n/2
  nx=n+1
  ink=inc+inc
!
!  A(0) AND A(N/2)
  ia=1
  ib=n*inc+1
  ja=1
  jb=2
!DIR$ IVDEP
  DO l=1,lot
    work(ja)=a(ia)+a(ib)
    work(jb)=a(ia)-a(ib)
    ia=ia+jump
    ib=ib+jump
    ja=ja+nx
    jb=jb+nx
  END DO
!
!  REMAINING WAVENUMBERS
  iabase=2*inc+1
  ibbase=(n-2)*inc+1
  jabase=3
  jbbase=n-1
!
  DO k=3,nh,2
    ia=iabase
    ib=ibbase
    ja=jabase
    jb=jbbase
    c=trigs(n+k)
    s=trigs(n+k+1)
!DIR$ IVDEP
    DO l=1,lot
      work(ja)=(a(ia)+a(ib))-                                           &
          (s*(a(ia)-a(ib))+c*(a(ia+inc)+a(ib+inc)))
      work(jb)=(a(ia)+a(ib))+                                           &
          (s*(a(ia)-a(ib))+c*(a(ia+inc)+a(ib+inc)))
      work(ja+1)=(c*(a(ia)-a(ib))-s*(a(ia+inc)+a(ib+inc)))+             &
          (a(ia+inc)-a(ib+inc))
      work(jb+1)=(c*(a(ia)-a(ib))-s*(a(ia+inc)+a(ib+inc)))-             &
          (a(ia+inc)-a(ib+inc))
      ia=ia+jump
      ib=ib+jump
      ja=ja+nx
      jb=jb+nx
    END DO
    iabase=iabase+ink
    ibbase=ibbase-ink
    jabase=jabase+2
    jbbase=jbbase-2
  END DO
!
  IF (iabase /= ibbase) GO TO 50
!  WAVENUMBER N/4 (IF IT EXISTS)
  ia=iabase
  ja=jabase
!DIR$ IVDEP
  DO l=1,lot
    work(ja)=2.0*a(ia)
    work(ja+1)=-2.0*a(ia+inc)
    ia=ia+jump
    ja=ja+nx
  END DO
!
  50 CONTINUE
  RETURN
END SUBROUTINE fft99a


SUBROUTINE fft99b(work,a,trigs,inc,jump,n,lot) 2
  DIMENSION work(n),a(n),trigs(n)
!
!  SUBROUTINE FFT99B - POSTPROCESSING STEP FOR FFT99, ISIGN=-1
!  (GRIDPOINT TO SPECTRAL TRANSFORM)
!
  nh=n/2
  nx=n+1
  ink=inc+inc
!
!  A(0) AND A(N/2)
  scale=1.0/FLOAT(n)
  ia=1
  ib=2
  ja=1
  jb=n*inc+1
!DIR$ IVDEP
  DO l=1,lot
    a(ja)=scale*(work(ia)+work(ib))
    a(jb)=scale*(work(ia)-work(ib))
    a(ja+inc)=0.0
    a(jb+inc)=0.0
    ia=ia+nx
    ib=ib+nx
    ja=ja+jump
    jb=jb+jump
  END DO
!
!  REMAINING WAVENUMBERS
  scale=0.5*scale
  iabase=3
  ibbase=n-1
  jabase=2*inc+1
  jbbase=(n-2)*inc+1
!
  DO k=3,nh,2
    ia=iabase
    ib=ibbase
    ja=jabase
    jb=jbbase
    c=trigs(n+k)
    s=trigs(n+k+1)
!DIR$ IVDEP
    DO l=1,lot
      a(ja)=scale*((work(ia)+work(ib))                                  &
          +(c*(work(ia+1)+work(ib+1))+s*(work(ia)-work(ib))))
      a(jb)=scale*((work(ia)+work(ib))                                  &
          -(c*(work(ia+1)+work(ib+1))+s*(work(ia)-work(ib))))
      a(ja+inc)=scale*((c*(work(ia)-work(ib))-s*(work(ia+1)+work(ib+1))) &
          +(work(ib+1)-work(ia+1)))
      a(jb+inc)=scale*((c*(work(ia)-work(ib))-s*(work(ia+1)+work(ib+1))) &
          -(work(ib+1)-work(ia+1)))
      ia=ia+nx
      ib=ib+nx
      ja=ja+jump
      jb=jb+jump
    END DO
    iabase=iabase+2
    ibbase=ibbase-2
    jabase=jabase+ink
    jbbase=jbbase-ink
  END DO
!
  IF (iabase /= ibbase) GO TO 50
!  WAVENUMBER N/4 (IF IT EXISTS)
  ia=iabase
  ja=jabase
  scale=2.0*scale
!DIR$ IVDEP
  DO l=1,lot
    a(ja)=scale*work(ia)
    a(ja+inc)=-scale*work(ia+1)
    ia=ia+nx
    ja=ja+jump
  END DO
!
  50 CONTINUE
  RETURN
END SUBROUTINE fft99b


SUBROUTINE fft991(a,work,trigs,ifax,inc,jump,n,lot,ISIGN) 8,4
  DIMENSION a(n),work(n),trigs(n),ifax(1)
!
!  SUBROUTINE "FFT991" - MULTIPLE REAL/HALF-COMPLEX PERIODIC
!  FAST FOURIER TRANSFORM
!
!  SAME AS FFT99 EXCEPT THAT ORDERING OF DATA CORRESPONDS TO
!  THAT IN MRFFT2
!
!  PROCEDURE USED TO CONVERT TO HALF-LENGTH COMPLEX TRANSFORM
!  IS GIVEN BY COOLEY, LEWIS AND WELCH (J. SOUND VIB., VOL. 12
!  (1970), 315-337)
!
!  A IS THE ARRAY CONTAINING INPUT AND OUTPUT DATA
!  WORK IS AN AREA OF SIZE (N+1)*LOT
!  TRIGS IS A PREVIOUSLY PREPARED LIST OF TRIG FUNCTION VALUES
!  IFAX IS A PREVIOUSLY PREPARED LIST OF FACTORS OF N/2
!  INC IS THE INCREMENT WITHIN EACH DATA 'VECTOR'
!      (E.G. INC=1 FOR CONSECUTIVELY STORED DATA)
!  JUMP IS THE INCREMENT BETWEEN THE START OF EACH DATA VECTOR
!  N IS THE LENGTH OF THE DATA VECTORS
!  LOT IS THE NUMBER OF DATA VECTORS
!  ISIGN = +1 FOR TRANSFORM FROM SPECTRAL TO GRIDPOINT
!        = -1 FOR TRANSFORM FROM GRIDPOINT TO SPECTRAL
!
!  ORDERING OF COEFFICIENTS:
!      A(0),B(0),A(1),B(1),A(2),B(2),...,A(N/2),B(N/2)
!      WHERE B(0)=B(N/2)=0; (N+2) LOCATIONS REQUIRED
!
!  ORDERING OF DATA:
!      X(0),X(1),X(2),...,X(N-1)
!
!  VECTORIZATION IS ACHIEVED ON CRAY BY DOING THE TRANSFORMS IN
!  PARALLEL
!
!  *** N.B. N IS ASSUMED TO BE AN EVEN NUMBER
!
!  DEFINITION OF TRANSFORMS:
!  -------------------------
!
!  ISIGN=+1: X(J)=SUM(K=0,...,N-1)(C(K)*EXP(2*I*J*K*PI/N))
!      WHERE C(K)=A(K)+I*B(K) AND C(N-K)=A(K)-I*B(K)
!
!  ISIGN=-1: A(K)=(1/N)*SUM(J=0,...,N-1)(X(J)*COS(2*J*K*PI/N))
!            B(K)=-(1/N)*SUM(J=0,...,N-1)(X(J)*SIN(2*J*K*PI/N))
!
!
!
  nfax=ifax(1)
  nx=n+1
  nh=n/2
  ink=inc+inc
  IF (ISIGN == +1) GO TO 30
!
!  IF NECESSARY, TRANSFER DATA TO WORK AREA
  igo=50
  IF (MOD(nfax,2) == 1) GO TO 40
  ibase=1
  jbase=1
  DO l=1,lot
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO m=1,n
      work(j)=a(i)
      i=i+inc
      j=j+1
    END DO
    ibase=ibase+jump
    jbase=jbase+nx
  END DO
!
  igo=60
  GO TO 40
!
!  PREPROCESSING (ISIGN=+1)
!  ------------------------
!
  30 CONTINUE
  CALL fft99a(a,work,trigs,inc,jump,n,lot)
  igo=60
!
!  COMPLEX TRANSFORM
!  -----------------
!
  40 CONTINUE
  ia=1
  la=1
  DO k=1,nfax
    IF (igo == 60) GO TO 60
!    50 CONTINUE
    CALL vpassm(a(ia),a(ia+inc),work(1),work(2),trigs,                  &
        ink,2,jump,nx,lot,nh,ifax(k+1),la)
    igo=60
    GO TO 70
    60 CONTINUE
    CALL vpassm(work(1),work(2),a(ia),a(ia+inc),trigs,                  &
        2,ink,nx,jump,lot,nh,ifax(k+1),la)
    igo=50
    70 CONTINUE
    la=la*ifax(k+1)
  END DO
!
  IF (ISIGN == -1) GO TO 130
!
!  IF NECESSARY, TRANSFER DATA FROM WORK AREA
  IF (MOD(nfax,2) == 1) GO TO 110
  ibase=1
  jbase=1
  DO l=1,lot
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO m=1,n
      a(j)=work(i)
      i=i+1
      j=j+inc
    END DO
    ibase=ibase+nx
    jbase=jbase+jump
  END DO
!
!  FILL IN ZEROS AT END
  110 CONTINUE
  ib=n*inc+1
!DIR$ IVDEP
  DO l=1,lot
    a(ib)=0.0
    a(ib+inc)=0.0
    ib=ib+jump
  END DO
  GO TO 140
!
!  POSTPROCESSING (ISIGN=-1):
!  --------------------------
!
  130 CONTINUE
  CALL fft99b(work,a,trigs,inc,jump,n,lot)
!
  140 CONTINUE
  RETURN
END SUBROUTINE fft991


SUBROUTINE set99 (trigs, ifax, n) 8,3
  DIMENSION ifax(13),trigs(3*n/2+1)
!
! MODE 3 IS USED FOR REAL/HALF-COMPLEX TRANSFORMS.  IT IS POSSIBLE
! TO DO COMPLEX/COMPLEX TRANSFORMS WITH OTHER VALUES OF MODE, BUT
! DOCUMENTATION OF THE DETAILS WERE NOT AVAILABLE WHEN THIS ROUTINE
! WAS WRITTEN.
!
  DATA mode /3/
  CALL fax (ifax, n, mode)
  i = ifax(1)
  IF (ifax(i+1) > 5 .OR. n <= 4) ifax(1) = -99
  IF (ifax(1) <= 0 ) THEN
    WRITE(6,*) ' SET99 -- INVALID N'
    CALL arpsstop('arpsstop called from SET99',1)
  END IF
  CALL fftrig (trigs, n, mode)
  RETURN
END SUBROUTINE set99


SUBROUTINE fax(ifax,n,mode) 1
  DIMENSION ifax(10)
  nn=n
  IF (IABS(mode) == 1) GO TO 10
  IF (IABS(mode) == 8) GO TO 10
  nn=n/2
  IF ((nn+nn) == n) GO TO 10
  ifax(1)=-99
  RETURN
  10 k=1
!  TEST FOR FACTORS OF 4
  20 IF (MOD(nn,4) /= 0) GO TO 30
  k=k+1
  ifax(k)=4
  nn=nn/4
  IF (nn == 1) GO TO 80
  GO TO 20
!  TEST FOR EXTRA FACTOR OF 2
  30 IF (MOD(nn,2) /= 0) GO TO 40
  k=k+1
  ifax(k)=2
  nn=nn/2
  IF (nn == 1) GO TO 80
!  TEST FOR FACTORS OF 3
  40 IF (MOD(nn,3) /= 0) GO TO 50
  k=k+1
  ifax(k)=3
  nn=nn/3
  IF (nn == 1) GO TO 80
  GO TO 40
!  NOW FIND REMAINING FACTORS
  50 l=5
  inc=2
!  INC ALTERNATELY TAKES ON VALUES 2 AND 4
  60 IF (MOD(nn,l) /= 0) GO TO 70
  k=k+1
  ifax(k)=l
  nn=nn/l
  IF (nn == 1) GO TO 80
  GO TO 60
  70 l=l+inc
  inc=6-inc
  GO TO 60
  80 ifax(1)=k-1
!  IFAX(1) CONTAINS NUMBER OF FACTORS
  nfax=ifax(1)
!  SORT FACTORS INTO ASCENDING ORDER
  IF (nfax == 1) GO TO 110
  DO ii=2,nfax
    istop=nfax+2-ii
    DO i=2,istop
      IF (ifax(i+1) >= ifax(i)) CYCLE
      item=ifax(i)
      ifax(i)=ifax(i+1)
      ifax(i+1)=item
    END DO
  END DO
  110 CONTINUE
  RETURN
END SUBROUTINE fax


SUBROUTINE fftrig(trigs,n,mode) 1
  DIMENSION trigs(1)
  pi=2.0*ASIN(1.0)
  imode=IABS(mode)
  nn=n
  IF (imode > 1.AND.imode < 6) nn=n/2
  del=(pi+pi)/FLOAT(nn)
  l=nn+nn
  DO i=1,l,2
    angle=0.5*FLOAT(i-1)*del
    trigs(i)=COS(angle)
    trigs(i+1)=SIN(angle)
  END DO
  IF (imode == 1) RETURN
  IF (imode == 8) RETURN
  del=0.5*del
  nh=(nn+1)/2
  l=nh+nh
  la=nn+nn
  DO i=1,l,2
    angle=0.5*FLOAT(i-1)*del
    trigs(la+i)=COS(angle)
    trigs(la+i+1)=SIN(angle)
  END DO
  IF (imode <= 3) RETURN
  del=0.5*del
  la=la+nn
  IF (mode == 5) GO TO 40
  DO i=2,nn
    angle=FLOAT(i-1)*del
    trigs(la+i)=2.0*SIN(angle)
  END DO
  RETURN
  40 CONTINUE
  del=0.5*del
  DO i=2,n
    angle=FLOAT(i-1)*del
    trigs(la+i)=SIN(angle)
  END DO
  RETURN
END SUBROUTINE fftrig


SUBROUTINE vpassm(a,b,c,d,trigs,inc1,inc2,inc3,inc4,lot,n,ifac,la) 4
  DIMENSION a(n),b(n),c(n),d(n),trigs(n)
!
!  SUBROUTINE "VPASSM" - MULTIPLE VERSION OF "VPASSA"
!  PERFORMS ONE PASS THROUGH DATA
!  AS PART OF MULTIPLE COMPLEX FFT ROUTINE
!  A IS FIRST REAL INPUT VECTOR
!  B IS FIRST IMAGINARY INPUT VECTOR
!  C IS FIRST REAL OUTPUT VECTOR
!  D IS FIRST IMAGINARY OUTPUT VECTOR
!  TRIGS IS PRECALCULATED TABLE OF SINES " COSINES
!  INC1 IS ADDRESSING INCREMENT FOR A AND B
!  INC2 IS ADDRESSING INCREMENT FOR C AND D
!  INC3 IS ADDRESSING INCREMENT BETWEEN A"S & B"S
!  INC4 IS ADDRESSING INCREMENT BETWEEN C"S & D"S
!  LOT IS THE NUMBER OF VECTORS
!  N IS LENGTH OF VECTORS
!  IFAC IS CURRENT FACTOR OF N
!  LA IS PRODUCT OF PREVIOUS FACTORS
!
  DATA sin36/0.587785252292473/,cos36/0.809016994374947/,               &
       sin72/0.951056516295154/,cos72/0.309016994374947/,               &
       sin60/0.866025403784437/
!
  m=n/ifac
  iink=m*inc1
  jink=la*inc2
  jump=(ifac-1)*jink
  ibase=0
  jbase=0
  igo=ifac-1
  IF (igo > 4) RETURN
!  GO TO (10,50,90,130),igo
!
!  obsolescent feature correction temporarily by WYH.
!
   SELECT CASE (igo)
   CASE (1)
     GO TO 10
   CASE (2)
     GO TO 50
   CASE (3)
     GO TO 90
   CASE (4)
     GO TO 130
   CASE DEFAULT
!    Do nothing
   END SELECT
!
!  end of correction by WYH.
!
!
!  CODING FOR FACTOR 2
!
  10 ia=1
  ja=1
  ib=ia+iink
  jb=ja+jink
  DO l=1,la
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO ijk=1,lot
      c(ja+j)=a(ia+i)+a(ib+i)
      d(ja+j)=b(ia+i)+b(ib+i)
      c(jb+j)=a(ia+i)-a(ib+i)
      d(jb+j)=b(ia+i)-b(ib+i)
      i=i+inc3
      j=j+inc4
    END DO
    ibase=ibase+inc1
    jbase=jbase+inc2
  END DO
  IF (la == m) RETURN
  la1=la+1
  jbase=jbase+jump
  DO k=la1,m,la
    kb=k+k-2
    c1=trigs(kb+1)
    s1=trigs(kb+2)
    DO l=1,la
      i=ibase
      j=jbase
!DIR$ IVDEP
      DO ijk=1,lot
        c(ja+j)=a(ia+i)+a(ib+i)
        d(ja+j)=b(ia+i)+b(ib+i)
        c(jb+j)=c1*(a(ia+i)-a(ib+i))-s1*(b(ia+i)-b(ib+i))
        d(jb+j)=s1*(a(ia+i)-a(ib+i))+c1*(b(ia+i)-b(ib+i))
        i=i+inc3
        j=j+inc4
      END DO
      ibase=ibase+inc1
      jbase=jbase+inc2
    END DO
    jbase=jbase+jump
  END DO
  RETURN
!
!  CODING FOR FACTOR 3
!
  50 ia=1
  ja=1
  ib=ia+iink
  jb=ja+jink
  ic=ib+iink
  jc=jb+jink
  DO l=1,la
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO ijk=1,lot
      c(ja+j)=a(ia+i)+(a(ib+i)+a(ic+i))
      d(ja+j)=b(ia+i)+(b(ib+i)+b(ic+i))
      c(jb+j)=(a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))
      c(jc+j)=(a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))
      d(jb+j)=(b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i)))
      d(jc+j)=(b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i)))
      i=i+inc3
      j=j+inc4
    END DO
    ibase=ibase+inc1
    jbase=jbase+inc2
  END DO
  IF (la == m) RETURN
  la1=la+1
  jbase=jbase+jump
  DO k=la1,m,la
    kb=k+k-2
    kc=kb+kb
    c1=trigs(kb+1)
    s1=trigs(kb+2)
    c2=trigs(kc+1)
    s2=trigs(kc+2)
    DO l=1,la
      i=ibase
      j=jbase
!DIR$ IVDEP
      DO ijk=1,lot
        c(ja+j)=a(ia+i)+(a(ib+i)+a(ic+i))
        d(ja+j)=b(ia+i)+(b(ib+i)+b(ic+i))
        c(jb+j)=                                                        &
            c1*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))) &
            -s1*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i))))
        d(jb+j)=                                                        &
            s1*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))) &
            +c1*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i))))
        c(jc+j)=                                                        &
            c2*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))) &
            -s2*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i))))
        d(jc+j)=                                                        &
            s2*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))) &
            +c2*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i))))
        i=i+inc3
        j=j+inc4
      END DO
      ibase=ibase+inc1
      jbase=jbase+inc2
    END DO
    jbase=jbase+jump
  END DO
  RETURN
!
!  CODING FOR FACTOR 4
!
  90 ia=1
  ja=1
  ib=ia+iink
  jb=ja+jink
  ic=ib+iink
  jc=jb+jink
  id=ic+iink
  jd=jc+jink
  DO l=1,la
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO ijk=1,lot
      c(ja+j)=(a(ia+i)+a(ic+i))+(a(ib+i)+a(id+i))
      c(jc+j)=(a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i))
      d(ja+j)=(b(ia+i)+b(ic+i))+(b(ib+i)+b(id+i))
      d(jc+j)=(b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i))
      c(jb+j)=(a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i))
      c(jd+j)=(a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i))
      d(jb+j)=(b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i))
      d(jd+j)=(b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i))
      i=i+inc3
      j=j+inc4
    END DO
    ibase=ibase+inc1
    jbase=jbase+inc2
  END DO
  IF (la == m) RETURN
  la1=la+1
  jbase=jbase+jump
  DO k=la1,m,la
    kb=k+k-2
    kc=kb+kb
    kd=kc+kb
    c1=trigs(kb+1)
    s1=trigs(kb+2)
    c2=trigs(kc+1)
    s2=trigs(kc+2)
    c3=trigs(kd+1)
    s3=trigs(kd+2)
    DO l=1,la
      i=ibase
      j=jbase
!DIR$ IVDEP
      DO ijk=1,lot
        c(ja+j)=(a(ia+i)+a(ic+i))+(a(ib+i)+a(id+i))
        d(ja+j)=(b(ia+i)+b(ic+i))+(b(ib+i)+b(id+i))
        c(jc+j)=                                                        &
            c2*((a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i)))                    &
            -s2*((b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i)))
        d(jc+j)=                                                        &
            s2*((a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i)))                    &
            +c2*((b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i)))
        c(jb+j)=                                                        &
            c1*((a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i)))                    &
            -s1*((b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i)))
        d(jb+j)=                                                        &
            s1*((a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i)))                    &
            +c1*((b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i)))
        c(jd+j)=                                                        &
            c3*((a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i)))                    &
            -s3*((b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i)))
        d(jd+j)=                                                        &
            s3*((a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i)))                    &
            +c3*((b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i)))
        i=i+inc3
        j=j+inc4
      END DO
      ibase=ibase+inc1
      jbase=jbase+inc2
    END DO
    jbase=jbase+jump
  END DO
  RETURN
!
!  CODING FOR FACTOR 5
!
  130 ia=1
  ja=1
  ib=ia+iink
  jb=ja+jink
  ic=ib+iink
  jc=jb+jink
  id=ic+iink
  jd=jc+jink
  ie=id+iink
  je=jd+jink
  DO l=1,la
    i=ibase
    j=jbase
!DIR$ IVDEP
    DO ijk=1,lot
      c(ja+j)=a(ia+i)+(a(ib+i)+a(ie+i))+(a(ic+i)+a(id+i))
      d(ja+j)=b(ia+i)+(b(ib+i)+b(ie+i))+(b(ic+i)+b(id+i))
      c(jb+j)=(a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
          -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))
      c(je+j)=(a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
          +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))
      d(jb+j)=(b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
          +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i)))
      d(je+j)=(b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
          -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i)))
      c(jc+j)=(a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
          -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))
      c(jd+j)=(a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
          +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))
      d(jc+j)=(b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
          +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i)))
      d(jd+j)=(b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
          -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i)))
      i=i+inc3
      j=j+inc4
    END DO
    ibase=ibase+inc1
    jbase=jbase+inc2
  END DO
  IF (la == m) RETURN
  la1=la+1
  jbase=jbase+jump
  DO k=la1,m,la
    kb=k+k-2
    kc=kb+kb
    kd=kc+kb
    ke=kd+kb
    c1=trigs(kb+1)
    s1=trigs(kb+2)
    c2=trigs(kc+1)
    s2=trigs(kc+2)
    c3=trigs(kd+1)
    s3=trigs(kd+2)
    c4=trigs(ke+1)
    s4=trigs(ke+2)
    DO l=1,la
      i=ibase
      j=jbase
!DIR$ IVDEP
      DO ijk=1,lot
        c(ja+j)=a(ia+i)+(a(ib+i)+a(ie+i))+(a(ic+i)+a(id+i))
        d(ja+j)=b(ia+i)+(b(ib+i)+b(ie+i))+(b(ic+i)+b(id+i))
        c(jb+j)=                                                        &
            c1*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
              -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i))))       &
            -s1*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
              +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
        d(jb+j)=                                                        &
            s1*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
              -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i))))       &
            +c1*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
              +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
        c(je+j)=                                                        &
            c4*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
              +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i))))       &
            -s4*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
              -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
        d(je+j)=                                                        &
            s4*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
              +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i))))       &
            +c4*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
              -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
        c(jc+j)=                                                        &
            c2*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
              -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i))))       &
            -s2*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
              +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
        d(jc+j)=                                                        &
            s2*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
              -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i))))       &
            +c2*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
              +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
        c(jd+j)=                                                        &
            c3*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
              +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i))))       &
            -s3*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
              -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
        d(jd+j)=                                                        &
            s3*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
              +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i))))       &
            +c3*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
              -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
        i=i+inc3
        j=j+inc4
      END DO
      ibase=ibase+inc1
      jbase=jbase+inc2
    END DO
    jbase=jbase+jump
  END DO
  RETURN
END SUBROUTINE vpassm