2457 lines
		
	
	
		
			90 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			2457 lines
		
	
	
		
			90 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								@node FFTW Reference, Multi-threaded FFTW, Other Important Topics, Top
							 | 
						||
| 
								 | 
							
								@chapter FFTW Reference
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This chapter provides a complete reference for all sequential (i.e.,
							 | 
						||
| 
								 | 
							
								one-processor) FFTW functions.  Parallel transforms are described in
							 | 
						||
| 
								 | 
							
								later chapters.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Data Types and Files::
							 | 
						||
| 
								 | 
							
								* Using Plans::
							 | 
						||
| 
								 | 
							
								* Basic Interface::
							 | 
						||
| 
								 | 
							
								* Advanced Interface::
							 | 
						||
| 
								 | 
							
								* Guru Interface::
							 | 
						||
| 
								 | 
							
								* New-array Execute Functions::
							 | 
						||
| 
								 | 
							
								* Wisdom::
							 | 
						||
| 
								 | 
							
								* What FFTW Really Computes::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Data Types and Files, Using Plans, FFTW Reference, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Data Types and Files
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								All programs using FFTW should include its header file:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								#include <fftw3.h>
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You must also link to the FFTW library.  On Unix, this
							 | 
						||
| 
								 | 
							
								means adding @code{-lfftw3 -lm} at the @emph{end} of the link command.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Complex numbers::
							 | 
						||
| 
								 | 
							
								* Precision::
							 | 
						||
| 
								 | 
							
								* Memory Allocation::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Complex numbers, Precision, Data Types and Files, Data Types and Files
							 | 
						||
| 
								 | 
							
								@subsection Complex numbers
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The default FFTW interface uses @code{double} precision for all
							 | 
						||
| 
								 | 
							
								floating-point numbers, and defines a @code{fftw_complex} type to hold
							 | 
						||
| 
								 | 
							
								complex numbers as:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								typedef double fftw_complex[2];
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@tindex fftw_complex
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Here, the @code{[0]} element holds the real part and the @code{[1]}
							 | 
						||
| 
								 | 
							
								element holds the imaginary part.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Alternatively, if you have a C compiler (such as @code{gcc}) that
							 | 
						||
| 
								 | 
							
								supports the C99 revision of the ANSI C standard, you can use C's new
							 | 
						||
| 
								 | 
							
								native complex type (which is binary-compatible with the typedef above).
							 | 
						||
