FV3 Bundle
fft99.F90
Go to the documentation of this file.
1 !***********************************************************************
2 !* GNU Lesser General Public License
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* FMS is free software: you can redistribute it and/or modify it under
7 !* the terms of the GNU Lesser General Public License as published by
8 !* the Free Software Foundation, either version 3 of the License, or (at
9 !* your option) any later version.
10 !*
11 !* FMS is distributed in the hope that it will be useful, but WITHOUT
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 !* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 !* for more details.
15 !*
16 !* You should have received a copy of the GNU Lesser General Public
17 !* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 !***********************************************************************
19 
20 
21 module fft99_mod
22 
23 use constants_mod, only: pi
24 use mpp_mod, only: mpp_error, fatal
25 
26 implicit none
27 private
28 
29 public :: fft99, fft991, set99
30 
31 contains
32 
33 !##########################################################################
34 
35  subroutine fft99 (a,work,trigs,ifax,inc,jump,n,lot,isign)
36 
37 ! purpose performs multiple fast fourier transforms. this package
38 ! will perform a number of simultaneous real/half-complex
39 ! periodic fourier transforms or corresponding inverse
40 ! transforms, i.e. given a set of real data vectors, the
41 ! package returns a set of 'half-complex' fourier
42 ! coefficient vectors, or vice versa. the length of the
43 ! transforms must be an even number greater than 4 that has
44 ! no other factors except possibly powers of 2, 3, and 5.
45 ! this is an all-fortran version of a optimized routine
46 ! fft99 written for xmp/ymps by dr. clive temperton of
47 ! ecmwf.
48 !
49 ! the package fft99f contains several user-level routines:
50 !
51 ! subroutine set99
52 ! an initialization routine that must be called once
53 ! before a sequence of calls to the fft routines
54 ! (provided that n is not changed).
55 !
56 ! subroutines fft99 and fft991
57 ! two fft routines that return slightly different
58 ! arrangements of the data in gridpoint space.
59 !
60 ! usage let n be of the form 2**p * 3**q * 5**r, where p .ge. 1,
61 ! q .ge. 0, and r .ge. 0. then a typical sequence of
62 ! calls to transform a given set of real vectors of length
63 ! n to a set of 'half-complex' fourier coefficient vectors
64 ! of length n is
65 !
66 ! dimension ifax(13),trigs(3*n/2+1),a(m*(n+2)),
67 ! + work(m*(n+1))
68 !
69 ! call set99 (trigs, ifax, n)
70 ! call fft99 (a,work,trigs,ifax,inc,jump,n,m,isign)
71 !
72 ! see the individual write-ups for set99, fft99, and
73 ! fft991 below, for a detailed description of the
74 ! arguments.
75 !
76 ! history the package was written by clive temperton at ecmwf in
77 ! november, 1978. it was modified, documented, and tested
78 ! for ncar by russ rew in september, 1980.
79 !
80 !-----------------------------------------------------------------------
81 !
82 ! subroutine set99 (trigs, ifax, n)
83 !
84 ! purpose a set-up routine for fft99 and fft991. it need only be
85 ! called once before a sequence of calls to the fft
86 ! routines (provided that n is not changed).
87 !
88 ! argument ifax(13),trigs(3*n/2+1)
89 ! dimensions
90 !
91 ! arguments
92 !
93 ! on input trigs
94 ! a floating point array of dimension 3*n/2 if n/2 is
95 ! even, or 3*n/2+1 if n/2 is odd.
96 !
97 ! ifax
98 ! an integer array. the number of elements actually used
99 ! will depend on the factorization of n. dimensioning
100 ! ifax for 13 suffices for all n less than a million.
101 !
102 ! n
103 ! an even number greater than 4 that has no prime factor
104 ! greater than 5. n is the length of the transforms (see
105 ! the documentation for fft99 and fft991 for the
106 ! definitions of the transforms).
107 !
108 ! on output ifax
109 ! contains the factorization of n/2. ifax(1) is the
110 ! number of factors, and the factors themselves are stored
111 ! in ifax(2),ifax(3),... if set99 is called with n odd,
112 ! or if n has any prime factors greater than 5, ifax(1)
113 ! is set to -99.
114 !
115 ! trigs
116 ! an array of trigonometric function values subsequently
117 ! used by the fft routines.
118 !
119 !-----------------------------------------------------------------------
120 !
121 ! subroutine fft991 (a,work,trigs,ifax,inc,jump,n,m,isign)
122 ! and
123 ! subroutine fft99 (a,work,trigs,ifax,inc,jump,n,m,isign)
124 !
125 ! purpose perform a number of simultaneous real/half-complex
126 ! periodic fourier transforms or corresponding inverse
127 ! transforms, using ordinary spatial order of gridpoint
128 ! values (fft991) or explicit cyclic continuity in the
129 ! gridpoint values (fft99). given a set
130 ! of real data vectors, the package returns a set of
131 ! 'half-complex' fourier coefficient vectors, or vice
132 ! versa. the length of the transforms must be an even
133 ! number that has no other factors except possibly powers
134 ! of 2, 3, and 5. this is an all-fortran version of
135 ! optimized routine fft991 written for xmp/ymps by
136 ! dr. clive temperton of ecmwf.
137 !
138 ! argument a(m*(n+2)), work(m*(n+1)), trigs(3*n/2+1), ifax(13)
139 ! dimensions
140 !
141 ! arguments
142 !
143 ! on input a
144 ! an array of length m*(n+2) containing the input data
145 ! or coefficient vectors. this array is overwritten by
146 ! the results.
147 !
148 ! work
149 ! a work array of dimension m*(n+1)
150 !
151 ! trigs
152 ! an array set up by set99, which must be called first.
153 !
154 ! ifax
155 ! an array set up by set99, which must be called first.
156 !
157 ! inc
158 ! the increment (in words) between successive elements of
159 ! each data or coefficient vector (e.g. inc=1 for
160 ! consecutively stored data).
161 !
162 ! jump
163 ! the increment (in words) between the first elements of
164 ! successive data or coefficient vectors. on crays,
165 ! try to arrange data so that jump is not a multiple of 8
166 ! (to avoid memory bank conflicts). for clarification of
167 ! inc and jump, see the examples below.
168 !
169 ! n
170 ! the length of each transform (see definition of
171 ! transforms, below).
172 !
173 ! m
174 ! the number of transforms to be done simultaneously.
175 !
176 ! isign
177 ! = +1 for a transform from fourier coefficients to
178 ! gridpoint values.
179 ! = -1 for a transform from gridpoint values to fourier
180 ! coefficients.
181 !
182 ! on output a
183 ! if isign = +1, and m coefficient vectors are supplied
184 ! each containing the sequence:
185 !
186 ! a(0),b(0),a(1),b(1),...,a(n/2),b(n/2) (n+2 values)
187 !
188 ! then the result consists of m data vectors each
189 ! containing the corresponding n+2 gridpoint values:
190 !
191 ! for fft991, x(0), x(1), x(2),...,x(n-1),0,0.
192 ! for fft99, x(n-1),x(0),x(1),x(2),...,x(n-1),x(0).
193 ! (explicit cyclic continuity)
194 !
195 ! when isign = +1, the transform is defined by:
196 ! x(j)=sum(k=0,...,n-1)(c(k)*exp(2*i*j*k*pi/n))
197 ! where c(k)=a(k)+i*b(k) and c(n-k)=a(k)-i*b(k)
198 ! and i=sqrt (-1)
199 !
200 ! if isign = -1, and m data vectors are supplied each
201 ! containing a sequence of gridpoint values x(j) as
202 ! defined above, then the result consists of m vectors
203 ! each containing the corresponding fourier cofficients
204 ! a(k), b(k), 0 .le. k .le n/2.
205 !
206 ! when isign = -1, the inverse transform is defined by:
207 ! c(k)=(1/n)*sum(j=0,...,n-1)(x(j)*exp(-2*i*j*k*pi/n))
208 ! where c(k)=a(k)+i*b(k) and i=sqrt(-1)
209 !
210 ! a call with isign=+1 followed by a call with isign=-1
211 ! (or vice versa) returns the original data.
212 !
213 ! note: the fact that the gridpoint values x(j) are real
214 ! implies that b(0)=b(n/2)=0. for a call with isign=+1,
215 ! it is not actually necessary to supply these zeros.
216 !
217 ! examples given 19 data vectors each of length 64 (+2 for explicit
218 ! cyclic continuity), compute the corresponding vectors of
219 ! fourier coefficients. the data may, for example, be
220 ! arranged like this:
221 !
222 ! first data a(1)= . . . a(66)= a(70)
223 ! vector x(63) x(0) x(1) x(2) ... x(63) x(0) (4 empty locations)
224 !
225 ! second data a(71)= . . . a(140)
226 ! vector x(63) x(0) x(1) x(2) ... x(63) x(0) (4 empty locations)
227 !
228 ! and so on. here inc=1, jump=70, n=64, m=19, isign=-1,
229 ! and fft99 should be used (because of the explicit cyclic
230 ! continuity).
231 !
232 ! alternatively the data may be arranged like this:
233 !
234 ! first second last
235 ! data data data
236 ! vector vector vector
237 !
238 ! a(1)= a(2)= a(19)=
239 !
240 ! x(63) x(63) . . . x(63)
241 ! a(20)= x(0) x(0) . . . x(0)
242 ! a(39)= x(1) x(1) . . . x(1)
243 ! . . .
244 ! . . .
245 ! . . .
246 !
247 ! in which case we have inc=19, jump=1, and the remaining
248 ! parameters are the same as before. in either case, each
249 ! coefficient vector overwrites the corresponding input
250 ! data vector.
251 !
252 !-----------------------------------------------------------------------
253  integer, intent(in) :: inc,jump,n,lot,isign
254  integer, intent(inout) :: ifax(:)
255  real, intent(in) :: trigs(:)
256  real, intent(inout) :: a(*),work(*)
257 
258 ! dimension a(n),work(n),trigs(n),ifax(1)
259 !
260 ! subroutine "fft99" - multiple fast real periodic transform
261 ! corresponding to old scalar routine fft9
262 ! procedure used to convert to half-length complex transform
263 ! is given by cooley, lewis and welch (j. sound vib., vol. 12
264 ! (1970), 315-337)
265 !
266 ! a is the array containing input and output data
267 ! work is an area of size (n+1)*lot
268 ! trigs is a previously prepared list of trig function values
269 ! ifax is a previously prepared list of factors of n/2
270 ! inc is the increment within each data 'vector'
271 ! (e.g. inc=1 for consecutively stored data)
272 ! jump is the increment between the start of each data vector
273 ! n is the length of the data vectors
274 ! lot is the number of data vectors
275 ! isign = +1 for transform from spectral to gridpoint
276 ! = -1 for transform from gridpoint to spectral
277 !
278 ! ordering of coefficients:
279 ! a(0),b(0),a(1),b(1),a(2),b(2),...,a(n/2),b(n/2)
280 ! where b(0)=b(n/2)=0; (n+2) locations required
281 !
282 ! ordering of data:
283 ! x(n-1),x(0),x(1),x(2),...,x(n),x(0)
284 ! i.e. explicit cyclic continuity; (n+2) locations required
285 !
286 ! vectorization is achieved on cray by doing the transforms in
287 ! parallel
288 !
289 ! *** n.b. n is assumed to be an even number
290 !
291 ! definition of transforms:
292 ! -------------------------
293 !
294 ! isign=+1: x(j)=sum(k=0,...,n-1)(c(k)*exp(2*i*j*k*pi/n))
295 ! where c(k)=a(k)+i*b(k) and c(n-k)=a(k)-i*b(k)
296 !
297 ! isign=-1: a(k)=(1/n)*sum(j=0,...,n-1)(x(j)*cos(2*j*k*pi/n))
298 ! b(k)=-(1/n)*sum(j=0,...,n-1)(x(j)*sin(2*j*k*pi/n))
299 !
300 
301  integer :: nfax, nx, nh, ink, igo, ibase, jbase
302  integer :: i, j, k, l, m, ia, la, ib
303 
304  nfax=ifax(1)
305  nx=n+1
306  nh=n/2
307  ink=inc+inc
308  if (isign.eq.+1) go to 30
309 
310 ! if necessary, transfer data to work area
311  igo=50
312  if (mod(nfax,2).eq.1) goto 40
313  ibase=inc+1
314  jbase=1
315  do l=1,lot
316  i=ibase
317  j=jbase
318 !dir$ ivdep
319  do m=1,n
320  work(j)=a(i)
321  i=i+inc
322  j=j+1
323  enddo
324  ibase=ibase+jump
325  jbase=jbase+nx
326  enddo
327 
328  igo=60
329  go to 40
330 
331 ! preprocessing (isign=+1)
332 ! ------------------------
333 
334  30 continue
335  call fft99a(a,work,trigs,inc,jump,n,lot)
336  igo=60
337 
338 ! complex transform
339 ! -----------------
340 
341  40 continue
342  ia=inc+1
343  la=1
344  do 80 k=1,nfax
345  if (igo.eq.60) go to 60
346  50 continue
347  call vpassm (a(ia),a(ia+inc),work(1),work(2),trigs, &
348  ink,2,jump,nx,lot,nh,ifax(k+1),la)
349  igo=60
350  go to 70
351  60 continue
352  call vpassm (work(1),work(2),a(ia),a(ia+inc),trigs, &
353  2,ink,nx,jump,lot,nh,ifax(k+1),la)
354  igo=50
355  70 continue
356  la=la*ifax(k+1)
357  80 continue
358 
359  if (isign.eq.-1) go to 130
360 
361 ! if necessary, transfer data from work area
362 
363  if (mod(nfax,2).ne.1) then
364  ibase=1
365  jbase=ia
366  do l=1,lot
367  i=ibase
368  j=jbase
369 !dir$ ivdep
370  do m=1,n
371  a(j)=work(i)
372  i=i+1
373  j=j+inc
374  enddo
375  ibase=ibase+nx
376  jbase=jbase+jump
377  enddo
378  endif
379 
380 ! fill in cyclic boundary points
381  ia=1
382  ib=n*inc+1
383 !dir$ ivdep
384  do l=1,lot
385  a(ia)=a(ib)
386  a(ib+inc)=a(ia+inc)
387  ia=ia+jump
388  ib=ib+jump
389  enddo
390  go to 140
391 
392 ! postprocessing (isign=-1):
393 ! --------------------------
394 
395  130 continue
396  call fft99b(work,a,trigs,inc,jump,n,lot)
397 
398  140 continue
399 
400  end subroutine fft99
401 
402 !##########################################################################
403 
404  subroutine fft99a (a,work,trigs,inc,jump,n,lot)
405  integer, intent(in) :: inc,jump,n,lot
406  real, intent(in) :: trigs(:)
407  real, intent(inout) :: a(*),work(*)
408 
409 ! dimension a(n),work(n),trigs(n)
410 !
411 ! subroutine fft99a - preprocessing step for fft99, isign=+1
412 ! (spectral to gridpoint transform)
413 
414  integer :: nh, nx, ink, k, L
415  integer :: ia, ib, ja, jb, iabase, ibbase, jabase, jbbase
416  real :: c, s
417 
418  nh=n/2
419  nx=n+1
420  ink=inc+inc
421 
422 ! a(0) and a(n/2)
423  ia=1
424  ib=n*inc+1
425  ja=1
426  jb=2
427 !dir$ ivdep
428  do l=1,lot
429  work(ja)=a(ia)+a(ib)
430  work(jb)=a(ia)-a(ib)
431  ia=ia+jump
432  ib=ib+jump
433  ja=ja+nx
434  jb=jb+nx
435  enddo
436 
437 ! remaining wavenumbers
438  iabase=2*inc+1
439  ibbase=(n-2)*inc+1
440  jabase=3
441  jbbase=n-1
442 
443  do k=3,nh,2
444  ia=iabase
445  ib=ibbase
446  ja=jabase
447  jb=jbbase
448  c=trigs(n+k)
449  s=trigs(n+k+1)
450 !dir$ ivdep
451  do l=1,lot
452  work(ja)=(a(ia)+a(ib))- &
453  (s*(a(ia)-a(ib))+c*(a(ia+inc)+a(ib+inc)))
454  work(jb)=(a(ia)+a(ib))+ &
455  (s*(a(ia)-a(ib))+c*(a(ia+inc)+a(ib+inc)))
456  work(ja+1)=(c*(a(ia)-a(ib))-s*(a(ia+inc)+a(ib+inc)))+ &
457  (a(ia+inc)-a(ib+inc))
458  work(jb+1)=(c*(a(ia)-a(ib))-s*(a(ia+inc)+a(ib+inc)))- &
459  (a(ia+inc)-a(ib+inc))
460  ia=ia+jump
461  ib=ib+jump
462  ja=ja+nx
463  jb=jb+nx
464  enddo
465  iabase=iabase+ink
466  ibbase=ibbase-ink
467  jabase=jabase+2
468  jbbase=jbbase-2
469  enddo
470 
471 ! wavenumber n/4 (if it exists)
472  if (iabase.eq.ibbase) then
473  ia=iabase
474  ja=jabase
475 !dir$ ivdep
476  do l=1,lot
477  work(ja)=2.0*a(ia)
478  work(ja+1)=-2.0*a(ia+inc)
479  ia=ia+jump
480  ja=ja+nx
481  enddo
482  endif
483 
484  end subroutine fft99a
485 
486 !##########################################################################
487 
488  subroutine fft99b (work,a,trigs,inc,jump,n,lot)
489  integer, intent(in) :: inc,jump,n,lot
490  real, intent(in) :: trigs(:)
491  real, intent(inout) :: a(*),work(*)
492 
493 ! dimension work(n),a(n),trigs(n)
494 !
495 ! subroutine fft99b - postprocessing step for fft99, isign=-1
496 ! (gridpoint to spectral transform)
497 
498  integer :: nh, nx, ink, k, L
499  integer :: ia, ib, ja, jb, iabase, ibbase, jabase, jbbase
500  real :: scale, c, s
501 
502  nh=n/2
503  nx=n+1
504  ink=inc+inc
505 
506 ! a(0) and a(n/2)
507  scale=1.0/real(n)
508  ia=1
509  ib=2
510  ja=1
511  jb=n*inc+1
512 !dir$ ivdep
513  do l=1,lot
514  a(ja)=scale*(work(ia)+work(ib))
515  a(jb)=scale*(work(ia)-work(ib))
516  a(ja+inc)=0.0
517  a(jb+inc)=0.0
518  ia=ia+nx
519  ib=ib+nx
520  ja=ja+jump
521  jb=jb+jump
522  enddo
523 
524 ! remaining wavenumbers
525  scale=0.5*scale
526  iabase=3
527  ibbase=n-1
528  jabase=2*inc+1
529  jbbase=(n-2)*inc+1
530 
531  do k=3,nh,2
532  ia=iabase
533  ib=ibbase
534  ja=jabase
535  jb=jbbase
536  c=trigs(n+k)
537  s=trigs(n+k+1)
538 !dir$ ivdep
539  do l=1,lot
540  a(ja)=scale*((work(ia)+work(ib)) &
541  +(c*(work(ia+1)+work(ib+1))+s*(work(ia)-work(ib))))
542  a(jb)=scale*((work(ia)+work(ib)) &
543  -(c*(work(ia+1)+work(ib+1))+s*(work(ia)-work(ib))))
544  a(ja+inc)=scale*((c*(work(ia)-work(ib))-s*(work(ia+1)+work(ib+1))) &
545  +(work(ib+1)-work(ia+1)))
546  a(jb+inc)=scale*((c*(work(ia)-work(ib))-s*(work(ia+1)+work(ib+1))) &
547  -(work(ib+1)-work(ia+1)))
548  ia=ia+nx
549  ib=ib+nx
550  ja=ja+jump
551  jb=jb+jump
552  enddo
553  iabase=iabase+2
554  ibbase=ibbase-2
555  jabase=jabase+ink
556  jbbase=jbbase-ink
557  enddo
558 
559 ! wavenumber n/4 (if it exists)
560  if (iabase.eq.ibbase) then
561  ia=iabase
562  ja=jabase
563  scale=2.0*scale
564 !dir$ ivdep
565  do l=1,lot
566  a(ja)=scale*work(ia)
567  a(ja+inc)=-scale*work(ia+1)
568  ia=ia+nx
569  ja=ja+jump
570  enddo
571  endif
572 
573  end subroutine fft99b
574 
575 !##########################################################################
576 
577  subroutine fft991(a,work,trigs,ifax,inc,jump,n,lot,isign)
578  integer, intent(in) :: inc,jump,n,lot,isign
579  integer, intent(inout) :: ifax(:)
580  real, intent(in) :: trigs(:)
581  real, intent(inout) :: a(*),work((n+1)*lot)
582 
583 ! dimension a(n),work(n),trigs(n),ifax(1)
584 !
585 ! subroutine "fft991" - multiple real/half-complex periodic
586 ! fast fourier transform
587 !
588 ! same as fft99 except that ordering of data corresponds to
589 ! that in mrfft2
590 !
591 ! procedure used to convert to half-length complex transform
592 ! is given by cooley, lewis and welch (j. sound vib., vol. 12
593 ! (1970), 315-337)
594 !
595 ! a is the array containing input and output data
596 ! work is an area of size (n+1)*lot
597 ! trigs is a previously prepared list of trig function values
598 ! ifax is a previously prepared list of factors of n/2
599 ! inc is the increment within each data 'vector'
600 ! (e.g. inc=1 for consecutively stored data)
601 ! jump is the increment between the start of each data vector
602 ! n is the length of the data vectors
603 ! lot is the number of data vectors
604 ! isign = +1 for transform from spectral to gridpoint
605 ! = -1 for transform from gridpoint to spectral
606 !
607 ! ordering of coefficients:
608 ! a(0),b(0),a(1),b(1),a(2),b(2),...,a(n/2),b(n/2)
609 ! where b(0)=b(n/2)=0; (n+2) locations required
610 !
611 ! ordering of data:
612 ! x(0),x(1),x(2),...,x(n-1)
613 !
614 ! vectorization is achieved on cray by doing the transforms in
615 ! parallel
616 !
617 ! *** n.b. n is assumed to be an even number
618 !
619 ! definition of transforms:
620 ! -------------------------
621 !
622 ! isign=+1: x(j)=sum(k=0,...,n-1)(c(k)*exp(2*i*j*k*pi/n))
623 ! where c(k)=a(k)+i*b(k) and c(n-k)=a(k)-i*b(k)
624 !
625 ! isign=-1: a(k)=(1/n)*sum(j=0,...,n-1)(x(j)*cos(2*j*k*pi/n))
626 ! b(k)=-(1/n)*sum(j=0,...,n-1)(x(j)*sin(2*j*k*pi/n))
627 !
628 
629  integer :: nfax, nx, nh, ink, igo, ibase, jbase
630  integer :: i, j, k, l, m, ia, la, ib
631 
632 
633  nfax=ifax(1)
634  nx=n+1
635  nh=n/2
636  ink=inc+inc
637  if (isign.eq.+1) go to 30
638 
639 ! if necessary, transfer data to work area
640  igo=50
641  if (mod(nfax,2).eq.1) goto 40
642  ibase=1
643  jbase=1
644  do l=1,lot
645  i=ibase
646  j=jbase
647 !dir$ ivdep
648  do m=1,n
649  work(j)=a(i)
650  i=i+inc
651  j=j+1
652  enddo
653  ibase=ibase+jump
654  jbase=jbase+nx
655  enddo
656 !
657  igo=60
658  go to 40
659 !
660 ! preprocessing (isign=+1)
661 ! ------------------------
662 !
663  30 continue
664  call fft99a(a,work,trigs,inc,jump,n,lot)
665  igo=60
666 !
667 ! complex transform
668 ! -----------------
669 !
670  40 continue
671  ia=1
672  la=1
673  do k=1,nfax
674  if (igo.eq.60) go to 60
675  50 continue
676  call vpassm (a(ia),a(ia+inc),work(1),work(2),trigs, &
677  ink,2,jump,nx,lot,nh,ifax(k+1),la)
678  igo=60
679  go to 70
680  60 continue
681  call vpassm (work(1),work(2),a(ia),a(ia+inc),trigs, &
682  2,ink,nx,jump,lot,nh,ifax(k+1),la)
683  igo=50
684  70 continue
685  la=la*ifax(k+1)
686  enddo
687 
688  if (isign.eq.-1) go to 130
689 
690 ! if necessary, transfer data from work area
691  if (mod(nfax,2).ne.1) then
692  ibase=1
693  jbase=1
694  do l=1,lot
695  i=ibase
696  j=jbase
697 !dir$ ivdep
698  do m=1,n
699  a(j)=work(i)
700  i=i+1
701  j=j+inc
702  enddo
703  ibase=ibase+nx
704  jbase=jbase+jump
705  enddo
706  endif
707 
708 ! fill in zeros at end
709  ib=n*inc+1
710 !dir$ ivdep
711  do l=1,lot
712  a(ib)=0.0
713  a(ib+inc)=0.0
714  ib=ib+jump
715  enddo
716  go to 140
717 
718 ! postprocessing (isign=-1):
719 ! --------------------------
720 
721  130 continue
722  call fft99b (work,a,trigs,inc,jump,n,lot)
723 
724  140 continue
725 
726  end subroutine fft991
727 
728 !##########################################################################
729 
730  subroutine set99 (trigs, ifax, n)
731  integer, intent(in) :: n
732  integer, intent(out) :: ifax(:)
733  real, intent(out) :: trigs(:)
734 
735 ! dimension ifax(13),trigs(1)
736 !
737 ! mode 3 is used for real/half-complex transforms. it is possible
738 ! to do complex/complex transforms with other values of mode, but
739 ! documentation of the details were not available when this routine
740 ! was written.
741 !
742  integer :: mode = 3
743  integer :: i
744 
745  call fax (ifax, n, mode)
746  i = ifax(1)
747  if (ifax(i+1) .gt. 5 .or. n .le. 4) ifax(1) = -99
748  if (ifax(1) .le. 0 ) then
749  call mpp_error(fatal,'fft99_mod: in routine set99 -- invalid n')
750  endif
751  call fftrig (trigs, n, mode)
752 
753  end subroutine set99
754 
755 !##########################################################################
756 
757  subroutine fax (ifax,n,mode)
758  integer, intent(out) :: ifax(:)
759  integer, intent(in) :: n, mode
760 
761  integer :: nn, k, L, inc, nfax, ii, istop, i, item
762 
763  nn=n
764  if (iabs(mode).eq.1) go to 10
765  if (iabs(mode).eq.8) go to 10
766  nn=n/2
767  if ((nn+nn).eq.n) go to 10
768  ifax(1)=-99
769  return
770  10 k=1
771 ! test for factors of 4
772  20 if (mod(nn,4).ne.0) go to 30
773  k=k+1
774  ifax(k)=4
775  nn=nn/4
776  if (nn.eq.1) go to 80
777  go to 20
778 ! test for extra factor of 2
779  30 if (mod(nn,2).ne.0) go to 40
780  k=k+1
781  ifax(k)=2
782  nn=nn/2
783  if (nn.eq.1) go to 80
784 ! test for factors of 3
785  40 if (mod(nn,3).ne.0) go to 50
786  k=k+1
787  ifax(k)=3
788  nn=nn/3
789  if (nn.eq.1) go to 80
790  go to 40
791 ! now find remaining factors
792  50 l=5
793  inc=2
794 ! inc alternately takes on values 2 and 4
795  60 if (mod(nn,l).ne.0) go to 70
796  k=k+1
797  ifax(k)=l
798  nn=nn/l
799  if (nn.eq.1) go to 80
800  go to 60
801  70 l=l+inc
802  inc=6-inc
803  go to 60
804  80 ifax(1)=k-1
805 ! ifax(1) contains number of factors
806  nfax=ifax(1)
807 ! sort factors into ascending order
808  if (nfax.eq.1) go to 110
809  do 100 ii=2,nfax
810  istop=nfax+2-ii
811  do 90 i=2,istop
812  if (ifax(i+1).ge.ifax(i)) go to 90
813  item=ifax(i)
814  ifax(i)=ifax(i+1)
815  ifax(i+1)=item
816  90 continue
817  100 continue
818  110 continue
819 
820  end subroutine fax
821 
822 !##########################################################################
823 
824  subroutine fftrig (trigs,n,mode)
825  real, intent(out) :: trigs(:)
826  integer, intent(in) :: n, mode
827 
828  real :: del, angle
829  integer :: imode, nn, nh, i, L, la
830 
831  imode=iabs(mode)
832  nn=n
833  if (imode.gt.1.and.imode.lt.6) nn=n/2
834  del=(pi+pi)/real(nn)
835  l=nn+nn
836  do i=1,l,2
837  angle=0.5*real(i-1)*del
838  trigs(i)=cos(angle)
839  trigs(i+1)=sin(angle)
840  enddo
841  if (imode.eq.1) return
842  if (imode.eq.8) return
843 
844  del=0.5*del
845  nh=(nn+1)/2
846  l=nh+nh
847  la=nn+nn
848  do i=1,l,2
849  angle=0.5*real(i-1)*del
850  trigs(la+i)=cos(angle)
851  trigs(la+i+1)=sin(angle)
852  enddo
853  if (imode.le.3) return
854 
855  del=0.5*del
856  la=la+nn
857  if (mode.ne.5) then
858  do i=2,nn
859  angle=real(i-1)*del
860  trigs(la+i)=2.0*sin(angle)
861  enddo
862  return
863  endif
864 
865  del=0.5*del
866  do i=2,n
867  angle=real(i-1)*del
868  trigs(la+i)=sin(angle)
869  enddo
870 
871  end subroutine fftrig
872 
873 !##########################################################################
874 
875  subroutine vpassm (a,b,c,d,trigs,inc1,inc2,inc3,inc4,lot,n,ifac,la)
876  integer, intent(in) :: inc1, inc2, inc3, inc4, lot, n, ifac, la
877  real, intent(in) :: a(*),b(*),trigs(*)
878  real, intent(out) :: c(*),d(*)
879 !
880 ! subroutine "vpassm" - multiple version of "vpassa"
881 ! performs one pass through data
882 ! as part of multiple complex fft routine
883 ! a is first real input vector
884 ! b is first imaginary input vector
885 ! c is first real output vector
886 ! d is first imaginary output vector
887 ! trigs is precalculated table of sines " cosines
888 ! inc1 is addressing increment for a and b
889 ! inc2 is addressing increment for c and d
890 ! inc3 is addressing increment between a"s & b"s
891 ! inc4 is addressing increment between c"s & d"s
892 ! lot is the number of vectors
893 ! n is length of vectors
894 ! ifac is current factor of n
895 ! la is product of previous factors
896 !
897 
898  real :: sin36=0.587785252292473
899  real :: cos36=0.809016994374947
900  real :: sin72=0.951056516295154
901  real :: cos72=0.309016994374947
902  real :: sin60=0.866025403784437
903 
904  integer :: i, j, k, L, m, iink, jink, jump, ibase, jbase, igo, ijk, la1
905  integer :: ia, ja, ib, jb, kb, ic, jc, kc, id, jd, kd, ie, je, ke
906  real :: c1, s1, c2, s2, c3, s3, c4, s4
907 
908  m=n/ifac
909  iink=m*inc1
910  jink=la*inc2
911  jump=(ifac-1)*jink
912  ibase=0
913  jbase=0
914  igo=ifac-1
915  if (igo.gt.4) return
916 !del go to (10,50,90,130),igo
917 
918  select case (igo)
919 
920 ! coding for factor 2
921 
922  case (1)
923  10 ia=1
924  ja=1
925  ib=ia+iink
926  jb=ja+jink
927  do 20 l=1,la
928  i=ibase
929  j=jbase
930 !dir$ ivdep
931  do 15 ijk=1,lot
932  c(ja+j)=a(ia+i)+a(ib+i)
933  d(ja+j)=b(ia+i)+b(ib+i)
934  c(jb+j)=a(ia+i)-a(ib+i)
935  d(jb+j)=b(ia+i)-b(ib+i)
936  i=i+inc3
937  j=j+inc4
938  15 continue
939  ibase=ibase+inc1
940  jbase=jbase+inc2
941  20 continue
942  if (la.eq.m) return
943  la1=la+1
944  jbase=jbase+jump
945  do 40 k=la1,m,la
946  kb=k+k-2
947  c1=trigs(kb+1)
948  s1=trigs(kb+2)
949  do 30 l=1,la
950  i=ibase
951  j=jbase
952 !dir$ ivdep
953  do 25 ijk=1,lot
954  c(ja+j)=a(ia+i)+a(ib+i)
955  d(ja+j)=b(ia+i)+b(ib+i)
956  c(jb+j)=c1*(a(ia+i)-a(ib+i))-s1*(b(ia+i)-b(ib+i))
957  d(jb+j)=s1*(a(ia+i)-a(ib+i))+c1*(b(ia+i)-b(ib+i))
958  i=i+inc3
959  j=j+inc4
960  25 continue
961  ibase=ibase+inc1
962  jbase=jbase+inc2
963  30 continue
964  jbase=jbase+jump
965  40 continue
966 ! return
967 
968 ! coding for factor 3
969 
970  case (2)
971  50 ia=1
972  ja=1
973  ib=ia+iink
974  jb=ja+jink
975  ic=ib+iink
976  jc=jb+jink
977  do 60 l=1,la
978  i=ibase
979  j=jbase
980 !dir$ ivdep
981  do 55 ijk=1,lot
982  c(ja+j)=a(ia+i)+(a(ib+i)+a(ic+i))
983  d(ja+j)=b(ia+i)+(b(ib+i)+b(ic+i))
984  c(jb+j)=(a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))
985  c(jc+j)=(a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))
986  d(jb+j)=(b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i)))
987  d(jc+j)=(b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i)))
988  i=i+inc3
989  j=j+inc4
990  55 continue
991  ibase=ibase+inc1
992  jbase=jbase+inc2
993  60 continue
994  if (la.eq.m) return
995  la1=la+1
996  jbase=jbase+jump
997  do 80 k=la1,m,la
998  kb=k+k-2
999  kc=kb+kb
1000  c1=trigs(kb+1)
1001  s1=trigs(kb+2)
1002  c2=trigs(kc+1)
1003  s2=trigs(kc+2)
1004  do 70 l=1,la
1005  i=ibase
1006  j=jbase
1007 !dir$ ivdep
1008  do 65 ijk=1,lot
1009  c(ja+j)=a(ia+i)+(a(ib+i)+a(ic+i))
1010  d(ja+j)=b(ia+i)+(b(ib+i)+b(ic+i))
1011  c(jb+j)= &
1012  c1*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))) &
1013  -s1*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i))))
1014  d(jb+j)= &
1015  s1*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))-(sin60*(b(ib+i)-b(ic+i)))) &
1016  +c1*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))+(sin60*(a(ib+i)-a(ic+i))))
1017  c(jc+j)= &
1018  c2*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))) &
1019  -s2*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i))))
1020  d(jc+j)= &
1021  s2*((a(ia+i)-0.5*(a(ib+i)+a(ic+i)))+(sin60*(b(ib+i)-b(ic+i)))) &
1022  +c2*((b(ia+i)-0.5*(b(ib+i)+b(ic+i)))-(sin60*(a(ib+i)-a(ic+i))))
1023  i=i+inc3
1024  j=j+inc4
1025  65 continue
1026  ibase=ibase+inc1
1027  jbase=jbase+inc2
1028  70 continue
1029  jbase=jbase+jump
1030  80 continue
1031 ! return
1032 
1033 ! coding for factor 4
1034 
1035  case (3)
1036  90 ia=1
1037  ja=1
1038  ib=ia+iink
1039  jb=ja+jink
1040  ic=ib+iink
1041  jc=jb+jink
1042  id=ic+iink
1043  jd=jc+jink
1044  do 100 l=1,la
1045  i=ibase
1046  j=jbase
1047 !dir$ ivdep
1048  do 95 ijk=1,lot
1049  c(ja+j)=(a(ia+i)+a(ic+i))+(a(ib+i)+a(id+i))
1050  c(jc+j)=(a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i))
1051  d(ja+j)=(b(ia+i)+b(ic+i))+(b(ib+i)+b(id+i))
1052  d(jc+j)=(b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i))
1053  c(jb+j)=(a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i))
1054  c(jd+j)=(a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i))
1055  d(jb+j)=(b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i))
1056  d(jd+j)=(b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i))
1057  i=i+inc3
1058  j=j+inc4
1059  95 continue
1060  ibase=ibase+inc1
1061  jbase=jbase+inc2
1062  100 continue
1063  if (la.eq.m) return
1064  la1=la+1
1065  jbase=jbase+jump
1066  do 120 k=la1,m,la
1067  kb=k+k-2
1068  kc=kb+kb
1069  kd=kc+kb
1070  c1=trigs(kb+1)
1071  s1=trigs(kb+2)
1072  c2=trigs(kc+1)
1073  s2=trigs(kc+2)
1074  c3=trigs(kd+1)
1075  s3=trigs(kd+2)
1076  do 110 l=1,la
1077  i=ibase
1078  j=jbase
1079 !dir$ ivdep
1080  do 105 ijk=1,lot
1081  c(ja+j)=(a(ia+i)+a(ic+i))+(a(ib+i)+a(id+i))
1082  d(ja+j)=(b(ia+i)+b(ic+i))+(b(ib+i)+b(id+i))
1083  c(jc+j)= &
1084  c2*((a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i))) &
1085  -s2*((b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i)))
1086  d(jc+j)= &
1087  s2*((a(ia+i)+a(ic+i))-(a(ib+i)+a(id+i))) &
1088  +c2*((b(ia+i)+b(ic+i))-(b(ib+i)+b(id+i)))
1089  c(jb+j)= &
1090  c1*((a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i))) &
1091  -s1*((b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i)))
1092  d(jb+j)= &
1093  s1*((a(ia+i)-a(ic+i))-(b(ib+i)-b(id+i))) &
1094  +c1*((b(ia+i)-b(ic+i))+(a(ib+i)-a(id+i)))
1095  c(jd+j)= &
1096  c3*((a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i))) &
1097  -s3*((b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i)))
1098  d(jd+j)= &
1099  s3*((a(ia+i)-a(ic+i))+(b(ib+i)-b(id+i))) &
1100  +c3*((b(ia+i)-b(ic+i))-(a(ib+i)-a(id+i)))
1101  i=i+inc3
1102  j=j+inc4
1103  105 continue
1104  ibase=ibase+inc1
1105  jbase=jbase+inc2
1106  110 continue
1107  jbase=jbase+jump
1108  120 continue
1109 ! return
1110 
1111 ! coding for factor 5
1112 
1113  case (4)
1114  130 ia=1
1115  ja=1
1116  ib=ia+iink
1117  jb=ja+jink
1118  ic=ib+iink
1119  jc=jb+jink
1120  id=ic+iink
1121  jd=jc+jink
1122  ie=id+iink
1123  je=jd+jink
1124  do 140 l=1,la
1125  i=ibase
1126  j=jbase
1127 !dir$ ivdep
1128  do 135 ijk=1,lot
1129  c(ja+j)=a(ia+i)+(a(ib+i)+a(ie+i))+(a(ic+i)+a(id+i))
1130  d(ja+j)=b(ia+i)+(b(ib+i)+b(ie+i))+(b(ic+i)+b(id+i))
1131  c(jb+j)=(a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1132  -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))
1133  c(je+j)=(a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1134  +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))
1135  d(jb+j)=(b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1136  +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i)))
1137  d(je+j)=(b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1138  -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i)))
1139  c(jc+j)=(a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1140  -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))
1141  c(jd+j)=(a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1142  +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))
1143  d(jc+j)=(b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1144  +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i)))
1145  d(jd+j)=(b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1146  -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i)))
1147  i=i+inc3
1148  j=j+inc4
1149  135 continue
1150  ibase=ibase+inc1
1151  jbase=jbase+inc2
1152  140 continue
1153  if (la.eq.m) return
1154  la1=la+1
1155  jbase=jbase+jump
1156  do 160 k=la1,m,la
1157  kb=k+k-2
1158  kc=kb+kb
1159  kd=kc+kb
1160  ke=kd+kb
1161  c1=trigs(kb+1)
1162  s1=trigs(kb+2)
1163  c2=trigs(kc+1)
1164  s2=trigs(kc+2)
1165  c3=trigs(kd+1)
1166  s3=trigs(kd+2)
1167  c4=trigs(ke+1)
1168  s4=trigs(ke+2)
1169  do 150 l=1,la
1170  i=ibase
1171  j=jbase
1172 !dir$ ivdep
1173  do 145 ijk=1,lot
1174  c(ja+j)=a(ia+i)+(a(ib+i)+a(ie+i))+(a(ic+i)+a(id+i))
1175  d(ja+j)=b(ia+i)+(b(ib+i)+b(ie+i))+(b(ic+i)+b(id+i))
1176  c(jb+j)= &
1177  c1*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1178  -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))) &
1179  -s1*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1180  +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
1181  d(jb+j)= &
1182  s1*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1183  -(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))) &
1184  +c1*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1185  +(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
1186  c(je+j)= &
1187  c4*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1188  +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))) &
1189  -s4*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1190  -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
1191  d(je+j)= &
1192  s4*((a(ia+i)+cos72*(a(ib+i)+a(ie+i))-cos36*(a(ic+i)+a(id+i))) &
1193  +(sin72*(b(ib+i)-b(ie+i))+sin36*(b(ic+i)-b(id+i)))) &
1194  +c4*((b(ia+i)+cos72*(b(ib+i)+b(ie+i))-cos36*(b(ic+i)+b(id+i))) &
1195  -(sin72*(a(ib+i)-a(ie+i))+sin36*(a(ic+i)-a(id+i))))
1196  c(jc+j)= &
1197  c2*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1198  -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))) &
1199  -s2*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1200  +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
1201  d(jc+j)= &
1202  s2*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1203  -(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))) &
1204  +c2*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1205  +(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
1206  c(jd+j)= &
1207  c3*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1208  +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))) &
1209  -s3*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1210  -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
1211  d(jd+j)= &
1212  s3*((a(ia+i)-cos36*(a(ib+i)+a(ie+i))+cos72*(a(ic+i)+a(id+i))) &
1213  +(sin36*(b(ib+i)-b(ie+i))-sin72*(b(ic+i)-b(id+i)))) &
1214  +c3*((b(ia+i)-cos36*(b(ib+i)+b(ie+i))+cos72*(b(ic+i)+b(id+i))) &
1215  -(sin36*(a(ib+i)-a(ie+i))-sin72*(a(ic+i)-a(id+i))))
1216  i=i+inc3
1217  j=j+inc4
1218  145 continue
1219  ibase=ibase+inc1
1220  jbase=jbase+inc2
1221  150 continue
1222  jbase=jbase+jump
1223  160 continue
1224 
1225  end select
1226 
1227  end subroutine vpassm
1228 
1229 !##########################################################################
1230 
1231 end module fft99_mod
1232 
subroutine, public fft991(a, work, trigs, ifax, inc, jump, n, lot, isign)
Definition: fft99.F90:578
subroutine fax(ifax, n, mode)
Definition: fft99.F90:758
Definition: mpp.F90:39
subroutine, public set99(trigs, ifax, n)
Definition: fft99.F90:731
subroutine, public fft99(a, work, trigs, ifax, inc, jump, n, lot, isign)
Definition: fft99.F90:36
subroutine fft99a(a, work, trigs, inc, jump, n, lot)
Definition: fft99.F90:405
subroutine vpassm(a, b, c, d, trigs, inc1, inc2, inc3, inc4, lot, n, ifac, la)
Definition: fft99.F90:876
subroutine fftrig(trigs, n, mode)
Definition: fft99.F90:825
subroutine fft99b(work, a, trigs, inc, jump, n, lot)
Definition: fft99.F90:489
real(fp), parameter, public pi