CCFFTM(3S)CCFFTM(3S)NAME
CCFFTM, ZZFFTM - Applies multiple complex-to-complex Fast Fourier
Transforms (FFTs)
SYNOPSIS
Single precision complex -> Single precision complex
Fortran:
CALL CCFFTM (isign, n, lot, scale, x, ldx, y, ldy, table, work,
isys)
C/C++:
#include <scsl_fft.h>
int ccfftm (int isign, int n, int lot, float scale,
scsl_complex *x, int ldx, scsl_complex *y, int ldy, float
*table, float *work, int *isys);
C++ STL:
#include <complex.h>
#include <scsl_fft.h>
int ccfftm (int *isign, int *n, int *lot, float *scale,
complex<float> *x, int *ldx, complex<float> *y, int *ldy, float
*table, float *work, int *isys);
Double precision complex -> Double precision complex
Fortran:
CALL ZZFFTM (isign, n, lot, scale, x, ldx, y, ldy, table, work,
isys)
C/C++:
#include <scsl_fft.h>
int zzfftm (int isign, int n, int lot, double scale,
scsl_zomplex *x, int ldx, scsl_zomplex *y, int ldy, double
*table, double *work, int *isys);
C++ STL:
#include <complex.h>
#include <scsl_fft.h>
int zzfftm (int *isign, int *n, int *lot, double *scale,
complex<double> *x, int *ldx, complex<double> *y, int *ldy,
double *table, double *work, int *isys) int *isys);
IMPLEMENTATION
These routines are part of the SCSL Scientific Library and can be loaded
using either the -lscs or the -lscs_mp option. The -lscs_mp option
directs the linker to use the multi-processor version of the library.
When linking to SCSL with -lscs or -lscs_mp, the default integer size is
4 bytes (32 bits). Another version of SCSL is available in which integers
are 8 bytes (64 bits). This version allows the user access to larger
memory sizes and helps when porting legacy Cray codes. It can be loaded
Page 1
CCFFTM(3S)CCFFTM(3S)
by using the -lscs_i8 option or the -lscs_i8_mp option. A program may use
only one of the two versions; 4-byte integer and 8-byte integer library
calls cannot be mixed.
The C and C++ prototypes shown above are appropriate for the 4-byte
integer version of SCSL. When using the 8-byte integer version, the
variables of type int become long long and the <scsl_fft_i8.h> header
file should be #included.
DESCRIPTION
CCFFTM/ZZFFTM computes the FFT of each column of the complex matrix X,
and stores the results in the columns of complex matrix Y.
Suppose the arrays are declared as follows:
Fortran:
COMPLEX X(0:ldx-1, 0:lot-1)
COMPLEX Y(0:ldy-1, 0:lot-1)
C/C++:
scsl_complex x[lot][ldx], y[lot][ldy];
C++ STL:
complex<float> x[lot][ldx], y[lot][ldy];
where ldx >= n, ldy >= n.
Then column L of the output array is the FFT of column L of the input
array, using the following formula for the FFT:
n-1 isign * j * k
Y, = scale * Sum [X * w ]
k,L j=0 j
for k = 0, ..., n-1
L = 0, ..., lot-1
where:
w = exp(2*pi*i/n),
i = + sqrt(-1),
Page 2
CCFFTM(3S)CCFFTM(3S)
pi = 3.14159...,
isign = +1 or -1
lot = the number of columns to transform
Different authors use different conventions for which of the transforms,
isign = +1 or isign = -1, is the forward or inverse transform, and what
the scale factor should be in either case. You can make this routine
compute any of the various possible definitions, however, by choosing the
appropriate values for isign and scale.
The relevant fact from FFT theory is this: If you take the FFT with any
particular values of isign and scale, the mathematical inverse function
is computed by taking the FFT with -isign and 1/(n * scale). In
particular, if you use isign = +1 and scale = 1.0 for the forward FFT,
you can compute the inverse FFT by using the following: isign = -1 and
scale = 1.0/n.
See the NOTES section of this man page for information about the
interpretation of the data types described in the following arguments.
This routine has the following arguments:
isign Integer. (input)
Specifies whether to initialize the table array or to do the
forward or inverse Fourier transform, as follows:
If isign = 0, the routine initializes table and returns. In
this case, the only arguments used or checked are isign, n, and
table.
If isign = +1 or -1, the value of isign is the sign of the
exponent used in the FFT formula.
n Integer. (input)
Size of each transform (the number of elements in each column
of the input and output matrix to be transformed). n >= 0; if n
= 0, the routine returns.
lot Integer. (input)
The number of transforms to be computed (lot size). This is
the number of elements in each row of the input and output
matrix. lot >= 0. If lot = 0, the routine returns.
scale Scale factor. (input)
CCFFTM: Single precision.
ZZFFTM: Double precision.
Each element of the output array is multiplied by the scale
factor after taking the Fourier transform, as defined
previously.
Page 3
CCFFTM(3S)CCFFTM(3S)
x Array of dimension (ldx, lot). (input)
CCFFTM: Single precision complex array.
ZZFFTM: Double precision complex array.
Input array of values to be transformed.
ldx Integer. (input)
The number of rows in x, as it was declared in the calling
program (the leading dimension of X). ldx >= MAX(n, 1).
y Array of dimensions (ldy, lot). (output)
CCFFTM: Single precision complex array.
ZZFFTM: Double precision complex array.
Output array of transformed values. Each column of the output
array, y, is the FFT of the corresponding column of the input
array, x, computed according to the preceding formula.
The output array may be the same as the input array. In that
case, the transform is done in place. The input array is
overwritten with the transformed values. In this case, it is
necessary that ldx = ldy.
ldy Integer. (input)
The number of rows in the Y array, as it was declared in the
calling program (the leading dimension of Y). ldy >= MAX(n,
1).
table Array of dimension (2 * n + NF) (input or output)
CCFFTM: Single precision array.
ZZFFTM: Double precision array.
Table of factors and root of unity. See the description of the
isys argument for the value of NF.
If isign = 0, the routine initializes table (table is output
only).
If isign = +1 or -1, the values in table are assumed to be
initialized already by a prior call with isign = 0 (table is
input only).
work Array of dimension ( 2 * n).
CCFFTM: Single precision array.
ZZFFTM: Double precision array.
Work array. This is a scratch array used for intermediate
calculations. Its address space must be different from the
input and output arrays.
isys Integer array dimensioned 0..isys(0).
An array that gives implementation-specific information. All
features and functions of the FFT routines specific to any
particular implementation are confined to this isys array.
Page 4
CCFFTM(3S)CCFFTM(3S)
In the Origin series implementation, isys(0)=0 and isys(0)=1
are supported. In SCSL versions prior to 1.3, only isys(0)=0
was allowed. For isys(0)=0, NF=30, and for isys(0)=1, NF=256.
The NF words of storage in the table array contain a
factorization of the length of the transform.
The smaller value of NF for isys(0)=0 is historical. It is too
small to store all the required factors for the highest
performing FFT, so when isys(0)=0, extra space is allocated
when the table array is initialized. To avoid memory leaks,
this extra space must be deallocated when the table array is no
longer needed. The CCFFTMF routine is used to release this
memory. Due to the potential for memory leaks, the use of
isys(0)=0 should be avoided.
For isys(0)=1, the value of NF is large enough so that no extra
memory needs to be allocated, and there is no need to call
CCFFTMF to release memory. If called, it does nothing.
NOTE: isys(0)=1 means that isys is an integer array with two
elements. The second element, isys(1), will not be accessed.
NOTES
The following data types are described in this documentation:
Term Used Data type
Fortran:
Array dimensioned 0..n-1 x(0:n-1)
Array of dimensions (m,n) x(m,n)
Array of dimensions (m,n,p) x(m,n,p)
Integer INTEGER (INTEGER*8 for -lscs_i8[_mp])
Single precision REAL
Double precision DOUBLE PRECISION
Single precision complex COMPLEX
Double precision complex DOUBLE COMPLEX
C/C++:
Array dimensioned 0..n-1 x[n]
Array of dimensions (m,n) x[m*n] or x[n][m]
Page 5
CCFFTM(3S)CCFFTM(3S)
Array of dimensions (m,n,p) x[m*n*p] or x[p][n][m]
Integer int (long long for -lscs_i8[_mp])
Single precision float
Double precision double
Single precision complex scsl_complex
Double precision complex scsl_zomplex
C++ STL:
Array dimensioned 0..n-1 x[n]
Array of dimensions (m,n) x[m*n] or x[n][m]
Array of dimensions (m,n,p) x[m*n*p] or x[p][n][m]
Integer int (long long for -lscs_i8[_mp])
Single precision float
Double precision double
Single precision complex complex<float>
Double precision complex complex<double>
CAUTIONS
Transform sizes with a prime factor exceeding 232-1 are not supported for
the 8-byte integer version of the library.
In addition to the work array, the FFT routines also dynamically allocate
scratch space from the stack. The amount of space allocated can be
slightly bigger than the size of the largest processor cache. For single
processor runs, the default stack size is large enough that these
allocations generally cause no problems. But for parallel runs, you need
to ensure that the stack size of slave threads is big enough to hold this
scratch space. Failure to reserve sufficient stack space will cause
programs to dump core due to stack overflows. The stack size of MP
library slave threads is controlled via the MP_SLAVE_STACKSIZE
environment variable or the mp_set_slave_stacksize() library routine. See
the mp(3C), mp(3F) and pe_environ(5) reference pages for more information
on controlling the slave stack size. For pthreads applications, the
thread's stack size is specified as one of many creation attributes
provided in the pthread_attr_t argument to pthread_create(3P). The
stacksize attribute should be set explicitly to a non-default value using
the pthread_attr_setstacksize(3P) call, described in the
pthread_attr_init(3P) man page.
Page 6
CCFFTM(3S)CCFFTM(3S)
Care must be exercised if copies of the table array are used: even though
a copy exists, the original must persist. As an example, the following
code will not work:
#include <scsl_fft.h>
scsl_complex x[56][129], y[56][129];
float table[2*128 + 256];
float work[2*128];
int isys[2];
isys[0] = 1;
{
float table_orig[2*128 + 256];
ccfftm(0, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table_orig, work, isys);
bcopy(table_orig, table, (2*128+256)*sizeof(float));
}
ccfftm(1, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table, work, isys);
In this example, because table_orig is a stack variable that does not
persist outside of the code block delimited by the braces, the data in
the copy, table, are not guaranteed to be valid. However, the following
code will work because table_orig is persistent:
#include <scsl_fft.h>
scsl_complex x[56][129], y[56][129];
float table_orig[2*128 + 256];
float table[2*128 + 256];
float work[2*128];
int isys[2];
isys[0] = 1;
ccfftm(0, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table_orig, work, isys);
bcopy(table_orig, table, (2*128+256)*sizeof(float));
ccfftm(1, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table, work, isys);
EXAMPLES
These examples use the table and workspace sizes appropriate to the
Origin series.
Example 1: Initialize the table array in preparation for doing FFTs of
size 128. Only the isign, n, and table arguments are used in this case.
You can use dummy arguments or zeros for the other arguments in the
subroutine call.
Fortran:
REAL TABLE(2*128 + 256)
Page 7
CCFFTM(3S)CCFFTM(3S)
INTEGER ISYS(0:1)
ISYS(0) = 1
CALL CCFFTM(0, 128, 0, 0.0, DUMMY, 1, DUMMY, 1,
& TABLE, DUMMY, ISYS)
C/C++:
#include <scsl_fft.h>
float table[2*128 + 256];
int isys[2];
isys[0] = 1;
ccfftm(0, 128, 0, 0.0f, NULL, 1, NULL, 1, table, NULL, isys);
C++ STL:
#include <complex.h>
#include <scsl_fft.h>
float table[2*128 + 256];
int isys[2];
isys[0] = 1;
ccfftm(0, 128, 0, 0.0f, NULL, 1, NULL, 1, table, NULL, isys);
Example 2: X and Y are complex arrays dimensioned (0:128) by (0:55).
The first 128 elements of each column contain data. For performance
reasons, the extra element forces the leading dimension to be an odd
number. Take the FFT of the first 50 columns of X and store the results
in the first 50 columns of Y. Before taking the FFT, initialize the
TABLE array, as in example 1.
Fortran:
COMPLEX X(0:128, 0:55)
COMPLEX Y(0:128, 0:55)
REAL TABLE(2*128 + 256)
REAL WORK(2*128)
INTEGER ISYS(0:1)
ISYS(0) = 1
CALL CCFFTM(0, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, ISYS)
CALL CCFFTM(1, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, ISYS)
C/C++:
#include <scsl_fft.h>
scsl_complex x[56][129], y[56][129];
float table[2*128 + 256];
float work[2*128];
int isys[2];
isys[0] = 1;
Page 8
CCFFTM(3S)CCFFTM(3S)
ccfftm(0, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table, work, isys);
ccfftm(1, 128, 50, 1.0f, (scsl_complex *) x, 129,
(scsl_complex *) y, 129, table, work, isys);
C++ STL:
#include <complex.h>
#include <scsl_fft.h>
complex<float> x[56][129], y[56][129];
float table[2*128 + 256];
float work[2*128];
int isys[2];
isys[0] = 1;
ccfftm(0, 128, 50, 1.0f, (complex<float> *) x, 129,
(complex<float> *) y, 129, table, work, isys);
ccfftm(1, 128, 50, 1.0f, (complex<float> *) x, 129,
(complex<float> *) y, 129, table, work, isys);
Example 3: With X and Y as in example 2, take the inverse FFT of Y and
store it back in X. The scale factor 1/128 is used. Assume that the
TABLE array is already initialized.
Fortran:
CALL CCFFTM(-1, 128, 50, 1.0/128.0, Y, 129, X, 129,
& TABLE,WORK,0)
C/C++:
ccfftm(-1, 128, 50, 1.0f/128.0f, (scsl_complex *) y, 129,
(scsl_complex *) x, 129, table, work, isys);
C++ STL:
ccfftm(-1, 128, 50, 1.0f/128.0f, (complex<float> *) y, 129,
(complex<float> *) x, 129, table, work, isys);
Example 4: Perform the same computation as in example 2, but put the
output back in array xto save storage space. Use the 8-byte integer
version of SCSL.
Fortran:
COMPLEX X(0:128, 0:55)
REAL TABLE(2*128 + 256)
REAL WORK(2*128)
Page 9
CCFFTM(3S)CCFFTM(3S)
INTEGER*8 ISYS(0:1)
ISYS(0) = 1_8
CALL CCFFTM(0_8, 128_8, 50_8, 1.0, X, 129_8, X, 129_8,
& TABLE, WORK, ISYS)
CALL CCFFTM(1_8, 128_8, 50_8, 1.0, X, 129_8, X, 129_8,
& TABLE, WORK, ISYS)
C/C++:
#include <scsl_fft_i8.h>
scsl_complex x[56][129];
float table[2*128 + 256];
float work[2*128];
long long isys[2];
isys[0] = 1LL
ccfftm(0LL, 128LL, 50LL, 1.0f, (scsl_complex *) x, 129LL,
(scsl_complex *) x, 129LL, table, work, isys);
ccfftm(1LL, 128LL, 50LL, 1.0f, (scsl_complex *) x, 129LL,
(scsl_complex *) x, 129LL, table, work, isys);
C++ STL:
#include <complex.h>
#include <scsl_fft_i8.h>
complex<float> x[56][129];
float table[2*128 + 256];
float work[2*128];
long long isys[2];
isys[0] = 1LL
ccfftm(0LL, 128LL, 50LL, 1.0f, (complex<float> *) x, 129LL,
(complex<float> *) x, 129LL, table, work, isys);
ccfftm(1LL, 128LL, 50LL, 1.0f, (complex<float> *) x, 129LL,
(complex<float> *) x, 129LL, table, work, isys);
Example 5: Perform the same computation as in example 2, but assume that
the lower bound of each Fortran array is 1, rather than 0. The
subroutine calls are not changed.
Fortran:
COMPLEX X(129, 55)
COMPLEX Y(129, 55)
CALL CCFFTM(0, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, ISYS)
CALL CCFFTM(1, 128, 50, 1.0, X, 129, Y, 129, TABLE, WORK, ISYS)
Page 10
CCFFTM(3S)CCFFTM(3S)SEE ALSOINTRO_FFT(3S), INTRO_SCSL(3S), CCFFT(3S), SCFFT(3S), SCFFTM(3S)
Page 11