There are three "top-level" routines (expecting COMPLEX*16/REAL*8 input): FFT3DC(ARRAY,MESH_SIZE,ISIGN) FFT3DH(ARRAY,MESH_SIZE,ISIGN) FFT3DR(ARRAY,MESH_SIZE,ISIGN) As one can see the calling conventions are coherently identical. In all cases MESH_SIZE has to be defined as an integer array, ISIGN as an integer variable. INTEGER MESH_SIZE(3),ISIGN The array MESH_SIZE must contain the number of mesh points in each direction (i.e. MESH_SIZE(1)=number of mesh points in "x"-direction, MESH_SIZE(2)=number of mesh points in "y"-direction, and MESH_SIZE(3)=number of mesh points in "z"-direction). These number are restricted to an upper limit which defaults to 8192. The limit can only be redefined by recompiling the code (see also README). Furthermore, the FFT routines will not accept any numbers smaller than two. The number of mesh points in each direction must be a product of powers of 2, 3, 5, or 7. Any other prime factors appearing in the facorized number will cause error messages upon initialization. Initialization is done automatically. ISIGN determines the sign of the exponential phase factors, i.e. ISIGN=1 (or greater of equal zero) correponds to a FFT v(q)=sum_r v(r) exp(+iqr) , ISIGN=-1 (or lower than zero) correspond to v(q)=sum_r v(r) exp(-iqr) . The array A has to contain the data to be transformed. The three routines perform following tasks: FFT3DC: complex <-> complex transform FFT3DH: hermite complex -> real transform for ISIGN=+1 real -> hermite complex transform for ISIGN=-1 FFT3DR: real -> hermite complex transform for ISIGN=+1 hermite complex -> real transform for ISIGN=-1 In the complex <-> complex case A has to be defined as an array COMPLEX*16 A(MESH_SIZE(1),MESH_SIZE(2),MESH_SIZE(3)) In the real <-> hermite complex case A has to be defined either as COMPLEX*16 A(MESH_SIZE(1)/2+1,MESH_SIZE(2),MESH_SIZE(3)) on the complex side or as REAL*8 A(MESH_SIZE(1))+2,MESH_SIZE(2),MESH_SIZE(3)) on the real side. Note: MESH_SIZE(1) must be an even number! Any dimension specification will not work with these routines (however, there are "low-level" routines available offering the choice to define the mesh sizes and the array dimensions independent of each other - anyway, it is usually not necessary). On output A will contain the transformed data set (input is detroyed!). The output will not be normalised in any way (as usual for most FFT libraries). On the real side the indexes I,J,K of array elements A(I,J,K) will cover the ranges 1<=I<=MESH_SIZE(1), 1<=J<=MESH_SIZE(2), and 1<=K<=MESH_SIZE(3). The "excess" array elements with indexes I=MESH_SIZE(1)+1 and I=MESH_SIZE(1)+2 will not be used. They are only needed in order to match the corresponding COMPLEX array size on the hermite complex side. On the hermite complex side which only requires the storage of the symmetry-irreducible part of the transformed data the indexes I,J,K of array elements A(I,J,K) will cover the ranges 1<=I<=MESH_SIZE(1)/2+1, 1<=J<=MESH_SIZE(2), and 1<=K<=MESH_SIZE(3). The hermite symmetry reduction is done with respect to the first dimension which corresponds to the conventions used in many other FFT libraries. The ordinary complex storage mode is used, i.e. when mapping back the complex output to a REAL array real and imaginary parts are stored alternatingly. No "top-level" routines for 2D or 1D FFTs are available. However, the package contains various "low-level" routines will allow to build up FFTs for any dimension (also 4D or 7D if you would like ... ;-). Have a look at fft.F. Following a very short description of the most important ones (which are by the way written to match some Cray routines very closely ...): The two most important routines in the package are CFFTML and RHFFTM which allow 1D transforms on multiple data sets. It is possible to build up FFTs in higher dimensions by sequentially calling these routines D times passing each time over one dimension where all indexes on the remaining D-1 dimensions span the multiple data sets to be fed into the routines. CFFTML has to be used for complex<->complex transforms, real<->complex hermite transforms require one call to RHFFTM (for the dimension which is used to perform the hermite symmetry reduction). In order to initialize the transforms in each direction one has to use the corresponding initialization routines CFTTAB and RFTTAB. The most complicate task is to call each pass with the correct increments between the first elements of each data set and the individual elements within each data set. Puzzling together the correct increments according to the data layout of multi-dimensional Fortran (or C) arrays is no really trivial task! On vector machines even more complicated tricks like intermediate "swapping of array dimensions" on work arrays (in order to achieve loops always running over the physically "first dimension") may be required to obtain maximum speed. Such tricky things require to use the "lowest-level" routines available: FPASSM, IPASSM, and SPASSM (performing the elementary transform step for each single factor obtained from the factorization of the transform length) and HCOMB/RCOMB if one likes to build up real <-> hermite complex transforms. However, be warned that puzzling together all the increments on the input and output arrays can become even more complicated than for CFFTML and RHFFTM. Some examples which show (for the special case of 3D transforms) how these routines could be used are the intermediate-level routines FFTC3N/FFTCRN which build up transform using CFFTML/RHFFTM (along with efficient use of data caches) or FFTC3V/FFTR3V using FPASSM/IPASSM/SPASSM and RCOMB/HCOMB. If you ever understand what is going on in these routines you will be able to build up other top-level routines for other purposes (e.g. 2D or 4D FFTs, different storage modes separating real and imaginary parts into two real arrays or FFTs which allow array dimensions deviating from the transform lengths, different hermite complex symmetry reduction directions, ...). If you do not understand what is going on forget even to think about such things! Juergen Furthmueller