| 
								 | 
							
								In particular, if you @code{#include <complex.h>} @emph{before}
							 | 
						||
| 
								 | 
							
								@code{<fftw3.h>}, then @code{fftw_complex} is defined to be the native
							 | 
						||
| 
								 | 
							
								complex type and you can manipulate it with ordinary arithmetic
							 | 
						||
| 
								 | 
							
								(e.g. @code{x = y * (3+4*I)}, where @code{x} and @code{y} are
							 | 
						||
| 
								 | 
							
								@code{fftw_complex} and @code{I} is the standard symbol for the
							 | 
						||
| 
								 | 
							
								imaginary unit);
							 | 
						||
| 
								 | 
							
								@cindex C99
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								C++ has its own @code{complex<T>} template class, defined in the
							 | 
						||
| 
								 | 
							
								standard @code{<complex>} header file.  Reportedly, the C++ standards
							 | 
						||
| 
								 | 
							
								committee has recently agreed to mandate that the storage format used
							 | 
						||
| 
								 | 
							
								for this type be binary-compatible with the C99 type, i.e. an array
							 | 
						||
| 
								 | 
							
								@code{T[2]} with consecutive real @code{[0]} and imaginary @code{[1]}
							 | 
						||
| 
								 | 
							
								parts.  (See report
							 | 
						||
| 
								 | 
							
								@uref{http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2002/n1388.pdf
							 | 
						||
| 
								 | 
							
								WG21/N1388}.)  Although not part of the official standard as of this
							 | 
						||
| 
								 | 
							
								writing, the proposal stated that: ``This solution has been tested with
							 | 
						||
| 
								 | 
							
								all current major implementations of the standard library and shown to
							 | 
						||
| 
								 | 
							
								be working.''  To the extent that this is true, if you have a variable
							 | 
						||
| 
								 | 
							
								@code{complex<double> *x}, you can pass it directly to FFTW via
							 | 
						||
| 
								 | 
							
								@code{reinterpret_cast<fftw_complex*>(x)}.
							 | 
						||
| 
								 | 
							
								@cindex C++
							 | 
						||
| 
								 | 
							
								@cindex portability
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Precision, Memory Allocation, Complex numbers, Data Types and Files
							 | 
						||
| 
								 | 
							
								@subsection Precision
							 | 
						||
| 
								 | 
							
								@cindex precision
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can install single and long-double precision versions of FFTW,
							 | 
						||
| 
								 | 
							
								which replace @code{double} with @code{float} and @code{long double},
							 | 
						||
| 
								 | 
							
								respectively (@pxref{Installation and Customization}).  To use these
							 | 
						||
| 
								 | 
							
								interfaces, you:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								Link to the single/long-double libraries; on Unix, @code{-lfftw3f} or
							 | 
						||
| 
								 | 
							
								@code{-lfftw3l} instead of (or in addition to) @code{-lfftw3}.  (You
							 | 
						||
| 
								 | 
							
								can link to the different-precision libraries simultaneously.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								Include the @emph{same} @code{<fftw3.h>} header file.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								Replace all lowercase instances of @samp{fftw_} with @samp{fftwf_} or
							 | 
						||
| 
								 | 
							
								@samp{fftwl_} for single or long-double precision, respectively.
							 | 
						||
| 
								 | 
							
								(@code{fftw_complex} becomes @code{fftwf_complex}, @code{fftw_execute}
							 | 
						||
| 
								 | 
							
								becomes @code{fftwf_execute}, etcetera.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								Uppercase names, i.e. names beginning with @samp{FFTW_}, remain the
							 | 
						||
| 
								 | 
							
								same.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								Replace @code{double} with @code{float} or @code{long double} for
							 | 
						||
| 
								 | 
							
								subroutine parameters.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Depending upon your compiler and/or hardware, @code{long double} may not
							 | 
						||
| 
								 | 
							
								be any more precise than @code{double} (or may not be supported at all,
							 | 
						||
| 
								 | 
							
								although it is standard in C99).
							 | 
						||
| 
								 | 
							
								@cindex C99
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We also support using the nonstandard @code{__float128}
							 | 
						||
| 
								 | 
							
								quadruple-precision type provided by recent versions of @code{gcc} on
							 | 
						||
| 
								 | 
							
								32- and 64-bit x86 hardware (@pxref{Installation and Customization}).
							 | 
						||
| 
								 | 
							
								To use this type, link with @code{-lfftw3q -lquadmath -lm} (the
							 | 
						||
| 
								 | 
							
								@code{libquadmath} library provided by @code{gcc} is needed for
							 | 
						||
| 
								 | 
							
								quadruple-precision trigonometric functions) and use @samp{fftwq_}
							 | 
						||
| 
								 | 
							
								identifiers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Memory Allocation,  , Precision, Data Types and Files
							 | 
						||
| 
								 | 
							
								@subsection Memory Allocation
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void *fftw_malloc(size_t n);
							 | 
						||
| 
								 | 
							
								void fftw_free(void *p);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_malloc
							 | 
						||
| 
								 | 
							
								@findex fftw_free
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These are functions that behave identically to @code{malloc} and
							 | 
						||
| 
								 | 
							
								@code{free}, except that they guarantee that the returned pointer obeys
							 | 
						||
| 
								 | 
							
								any special alignment restrictions imposed by any algorithm in FFTW
							 | 
						||
| 
								 | 
							
								(e.g. for SIMD acceleration).  @xref{SIMD alignment and fftw_malloc}.
							 | 
						||
| 
								 | 
							
								@cindex alignment
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Data allocated by @code{fftw_malloc} @emph{must} be deallocated by
							 | 
						||
| 
								 | 
							
								@code{fftw_free} and not by the ordinary @code{free}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These routines simply call through to your operating system's
							 | 
						||
| 
								 | 
							
								@code{malloc} or, if necessary, its aligned equivalent
							 | 
						||
| 
								 | 
							
								(e.g. @code{memalign}), so you normally need not worry about any
							 | 
						||
| 
								 | 
							
								significant time or space overhead.  You are @emph{not required} to use
							 | 
						||
| 
								 | 
							
								them to allocate your data, but we strongly recommend it.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note: in C++, just as with ordinary @code{malloc}, you must typecast
							 | 
						||
| 
								 | 
							
								the output of @code{fftw_malloc} to whatever pointer type you are
							 | 
						||
| 
								 | 
							
								allocating.
							 | 
						||
| 
								 | 
							
								@cindex C++
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We also provide the following two convenience functions to allocate
							 | 
						||
| 
								 | 
							
								real and complex arrays with @code{n} elements, which are equivalent
							 | 
						||
| 
								 | 
							
								to @code{(double *) fftw_malloc(sizeof(double) * n)} and
							 | 
						||
| 
								 | 
							
								@code{(fftw_complex *) fftw_malloc(sizeof(fftw_complex) * n)},
							 | 
						||
| 
								 | 
							
								respectively:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								double *fftw_alloc_real(size_t n);
							 | 
						||
| 
								 | 
							
								fftw_complex *fftw_alloc_complex(size_t n);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_alloc_real
							 | 
						||
| 
								 | 
							
								@findex fftw_alloc_complex
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The equivalent functions in other precisions allocate arrays of @code{n}
							 | 
						||
| 
								 | 
							
								elements in that precision.  e.g. @code{fftwf_alloc_real(n)} is
							 | 
						||
| 
								 | 
							
								equivalent to @code{(float *) fftwf_malloc(sizeof(float) * n)}.
							 | 
						||
| 
								 | 
							
								@cindex precision
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Using Plans, Basic Interface, Data Types and Files, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Using Plans
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plans for all transform types in FFTW are stored as type
							 | 
						||
| 
								 | 
							
								@code{fftw_plan} (an opaque pointer type), and are created by one of the
							 | 
						||
| 
								 | 
							
								various planning routines described in the following sections.
							 | 
						||
| 
								 | 
							
								@tindex fftw_plan
							 | 
						||
| 
								 | 
							
								An @code{fftw_plan} contains all information necessary to compute the
							 | 
						||
| 
								 | 
							
								transform, including the pointers to the input and output arrays.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_execute(const fftw_plan plan);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_execute
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This executes the @code{plan}, to compute the corresponding transform on
							 | 
						||
| 
								 | 
							
								the arrays for which it was planned (which must still exist).  The plan
							 | 
						||
| 
								 | 
							
								is not modified, and @code{fftw_execute} can be called as many times as
							 | 
						||
| 
								 | 
							
								desired.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To apply a given plan to a different array, you can use the new-array execute
							 | 
						||
| 
								 | 
							
								interface.  @xref{New-array Execute Functions}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_execute} (and equivalents) is the only function in FFTW
							 | 
						||
| 
								 | 
							
								guaranteed to be thread-safe; see @ref{Thread safety}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This function:
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_destroy_plan(fftw_plan plan);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_destroy_plan
							 | 
						||
| 
								 | 
							
								deallocates the @code{plan} and all its associated data.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW's planner saves some other persistent data, such as the
							 | 
						||
| 
								 | 
							
								accumulated wisdom and a list of algorithms available in the current
							 | 
						||
| 
								 | 
							
								configuration.  If you want to deallocate all of that and reset FFTW
							 | 
						||
| 
								 | 
							
								to the pristine state it was in when you started your program, you can
							 | 
						||
| 
								 | 
							
								call:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_cleanup(void);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_cleanup
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								After calling @code{fftw_cleanup}, all existing plans become undefined,
							 | 
						||
| 
								 | 
							
								and you should not attempt to execute them nor to destroy them.  You can
							 | 
						||
| 
								 | 
							
								however create and execute/destroy new plans, in which case FFTW starts
							 | 
						||
| 
								 | 
							
								accumulating wisdom information again.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_cleanup} does not deallocate your plans, however.  To prevent
							 | 
						||
| 
								 | 
							
								memory leaks, you must still call @code{fftw_destroy_plan} before
							 | 
						||
| 
								 | 
							
								executing @code{fftw_cleanup}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Occasionally, it may useful to know FFTW's internal ``cost'' metric
							 | 
						||
| 
								 | 
							
								that it uses to compare plans to one another; this cost is
							 | 
						||
| 
								 | 
							
								proportional to an execution time of the plan, in undocumented units,
							 | 
						||
| 
								 | 
							
								if the plan was created with the @code{FFTW_MEASURE} or other
							 | 
						||
| 
								 | 
							
								timing-based options, or alternatively is a heuristic cost function
							 | 
						||
| 
								 | 
							
								for @code{FFTW_ESTIMATE} plans.  (The cost values of measured and
							 | 
						||
| 
								 | 
							
								estimated plans are not comparable, being in different units.  Also,
							 | 
						||
| 
								 | 
							
								costs from different FFTW versions or the same version compiled
							 | 
						||
| 
								 | 
							
								differently may not be in the same units.  Plans created from wisdom
							 | 
						||
| 
								 | 
							
								have a cost of 0 since no timing measurement is performed for them.
							 | 
						||
| 
								 | 
							
								Finally, certain problems for which only one top-level algorithm was
							 | 
						||
| 
								 | 
							
								possible may have required no measurements of the cost of the whole
							 | 
						||
| 
								 | 
							
								plan, in which case @code{fftw_cost} will also return 0.)  The cost
							 | 
						||
| 
								 | 
							
								metric for a given plan is returned by:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								double fftw_cost(const fftw_plan plan);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_cost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The following two routines are provided purely for academic purposes
							 | 
						||
| 
								 | 
							
								(that is, for entertainment).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_flops(const fftw_plan plan, 
							 | 
						||
| 
								 | 
							
								                double *add, double *mul, double *fma);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_flops
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Given a @code{plan}, set @code{add}, @code{mul}, and @code{fma} to an
							 | 
						||
| 
								 | 
							
								exact count of the number of floating-point additions, multiplications,
							 | 
						||
| 
								 | 
							
								and fused multiply-add operations involved in the plan's execution.  The
							 | 
						||
| 
								 | 
							
								total number of floating-point operations (flops) is @code{add + mul +
							 | 
						||
| 
								 | 
							
								2*fma}, or @code{add + mul + fma} if the hardware supports fused
							 | 
						||
| 
								 | 
							
								multiply-add instructions (although the number of FMA operations is only
							 | 
						||
| 
								 | 
							
								approximate because of compiler voodoo).  (The number of operations
							 | 
						||
| 
								 | 
							
								should be an integer, but we use @code{double} to avoid overflowing
							 | 
						||
| 
								 | 
							
								@code{int} for large transforms; the arguments are of type @code{double}
							 | 
						||
| 
								 | 
							
								even for single and long-double precision versions of FFTW.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_fprint_plan(const fftw_plan plan, FILE *output_file);
							 | 
						||
| 
								 | 
							
								void fftw_print_plan(const fftw_plan plan);
							 | 
						||
| 
								 | 
							
								char *fftw_sprint_plan(const fftw_plan plan);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_fprint_plan
							 | 
						||
| 
								 | 
							
								@findex fftw_print_plan
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This outputs a ``nerd-readable'' representation of the @code{plan} to
							 | 
						||
| 
								 | 
							
								the given file, to @code{stdout}, or two a newly allocated
							 | 
						||
| 
								 | 
							
								NUL-terminated string (which the caller is responsible for deallocating
							 | 
						||
| 
								 | 
							
								with @code{free}), respectively.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Basic Interface, Advanced Interface, Using Plans, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Basic Interface
							 | 
						||
| 
								 | 
							
								@cindex basic interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Recall that the FFTW API is divided into three parts@footnote{@i{Gallia est
							 | 
						||
| 
								 | 
							
								omnis divisa in partes tres} (Julius Caesar).}: the @dfn{basic interface}
							 | 
						||
| 
								 | 
							
								computes a single transform of contiguous data, the @dfn{advanced
							 | 
						||
| 
								 | 
							
								interface} computes transforms of multiple or strided arrays, and the
							 | 
						||
| 
								 | 
							
								@dfn{guru interface} supports the most general data layouts,
							 | 
						||
| 
								 | 
							
								multiplicities, and strides.  This section describes the basic
							 | 
						||
| 
								 | 
							
								interface, which we expect to satisfy the needs of most users.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Complex DFTs::
							 | 
						||
| 
								 | 
							
								* Planner Flags::
							 | 
						||
| 
								 | 
							
								* Real-data DFTs::
							 | 
						||
| 
								 | 
							
								* Real-data DFT Array Format::
							 | 
						||
| 
								 | 
							
								* Real-to-Real Transforms::
							 | 
						||
| 
								 | 
							
								* Real-to-Real Transform Kinds::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Complex DFTs, Planner Flags, Basic Interface, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Complex DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_1d(int n0,
							 | 
						||
| 
								 | 
							
								                           fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                           int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_2d(int n0, int n1,
							 | 
						||
| 
								 | 
							
								                           fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                           int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2,
							 | 
						||
| 
								 | 
							
								                           fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                           int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft(int rank, const int *n,
							 | 
						||
| 
								 | 
							
								                        fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                        int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_1d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_2d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_3d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plan a complex input/output discrete Fourier transform (DFT) in zero or
							 | 
						||
| 
								 | 
							
								more dimensions, returning an @code{fftw_plan} (@pxref{Using Plans}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Once you have created a plan for a certain transform type and
							 | 
						||
| 
								 | 
							
								parameters, then creating another plan of the same type and parameters,
							 | 
						||
| 
								 | 
							
								but for different arrays, is fast and shares constant data with the
							 | 
						||
| 
								 | 
							
								first plan (if it still exists).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The planner returns @code{NULL} if the plan cannot be created.  In the
							 | 
						||
| 
								 | 
							
								standard FFTW distribution, the basic interface is guaranteed to return
							 | 
						||
| 
								 | 
							
								a non-@code{NULL} plan.  A plan may be @code{NULL}, however, if you are
							 | 
						||
| 
								 | 
							
								using a customized FFTW configuration supporting a restricted set of
							 | 
						||
| 
								 | 
							
								transforms.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Arguments
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{rank} is the rank of the transform (it should be the size of the
							 | 
						||
| 
								 | 
							
								array @code{*n}), and can be any non-negative integer.  (@xref{Complex
							 | 
						||
| 
								 | 
							
								Multi-Dimensional DFTs}, for the definition of ``rank''.)  The
							 | 
						||
| 
								 | 
							
								@samp{_1d}, @samp{_2d}, and @samp{_3d} planners correspond to a
							 | 
						||
| 
								 | 
							
								@code{rank} of @code{1}, @code{2}, and @code{3}, respectively.  The rank
							 | 
						||
| 
								 | 
							
								may be zero, which is equivalent to a rank-1 transform of size 1, i.e. a
							 | 
						||
| 
								 | 
							
								copy of one number from input to output.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{n0}, @code{n1}, @code{n2}, or @code{n[0..rank-1]} (as appropriate
							 | 
						||
| 
								 | 
							
								for each routine) specify the size of the transform dimensions.  They
							 | 
						||
| 
								 | 
							
								can be any positive integer.
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								@itemize @minus
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@cindex row-major
							 | 
						||
| 
								 | 
							
								Multi-dimensional arrays are stored in row-major order with dimensions:
							 | 
						||
| 
								 | 
							
								@code{n0} x @code{n1}; or @code{n0} x @code{n1} x @code{n2}; or
							 | 
						||
| 
								 | 
							
								@code{n[0]} x @code{n[1]} x ... x @code{n[rank-1]}.
							 | 
						||
| 
								 | 
							
								@xref{Multi-dimensional Array Format}.
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								FFTW is best at handling sizes of the form
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@math{2^a 3^b 5^c 7^d 11^e 13^f},
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$2^a 3^b 5^c 7^d 11^e 13^f$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								2<sup>a</sup> 3<sup>b</sup> 5<sup>c</sup> 7<sup>d</sup>
							 | 
						||
| 
								 | 
							
								        11<sup>e</sup> 13<sup>f</sup>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where @math{e+f} is either @math{0} or @math{1}, and the other exponents
							 | 
						||
| 
								 | 
							
								are arbitrary.  Other sizes are computed by means of a slow,
							 | 
						||
| 
								 | 
							
								general-purpose algorithm (which nevertheless retains @Onlogn{} performance even for prime sizes).  It is possible to customize FFTW
							 | 
						||
| 
								 | 
							
								for different array sizes; see @ref{Installation and Customization}.
							 | 
						||
| 
								 | 
							
								Transforms whose sizes are powers of @math{2} are especially fast.
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out} point to the input and output arrays of the
							 | 
						||
| 
								 | 
							
								transform, which may be the same (yielding an in-place transform).
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								These arrays are overwritten during planning, unless
							 | 
						||
| 
								 | 
							
								@code{FFTW_ESTIMATE} is used in the flags.  (The arrays need not be
							 | 
						||
| 
								 | 
							
								initialized, but they must be allocated.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If @code{in == out}, the transform is @dfn{in-place} and the input
							 | 
						||
| 
								 | 
							
								array is overwritten. If @code{in != out}, the two arrays must
							 | 
						||
| 
								 | 
							
								not overlap (but FFTW does not check for this condition).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_FORWARD
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_BACKWARD
							 | 
						||
| 
								 | 
							
								@code{sign} is the sign of the exponent in the formula that defines the
							 | 
						||
| 
								 | 
							
								Fourier transform.  It can be @math{-1} (= @code{FFTW_FORWARD}) or
							 | 
						||
| 
								 | 
							
								@math{+1} (= @code{FFTW_BACKWARD}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW computes an unnormalized transform: computing a forward followed by
							 | 
						||
| 
								 | 
							
								a backward transform (or vice versa) will result in the original data
							 | 
						||
| 
								 | 
							
								multiplied by the size of the transform (the product of the dimensions).
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								For more information, see @ref{What FFTW Really Computes}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Planner Flags, Real-data DFTs, Complex DFTs, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Planner Flags
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								All of the planner routines in FFTW accept an integer @code{flags}
							 | 
						||
| 
								 | 
							
								argument, which is a bitwise OR (@samp{|}) of zero or more of the flag
							 | 
						||
| 
								 | 
							
								constants defined below.  These flags control the rigor (and time) of
							 | 
						||
| 
								 | 
							
								the planning process, and can also impose (or lift) restrictions on the
							 | 
						||
| 
								 | 
							
								type of transform algorithm that is employed.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@emph{Important:} the planner overwrites the input array during
							 | 
						||
| 
								 | 
							
								planning unless a saved plan (@pxref{Wisdom}) is available for that
							 | 
						||
| 
								 | 
							
								problem, so you should initialize your input data after creating the
							 | 
						||
| 
								 | 
							
								plan.  The only exceptions to this are the @code{FFTW_ESTIMATE} and
							 | 
						||
| 
								 | 
							
								@code{FFTW_WISDOM_ONLY} flags, as mentioned below.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In all  cases, if  wisdom is  available for the  given problem  that was
							 | 
						||
| 
								 | 
							
								created  with equal-or-greater  planning rigor,  then the  more rigorous
							 | 
						||
| 
								 | 
							
								wisdom is used.  For example, in @code{FFTW_ESTIMATE} mode any available
							 | 
						||
| 
								 | 
							
								wisdom is used, whereas  in @code{FFTW_PATIENT} mode only wisdom created
							 | 
						||
| 
								 | 
							
								in patient or exhaustive mode can be used.  @xref{Words of Wisdom-Saving
							 | 
						||
| 
								 | 
							
								Plans}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Planning-rigor flags
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_ESTIMATE
							 | 
						||
| 
								 | 
							
								@code{FFTW_ESTIMATE} specifies that, instead of actual measurements of
							 | 
						||
| 
								 | 
							
								different algorithms, a simple heuristic is used to pick a (probably
							 | 
						||
| 
								 | 
							
								sub-optimal) plan quickly.  With this flag, the input/output arrays are
							 | 
						||
| 
								 | 
							
								not overwritten during planning.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_MEASURE
							 | 
						||
| 
								 | 
							
								@code{FFTW_MEASURE} tells FFTW to find an optimized plan by actually
							 | 
						||
| 
								 | 
							
								@emph{computing} several FFTs and measuring their execution time.
							 | 
						||
| 
								 | 
							
								Depending on your machine, this can take some time (often a few
							 | 
						||
| 
								 | 
							
								seconds).  @code{FFTW_MEASURE} is the default planning option.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_PATIENT
							 | 
						||
| 
								 | 
							
								@code{FFTW_PATIENT} is like @code{FFTW_MEASURE}, but considers a wider
							 | 
						||
| 
								 | 
							
								range of algorithms and often produces a ``more optimal'' plan
							 | 
						||
| 
								 | 
							
								(especially for large transforms), but at the expense of several times
							 | 
						||
| 
								 | 
							
								longer planning time (especially for large transforms).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_EXHAUSTIVE
							 | 
						||
| 
								 | 
							
								@code{FFTW_EXHAUSTIVE} is like @code{FFTW_PATIENT}, but considers an
							 | 
						||
| 
								 | 
							
								even wider range of algorithms, including many that we think are
							 | 
						||
| 
								 | 
							
								unlikely to be fast, to produce the most optimal plan but with a
							 | 
						||
| 
								 | 
							
								substantially increased planning time.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_WISDOM_ONLY
							 | 
						||
| 
								 | 
							
								@code{FFTW_WISDOM_ONLY} is a special planning mode in which the plan
							 | 
						||
| 
								 | 
							
								is only created if wisdom is available for the given problem, and
							 | 
						||
| 
								 | 
							
								otherwise a @code{NULL} plan is returned.  This can be combined with
							 | 
						||
| 
								 | 
							
								other flags, e.g. @samp{FFTW_WISDOM_ONLY | FFTW_PATIENT} creates a
							 | 
						||
| 
								 | 
							
								plan only if wisdom is available that was created in
							 | 
						||
| 
								 | 
							
								@code{FFTW_PATIENT} or @code{FFTW_EXHAUSTIVE} mode.  The
							 | 
						||
| 
								 | 
							
								@code{FFTW_WISDOM_ONLY} flag is intended for users who need to detect
							 | 
						||
| 
								 | 
							
								whether wisdom is available; for example, if wisdom is not available
							 | 
						||
| 
								 | 
							
								one may wish to allocate new arrays for planning so that user data is
							 | 
						||
| 
								 | 
							
								not overwritten.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Algorithm-restriction flags
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_DESTROY_INPUT
							 | 
						||
| 
								 | 
							
								@code{FFTW_DESTROY_INPUT} specifies that an out-of-place transform is
							 | 
						||
| 
								 | 
							
								allowed to @emph{overwrite its input} array with arbitrary data; this
							 | 
						||
| 
								 | 
							
								can sometimes allow more efficient algorithms to be employed.
							 | 
						||
| 
								 | 
							
								@cindex out-of-place
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_PRESERVE_INPUT
							 | 
						||
| 
								 | 
							
								@code{FFTW_PRESERVE_INPUT} specifies that an out-of-place transform must
							 | 
						||
| 
								 | 
							
								@emph{not change its input} array.  This is ordinarily the
							 | 
						||
| 
								 | 
							
								@emph{default}, except for c2r and hc2r (i.e. complex-to-real)
							 | 
						||
| 
								 | 
							
								transforms for which @code{FFTW_DESTROY_INPUT} is the default.  In the
							 | 
						||
| 
								 | 
							
								latter cases, passing @code{FFTW_PRESERVE_INPUT} will attempt to use
							 | 
						||
| 
								 | 
							
								algorithms that do not destroy the input, at the expense of worse
							 | 
						||
| 
								 | 
							
								performance; for multi-dimensional c2r transforms, however, no
							 | 
						||
| 
								 | 
							
								input-preserving algorithms are implemented and the planner will return
							 | 
						||
| 
								 | 
							
								@code{NULL} if one is requested.
							 | 
						||
| 
								 | 
							
								@cindex c2r
							 | 
						||
| 
								 | 
							
								@cindex hc2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_UNALIGNED
							 | 
						||
| 
								 | 
							
								@cindex alignment
							 | 
						||
| 
								 | 
							
								@findex fftw_malloc
							 | 
						||
| 
								 | 
							
								@findex fftw_alignment_of
							 | 
						||
| 
								 | 
							
								@code{FFTW_UNALIGNED} specifies that the algorithm may not impose any
							 | 
						||
| 
								 | 
							
								unusual alignment requirements on the input/output arrays (i.e. no
							 | 
						||
| 
								 | 
							
								SIMD may be used).  This flag is normally @emph{not necessary}, since
							 | 
						||
| 
								 | 
							
								the planner automatically detects misaligned arrays.  The only use for
							 | 
						||
| 
								 | 
							
								this flag is if you want to use the new-array execute interface to
							 | 
						||
| 
								 | 
							
								execute a given plan on a different array that may not be aligned like
							 | 
						||
| 
								 | 
							
								the original.  (Using @code{fftw_malloc} makes this flag unnecessary
							 | 
						||
| 
								 | 
							
								even then.  You can also use @code{fftw_alignment_of} to detect
							 | 
						||
| 
								 | 
							
								whether two arrays are equivalently aligned.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Limiting planning time
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								extern void fftw_set_timelimit(double seconds);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_set_timelimit
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This function instructs FFTW to spend at most @code{seconds} seconds
							 | 
						||
| 
								 | 
							
								(approximately) in the planner.  If @code{seconds ==
							 | 
						||
| 
								 | 
							
								FFTW_NO_TIMELIMIT} (the default value, which is negative), then
							 | 
						||
| 
								 | 
							
								planning time is unbounded.  Otherwise, FFTW plans with a
							 | 
						||
| 
								 | 
							
								progressively wider range of algorithms until the given time limit
							 | 
						||
| 
								 | 
							
								is reached or the given range of algorithms is explored, returning the
							 | 
						||
| 
								 | 
							
								best available plan.
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_NO_TIMELIMIT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For example, specifying @code{FFTW_PATIENT} first plans in
							 | 
						||
| 
								 | 
							
								@code{FFTW_ESTIMATE} mode, then in @code{FFTW_MEASURE} mode, then
							 | 
						||
| 
								 | 
							
								finally (time permitting) in @code{FFTW_PATIENT}.  If
							 | 
						||
| 
								 | 
							
								@code{FFTW_EXHAUSTIVE} is specified instead, the planner will further
							 | 
						||
| 
								 | 
							
								progress to @code{FFTW_EXHAUSTIVE} mode.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that the @code{seconds} argument specifies only a rough limit; in
							 | 
						||
| 
								 | 
							
								practice, the planner may use somewhat more time if the time limit is
							 | 
						||
| 
								 | 
							
								reached when the planner is in the middle of an operation that cannot
							 | 
						||
| 
								 | 
							
								be interrupted.  At the very least, the planner will complete planning
							 | 
						||
| 
								 | 
							
								in @code{FFTW_ESTIMATE} mode (which is thus equivalent to a time limit
							 | 
						||
| 
								 | 
							
								of 0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Real-data DFTs, Real-data DFT Array Format, Planner Flags, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Real-data DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_r2c_1d(int n0,
							 | 
						||
| 
								 | 
							
								                               double *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1,
							 | 
						||
| 
								 | 
							
								                               double *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2,
							 | 
						||
| 
								 | 
							
								                               double *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_r2c(int rank, const int *n,
							 | 
						||
| 
								 | 
							
								                            double *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								                            unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_r2c_1d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_r2c_2d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_r2c_3d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_r2c
							 | 
						||
| 
								 | 
							
								@cindex r2c
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plan a real-input/complex-output discrete Fourier transform (DFT) in
							 | 
						||
| 
								 | 
							
								zero or more dimensions, returning an @code{fftw_plan} (@pxref{Using
							 | 
						||
| 
								 | 
							
								Plans}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Once you have created a plan for a certain transform type and
							 | 
						||
| 
								 | 
							
								parameters, then creating another plan of the same type and parameters,
							 | 
						||
| 
								 | 
							
								but for different arrays, is fast and shares constant data with the
							 | 
						||
| 
								 | 
							
								first plan (if it still exists).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The planner returns @code{NULL} if the plan cannot be created.  A
							 | 
						||
| 
								 | 
							
								non-@code{NULL} plan is always returned by the basic interface unless
							 | 
						||
| 
								 | 
							
								you are using a customized FFTW configuration supporting a restricted
							 | 
						||
| 
								 | 
							
								set of transforms, or if you use the @code{FFTW_PRESERVE_INPUT} flag
							 | 
						||
| 
								 | 
							
								with a multi-dimensional out-of-place c2r transform (see below).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Arguments
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{rank} is the rank of the transform (it should be the size of the
							 | 
						||
| 
								 | 
							
								array @code{*n}), and can be any non-negative integer.  (@xref{Complex
							 | 
						||
| 
								 | 
							
								Multi-Dimensional DFTs}, for the definition of ``rank''.)  The
							 | 
						||
| 
								 | 
							
								@samp{_1d}, @samp{_2d}, and @samp{_3d} planners correspond to a
							 | 
						||
| 
								 | 
							
								@code{rank} of @code{1}, @code{2}, and @code{3}, respectively.  The rank
							 | 
						||
| 
								 | 
							
								may be zero, which is equivalent to a rank-1 transform of size 1, i.e. a
							 | 
						||
| 
								 | 
							
								copy of one real number (with zero imaginary part) from input to output.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{n0}, @code{n1}, @code{n2}, or @code{n[0..rank-1]}, (as appropriate
							 | 
						||
| 
								 | 
							
								for each routine) specify the size of the transform dimensions.  They
							 | 
						||
| 
								 | 
							
								can be any positive integer.  This is different in general from the
							 | 
						||
| 
								 | 
							
								@emph{physical} array dimensions, which are described in @ref{Real-data
							 | 
						||
| 
								 | 
							
								DFT Array Format}.
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								@itemize @minus
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								FFTW is best at handling sizes of the form
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@math{2^a 3^b 5^c 7^d 11^e 13^f},
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$2^a 3^b 5^c 7^d 11^e 13^f$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								2<sup>a</sup> 3<sup>b</sup> 5<sup>c</sup> 7<sup>d</sup>
							 | 
						||
| 
								 | 
							
								        11<sup>e</sup> 13<sup>f</sup>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where @math{e+f} is either @math{0} or @math{1}, and the other exponents
							 | 
						||
| 
								 | 
							
								are arbitrary.  Other sizes are computed by means of a slow,
							 | 
						||
| 
								 | 
							
								general-purpose algorithm (which nevertheless retains @Onlogn{} performance even for prime sizes).  (It is possible to customize FFTW
							 | 
						||
| 
								 | 
							
								for different array sizes; see @ref{Installation and Customization}.)
							 | 
						||
| 
								 | 
							
								Transforms whose sizes are powers of @math{2} are especially fast, and
							 | 
						||
| 
								 | 
							
								it is generally beneficial for the @emph{last} dimension of an r2c/c2r
							 | 
						||
| 
								 | 
							
								transform to be @emph{even}.
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out} point to the input and output arrays of the
							 | 
						||
| 
								 | 
							
								transform, which may be the same (yielding an in-place transform).
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								These arrays are overwritten during planning, unless
							 | 
						||
| 
								 | 
							
								@code{FFTW_ESTIMATE} is used in the flags.  (The arrays need not be
							 | 
						||
| 
								 | 
							
								initialized, but they must be allocated.)  For an in-place transform, it
							 | 
						||
| 
								 | 
							
								is important to remember that the real array will require padding,
							 | 
						||
| 
								 | 
							
								described in @ref{Real-data DFT Array Format}.
							 | 
						||
| 
								 | 
							
								@cindex padding
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The inverse transforms, taking complex input (storing the non-redundant
							 | 
						||
| 
								 | 
							
								half of a logically Hermitian array) to real output, are given by:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_c2r_1d(int n0,
							 | 
						||
| 
								 | 
							
								                               fftw_complex *in, double *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_c2r_2d(int n0, int n1,
							 | 
						||
| 
								 | 
							
								                               fftw_complex *in, double *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_c2r_3d(int n0, int n1, int n2,
							 | 
						||
| 
								 | 
							
								                               fftw_complex *in, double *out,
							 | 
						||
| 
								 | 
							
								                               unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_dft_c2r(int rank, const int *n,
							 | 
						||
| 
								 | 
							
								                            fftw_complex *in, double *out,
							 | 
						||
| 
								 | 
							
								                            unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_c2r_1d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_c2r_2d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_c2r_3d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_dft_c2r
							 | 
						||
| 
								 | 
							
								@cindex c2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The arguments are the same as for the r2c transforms, except that the
							 | 
						||
| 
								 | 
							
								input and output data formats are reversed.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW computes an unnormalized transform: computing an r2c followed by a
							 | 
						||
| 
								 | 
							
								c2r transform (or vice versa) will result in the original data
							 | 
						||
| 
								 | 
							
								multiplied by the size of the transform (the product of the logical
							 | 
						||
| 
								 | 
							
								dimensions).
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								An r2c transform produces the same output as a @code{FFTW_FORWARD}
							 | 
						||
| 
								 | 
							
								complex DFT of the same input, and a c2r transform is correspondingly
							 | 
						||
| 
								 | 
							
								equivalent to @code{FFTW_BACKWARD}.  For more information, see @ref{What
							 | 
						||
| 
								 | 
							
								FFTW Really Computes}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Real-data DFT Array Format, Real-to-Real Transforms, Real-data DFTs, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Real-data DFT Array Format
							 | 
						||
| 
								 | 
							
								@cindex r2c/c2r multi-dimensional array format
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The output of a DFT of real data (r2c) contains symmetries that, in
							 | 
						||
| 
								 | 
							
								principle, make half of the outputs redundant (@pxref{What FFTW Really
							 | 
						||
| 
								 | 
							
								Computes}).  (Similarly for the input of an inverse c2r transform.)  In
							 | 
						||
| 
								 | 
							
								practice, it is not possible to entirely realize these savings in an
							 | 
						||
| 
								 | 
							
								efficient and understandable format that generalizes to
							 | 
						||
| 
								 | 
							
								multi-dimensional transforms.  Instead, the output of the r2c
							 | 
						||
| 
								 | 
							
								transforms is @emph{slightly} over half of the output of the
							 | 
						||
| 
								 | 
							
								corresponding complex transform.  We do not ``pack'' the data in any
							 | 
						||
| 
								 | 
							
								way, but store it as an ordinary array of @code{fftw_complex} values.
							 | 
						||
| 
								 | 
							
								In fact, this data is simply a subsection of what would be the array in
							 | 
						||
| 
								 | 
							
								the corresponding complex transform.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Specifically, for a real transform of @math{d} (= @code{rank})
							 | 
						||
| 
								 | 
							
								dimensions @ndims{}, the complex data is an @ndimshalf array of
							 | 
						||
| 
								 | 
							
								@code{fftw_complex} values in row-major order (with the division rounded
							 | 
						||
| 
								 | 
							
								down).  That is, we only store the @emph{lower} half (non-negative
							 | 
						||
| 
								 | 
							
								frequencies), plus one element, of the last dimension of the data from
							 | 
						||
| 
								 | 
							
								the ordinary complex transform.  (We could have instead taken half of
							 | 
						||
| 
								 | 
							
								any other dimension, but implementation turns out to be simpler if the
							 | 
						||
| 
								 | 
							
								last, contiguous, dimension is used.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex out-of-place
							 | 
						||
| 
								 | 
							
								For an out-of-place transform, the real data is simply an array with
							 | 
						||
| 
								 | 
							
								physical dimensions @ndims in row-major order.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								@cindex padding
							 | 
						||
| 
								 | 
							
								For an in-place transform, some complications arise since the complex data
							 | 
						||
| 
								 | 
							
								is slightly larger than the real data.  In this case, the final
							 | 
						||
| 
								 | 
							
								dimension of the real data must be @emph{padded} with extra values to
							 | 
						||
| 
								 | 
							
								accommodate the size of the complex data---two extra if the last
							 | 
						||
| 
								 | 
							
								dimension is even and one if it is odd.  That is, the last dimension of
							 | 
						||
| 
								 | 
							
								the real data must physically contain
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$2 (n_{d-1}/2+1)$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								2 * (n[d-1]/2+1)
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								2 * (n<sub>d-1</sub>/2+1)
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@code{double} values (exactly enough to hold the complex data).  This
							 | 
						||
| 
								 | 
							
								physical array size does not, however, change the @emph{logical} array
							 | 
						||
| 
								 | 
							
								size---only
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$n_{d-1}$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								n[d-1]
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								n<sub>d-1</sub>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								values are actually stored in the last dimension, and
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$n_{d-1}$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								n[d-1]
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								n<sub>d-1</sub>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								is the last dimension passed to the planner.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Real-to-Real Transforms, Real-to-Real Transform Kinds, Real-data DFT Array Format, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Real-to-Real Transforms
							 | 
						||
| 
								 | 
							
								@cindex r2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_r2r_1d(int n, double *in, double *out,
							 | 
						||
| 
								 | 
							
								                           fftw_r2r_kind kind, unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_r2r_2d(int n0, int n1, double *in, double *out,
							 | 
						||
| 
								 | 
							
								                           fftw_r2r_kind kind0, fftw_r2r_kind kind1,
							 | 
						||
| 
								 | 
							
								                           unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_r2r_3d(int n0, int n1, int n2,
							 | 
						||
| 
								 | 
							
								                           double *in, double *out,
							 | 
						||
| 
								 | 
							
								                           fftw_r2r_kind kind0,
							 | 
						||
| 
								 | 
							
								                           fftw_r2r_kind kind1,
							 | 
						||
| 
								 | 
							
								                           fftw_r2r_kind kind2,
							 | 
						||
| 
								 | 
							
								                           unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_r2r(int rank, const int *n, double *in, double *out,
							 | 
						||
| 
								 | 
							
								                        const fftw_r2r_kind *kind, unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_r2r_1d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_r2r_2d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_r2r_3d
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_r2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plan a real input/output (r2r) transform of various kinds in zero or
							 | 
						||
| 
								 | 
							
								more dimensions, returning an @code{fftw_plan} (@pxref{Using Plans}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Once you have created a plan for a certain transform type and
							 | 
						||
| 
								 | 
							
								parameters, then creating another plan of the same type and parameters,
							 | 
						||
| 
								 | 
							
								but for different arrays, is fast and shares constant data with the
							 | 
						||
| 
								 | 
							
								first plan (if it still exists).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The planner returns @code{NULL} if the plan cannot be created.  A
							 | 
						||
| 
								 | 
							
								non-@code{NULL} plan is always returned by the basic interface unless
							 | 
						||
| 
								 | 
							
								you are using a customized FFTW configuration supporting a restricted
							 | 
						||
| 
								 | 
							
								set of transforms, or for size-1 @code{FFTW_REDFT00} kinds (which are
							 | 
						||
| 
								 | 
							
								not defined).
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_REDFT00
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Arguments
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{rank} is the dimensionality of the transform (it should be the
							 | 
						||
| 
								 | 
							
								size of the arrays @code{*n} and @code{*kind}), and can be any
							 | 
						||
| 
								 | 
							
								non-negative integer.  The @samp{_1d}, @samp{_2d}, and @samp{_3d}
							 | 
						||
| 
								 | 
							
								planners correspond to a @code{rank} of @code{1}, @code{2}, and
							 | 
						||
| 
								 | 
							
								@code{3}, respectively.  A @code{rank} of zero is equivalent to a copy
							 | 
						||
| 
								 | 
							
								of one number from input to output.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{n}, or @code{n0}/@code{n1}/@code{n2}, or @code{n[rank]},
							 | 
						||
| 
								 | 
							
								respectively, gives the (physical) size of the transform dimensions.
							 | 
						||
| 
								 | 
							
								They can be any positive integer.
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								@itemize @minus
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@cindex row-major
							 | 
						||
| 
								 | 
							
								Multi-dimensional arrays are stored in row-major order with dimensions:
							 | 
						||
| 
								 | 
							
								@code{n0} x @code{n1}; or @code{n0} x @code{n1} x @code{n2}; or
							 | 
						||
| 
								 | 
							
								@code{n[0]} x @code{n[1]} x ... x @code{n[rank-1]}.
							 | 
						||
| 
								 | 
							
								@xref{Multi-dimensional Array Format}.
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								FFTW is generally best at handling sizes of the form
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@math{2^a 3^b 5^c 7^d 11^e 13^f},
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$2^a 3^b 5^c 7^d 11^e 13^f$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								2<sup>a</sup> 3<sup>b</sup> 5<sup>c</sup> 7<sup>d</sup>
							 | 
						||
| 
								 | 
							
								        11<sup>e</sup> 13<sup>f</sup>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where @math{e+f} is either @math{0} or @math{1}, and the other exponents
							 | 
						||
| 
								 | 
							
								are arbitrary.  Other sizes are computed by means of a slow,
							 | 
						||
| 
								 | 
							
								general-purpose algorithm (which nevertheless retains @Onlogn{} performance even for prime sizes).  (It is possible to customize FFTW
							 | 
						||
| 
								 | 
							
								for different array sizes; see @ref{Installation and Customization}.)
							 | 
						||
| 
								 | 
							
								Transforms whose sizes are powers of @math{2} are especially fast.
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								For a @code{REDFT00} or @code{RODFT00} transform kind in a dimension of
							 | 
						||
| 
								 | 
							
								size @math{n}, it is @math{n-1} or @math{n+1}, respectively, that
							 | 
						||
| 
								 | 
							
								should be factorizable in the above form.
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out} point to the input and output arrays of the
							 | 
						||
| 
								 | 
							
								transform, which may be the same (yielding an in-place transform).
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								These arrays are overwritten during planning, unless
							 | 
						||
| 
								 | 
							
								@code{FFTW_ESTIMATE} is used in the flags.  (The arrays need not be
							 | 
						||
| 
								 | 
							
								initialized, but they must be allocated.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@code{kind}, or @code{kind0}/@code{kind1}/@code{kind2}, or
							 | 
						||
| 
								 | 
							
								@code{kind[rank]}, is the kind of r2r transform used for the
							 | 
						||
| 
								 | 
							
								corresponding dimension.  The valid kind constants are described in
							 | 
						||
| 
								 | 
							
								@ref{Real-to-Real Transform Kinds}.  In a multi-dimensional transform,
							 | 
						||
| 
								 | 
							
								what is computed is the separable product formed by taking each
							 | 
						||
| 
								 | 
							
								transform kind along the corresponding dimension, one dimension after
							 | 
						||
| 
								 | 
							
								another.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Real-to-Real Transform Kinds,  , Real-to-Real Transforms, Basic Interface
							 | 
						||
| 
								 | 
							
								@subsection Real-to-Real Transform Kinds
							 | 
						||
| 
								 | 
							
								@cindex kind (r2r)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW currently supports 11 different r2r transform kinds, specified by
							 | 
						||
| 
								 | 
							
								one of the constants below.  For the precise definitions of these
							 | 
						||
| 
								 | 
							
								transforms, see @ref{What FFTW Really Computes}.  For a more colloquial
							 | 
						||
| 
								 | 
							
								introduction to these transform kinds, see @ref{More DFTs of Real Data}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For dimension of size @code{n}, there is a corresponding ``logical''
							 | 
						||
| 
								 | 
							
								dimension @code{N} that determines the normalization (and the optimal
							 | 
						||
| 
								 | 
							
								factorization); the formula for @code{N} is given for each kind below.
							 | 
						||
| 
								 | 
							
								Also, with each transform kind is listed its corrsponding inverse
							 | 
						||
| 
								 | 
							
								transform.  FFTW computes unnormalized transforms: a transform followed
							 | 
						||
| 
								 | 
							
								by its inverse will result in the original data multiplied by @code{N}
							 | 
						||
| 
								 | 
							
								(or the product of the @code{N}'s for each dimension, in
							 | 
						||
| 
								 | 
							
								multi-dimensions).
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_R2HC
							 | 
						||
| 
								 | 
							
								@code{FFTW_R2HC} computes a real-input DFT with output in
							 | 
						||
| 
								 | 
							
								``halfcomplex'' format, i.e. real and imaginary parts for a transform of
							 | 
						||
| 
								 | 
							
								size @code{n} stored as:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								r_0, r_1, r_2, \ldots, r_{n/2}, i_{(n+1)/2-1}, \ldots, i_2, i_1
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								r0, r1, r2, r(n/2), i((n+1)/2-1), ..., i2, i1
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<p align=center>
							 | 
						||
| 
								 | 
							
								r<sub>0</sub>, r<sub>1</sub>, r<sub>2</sub>, ..., r<sub>n/2</sub>, i<sub>(n+1)/2-1</sub>, ..., i<sub>2</sub>, i<sub>1</sub>
							 | 
						||
| 
								 | 
							
								</p>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								(Logical @code{N=n}, inverse is @code{FFTW_HC2R}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_HC2R
							 | 
						||
| 
								 | 
							
								@code{FFTW_HC2R} computes the reverse of @code{FFTW_R2HC}, above.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=n}, inverse is @code{FFTW_R2HC}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_DHT
							 | 
						||
| 
								 | 
							
								@code{FFTW_DHT} computes a discrete Hartley transform.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=n}, inverse is @code{FFTW_DHT}.)
							 | 
						||
| 
								 | 
							
								@cindex discrete Hartley transform
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_REDFT00
							 | 
						||
| 
								 | 
							
								@code{FFTW_REDFT00} computes an REDFT00 transform, i.e. a DCT-I.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*(n-1)}, inverse is @code{FFTW_REDFT00}.)
							 | 
						||
| 
								 | 
							
								@cindex discrete cosine transform
							 | 
						||
| 
								 | 
							
								@cindex DCT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_REDFT10
							 | 
						||
| 
								 | 
							
								@code{FFTW_REDFT10} computes an REDFT10 transform, i.e. a DCT-II (sometimes called ``the'' DCT).
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_REDFT01}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_REDFT01
							 | 
						||
| 
								 | 
							
								@code{FFTW_REDFT01} computes an REDFT01 transform, i.e. a DCT-III (sometimes called ``the'' IDCT, being the inverse of DCT-II).
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_REDFT=10}.)
							 | 
						||
| 
								 | 
							
								@cindex IDCT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_REDFT11
							 | 
						||
| 
								 | 
							
								@code{FFTW_REDFT11} computes an REDFT11 transform, i.e. a DCT-IV.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_REDFT11}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_RODFT00
							 | 
						||
| 
								 | 
							
								@code{FFTW_RODFT00} computes an RODFT00 transform, i.e. a DST-I.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*(n+1)}, inverse is @code{FFTW_RODFT00}.)
							 | 
						||
| 
								 | 
							
								@cindex discrete sine transform
							 | 
						||
| 
								 | 
							
								@cindex DST
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_RODFT10
							 | 
						||
| 
								 | 
							
								@code{FFTW_RODFT10} computes an RODFT10 transform, i.e. a DST-II.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_RODFT01}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_RODFT01
							 | 
						||
| 
								 | 
							
								@code{FFTW_RODFT01} computes an RODFT01 transform, i.e. a DST-III.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_RODFT=10}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_RODFT11
							 | 
						||
| 
								 | 
							
								@code{FFTW_RODFT11} computes an RODFT11 transform, i.e. a DST-IV.
							 | 
						||
| 
								 | 
							
								(Logical @code{N=2*n}, inverse is @code{FFTW_RODFT11}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Advanced Interface, Guru Interface, Basic Interface, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Advanced Interface
							 | 
						||
| 
								 | 
							
								@cindex advanced interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW's ``advanced'' interface supplements the basic interface with four
							 | 
						||
| 
								 | 
							
								new planner routines, providing a new level of flexibility: you can plan
							 | 
						||
| 
								 | 
							
								a transform of multiple arrays simultaneously, operate on non-contiguous
							 | 
						||
| 
								 | 
							
								(strided) data, and transform a subset of a larger multi-dimensional
							 | 
						||
| 
								 | 
							
								array.  Other than these additional features, the planner operates in
							 | 
						||
| 
								 | 
							
								the same fashion as in the basic interface, and the resulting
							 | 
						||
| 
								 | 
							
								@code{fftw_plan} is used in the same way (@pxref{Using Plans}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Advanced Complex DFTs::
							 | 
						||
| 
								 | 
							
								* Advanced Real-data DFTs::
							 | 
						||
| 
								 | 
							
								* Advanced Real-to-real Transforms::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Advanced Complex DFTs, Advanced Real-data DFTs, Advanced Interface, Advanced Interface
							 | 
						||
| 
								 | 
							
								@subsection Advanced Complex DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_many_dft(int rank, const int *n, int howmany,
							 | 
						||
| 
								 | 
							
								                             fftw_complex *in, const int *inembed,
							 | 
						||
| 
								 | 
							
								                             int istride, int idist,
							 | 
						||
| 
								 | 
							
								                             fftw_complex *out, const int *onembed,
							 | 
						||
| 
								 | 
							
								                             int ostride, int odist,
							 | 
						||
| 
								 | 
							
								                             int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_many_dft
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This routine plans multiple multidimensional complex DFTs, and it
							 | 
						||
| 
								 | 
							
								extends the @code{fftw_plan_dft} routine (@pxref{Complex DFTs}) to
							 | 
						||
| 
								 | 
							
								compute @code{howmany} transforms, each having rank @code{rank} and size
							 | 
						||
| 
								 | 
							
								@code{n}.  In addition, the transform data need not be contiguous, but
							 | 
						||
| 
								 | 
							
								it may be laid out in memory with an arbitrary stride.  To account for
							 | 
						||
| 
								 | 
							
								these possibilities, @code{fftw_plan_many_dft} adds the new parameters
							 | 
						||
| 
								 | 
							
								@code{howmany}, @{@code{i},@code{o}@}@code{nembed},
							 | 
						||
| 
								 | 
							
								@{@code{i},@code{o}@}@code{stride}, and
							 | 
						||
| 
								 | 
							
								@{@code{i},@code{o}@}@code{dist}.  The FFTW basic interface
							 | 
						||
| 
								 | 
							
								(@pxref{Complex DFTs}) provides routines specialized for ranks 1, 2,
							 | 
						||
| 
								 | 
							
								and@tie{}3, but the advanced interface handles only the general-rank
							 | 
						||
| 
								 | 
							
								case.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{howmany} is the (nonnegative) number of transforms to compute.  The resulting
							 | 
						||
| 
								 | 
							
								plan computes @code{howmany} transforms, where the input of the
							 | 
						||
| 
								 | 
							
								@code{k}-th transform is at location @code{in+k*idist} (in C pointer
							 | 
						||
| 
								 | 
							
								arithmetic), and its output is at location @code{out+k*odist}.  Plans
							 | 
						||
| 
								 | 
							
								obtained in this way can often be faster than calling FFTW multiple
							 | 
						||
| 
								 | 
							
								times for the individual transforms.  The basic @code{fftw_plan_dft}
							 | 
						||
| 
								 | 
							
								interface corresponds to @code{howmany=1} (in which case the @code{dist}
							 | 
						||
| 
								 | 
							
								parameters are ignored).
							 | 
						||
| 
								 | 
							
								@cindex howmany parameter
							 | 
						||
| 
								 | 
							
								@cindex dist
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Each of the @code{howmany} transforms has rank @code{rank} and size
							 | 
						||
| 
								 | 
							
								@code{n}, as in the basic interface.  In addition, the advanced
							 | 
						||
| 
								 | 
							
								interface allows the input and output arrays of each transform to be
							 | 
						||
| 
								 | 
							
								row-major subarrays of larger rank-@code{rank} arrays, described by
							 | 
						||
| 
								 | 
							
								@code{inembed} and @code{onembed} parameters, respectively.
							 | 
						||
| 
								 | 
							
								@{@code{i},@code{o}@}@code{nembed} must be arrays of length @code{rank},
							 | 
						||
| 
								 | 
							
								and @code{n} should be elementwise less than or equal to
							 | 
						||
| 
								 | 
							
								@{@code{i},@code{o}@}@code{nembed}.  Passing @code{NULL} for an
							 | 
						||
| 
								 | 
							
								@code{nembed} parameter is equivalent to passing @code{n} (i.e. same
							 | 
						||
| 
								 | 
							
								physical and logical dimensions, as in the basic interface.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @code{stride} parameters indicate that the @code{j}-th element of
							 | 
						||
| 
								 | 
							
								the input or output arrays is located at @code{j*istride} or
							 | 
						||
| 
								 | 
							
								@code{j*ostride}, respectively.  (For a multi-dimensional array,
							 | 
						||
| 
								 | 
							
								@code{j} is the ordinary row-major index.)  When combined with the
							 | 
						||
| 
								 | 
							
								@code{k}-th transform in a @code{howmany} loop, from above, this means
							 | 
						||
| 
								 | 
							
								that the (@code{j},@code{k})-th element is at @code{j*stride+k*dist}.
							 | 
						||
| 
								 | 
							
								(The basic @code{fftw_plan_dft} interface corresponds to a stride of 1.)
							 | 
						||
| 
								 | 
							
								@cindex stride
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For in-place transforms, the input and output @code{stride} and
							 | 
						||
| 
								 | 
							
								@code{dist} parameters should be the same; otherwise, the planner may
							 | 
						||
| 
								 | 
							
								return @code{NULL}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Arrays @code{n}, @code{inembed}, and @code{onembed} are not used after
							 | 
						||
| 
								 | 
							
								this function returns.  You can safely free or reuse them.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@strong{Examples}:
							 | 
						||
| 
								 | 
							
								One transform of one 5 by 6 array contiguous in memory:
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								   int rank = 2;
							 | 
						||
| 
								 | 
							
								   int n[] = @{5, 6@};
							 | 
						||
| 
								 | 
							
								   int howmany = 1;
							 | 
						||
| 
								 | 
							
								   int idist = odist = 0; /* unused because howmany = 1 */
							 | 
						||
| 
								 | 
							
								   int istride = ostride = 1; /* array is contiguous in memory */
							 | 
						||
| 
								 | 
							
								   int *inembed = n, *onembed = n;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Transform of three 5 by 6 arrays, each contiguous in memory,
							 | 
						||
| 
								 | 
							
								stored in memory one after another:
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								   int rank = 2;
							 | 
						||
| 
								 | 
							
								   int n[] = @{5, 6@};
							 | 
						||
| 
								 | 
							
								   int howmany = 3;
							 | 
						||
| 
								 | 
							
								   int idist = odist = n[0]*n[1]; /* = 30, the distance in memory
							 | 
						||
| 
								 | 
							
								                                     between the first element
							 | 
						||
| 
								 | 
							
								                                     of the first array and the
							 | 
						||
| 
								 | 
							
								                                     first element of the second array */
							 | 
						||
| 
								 | 
							
								   int istride = ostride = 1; /* array is contiguous in memory */
							 | 
						||
| 
								 | 
							
								   int *inembed = n, *onembed = n;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Transform each column of a 2d array with 10 rows and 3 columns:
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								   int rank = 1; /* not 2: we are computing 1d transforms */
							 | 
						||
| 
								 | 
							
								   int n[] = @{10@}; /* 1d transforms of length 10 */
							 | 
						||
| 
								 | 
							
								   int howmany = 3;
							 | 
						||
| 
								 | 
							
								   int idist = odist = 1;
							 | 
						||
| 
								 | 
							
								   int istride = ostride = 3; /* distance between two elements in 
							 | 
						||
| 
								 | 
							
								                                 the same column */
							 | 
						||
| 
								 | 
							
								   int *inembed = n, *onembed = n;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Advanced Real-data DFTs, Advanced Real-to-real Transforms, Advanced Complex DFTs, Advanced Interface
							 | 
						||
| 
								 | 
							
								@subsection Advanced Real-data DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_many_dft_r2c(int rank, const int *n, int howmany,
							 | 
						||
| 
								 | 
							
								                                 double *in, const int *inembed,
							 | 
						||
| 
								 | 
							
								                                 int istride, int idist,
							 | 
						||
| 
								 | 
							
								                                 fftw_complex *out, const int *onembed,
							 | 
						||
| 
								 | 
							
								                                 int ostride, int odist,
							 | 
						||
| 
								 | 
							
								                                 unsigned flags);
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_many_dft_c2r(int rank, const int *n, int howmany,
							 | 
						||
| 
								 | 
							
								                                 fftw_complex *in, const int *inembed,
							 | 
						||
| 
								 | 
							
								                                 int istride, int idist,
							 | 
						||
| 
								 | 
							
								                                 double *out, const int *onembed,
							 | 
						||
| 
								 | 
							
								                                 int ostride, int odist,
							 | 
						||
| 
								 | 
							
								                                 unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_many_dft_r2c
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_many_dft_c2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Like @code{fftw_plan_many_dft}, these two functions add @code{howmany},
							 | 
						||
| 
								 | 
							
								@code{nembed}, @code{stride}, and @code{dist} parameters to the
							 | 
						||
| 
								 | 
							
								@code{fftw_plan_dft_r2c} and @code{fftw_plan_dft_c2r} functions, but
							 | 
						||
| 
								 | 
							
								otherwise behave the same as the basic interface.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The interpretation of @code{howmany}, @code{stride}, and @code{dist} are
							 | 
						||
| 
								 | 
							
								the same as for @code{fftw_plan_many_dft}, above.  Note that the
							 | 
						||
| 
								 | 
							
								@code{stride} and @code{dist} for the real array are in units of
							 | 
						||
| 
								 | 
							
								@code{double}, and for the complex array are in units of
							 | 
						||
| 
								 | 
							
								@code{fftw_complex}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If an @code{nembed} parameter is @code{NULL}, it is interpreted as what
							 | 
						||
| 
								 | 
							
								it would be in the basic interface, as described in @ref{Real-data DFT
							 | 
						||
| 
								 | 
							
								Array Format}.  That is, for the complex array the size is assumed to be
							 | 
						||
| 
								 | 
							
								the same as @code{n}, but with the last dimension cut roughly in half.
							 | 
						||
| 
								 | 
							
								For the real array, the size is assumed to be @code{n} if the transform
							 | 
						||
| 
								 | 
							
								is out-of-place, or @code{n} with the last dimension ``padded'' if the
							 | 
						||
| 
								 | 
							
								transform is in-place.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If an @code{nembed} parameter is non-@code{NULL}, it is interpreted as
							 | 
						||
| 
								 | 
							
								the physical size of the corresponding array, in row-major order, just
							 | 
						||
| 
								 | 
							
								as for @code{fftw_plan_many_dft}.  In this case, each dimension of
							 | 
						||
| 
								 | 
							
								@code{nembed} should be @code{>=} what it would be in the basic
							 | 
						||
| 
								 | 
							
								interface (e.g. the halved or padded @code{n}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Arrays @code{n}, @code{inembed}, and @code{onembed} are not used after
							 | 
						||
| 
								 | 
							
								this function returns.  You can safely free or reuse them.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Advanced Real-to-real Transforms,  , Advanced Real-data DFTs, Advanced Interface
							 | 
						||
| 
								 | 
							
								@subsection Advanced Real-to-real Transforms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_many_r2r(int rank, const int *n, int howmany,
							 | 
						||
| 
								 | 
							
								                             double *in, const int *inembed,
							 | 
						||
| 
								 | 
							
								                             int istride, int idist,
							 | 
						||
| 
								 | 
							
								                             double *out, const int *onembed,
							 | 
						||
| 
								 | 
							
								                             int ostride, int odist,
							 | 
						||
| 
								 | 
							
								                             const fftw_r2r_kind *kind, unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_many_r2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Like @code{fftw_plan_many_dft}, this functions adds @code{howmany},
							 | 
						||
| 
								 | 
							
								@code{nembed}, @code{stride}, and @code{dist} parameters to the
							 | 
						||
| 
								 | 
							
								@code{fftw_plan_r2r} function, but otherwise behave the same as the
							 | 
						||
| 
								 | 
							
								basic interface.  The interpretation of those additional parameters are
							 | 
						||
| 
								 | 
							
								the same as for @code{fftw_plan_many_dft}.  (Of course, the
							 | 
						||
| 
								 | 
							
								@code{stride} and @code{dist} parameters are now in units of
							 | 
						||
| 
								 | 
							
								@code{double}, not @code{fftw_complex}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Arrays @code{n}, @code{inembed}, @code{onembed}, and @code{kind} are not
							 | 
						||
| 
								 | 
							
								used after this function returns.  You can safely free or reuse them.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Guru Interface, New-array Execute Functions, Advanced Interface, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Guru Interface
							 | 
						||
| 
								 | 
							
								@cindex guru interface
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The ``guru'' interface to FFTW is intended to expose as much as possible
							 | 
						||
| 
								 | 
							
								of the flexibility in the underlying FFTW architecture.  It allows one
							 | 
						||
| 
								 | 
							
								to compute multi-dimensional ``vectors'' (loops) of multi-dimensional
							 | 
						||
| 
								 | 
							
								transforms, where each vector/transform dimension has an independent
							 | 
						||
| 
								 | 
							
								size and stride.
							 | 
						||
| 
								 | 
							
								@cindex vector
							 | 
						||
| 
								 | 
							
								One can also use more general complex-number formats, e.g. separate real
							 | 
						||
| 
								 | 
							
								and imaginary arrays.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For those users who require the flexibility of the guru interface, it is
							 | 
						||
| 
								 | 
							
								important that they pay special attention to the documentation lest they
							 | 
						||
| 
								 | 
							
								shoot themselves in the foot.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Interleaved and split arrays::
							 | 
						||
| 
								 | 
							
								* Guru vector and transform sizes::
							 | 
						||
| 
								 | 
							
								* Guru Complex DFTs::
							 | 
						||
| 
								 | 
							
								* Guru Real-data DFTs::
							 | 
						||
| 
								 | 
							
								* Guru Real-to-real Transforms::
							 | 
						||
| 
								 | 
							
								* 64-bit Guru Interface::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node  Interleaved and split arrays, Guru vector and transform sizes, Guru Interface, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection Interleaved and split arrays
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The guru interface supports two representations of complex numbers,
							 | 
						||
| 
								 | 
							
								which we call the interleaved and the split format.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @dfn{interleaved} format is the same one used by the basic and
							 | 
						||
| 
								 | 
							
								advanced interfaces, and it is documented in @ref{Complex numbers}.
							 | 
						||
| 
								 | 
							
								In the interleaved format, you provide pointers to the real part of a
							 | 
						||
| 
								 | 
							
								complex number, and the imaginary part understood to be stored in the
							 | 
						||
| 
								 | 
							
								next memory location.
							 | 
						||
| 
								 | 
							
								@cindex interleaved format
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @dfn{split} format allows separate pointers to the real and
							 | 
						||
| 
								 | 
							
								imaginary parts of a complex array.
							 | 
						||
| 
								 | 
							
								@cindex split format
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Technically, the interleaved format is redundant, because you can
							 | 
						||
| 
								 | 
							
								always express an interleaved array in terms of a split array with
							 | 
						||
| 
								 | 
							
								appropriate pointers and strides.  On the other hand, the interleaved
							 | 
						||
| 
								 | 
							
								format is simpler to use, and it is common in practice.  Hence, FFTW
							 | 
						||
| 
								 | 
							
								supports it as a special case.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Guru vector and transform sizes, Guru Complex DFTs, Interleaved and split arrays, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection Guru vector and transform sizes
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The guru interface introduces one basic new data structure,
							 | 
						||
| 
								 | 
							
								@code{fftw_iodim}, that is used to specify sizes and strides for
							 | 
						||
| 
								 | 
							
								multi-dimensional transforms and vectors:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								typedef struct @{
							 | 
						||
| 
								 | 
							
								     int n;
							 | 
						||
| 
								 | 
							
								     int is;
							 | 
						||
| 
								 | 
							
								     int os;
							 | 
						||
| 
								 | 
							
								@} fftw_iodim;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@tindex fftw_iodim
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Here, @code{n} is the size of the dimension, and @code{is} and @code{os}
							 | 
						||
| 
								 | 
							
								are the strides of that dimension for the input and output arrays.  (The
							 | 
						||
| 
								 | 
							
								stride is the separation of consecutive elements along this dimension.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The meaning of the stride parameter depends on the type of the array
							 | 
						||
| 
								 | 
							
								that the stride refers to.  @emph{If the array is interleaved complex,
							 | 
						||
| 
								 | 
							
								strides are expressed in units of complex numbers
							 | 
						||
| 
								 | 
							
								(@code{fftw_complex}).  If the array is split complex or real, strides
							 | 
						||
| 
								 | 
							
								are expressed in units of real numbers (@code{double}).}  This
							 | 
						||
| 
								 | 
							
								convention is consistent with the usual pointer arithmetic in the C
							 | 
						||
| 
								 | 
							
								language.  An interleaved array is denoted by a pointer @code{p} to
							 | 
						||
| 
								 | 
							
								@code{fftw_complex}, so that @code{p+1} points to the next complex
							 | 
						||
| 
								 | 
							
								number.  Split arrays are denoted by pointers to @code{double}, in
							 | 
						||
| 
								 | 
							
								which case pointer arithmetic operates in units of
							 | 
						||
| 
								 | 
							
								@code{sizeof(double)}.
							 | 
						||
| 
								 | 
							
								@cindex stride
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The guru planner interfaces all take a (@code{rank}, @code{dims[rank]})
							 | 
						||
| 
								 | 
							
								pair describing the transform size, and a (@code{howmany_rank},
							 | 
						||
| 
								 | 
							
								@code{howmany_dims[howmany_rank]}) pair describing the ``vector'' size (a
							 | 
						||
| 
								 | 
							
								multi-dimensional loop of transforms to perform), where @code{dims} and
							 | 
						||
| 
								 | 
							
								@code{howmany_dims} are arrays of @code{fftw_iodim}.  Each @code{n} field must
							 | 
						||
| 
								 | 
							
								be positive for @code{dims} and nonnegative for @code{howmany_dims}, while both
							 | 
						||
| 
								 | 
							
								@code{rank} and @code{howmany_rank} must be nonnegative.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For example, the @code{howmany} parameter in the advanced complex-DFT
							 | 
						||
| 
								 | 
							
								interface corresponds to @code{howmany_rank} = 1,
							 | 
						||
| 
								 | 
							
								@code{howmany_dims[0].n} = @code{howmany}, @code{howmany_dims[0].is} =
							 | 
						||
| 
								 | 
							
								@code{idist}, and @code{howmany_dims[0].os} = @code{odist}.
							 | 
						||
| 
								 | 
							
								@cindex howmany loop
							 | 
						||
| 
								 | 
							
								@cindex dist
							 | 
						||
| 
								 | 
							
								(To compute a single transform, you can just use @code{howmany_rank} = 0.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A row-major multidimensional array with dimensions @code{n[rank]}
							 | 
						||
| 
								 | 
							
								(@pxref{Row-major Format}) corresponds to @code{dims[i].n} =
							 | 
						||
| 
								 | 
							
								@code{n[i]} and the recurrence @code{dims[i].is} = @code{n[i+1] *
							 | 
						||
| 
								 | 
							
								dims[i+1].is} (similarly for @code{os}).  The stride of the last
							 | 
						||
| 
								 | 
							
								(@code{i=rank-1}) dimension is the overall stride of the array.
							 | 
						||
| 
								 | 
							
								e.g. to be equivalent to the advanced complex-DFT interface, you would
							 | 
						||
| 
								 | 
							
								have @code{dims[rank-1].is} = @code{istride} and
							 | 
						||
| 
								 | 
							
								@code{dims[rank-1].os} = @code{ostride}.
							 | 
						||
| 
								 | 
							
								@cindex row-major
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In general, we only guarantee FFTW to return a non-@code{NULL} plan if
							 | 
						||
| 
								 | 
							
								the vector and transform dimensions correspond to a set of distinct
							 | 
						||
| 
								 | 
							
								indices, and for in-place transforms the input/output strides should
							 | 
						||
| 
								 | 
							
								be the same.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Guru Complex DFTs, Guru Real-data DFTs, Guru vector and transform sizes, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection Guru Complex DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_dft(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								     int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_split_dft(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     double *ri, double *ii, double *ro, double *io,
							 | 
						||
| 
								 | 
							
								     unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_dft
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_split_dft
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These two functions plan a complex-data, multi-dimensional DFT
							 | 
						||
| 
								 | 
							
								for the interleaved and split format, respectively.
							 | 
						||
| 
								 | 
							
								Transform dimensions are given by (@code{rank}, @code{dims}) over a
							 | 
						||
| 
								 | 
							
								multi-dimensional vector (loop) of dimensions (@code{howmany_rank},
							 | 
						||
| 
								 | 
							
								@code{howmany_dims}).  @code{dims} and @code{howmany_dims} should point
							 | 
						||
| 
								 | 
							
								to @code{fftw_iodim} arrays of length @code{rank} and
							 | 
						||
| 
								 | 
							
								@code{howmany_rank}, respectively.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In the @code{fftw_plan_guru_dft} function, the pointers @code{in} and
							 | 
						||
| 
								 | 
							
								@code{out} point to the interleaved input and output arrays,
							 | 
						||
| 
								 | 
							
								respectively.  The sign can be either @math{-1} (=
							 | 
						||
| 
								 | 
							
								@code{FFTW_FORWARD}) or @math{+1} (= @code{FFTW_BACKWARD}).  If the
							 | 
						||
| 
								 | 
							
								pointers are equal, the transform is in-place.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In the @code{fftw_plan_guru_split_dft} function,
							 | 
						||
| 
								 | 
							
								@code{ri} and @code{ii} point to the real and imaginary input arrays,
							 | 
						||
| 
								 | 
							
								and @code{ro} and @code{io} point to the real and imaginary output
							 | 
						||
| 
								 | 
							
								arrays.  The input and output pointers may be the same, indicating an
							 | 
						||
| 
								 | 
							
								in-place transform.  For example, for @code{fftw_complex} pointers
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out}, the corresponding parameters are:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								ri = (double *) in;
							 | 
						||
| 
								 | 
							
								ii = (double *) in + 1;
							 | 
						||
| 
								 | 
							
								ro = (double *) out;
							 | 
						||
| 
								 | 
							
								io = (double *) out + 1;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Because @code{fftw_plan_guru_split_dft} accepts split arrays, strides
							 | 
						||
| 
								 | 
							
								are expressed in units of @code{double}.  For a contiguous
							 | 
						||
| 
								 | 
							
								@code{fftw_complex} array, the overall stride of the transform should
							 | 
						||
| 
								 | 
							
								be 2, the distance between consecutive real parts or between
							 | 
						||
| 
								 | 
							
								consecutive imaginary parts; see @ref{Guru vector and transform
							 | 
						||
| 
								 | 
							
								sizes}.  Note that the dimension strides are applied equally to the
							 | 
						||
| 
								 | 
							
								real and imaginary parts; real and imaginary arrays with different
							 | 
						||
| 
								 | 
							
								strides are not supported.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There is no @code{sign} parameter in @code{fftw_plan_guru_split_dft}.
							 | 
						||
| 
								 | 
							
								This function always plans for an @code{FFTW_FORWARD} transform.  To
							 | 
						||
| 
								 | 
							
								plan for an @code{FFTW_BACKWARD} transform, you can exploit the
							 | 
						||
| 
								 | 
							
								identity that the backwards DFT is equal to the forwards DFT with the
							 | 
						||
| 
								 | 
							
								real and imaginary parts swapped.  For example, in the case of the
							 | 
						||
| 
								 | 
							
								@code{fftw_complex} arrays above, the @code{FFTW_BACKWARD} transform
							 | 
						||
| 
								 | 
							
								is computed by the parameters:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								ri = (double *) in + 1;
							 | 
						||
| 
								 | 
							
								ii = (double *) in;
							 | 
						||
| 
								 | 
							
								ro = (double *) out + 1;
							 | 
						||
| 
								 | 
							
								io = (double *) out;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Guru Real-data DFTs, Guru Real-to-real Transforms, Guru Complex DFTs, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection Guru Real-data DFTs
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_dft_r2c(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     double *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								     unsigned flags);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_split_dft_r2c(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     double *in, double *ro, double *io,
							 | 
						||
| 
								 | 
							
								     unsigned flags);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_dft_c2r(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     fftw_complex *in, double *out,
							 | 
						||
| 
								 | 
							
								     unsigned flags);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_split_dft_c2r(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								     double *ri, double *ii, double *out,
							 | 
						||
| 
								 | 
							
								     unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_dft_r2c
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_split_dft_r2c
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_dft_c2r
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_split_dft_c2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plan a real-input (r2c) or real-output (c2r), multi-dimensional DFT with
							 | 
						||
| 
								 | 
							
								transform dimensions given by (@code{rank}, @code{dims}) over a
							 | 
						||
| 
								 | 
							
								multi-dimensional vector (loop) of dimensions (@code{howmany_rank},
							 | 
						||
| 
								 | 
							
								@code{howmany_dims}).  @code{dims} and @code{howmany_dims} should point
							 | 
						||
| 
								 | 
							
								to @code{fftw_iodim} arrays of length @code{rank} and
							 | 
						||
| 
								 | 
							
								@code{howmany_rank}, respectively.  As for the basic and advanced
							 | 
						||
| 
								 | 
							
								interfaces, an r2c transform is @code{FFTW_FORWARD} and a c2r transform
							 | 
						||
| 
								 | 
							
								is @code{FFTW_BACKWARD}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @emph{last} dimension of @code{dims} is interpreted specially:
							 | 
						||
| 
								 | 
							
								that dimension of the real array has size @code{dims[rank-1].n}, but
							 | 
						||
| 
								 | 
							
								that dimension of the complex array has size @code{dims[rank-1].n/2+1}
							 | 
						||
| 
								 | 
							
								(division rounded down).  The strides, on the other hand, are taken to
							 | 
						||
| 
								 | 
							
								be exactly as specified.  It is up to the user to specify the strides
							 | 
						||
| 
								 | 
							
								appropriately for the peculiar dimensions of the data, and we do not
							 | 
						||
| 
								 | 
							
								guarantee that the planner will succeed (return non-@code{NULL}) for
							 | 
						||
| 
								 | 
							
								any dimensions other than those described in @ref{Real-data DFT Array
							 | 
						||
| 
								 | 
							
								Format} and generalized in @ref{Advanced Real-data DFTs}.  (That is,
							 | 
						||
| 
								 | 
							
								for an in-place transform, each individual dimension should be able to
							 | 
						||
| 
								 | 
							
								operate in place.)
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out} point to the input and output arrays for r2c
							 | 
						||
| 
								 | 
							
								and c2r transforms, respectively.  For split arrays, @code{ri} and
							 | 
						||
| 
								 | 
							
								@code{ii} point to the real and imaginary input arrays for a c2r
							 | 
						||
| 
								 | 
							
								transform, and @code{ro} and @code{io} point to the real and imaginary
							 | 
						||
| 
								 | 
							
								output arrays for an r2c transform.  @code{in} and @code{ro} or
							 | 
						||
| 
								 | 
							
								@code{ri} and @code{out} may be the same, indicating an in-place
							 | 
						||
| 
								 | 
							
								transform.   (In-place transforms where @code{in} and @code{io} or
							 | 
						||
| 
								 | 
							
								@code{ii} and @code{out} are the same are not currently supported.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In-place transforms of rank greater than 1 are currently only
							 | 
						||
| 
								 | 
							
								supported for interleaved arrays.  For split arrays, the planner will
							 | 
						||
| 
								 | 
							
								return @code{NULL}.
							 | 
						||
| 
								 | 
							
								@cindex in-place
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Guru Real-to-real Transforms, 64-bit Guru Interface, Guru Real-data DFTs, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection Guru Real-to-real Transforms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru_r2r(int rank, const fftw_iodim *dims,
							 | 
						||
| 
								 | 
							
								                             int howmany_rank,
							 | 
						||
| 
								 | 
							
								                             const fftw_iodim *howmany_dims,
							 | 
						||
| 
								 | 
							
								                             double *in, double *out,
							 | 
						||
| 
								 | 
							
								                             const fftw_r2r_kind *kind,
							 | 
						||
| 
								 | 
							
								                             unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru_r2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Plan a real-to-real (r2r) multi-dimensional @code{FFTW_FORWARD}
							 | 
						||
| 
								 | 
							
								transform with transform dimensions given by (@code{rank}, @code{dims})
							 | 
						||
| 
								 | 
							
								over a multi-dimensional vector (loop) of dimensions
							 | 
						||
| 
								 | 
							
								(@code{howmany_rank}, @code{howmany_dims}).  @code{dims} and
							 | 
						||
| 
								 | 
							
								@code{howmany_dims} should point to @code{fftw_iodim} arrays of length
							 | 
						||
| 
								 | 
							
								@code{rank} and @code{howmany_rank}, respectively.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The transform kind of each dimension is given by the @code{kind}
							 | 
						||
| 
								 | 
							
								parameter, which should point to an array of length @code{rank}.  Valid
							 | 
						||
| 
								 | 
							
								@code{fftw_r2r_kind} constants are given in @ref{Real-to-Real Transform
							 | 
						||
| 
								 | 
							
								Kinds}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{in} and @code{out} point to the real input and output arrays; they
							 | 
						||
| 
								 | 
							
								may be the same, indicating an in-place transform.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex flags
							 | 
						||
| 
								 | 
							
								@code{flags} is a bitwise OR (@samp{|}) of zero or more planner flags,
							 | 
						||
| 
								 | 
							
								as defined in @ref{Planner Flags}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node 64-bit Guru Interface,  , Guru Real-to-real Transforms, Guru Interface
							 | 
						||
| 
								 | 
							
								@subsection 64-bit Guru Interface
							 | 
						||
| 
								 | 
							
								@cindex 64-bit architecture
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								When compiled in 64-bit mode on a 64-bit architecture (where addresses
							 | 
						||
| 
								 | 
							
								are 64 bits wide), FFTW uses 64-bit quantities internally for all
							 | 
						||
| 
								 | 
							
								transform sizes, strides, and so on---you don't have to do anything
							 | 
						||
| 
								 | 
							
								special to exploit this.  However, in the ordinary FFTW interfaces,
							 | 
						||
| 
								 | 
							
								you specify the transform size by an @code{int} quantity, which is
							 | 
						||
| 
								 | 
							
								normally only 32 bits wide.  This means that, even though FFTW is
							 | 
						||
| 
								 | 
							
								using 64-bit sizes internally, you cannot specify a single transform
							 | 
						||
| 
								 | 
							
								dimension larger than
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								2^31-1
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								2<sup><small>31</small></sup>−1
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$2^{31}-1$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								numbers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We expect that few users will require transforms larger than this, but,
							 | 
						||
| 
								 | 
							
								for those who do, we provide a 64-bit version of the guru interface in
							 | 
						||
| 
								 | 
							
								which all sizes are specified as integers of type @code{ptrdiff_t}
							 | 
						||
| 
								 | 
							
								instead of @code{int}.  (@code{ptrdiff_t} is a signed integer type
							 | 
						||
| 
								 | 
							
								defined by the C standard to be wide enough to represent address
							 | 
						||
| 
								 | 
							
								differences, and thus must be at least 64 bits wide on a 64-bit
							 | 
						||
| 
								 | 
							
								machine.)  We stress that there is @emph{no performance advantage} to
							 | 
						||
| 
								 | 
							
								using this interface---the same internal FFTW code is employed
							 | 
						||
| 
								 | 
							
								regardless---and it is only necessary if you want to specify very
							 | 
						||
| 
								 | 
							
								large transform sizes.
							 | 
						||
| 
								 | 
							
								@tindex ptrdiff_t
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In particular, the 64-bit guru interface is a set of planner routines
							 | 
						||
| 
								 | 
							
								that are exactly the same as the guru planner routines, except that
							 | 
						||
| 
								 | 
							
								they are named with @samp{guru64} instead of @samp{guru} and they take
							 | 
						||
| 
								 | 
							
								arguments of type @code{fftw_iodim64} instead of @code{fftw_iodim}.
							 | 
						||
| 
								 | 
							
								For example, instead of @code{fftw_plan_guru_dft}, we have
							 | 
						||
| 
								 | 
							
								@code{fftw_plan_guru64_dft}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								fftw_plan fftw_plan_guru64_dft(
							 | 
						||
| 
								 | 
							
								     int rank, const fftw_iodim64 *dims,
							 | 
						||
| 
								 | 
							
								     int howmany_rank, const fftw_iodim64 *howmany_dims,
							 | 
						||
| 
								 | 
							
								     fftw_complex *in, fftw_complex *out,
							 | 
						||
| 
								 | 
							
								     int sign, unsigned flags);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_plan_guru64_dft
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @code{fftw_iodim64} type is similar to @code{fftw_iodim}, with the
							 | 
						||
| 
								 | 
							
								same interpretation, except that it uses type @code{ptrdiff_t} instead
							 | 
						||
| 
								 | 
							
								of type @code{int}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								typedef struct @{
							 | 
						||
| 
								 | 
							
								     ptrdiff_t n;
							 | 
						||
| 
								 | 
							
								     ptrdiff_t is;
							 | 
						||
| 
								 | 
							
								     ptrdiff_t os;
							 | 
						||
| 
								 | 
							
								@} fftw_iodim64;
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@tindex fftw_iodim64
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Every other @samp{fftw_plan_guru} function also has a
							 | 
						||
| 
								 | 
							
								@samp{fftw_plan_guru64} equivalent, but we do not repeat their
							 | 
						||
| 
								 | 
							
								documentation here since they are identical to the 32-bit versions
							 | 
						||
| 
								 | 
							
								except as noted above.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c -----------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node New-array Execute Functions, Wisdom, Guru Interface, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section New-array Execute Functions
							 | 
						||
| 
								 | 
							
								@cindex execute
							 | 
						||
| 
								 | 
							
								@cindex new-array execution
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Normally, one executes a plan for the arrays with which the plan was
							 | 
						||
| 
								 | 
							
								created, by calling @code{fftw_execute(plan)} as described in @ref{Using
							 | 
						||
| 
								 | 
							
								Plans}.
							 | 
						||
| 
								 | 
							
								@findex fftw_execute
							 | 
						||
| 
								 | 
							
								However, it is possible for sophisticated users to apply a given plan
							 | 
						||
| 
								 | 
							
								to a @emph{different} array using the ``new-array execute'' functions
							 | 
						||
| 
								 | 
							
								detailed below, provided that the following conditions are met:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@itemize @bullet
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								The array size, strides, etcetera are the same (since those are set by
							 | 
						||
| 
								 | 
							
								the plan).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								The input and output arrays are the same (in-place) or different
							 | 
						||
| 
								 | 
							
								(out-of-place) if the plan was originally created to be in-place or
							 | 
						||
| 
								 | 
							
								out-of-place, respectively.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								For split arrays, the separations between the real and imaginary
							 | 
						||
| 
								 | 
							
								parts, @code{ii-ri} and @code{io-ro}, are the same as they were for
							 | 
						||
| 
								 | 
							
								the input and output arrays when the plan was created.  (This
							 | 
						||
| 
								 | 
							
								condition is automatically satisfied for interleaved arrays.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@item
							 | 
						||
| 
								 | 
							
								The @dfn{alignment} of the new input/output arrays is the same as that
							 | 
						||
| 
								 | 
							
								of the input/output arrays when the plan was created, unless the plan
							 | 
						||
| 
								 | 
							
								was created with the @code{FFTW_UNALIGNED} flag.
							 | 
						||
| 
								 | 
							
								@ctindex FFTW_UNALIGNED
							 | 
						||
| 
								 | 
							
								Here, the alignment is a platform-dependent quantity (for example, it is
							 | 
						||
| 
								 | 
							
								the address modulo 16 if SSE SIMD instructions are used, but the address
							 | 
						||
| 
								 | 
							
								modulo 4 for non-SIMD single-precision FFTW on the same machine).  In
							 | 
						||
| 
								 | 
							
								general, only arrays allocated with @code{fftw_malloc} are guaranteed to
							 | 
						||
| 
								 | 
							
								be equally aligned (@pxref{SIMD alignment and fftw_malloc}).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@end itemize
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex alignment
							 | 
						||
| 
								 | 
							
								The alignment issue is especially critical, because if you don't use
							 | 
						||
| 
								 | 
							
								@code{fftw_malloc} then you may have little control over the alignment
							 | 
						||
| 
								 | 
							
								of arrays in memory.  For example, neither the C++ @code{new} function
							 | 
						||
| 
								 | 
							
								nor the Fortran @code{allocate} statement provide strong enough
							 | 
						||
| 
								 | 
							
								guarantees about data alignment.  If you don't use @code{fftw_malloc},
							 | 
						||
| 
								 | 
							
								therefore, you probably have to use @code{FFTW_UNALIGNED} (which
							 | 
						||
| 
								 | 
							
								disables most SIMD support).  If possible, it is probably better for
							 | 
						||
| 
								 | 
							
								you to simply create multiple plans (creating a new plan is quick once
							 | 
						||
| 
								 | 
							
								one exists for a given size), or better yet re-use the same array for
							 | 
						||
| 
								 | 
							
								your transforms.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@findex fftw_alignment_of
							 | 
						||
| 
								 | 
							
								For rare circumstances in which you cannot control the alignment of
							 | 
						||
| 
								 | 
							
								allocated memory, but wish to determine where a given array is
							 | 
						||
| 
								 | 
							
								aligned like the original array for which a plan was created, you can
							 | 
						||
| 
								 | 
							
								use the @code{fftw_alignment_of} function:
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								int fftw_alignment_of(double *p);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								Two arrays have equivalent alignment (for the purposes of applying a
							 | 
						||
| 
								 | 
							
								plan) if and only if @code{fftw_alignment_of} returns the same value
							 | 
						||
| 
								 | 
							
								for the corresponding pointers to their data (typecast to @code{double*} 
							 | 
						||
| 
								 | 
							
								if necessary).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are tempted to use the new-array execute interface because you
							 | 
						||
| 
								 | 
							
								want to transform a known bunch of arrays of the same size, you should
							 | 
						||
| 
								 | 
							
								probably go use the advanced interface instead (@pxref{Advanced
							 | 
						||
| 
								 | 
							
								Interface})).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The new-array execute functions are:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_execute_dft(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p, 
							 | 
						||
| 
								 | 
							
								     fftw_complex *in, fftw_complex *out);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_split_dft(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p, 
							 | 
						||
| 
								 | 
							
								     double *ri, double *ii, double *ro, double *io);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_dft_r2c(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p,
							 | 
						||
| 
								 | 
							
								     double *in, fftw_complex *out);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_split_dft_r2c(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p,
							 | 
						||
| 
								 | 
							
								     double *in, double *ro, double *io);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_dft_c2r(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p,
							 | 
						||
| 
								 | 
							
								     fftw_complex *in, double *out);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_split_dft_c2r(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p,
							 | 
						||
| 
								 | 
							
								     double *ri, double *ii, double *out);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void fftw_execute_r2r(
							 | 
						||
| 
								 | 
							
								     const fftw_plan p, 
							 | 
						||
| 
								 | 
							
								     double *in, double *out);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_dft
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_split_dft
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_dft_r2c
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_split_dft_r2c
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_dft_c2r
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_split_dft_c2r
							 | 
						||
| 
								 | 
							
								@findex fftw_execute_r2r
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These execute the @code{plan} to compute the corresponding transform on
							 | 
						||
| 
								 | 
							
								the input/output arrays specified by the subsequent arguments.  The
							 | 
						||
| 
								 | 
							
								input/output array arguments have the same meanings as the ones passed
							 | 
						||
| 
								 | 
							
								to the guru planner routines in the preceding sections.  The @code{plan}
							 | 
						||
| 
								 | 
							
								is not modified, and these routines can be called as many times as
							 | 
						||
| 
								 | 
							
								desired, or intermixed with calls to the ordinary @code{fftw_execute}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The @code{plan} @emph{must} have been created for the transform type
							 | 
						||
| 
								 | 
							
								corresponding to the execute function, e.g. it must be a complex-DFT
							 | 
						||
| 
								 | 
							
								plan for @code{fftw_execute_dft}.  Any of the planner routines for that
							 | 
						||
| 
								 | 
							
								transform type, from the basic to the guru interface, could have been
							 | 
						||
| 
								 | 
							
								used to create the plan, however.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node Wisdom, What FFTW Really Computes, New-array Execute Functions, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section Wisdom
							 | 
						||
| 
								 | 
							
								@cindex wisdom
							 | 
						||
| 
								 | 
							
								@cindex saving plans to disk
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This section documents the FFTW mechanism for saving and restoring
							 | 
						||
| 
								 | 
							
								plans from disk.  This mechanism is called @dfn{wisdom}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* Wisdom Export::
							 | 
						||
| 
								 | 
							
								* Wisdom Import::
							 | 
						||
| 
								 | 
							
								* Forgetting Wisdom::
							 | 
						||
| 
								 | 
							
								* Wisdom Utilities::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Wisdom Export, Wisdom Import, Wisdom, Wisdom
							 | 
						||
| 
								 | 
							
								@subsection Wisdom Export
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								int fftw_export_wisdom_to_filename(const char *filename);
							 | 
						||
| 
								 | 
							
								void fftw_export_wisdom_to_file(FILE *output_file);
							 | 
						||
| 
								 | 
							
								char *fftw_export_wisdom_to_string(void);
							 | 
						||
| 
								 | 
							
								void fftw_export_wisdom(void (*write_char)(char c, void *), void *data);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_export_wisdom
							 | 
						||
| 
								 | 
							
								@findex fftw_export_wisdom_to_filename
							 | 
						||
| 
								 | 
							
								@findex fftw_export_wisdom_to_file
							 | 
						||
| 
								 | 
							
								@findex fftw_export_wisdom_to_string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These functions allow you to export all currently accumulated wisdom
							 | 
						||
| 
								 | 
							
								in a form from which it can be later imported and restored, even
							 | 
						||
| 
								 | 
							
								during a separate run of the program. (@xref{Words of Wisdom-Saving
							 | 
						||
| 
								 | 
							
								Plans}.)  The current store of wisdom is not affected by calling any
							 | 
						||
| 
								 | 
							
								of these routines.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_export_wisdom} exports the wisdom to any output
							 | 
						||
| 
								 | 
							
								medium, as specified by the callback function
							 | 
						||
| 
								 | 
							
								@code{write_char}. @code{write_char} is a @code{putc}-like function that
							 | 
						||
| 
								 | 
							
								writes the character @code{c} to some output; its second parameter is
							 | 
						||
| 
								 | 
							
								the @code{data} pointer passed to @code{fftw_export_wisdom}.  For
							 | 
						||
| 
								 | 
							
								convenience, the following three ``wrapper'' routines are provided:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_export_wisdom_to_filename} writes wisdom to a file named
							 | 
						||
| 
								 | 
							
								@code{filename} (which is created or overwritten), returning @code{1}
							 | 
						||
| 
								 | 
							
								on success and @code{0} on failure.  A lower-level function, which
							 | 
						||
| 
								 | 
							
								requires you to open and close the file yourself (e.g. if you want to
							 | 
						||
| 
								 | 
							
								write wisdom to a portion of a larger file) is
							 | 
						||
| 
								 | 
							
								@code{fftw_export_wisdom_to_file}.  This writes the wisdom to the
							 | 
						||
| 
								 | 
							
								current position in @code{output_file}, which should be open with
							 | 
						||
| 
								 | 
							
								write permission; upon exit, the file remains open and is positioned
							 | 
						||
| 
								 | 
							
								at the end of the wisdom data.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_export_wisdom_to_string} returns a pointer to a
							 | 
						||
| 
								 | 
							
								@code{NULL}-terminated string holding the wisdom data. This string is
							 | 
						||
| 
								 | 
							
								dynamically allocated, and it is the responsibility of the caller to
							 | 
						||
| 
								 | 
							
								deallocate it with @code{free} when it is no longer needed.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								All of these routines export the wisdom in the same format, which we
							 | 
						||
| 
								 | 
							
								will not document here except to say that it is LISP-like ASCII text
							 | 
						||
| 
								 | 
							
								that is insensitive to white space.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Wisdom Import, Forgetting Wisdom, Wisdom Export, Wisdom
							 | 
						||
| 
								 | 
							
								@subsection Wisdom Import
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								int fftw_import_system_wisdom(void);
							 | 
						||
| 
								 | 
							
								int fftw_import_wisdom_from_filename(const char *filename);
							 | 
						||
| 
								 | 
							
								int fftw_import_wisdom_from_string(const char *input_string);
							 | 
						||
| 
								 | 
							
								int fftw_import_wisdom(int (*read_char)(void *), void *data);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_import_wisdom
							 | 
						||
| 
								 | 
							
								@findex fftw_import_system_wisdom
							 | 
						||
| 
								 | 
							
								@findex fftw_import_wisdom_from_filename
							 | 
						||
| 
								 | 
							
								@findex fftw_import_wisdom_from_file
							 | 
						||
| 
								 | 
							
								@findex fftw_import_wisdom_from_string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These functions import wisdom into a program from data stored by the
							 | 
						||
| 
								 | 
							
								@code{fftw_export_wisdom} functions above. (@xref{Words of
							 | 
						||
| 
								 | 
							
								Wisdom-Saving Plans}.)  The imported wisdom replaces any wisdom
							 | 
						||
| 
								 | 
							
								already accumulated by the running program.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_import_wisdom} imports wisdom from any input medium, as
							 | 
						||
| 
								 | 
							
								specified by the callback function @code{read_char}. @code{read_char} is
							 | 
						||
| 
								 | 
							
								a @code{getc}-like function that returns the next character in the
							 | 
						||
| 
								 | 
							
								input; its parameter is the @code{data} pointer passed to
							 | 
						||
| 
								 | 
							
								@code{fftw_import_wisdom}. If the end of the input data is reached
							 | 
						||
| 
								 | 
							
								(which should never happen for valid data), @code{read_char} should
							 | 
						||
| 
								 | 
							
								return @code{EOF} (as defined in @code{<stdio.h>}).  For convenience,
							 | 
						||
| 
								 | 
							
								the following three ``wrapper'' routines are provided:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_import_wisdom_from_filename} reads wisdom from a file named
							 | 
						||
| 
								 | 
							
								@code{filename}.  A lower-level function, which requires you to open
							 | 
						||
| 
								 | 
							
								and close the file yourself (e.g. if you want to read wisdom from a
							 | 
						||
| 
								 | 
							
								portion of a larger file) is @code{fftw_import_wisdom_from_file}. This
							 | 
						||
| 
								 | 
							
								reads wisdom from the current position in @code{input_file} (which
							 | 
						||
| 
								 | 
							
								should be open with read permission); upon exit, the file remains
							 | 
						||
| 
								 | 
							
								open, but the position of the read pointer is unspecified.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_import_wisdom_from_string} reads wisdom from the
							 | 
						||
| 
								 | 
							
								@code{NULL}-terminated string @code{input_string}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@code{fftw_import_system_wisdom} reads wisdom from an
							 | 
						||
| 
								 | 
							
								implementation-defined standard file (@code{/etc/fftw/wisdom} on Unix
							 | 
						||
| 
								 | 
							
								and GNU systems).
							 | 
						||
| 
								 | 
							
								@cindex wisdom, system-wide
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The return value of these import routines is @code{1} if the wisdom was
							 | 
						||
| 
								 | 
							
								read successfully and @code{0} otherwise. Note that, in all of these
							 | 
						||
| 
								 | 
							
								functions, any data in the input stream past the end of the wisdom data
							 | 
						||
| 
								 | 
							
								is simply ignored.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Forgetting Wisdom, Wisdom Utilities, Wisdom Import, Wisdom
							 | 
						||
| 
								 | 
							
								@subsection Forgetting Wisdom
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@example
							 | 
						||
| 
								 | 
							
								void fftw_forget_wisdom(void);
							 | 
						||
| 
								 | 
							
								@end example
							 | 
						||
| 
								 | 
							
								@findex fftw_forget_wisdom
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Calling @code{fftw_forget_wisdom} causes all accumulated @code{wisdom}
							 | 
						||
| 
								 | 
							
								to be discarded and its associated memory to be freed. (New
							 | 
						||
| 
								 | 
							
								@code{wisdom} can still be gathered subsequently, however.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Wisdom Utilities,  , Forgetting Wisdom, Wisdom
							 | 
						||
| 
								 | 
							
								@subsection Wisdom Utilities
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								FFTW includes two standalone utility programs that deal with wisdom.  We
							 | 
						||
| 
								 | 
							
								merely summarize them here, since they come with their own @code{man}
							 | 
						||
| 
								 | 
							
								pages for Unix and GNU systems (with HTML versions on our web site).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The first program is @code{fftw-wisdom} (or @code{fftwf-wisdom} in
							 | 
						||
| 
								 | 
							
								single precision, etcetera), which can be used to create a wisdom file
							 | 
						||
| 
								 | 
							
								containing plans for any of the transform sizes and types supported by
							 | 
						||
| 
								 | 
							
								FFTW.  It is preferable to create wisdom directly from your executable
							 | 
						||
| 
								 | 
							
								(@pxref{Caveats in Using Wisdom}), but this program is useful for
							 | 
						||
| 
								 | 
							
								creating global wisdom files for @code{fftw_import_system_wisdom}.
							 | 
						||
| 
								 | 
							
								@cindex fftw-wisdom utility
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The second program is @code{fftw-wisdom-to-conf}, which takes a wisdom
							 | 
						||
| 
								 | 
							
								file as input and produces a @dfn{configuration routine} as output.  The
							 | 
						||
| 
								 | 
							
								latter is a C subroutine that you can compile and link into your
							 | 
						||
| 
								 | 
							
								program, replacing a routine of the same name in the FFTW library, that
							 | 
						||
| 
								 | 
							
								determines which parts of FFTW are callable by your program.
							 | 
						||
| 
								 | 
							
								@code{fftw-wisdom-to-conf} produces a configuration routine that links
							 | 
						||
| 
								 | 
							
								to only those parts of FFTW needed by the saved plans in the wisdom,
							 | 
						||
| 
								 | 
							
								greatly reducing the size of statically linked executables (which should
							 | 
						||
| 
								 | 
							
								only attempt to create plans corresponding to those in the wisdom,
							 | 
						||
| 
								 | 
							
								however).
							 | 
						||
| 
								 | 
							
								@cindex fftw-wisdom-to-conf utility
							 | 
						||
| 
								 | 
							
								@cindex configuration routines
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c ------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								@node What FFTW Really Computes,  , Wisdom, FFTW Reference
							 | 
						||
| 
								 | 
							
								@section What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In this section, we provide precise mathematical definitions for the
							 | 
						||
| 
								 | 
							
								transforms that FFTW computes.  These transform definitions are fairly
							 | 
						||
| 
								 | 
							
								standard, but some authors follow slightly different conventions for the
							 | 
						||
| 
								 | 
							
								normalization of the transform (the constant factor in front) and the
							 | 
						||
| 
								 | 
							
								sign of the complex exponent.  We begin by presenting the
							 | 
						||
| 
								 | 
							
								one-dimensional (1d) transform definitions, and then give the
							 | 
						||
| 
								 | 
							
								straightforward extension to multi-dimensional transforms.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@menu
							 | 
						||
| 
								 | 
							
								* The 1d Discrete Fourier Transform (DFT)::
							 | 
						||
| 
								 | 
							
								* The 1d Real-data DFT::
							 | 
						||
| 
								 | 
							
								* 1d Real-even DFTs (DCTs)::
							 | 
						||
| 
								 | 
							
								* 1d Real-odd DFTs (DSTs)::
							 | 
						||
| 
								 | 
							
								* 1d Discrete Hartley Transforms (DHTs)::
							 | 
						||
| 
								 | 
							
								* Multi-dimensional Transforms::
							 | 
						||
| 
								 | 
							
								@end menu
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node The 1d Discrete Fourier Transform (DFT), The 1d Real-data DFT, What FFTW Really Computes, What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection The 1d Discrete Fourier Transform (DFT)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex discrete Fourier transform
							 | 
						||
| 
								 | 
							
								@cindex DFT
							 | 
						||
| 
								 | 
							
								The forward (@code{FFTW_FORWARD}) discrete Fourier transform (DFT) of a
							 | 
						||
| 
								 | 
							
								1d complex array @math{X} of size @math{n} computes an array @math{Y},
							 | 
						||
| 
								 | 
							
								where:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = \sum_{j = 0}^{n - 1} X_j e^{-2\pi j k \sqrt{-1}/n} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@center Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(-2 pi j k sqrt(-1)/n) .
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-dft.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								The backward (@code{FFTW_BACKWARD}) DFT computes:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = \sum_{j = 0}^{n - 1} X_j e^{2\pi j k \sqrt{-1}/n} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@center Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(2 pi j k sqrt(-1)/n) .
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-idft.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								FFTW computes an unnormalized transform, in that there is no coefficient
							 | 
						||
| 
								 | 
							
								in front of the summation in the DFT.  In other words, applying the
							 | 
						||
| 
								 | 
							
								forward and then the backward transform will multiply the input by
							 | 
						||
| 
								 | 
							
								@math{n}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex frequency
							 | 
						||
| 
								 | 
							
								From above, an @code{FFTW_FORWARD} transform corresponds to a sign of
							 | 
						||
| 
								 | 
							
								@math{-1} in the exponent of the DFT.  Note also that we use the
							 | 
						||
| 
								 | 
							
								standard ``in-order'' output ordering---the @math{k}-th output
							 | 
						||
| 
								 | 
							
								corresponds to the frequency @math{k/n} (or @math{k/T}, where @math{T}
							 | 
						||
| 
								 | 
							
								is your total sampling period).  For those who like to think in terms of
							 | 
						||
| 
								 | 
							
								positive and negative frequencies, this means that the positive
							 | 
						||
| 
								 | 
							
								frequencies are stored in the first half of the output and the negative
							 | 
						||
| 
								 | 
							
								frequencies are stored in backwards order in the second half of the
							 | 
						||
| 
								 | 
							
								output.  (The frequency @math{-k/n} is the same as the frequency
							 | 
						||
| 
								 | 
							
								@math{(n-k)/n}.)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node The 1d Real-data DFT, 1d Real-even DFTs (DCTs), The 1d Discrete Fourier Transform (DFT), What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection The 1d Real-data DFT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The real-input (r2c) DFT in FFTW computes the @emph{forward} transform
							 | 
						||
| 
								 | 
							
								@math{Y} of the size @code{n} real array @math{X}, exactly as defined
							 | 
						||
| 
								 | 
							
								above, i.e.
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = \sum_{j = 0}^{n - 1} X_j e^{-2\pi j k \sqrt{-1}/n} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@center Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(-2 pi j k sqrt(-1)/n) .
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-dft.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								This output array @math{Y} can easily be shown to possess the
							 | 
						||
| 
								 | 
							
								``Hermitian'' symmetry
							 | 
						||
| 
								 | 
							
								@cindex Hermitian
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_k = Y_{n-k}^*$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = Y[n-k]*,
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y<sub>k</sub> = Y<sub>n-k</sub></i><sup>*</sup>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where we take @math{Y} to be periodic so that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_n = Y_0$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[n] = Y[0].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y<sub>n</sub> = Y</i><sub>0</sub>.
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								As a result of this symmetry, half of the output @math{Y} is redundant
							 | 
						||
| 
								 | 
							
								(being the complex conjugate of the other half), and so the 1d r2c
							 | 
						||
| 
								 | 
							
								transforms only output elements @math{0}@dots{}@math{n/2} of @math{Y}
							 | 
						||
| 
								 | 
							
								(@math{n/2+1} complex numbers), where the division by @math{2} is
							 | 
						||
| 
								 | 
							
								rounded down. 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Moreover, the Hermitian symmetry implies that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_0$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[0]
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i><sub>0</sub>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								and, if @math{n} is even, the
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_{n/2}$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[n/2]
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i><sub><i>n</i>/2</sub>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								element, are purely real.  So, for the @code{R2HC} r2r transform, the
							 | 
						||
| 
								 | 
							
								halfcomplex format does not store the imaginary parts of these elements.
							 | 
						||
| 
								 | 
							
								@cindex r2r
							 | 
						||
| 
								 | 
							
								@ctindex R2HC
							 | 
						||
| 
								 | 
							
								@cindex halfcomplex format
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The c2r and @code{H2RC} r2r transforms compute the backward DFT of the
							 | 
						||
| 
								 | 
							
								@emph{complex} array @math{X} with Hermitian symmetry, stored in the
							 | 
						||
| 
								 | 
							
								r2c/@code{R2HC} output formats, respectively, where the backward
							 | 
						||
| 
								 | 
							
								transform is defined exactly as for the complex case:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = \sum_{j = 0}^{n - 1} X_j e^{2\pi j k \sqrt{-1}/n} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@center Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(2 pi j k sqrt(-1)/n) .
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-idft.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								The outputs @code{Y} of this transform can easily be seen to be purely
							 | 
						||
| 
								 | 
							
								real, and are stored as an array of real numbers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								Like FFTW's complex DFT, these transforms are unnormalized.  In other
							 | 
						||
| 
								 | 
							
								words, applying the real-to-complex (forward) and then the
							 | 
						||
| 
								 | 
							
								complex-to-real (backward) transform will multiply the input by
							 | 
						||
| 
								 | 
							
								@math{n}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node 1d Real-even DFTs (DCTs), 1d Real-odd DFTs (DSTs), The 1d Real-data DFT, What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection 1d Real-even DFTs (DCTs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The Real-even symmetry DFTs in FFTW are exactly equivalent to the unnormalized
							 | 
						||
| 
								 | 
							
								forward (and backward) DFTs as defined above, where the input array
							 | 
						||
| 
								 | 
							
								@math{X} of length @math{N} is purely real and is also @dfn{even} symmetry.  In
							 | 
						||
| 
								 | 
							
								this case, the output array is likewise real and even symmetry.
							 | 
						||
| 
								 | 
							
								@cindex real-even DFT
							 | 
						||
| 
								 | 
							
								@cindex REDFT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@ctindex REDFT00
							 | 
						||
| 
								 | 
							
								For the case of @code{REDFT00}, this even symmetry means that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$X_j = X_{N-j}$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								X[j] = X[N-j],
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>X<sub>j</sub> = X<sub>N-j</sub></i>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where we take @math{X} to be periodic so that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$X_N = X_0$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								X[N] = X[0].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>X<sub>N</sub> = X</i><sub>0</sub>.
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								Because of this redundancy, only the first @math{n} real numbers are
							 | 
						||
| 
								 | 
							
								actually stored, where @math{N = 2(n-1)}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The proper definition of even symmetry for @code{REDFT10},
							 | 
						||
| 
								 | 
							
								@code{REDFT01}, and @code{REDFT11} transforms is somewhat more intricate
							 | 
						||
| 
								 | 
							
								because of the shifts by @math{1/2} of the input and/or output, although
							 | 
						||
| 
								 | 
							
								the corresponding boundary conditions are given in @ref{Real even/odd
							 | 
						||
| 
								 | 
							
								DFTs (cosine/sine transforms)}.  Because of the even symmetry, however,
							 | 
						||
| 
								 | 
							
								the sine terms in the DFT all cancel and the remaining cosine terms are
							 | 
						||
| 
								 | 
							
								written explicitly below.  This formulation often leads people to call
							 | 
						||
| 
								 | 
							
								such a transform a @dfn{discrete cosine transform} (DCT), although it is
							 | 
						||
| 
								 | 
							
								really just a special case of the DFT.
							 | 
						||
| 
								 | 
							
								@cindex discrete cosine transform
							 | 
						||
| 
								 | 
							
								@cindex DCT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In each of the definitions below, we transform a real array @math{X} of
							 | 
						||
| 
								 | 
							
								length @math{n} to a real array @math{Y} of length @math{n}:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading REDFT00 (DCT-I)
							 | 
						||
| 
								 | 
							
								@ctindex REDFT00
							 | 
						||
| 
								 | 
							
								An @code{REDFT00} transform (type-I DCT) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = X_0 + (-1)^k X_{n-1}
							 | 
						||
| 
								 | 
							
								       + 2 \sum_{j=1}^{n-2} X_j \cos [ \pi j k / (n-1)].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = X[0] + (-1)^k X[n-1] + 2 (sum for j = 1 to n-2 of X[j] cos(pi jk /(n-1))).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-redft00.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								Note that this transform is not defined for @math{n=1}.  For @math{n=2},
							 | 
						||
| 
								 | 
							
								the summation term above is dropped as you might expect.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading REDFT10 (DCT-II)
							 | 
						||
| 
								 | 
							
								@ctindex REDFT10
							 | 
						||
| 
								 | 
							
								An @code{REDFT10} transform (type-II DCT, sometimes called ``the'' DCT) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = 2 \sum_{j=0}^{n-1} X_j \cos [\pi (j+1/2) k / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = 2 (sum for j = 0 to n-1 of X[j] cos(pi (j+1/2) k / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-redft10.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading REDFT01 (DCT-III)
							 | 
						||
| 
								 | 
							
								@ctindex REDFT01
							 | 
						||
| 
								 | 
							
								An @code{REDFT01} transform (type-III DCT) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = X_0 + 2 \sum_{j=1}^{n-1} X_j \cos [\pi j (k+1/2) / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = X[0] + 2 (sum for j = 1 to n-1 of X[j] cos(pi j (k+1/2) / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-redft01.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								In the case of @math{n=1}, this reduces to
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_0 = X_0$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[0] = X[0].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i><sub>0</sub> = <i>X</i><sub>0</sub>.
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								Up to a scale factor (see below), this is the inverse of @code{REDFT10} (``the'' DCT), and so the @code{REDFT01} (DCT-III) is sometimes called the ``IDCT''.
							 | 
						||
| 
								 | 
							
								@cindex IDCT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading REDFT11 (DCT-IV)
							 | 
						||
| 
								 | 
							
								@ctindex REDFT11
							 | 
						||
| 
								 | 
							
								An @code{REDFT11} transform (type-IV DCT) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = 2 \sum_{j=0}^{n-1} X_j \cos [\pi (j+1/2) (k+1/2) / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = 2 (sum for j = 0 to n-1 of X[j] cos(pi (j+1/2) (k+1/2) / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-redft11.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Inverses and Normalization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These definitions correspond directly to the unnormalized DFTs used
							 | 
						||
| 
								 | 
							
								elsewhere in FFTW (hence the factors of @math{2} in front of the
							 | 
						||
| 
								 | 
							
								summations).  The unnormalized inverse of @code{REDFT00} is
							 | 
						||
| 
								 | 
							
								@code{REDFT00}, of @code{REDFT10} is @code{REDFT01} and vice versa, and
							 | 
						||
| 
								 | 
							
								of @code{REDFT11} is @code{REDFT11}.  Each unnormalized inverse results
							 | 
						||
| 
								 | 
							
								in the original array multiplied by @math{N}, where @math{N} is the
							 | 
						||
| 
								 | 
							
								@emph{logical} DFT size.  For @code{REDFT00}, @math{N=2(n-1)} (note that
							 | 
						||
| 
								 | 
							
								@math{n=1} is not defined); otherwise, @math{N=2n}.
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In defining the discrete cosine transform, some authors also include
							 | 
						||
| 
								 | 
							
								additional factors of
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								sqrt(2)
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								√2
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$\sqrt{2}$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								(or its inverse) multiplying selected inputs and/or outputs.  This is a
							 | 
						||
| 
								 | 
							
								mostly cosmetic change that makes the transform orthogonal, but
							 | 
						||
| 
								 | 
							
								sacrifices the direct equivalence to a symmetric DFT.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node 1d Real-odd DFTs (DSTs), 1d Discrete Hartley Transforms (DHTs), 1d Real-even DFTs (DCTs), What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection 1d Real-odd DFTs (DSTs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The Real-odd symmetry DFTs in FFTW are exactly equivalent to the unnormalized
							 | 
						||
| 
								 | 
							
								forward (and backward) DFTs as defined above, where the input array
							 | 
						||
| 
								 | 
							
								@math{X} of length @math{N} is purely real and is also @dfn{odd} symmetry.  In
							 | 
						||
| 
								 | 
							
								this case, the output is odd symmetry and purely imaginary.
							 | 
						||
| 
								 | 
							
								@cindex real-odd DFT
							 | 
						||
| 
								 | 
							
								@cindex RODFT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@ctindex RODFT00
							 | 
						||
| 
								 | 
							
								For the case of @code{RODFT00}, this odd symmetry means that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$X_j = -X_{N-j}$,
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								X[j] = -X[N-j],
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>X<sub>j</sub> = -X<sub>N-j</sub></i>,
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								where we take @math{X} to be periodic so that
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$X_N = X_0$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								X[N] = X[0].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>X<sub>N</sub> = X</i><sub>0</sub>.
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								Because of this redundancy, only the first @math{n} real numbers
							 | 
						||
| 
								 | 
							
								starting at @math{j=1} are actually stored (the @math{j=0} element is
							 | 
						||
| 
								 | 
							
								zero), where @math{N = 2(n+1)}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The proper definition of odd symmetry for @code{RODFT10},
							 | 
						||
| 
								 | 
							
								@code{RODFT01}, and @code{RODFT11} transforms is somewhat more intricate
							 | 
						||
| 
								 | 
							
								because of the shifts by @math{1/2} of the input and/or output, although
							 | 
						||
| 
								 | 
							
								the corresponding boundary conditions are given in @ref{Real even/odd
							 | 
						||
| 
								 | 
							
								DFTs (cosine/sine transforms)}.  Because of the odd symmetry, however,
							 | 
						||
| 
								 | 
							
								the cosine terms in the DFT all cancel and the remaining sine terms are
							 | 
						||
| 
								 | 
							
								written explicitly below.  This formulation often leads people to call
							 | 
						||
| 
								 | 
							
								such a transform a @dfn{discrete sine transform} (DST), although it is
							 | 
						||
| 
								 | 
							
								really just a special case of the DFT.
							 | 
						||
| 
								 | 
							
								@cindex discrete sine transform
							 | 
						||
| 
								 | 
							
								@cindex DST
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In each of the definitions below, we transform a real array @math{X} of
							 | 
						||
| 
								 | 
							
								length @math{n} to a real array @math{Y} of length @math{n}:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading RODFT00 (DST-I)
							 | 
						||
| 
								 | 
							
								@ctindex RODFT00
							 | 
						||
| 
								 | 
							
								An @code{RODFT00} transform (type-I DST) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = 2 \sum_{j=0}^{n-1} X_j \sin [ \pi (j+1) (k+1) / (n+1)].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = 2 (sum for j = 0 to n-1 of X[j] sin(pi (j+1)(k+1) / (n+1))).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-rodft00.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading RODFT10 (DST-II)
							 | 
						||
| 
								 | 
							
								@ctindex RODFT10
							 | 
						||
| 
								 | 
							
								An @code{RODFT10} transform (type-II DST) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = 2 \sum_{j=0}^{n-1} X_j \sin [\pi (j+1/2) (k+1) / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = 2 (sum for j = 0 to n-1 of X[j] sin(pi (j+1/2) (k+1) / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-rodft10.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading RODFT01 (DST-III)
							 | 
						||
| 
								 | 
							
								@ctindex RODFT01
							 | 
						||
| 
								 | 
							
								An @code{RODFT01} transform (type-III DST) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = (-1)^k X_{n-1} + 2 \sum_{j=0}^{n-2} X_j \sin [\pi (j+1) (k+1/2) / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = (-1)^k X[n-1] + 2 (sum for j = 0 to n-2 of X[j] sin(pi (j+1) (k+1/2) / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-rodft01.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								In the case of @math{n=1}, this reduces to
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y_0 = X_0$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[0] = X[0].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i><sub>0</sub> = <i>X</i><sub>0</sub>.
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading RODFT11 (DST-IV)
							 | 
						||
| 
								 | 
							
								@ctindex RODFT11
							 | 
						||
| 
								 | 
							
								An @code{RODFT11} transform (type-IV DST) in FFTW is defined by:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = 2 \sum_{j=0}^{n-1} X_j \sin [\pi (j+1/2) (k+1/2) / n].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k] = 2 (sum for j = 0 to n-1 of X[j] sin(pi (j+1/2) (k+1/2) / n)).
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-rodft11.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@subsubheading Inverses and Normalization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								These definitions correspond directly to the unnormalized DFTs used
							 | 
						||
| 
								 | 
							
								elsewhere in FFTW (hence the factors of @math{2} in front of the
							 | 
						||
| 
								 | 
							
								summations).  The unnormalized inverse of @code{RODFT00} is
							 | 
						||
| 
								 | 
							
								@code{RODFT00}, of @code{RODFT10} is @code{RODFT01} and vice versa, and
							 | 
						||
| 
								 | 
							
								of @code{RODFT11} is @code{RODFT11}.  Each unnormalized inverse results
							 | 
						||
| 
								 | 
							
								in the original array multiplied by @math{N}, where @math{N} is the
							 | 
						||
| 
								 | 
							
								@emph{logical} DFT size.  For @code{RODFT00}, @math{N=2(n+1)};
							 | 
						||
| 
								 | 
							
								otherwise, @math{N=2n}.
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In defining the discrete sine transform, some authors also include
							 | 
						||
| 
								 | 
							
								additional factors of
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								sqrt(2)
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								√2
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$\sqrt{2}$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								(or its inverse) multiplying selected inputs and/or outputs.  This is a
							 | 
						||
| 
								 | 
							
								mostly cosmetic change that makes the transform orthogonal, but
							 | 
						||
| 
								 | 
							
								sacrifices the direct equivalence to an antisymmetric DFT.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node 1d Discrete Hartley Transforms (DHTs), Multi-dimensional Transforms, 1d Real-odd DFTs (DSTs), What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection 1d Discrete Hartley Transforms (DHTs)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex discrete Hartley transform
							 | 
						||
| 
								 | 
							
								@cindex DHT
							 | 
						||
| 
								 | 
							
								The discrete Hartley transform (DHT) of a 1d real array @math{X} of size
							 | 
						||
| 
								 | 
							
								@math{n} computes a real array @math{Y} of the same size, where:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y_k = \sum_{j = 0}^{n - 1} X_j [ \cos(2\pi j k / n) + \sin(2\pi j k / n)].
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								@center Y[k] = sum for j = 0 to (n - 1) of X[j] * [cos(2 pi j k / n) + sin(2 pi j k / n)].
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<center><img src="equation-dht.png" align="top">.</center>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex normalization
							 | 
						||
| 
								 | 
							
								FFTW computes an unnormalized transform, in that there is no coefficient
							 | 
						||
| 
								 | 
							
								in front of the summation in the DHT.  In other words, applying the
							 | 
						||
| 
								 | 
							
								transform twice (the DHT is its own inverse) will multiply the input by
							 | 
						||
| 
								 | 
							
								@math{n}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@c =========>
							 | 
						||
| 
								 | 
							
								@node Multi-dimensional Transforms,  , 1d Discrete Hartley Transforms (DHTs), What FFTW Really Computes
							 | 
						||
| 
								 | 
							
								@subsection Multi-dimensional Transforms
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The multi-dimensional transforms of FFTW, in general, compute simply the
							 | 
						||
| 
								 | 
							
								separable product of the given 1d transform along each dimension of the
							 | 
						||
| 
								 | 
							
								array.  Since each of these transforms is unnormalized, computing the
							 | 
						||
| 
								 | 
							
								forward followed by the backward/inverse multi-dimensional transform
							 | 
						||
| 
								 | 
							
								will result in the original array scaled by the product of the
							 | 
						||
| 
								 | 
							
								normalization factors for each dimension (e.g. the product of the
							 | 
						||
| 
								 | 
							
								dimension sizes, for a multi-dimensional DFT).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								As an explicit example, consider the following exact mathematical
							 | 
						||
| 
								 | 
							
								definition of our multi-dimensional DFT.  Let $X$ be a $d$-dimensional
							 | 
						||
| 
								 | 
							
								complex array whose elements are $X[j_1, j_2, \ldots, j_d]$, where $0
							 | 
						||
| 
								 | 
							
								\leq j_s < n_s$ for all~$s \in \{ 1, 2, \ldots, d \}$.  Let also
							 | 
						||
| 
								 | 
							
								$\omega_s = e^{2\pi \sqrt{-1}/n_s}$, for all ~$s \in \{ 1, 2, \ldots, d
							 | 
						||
| 
								 | 
							
								\}$.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The forward transform computes a complex array~$Y$, whose
							 | 
						||
| 
								 | 
							
								structure is the same as that of~$X$, defined by
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y[k_1, k_2, \ldots, k_d] =
							 | 
						||
| 
								 | 
							
								    \sum_{j_1 = 0}^{n_1 - 1}
							 | 
						||
| 
								 | 
							
								        \sum_{j_2 = 0}^{n_2 - 1}
							 | 
						||
| 
								 | 
							
								           \cdots
							 | 
						||
| 
								 | 
							
								              \sum_{j_d = 0}^{n_d - 1}
							 | 
						||
| 
								 | 
							
								                  X[j_1, j_2, \ldots, j_d] 
							 | 
						||
| 
								 | 
							
								                      \omega_1^{-j_1 k_1}
							 | 
						||
| 
								 | 
							
								                      \omega_2^{-j_2 k_2}
							 | 
						||
| 
								 | 
							
								                      \cdots
							 | 
						||
| 
								 | 
							
								                      \omega_d^{-j_d k_d} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The backward transform computes
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y[k_1, k_2, \ldots, k_d] =
							 | 
						||
| 
								 | 
							
								    \sum_{j_1 = 0}^{n_1 - 1}
							 | 
						||
| 
								 | 
							
								        \sum_{j_2 = 0}^{n_2 - 1}
							 | 
						||
| 
								 | 
							
								           \cdots
							 | 
						||
| 
								 | 
							
								              \sum_{j_d = 0}^{n_d - 1}
							 | 
						||
| 
								 | 
							
								                  X[j_1, j_2, \ldots, j_d] 
							 | 
						||
| 
								 | 
							
								                      \omega_1^{j_1 k_1}
							 | 
						||
| 
								 | 
							
								                      \omega_2^{j_2 k_2}
							 | 
						||
| 
								 | 
							
								                      \cdots
							 | 
						||
| 
								 | 
							
								                      \omega_d^{j_d k_d} \ .
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Computing the forward transform followed by the backward transform
							 | 
						||
| 
								 | 
							
								will multiply the array by $\prod_{s=1}^{d} n_d$.
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@cindex r2c
							 | 
						||
| 
								 | 
							
								The definition of FFTW's multi-dimensional DFT of real data (r2c)
							 | 
						||
| 
								 | 
							
								deserves special attention.  In this case, we logically compute the full
							 | 
						||
| 
								 | 
							
								multi-dimensional DFT of the input data; since the input data are purely
							 | 
						||
| 
								 | 
							
								real, the output data have the Hermitian symmetry and therefore only one
							 | 
						||
| 
								 | 
							
								non-redundant half need be stored.  More specifically, for an @ndims multi-dimensional real-input DFT, the full (logical) complex output array
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$Y[k_0, k_1, \ldots, k_{d-1}]$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i>[<i>k</i><sub>0</sub>, <i>k</i><sub>1</sub>, ...,
							 | 
						||
| 
								 | 
							
								<i>k</i><sub><i>d-1</i></sub>]
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k[0], k[1], ..., k[d-1]]
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								has the symmetry:
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								Y[k_0, k_1, \ldots, k_{d-1}] = Y[n_0 - k_0, n_1 - k_1, \ldots, n_{d-1} - k_{d-1}]^*
							 | 
						||
| 
								 | 
							
								$$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>Y</i>[<i>k</i><sub>0</sub>, <i>k</i><sub>1</sub>, ...,
							 | 
						||
| 
								 | 
							
								<i>k</i><sub><i>d-1</i></sub>] = <i>Y</i>[<i>n</i><sub>0</sub> -
							 | 
						||
| 
								 | 
							
								<i>k</i><sub>0</sub>, <i>n</i><sub>1</sub> - <i>k</i><sub>1</sub>, ...,
							 | 
						||
| 
								 | 
							
								<i>n</i><sub><i>d-1</i></sub> - <i>k</i><sub><i>d-1</i></sub>]<sup>*</sup>
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								Y[k[0], k[1], ..., k[d-1]] = Y[n[0] - k[0], n[1] - k[1], ..., n[d-1] - k[d-1]]*
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								(where each dimension is periodic).  Because of this symmetry, we only
							 | 
						||
| 
								 | 
							
								store the
							 | 
						||
| 
								 | 
							
								@tex
							 | 
						||
| 
								 | 
							
								$k_{d-1} = 0 \cdots n_{d-1}/2$
							 | 
						||
| 
								 | 
							
								@end tex
							 | 
						||
| 
								 | 
							
								@html
							 | 
						||
| 
								 | 
							
								<i>k</i><sub><i>d-1</i></sub> = 0...<i>n</i><sub><i>d-1</i></sub>/2+1
							 | 
						||
| 
								 | 
							
								@end html
							 | 
						||
| 
								 | 
							
								@ifinfo
							 | 
						||
| 
								 | 
							
								k[d-1] = 0...n[d-1]/2
							 | 
						||
| 
								 | 
							
								@end ifinfo
							 | 
						||
| 
								 | 
							
								elements of the @emph{last} dimension (division by @math{2} is rounded
							 | 
						||
| 
								 | 
							
								down).  (We could instead have cut any other dimension in half, but the
							 | 
						||
| 
								 | 
							
								last dimension proved computationally convenient.)  This results in the
							 | 
						||
| 
								 | 
							
								peculiar array format described in more detail by @ref{Real-data DFT
							 | 
						||
| 
								 | 
							
								Array Format}.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The multi-dimensional c2r transform is simply the unnormalized inverse
							 | 
						||
| 
								 | 
							
								of the r2c transform.  i.e. it is the same as FFTW's complex backward
							 | 
						||
| 
								 | 
							
								multi-dimensional DFT, operating on a Hermitian input array in the
							 | 
						||
| 
								 | 
							
								peculiar format mentioned above and outputting a real array (since the
							 | 
						||
| 
								 | 
							
								DFT output is purely real).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We should remind the user that the separable product of 1d transforms
							 | 
						||
| 
								 | 
							
								along each dimension, as computed by FFTW, is not always the same thing
							 | 
						||
| 
								 | 
							
								as the usual multi-dimensional transform.  A multi-dimensional
							 | 
						||
| 
								 | 
							
								@code{R2HC} (or @code{HC2R}) transform is not identical to the
							 | 
						||
| 
								 | 
							
								multi-dimensional DFT, requiring some post-processing to combine the
							 | 
						||
| 
								 | 
							
								requisite real and imaginary parts, as was described in @ref{The
							 | 
						||
| 
								 | 
							
								Halfcomplex-format DFT}.  Likewise, FFTW's multidimensional
							 | 
						||
| 
								 | 
							
								@code{FFTW_DHT} r2r transform is not the same thing as the logical
							 | 
						||
| 
								 | 
							
								multi-dimensional discrete Hartley transform defined in the literature,
							 | 
						||
| 
								 | 
							
								as discussed in @ref{The Discrete Hartley Transform}.
							 | 
						||
| 
								 | 
							
								
							 |