📄 fftw_3.html
字号:
<P>Specifically, for a real transform of dimensionsn<sub>1</sub> x n<sub>2</sub> x ... x n<sub>d</sub>,the complex data is ann<sub>1</sub> x n<sub>2</sub> x ... x (n<sub>d</sub>/2+1)array of <CODE>fftw_complex</CODE> values in row-major order (with thedivision rounded down). That is, we only store the lower half (plus oneelement) of the last dimension of the data from the ordinary complextransform. (We could have instead taken half of any other dimension,but implementation turns out to be simpler if the last, contiguous,dimension is used.)<P><A NAME="IDX178"></A><A NAME="IDX179"></A>Since the complex data is slightly larger than the real data, somecomplications arise for in-place transforms. In this case, the finaldimension of the real data must be padded with extra values toaccommodate the size of the complex data--two extra if the lastdimension is even and one if it is odd. That is, the last dimension ofthe real data must physically contain2 * (n<sub>d</sub>/2+1)<CODE>fftw_real</CODE> values (exactly enough to hold the complex data).This physical array size does not, however, change the <EM>logical</EM>array size--onlyn<sub>d</sub>values are actually stored in the last dimension, andn<sub>d</sub>is the last dimension passed to <CODE>rfftwnd_create_plan</CODE>.<H3><A NAME="SEC38">Strides in In-place RFFTWND</A></H3><P><A NAME="IDX180"></A><A NAME="IDX181"></A>The fact that the input and output datatypes are different for rfftwndcomplicates the meaning of the <CODE>stride</CODE> and <CODE>dist</CODE> parametersof in-place transforms--are they in units of <CODE>fftw_real</CODE> or<CODE>fftw_complex</CODE> elements? When reading the input, they areinterpreted in units of the datatype of the input data. When writingthe output, the <CODE>istride</CODE> and <CODE>idist</CODE> are translated to theoutput datatype's "units" in one of two ways, corresponding to the twomost common situations in which <CODE>stride</CODE> and <CODE>dist</CODE> parametersare useful. Below, we refer to these "translated" parameters as<CODE>ostride_t</CODE> and <CODE>odist_t</CODE>. (Note that these are computedinternally by rfftwnd; the actual <CODE>ostride</CODE> and <CODE>odist</CODE>parameters are ignored for in-place transforms.)<P>First, there is the case where you are transforming a number ofcontiguous arrays located one after another in memory. In thissituation, <CODE>istride</CODE> is <CODE>1</CODE> and <CODE>idist</CODE> is the product ofthe physical dimensions of the array. <CODE>ostride_t</CODE> and<CODE>odist_t</CODE> are then chosen so that the output arrays are contiguousand lie on top of the input arrays. <CODE>ostride_t</CODE> is therefore<CODE>1</CODE>. For a real-to-complex transform, <CODE>odist_t</CODE> is<CODE>idist/2</CODE>; for a complex-to-real transform, <CODE>odist_t</CODE> is<CODE>idist*2</CODE>.<P>The second case is when you have an array in which each element has<CODE>nc</CODE> components (e.g. a structure with <CODE>nc</CODE> numeric fields),and you want to transform all of the components at once. Here,<CODE>istride</CODE> is <CODE>nc</CODE> and <CODE>idist</CODE> is <CODE>1</CODE>. For thiscase, it is natural to want the output to also have <CODE>nc</CODE>consecutive components, now of the output data type; this is exactlywhat rfftwnd does. Specifically, it uses an <CODE>ostride_t</CODE> equal to<CODE>istride</CODE>, and an <CODE>odist_t</CODE> of <CODE>1</CODE>. (Astute readers willrealize that some extra buffer space is required in order to performsuch a transform; this is handled automatically by rfftwnd.)<P>The general rule is as follows. <CODE>ostride_t</CODE> equals <CODE>istride</CODE>.If <CODE>idist</CODE> is <CODE>1</CODE> and <CODE>idist</CODE> is less than<CODE>istride</CODE>, then <CODE>odist_t</CODE> is <CODE>1</CODE>. Otherwise, for areal-to-complex transform <CODE>odist_t</CODE> is <CODE>idist/2</CODE> and for acomplex-to-real transform <CODE>odist_t</CODE> is <CODE>idist*2</CODE>.<H3><A NAME="SEC39">Destroying a Multi-dimensional Plan</A></H3><PRE>#include <rfftw.h>void rfftwnd_destroy_plan(rfftwnd_plan plan);</PRE><P><A NAME="IDX182"></A><P>The function <CODE>rfftwnd_destroy_plan</CODE> frees the plan <CODE>plan</CODE>and releases all the memory associated with it. After destruction,a plan is no longer valid.<H3><A NAME="SEC40">What RFFTWND Really Computes</A></H3><P><A NAME="IDX183"></A><P>The conventions that we follow for the real multi-dimensional transformare analogous to those for the complex multi-dimensional transform. Inparticular, the forward transform has a negative sign in the exponentand neither the forward nor the backward transforms will perform anynormalization. Computing the backward transform of the forwardtransform will multiply the array by the product of its dimensions (thatis, the logical dimensions of the real data). The forward transform isreal-to-complex and the backward transform is complex-to-real.<P><A NAME="IDX184"></A><A NAME="IDX185"></A>The Gods forbade using HTML to display mathematical formulas. Pleasesee the TeX or Postscript version of this manual for the properdefinition of the n-dimensional real Fourier transform that RFFTWuses. For completeness, we include a bitmap of the TeX output below:<P><center><IMG SRC="equation-4.gif" ALIGN="top"></center><H2><A NAME="SEC41">Wisdom Reference</A></H2><P><A NAME="IDX186"></A><H3><A NAME="SEC42">Exporting Wisdom</A></H3><PRE>#include <fftw.h>void fftw_export_wisdom(void (*emitter)(char c, void *), void *data);void fftw_export_wisdom_to_file(FILE *output_file);char *fftw_export_wisdom_to_string(void);</PRE><P><A NAME="IDX187"></A><A NAME="IDX188"></A><A NAME="IDX189"></A><P>These functions allow you to export all currently accumulated<CODE>wisdom</CODE> in a form from which it can be later imported andrestored, even during a separate run of the program. (See Section <A HREF="fftw_2.html#SEC13">Words of Wisdom</A>.) The current store of <CODE>wisdom</CODE> is notaffected by calling any of these routines.<P><CODE>fftw_export_wisdom</CODE> exports the <CODE>wisdom</CODE> to any outputmedium, as specified by the callback function<CODE>emitter</CODE>. <CODE>emitter</CODE> is a <CODE>putc</CODE>-like function thatwrites the character <CODE>c</CODE> to some output; its second parameter isthe <CODE>data</CODE> pointer passed to <CODE>fftw_export_wisdom</CODE>. Forconvenience, the following two "wrapper" routines are provided:<P><CODE>fftw_export_wisdom_to_file</CODE> writes the <CODE>wisdom</CODE> to thecurrent position in <CODE>output_file</CODE>, which should be open with writepermission. Upon exit, the file remains open and is positioned at theend of the <CODE>wisdom</CODE> data.<P><CODE>fftw_export_wisdom_to_string</CODE> returns a pointer to a<CODE>NULL</CODE>-terminated string holding the <CODE>wisdom</CODE> data. Thisstring is dynamically allocated, and it is the responsibility of thecaller to deallocate it with <CODE>fftw_free</CODE> when it is no longerneeded.<P>All of these routines export the wisdom in the same format, which wewill not document here except to say that it is LISP-like ASCII textthat is insensitive to white space.<H3><A NAME="SEC43">Importing Wisdom</A></H3><PRE>#include <fftw.h>fftw_status fftw_import_wisdom(int (*get_input)(void *), void *data);fftw_status fftw_import_wisdom_from_file(FILE *input_file);fftw_status fftw_import_wisdom_from_string(const char *input_string);</PRE><P><A NAME="IDX190"></A><A NAME="IDX191"></A><A NAME="IDX192"></A><P>These functions import <CODE>wisdom</CODE> into a program from data stored bythe <CODE>fftw_export_wisdom</CODE> functions above. (See Section <A HREF="fftw_2.html#SEC13">Words of Wisdom</A>.)The imported <CODE>wisdom</CODE> supplements rather than replaces any<CODE>wisdom</CODE> already accumulated by the running program (except whenthere is conflicting <CODE>wisdom</CODE>, in which case the existing wisdom isreplaced).<P><CODE>fftw_import_wisdom</CODE> imports <CODE>wisdom</CODE> from any input medium,as specified by the callback function <CODE>get_input</CODE>. <CODE>get_input</CODE>is a <CODE>getc</CODE>-like function that returns the next character in theinput; its parameter is the <CODE>data</CODE> pointer passed to<CODE>fftw_import_wisdom</CODE>. If the end of the input data is reached(which should never happen for valid data), it may return either<CODE>NULL</CODE> (ASCII 0) or <CODE>EOF</CODE> (as defined in <CODE><stdio.h></CODE>).For convenience, the following two "wrapper" routines are provided:<P><CODE>fftw_import_wisdom_from_file</CODE> reads <CODE>wisdom</CODE> from thecurrent position in <CODE>input_file</CODE>, which should be open with readpermission. Upon exit, the file remains open and is positioned at theend of the <CODE>wisdom</CODE> data.<P><CODE>fftw_import_wisdom_from_string</CODE> reads <CODE>wisdom</CODE> from the<CODE>NULL</CODE>-terminated string <CODE>input_string</CODE>.<P>The return value of these routines is <CODE>FFTW_SUCCESS</CODE> if the wisdomwas read successfully, and <CODE>FFTW_FAILURE</CODE> otherwise. Note that, inall of these functions, any data in the input stream past the end of the<CODE>wisdom</CODE> data is simply ignored (it is not even read if the<CODE>wisdom</CODE> data is well-formed).<H3><A NAME="SEC44">Forgetting Wisdom</A></H3><PRE>#include <fftw.h>void fftw_forget_wisdom(void);</PRE><P><A NAME="IDX193"></A><P>Calling <CODE>fftw_forget_wisdom</CODE> causes all accumulated <CODE>wisdom</CODE>to be discarded and its associated memory to be freed. (New<CODE>wisdom</CODE> can still be gathered subsequently, however.)<H2><A NAME="SEC45">Memory Allocator Reference</A></H2><PRE>#include <fftw.h>void *(*fftw_malloc_hook) (size_t n);void (*fftw_free_hook) (void *p);</PRE><P><A NAME="IDX194"></A><A NAME="IDX195"></A><A NAME="IDX196"></A><A NAME="IDX197"></A><P>Whenever it has to allocate and release memory, FFTW ordinarily calls<CODE>malloc</CODE> and <CODE>free</CODE>. If <CODE>malloc</CODE> fails, FFTW prints an error message and exits. Thisbehavior may be undesirable in some applications. Also, specialmemory-handling functions may be necessary in certainenvironments. Consequently, FFTW provides means by which you can installyour own memory allocator and take whatever error-correcting action youfind appropriate. The variables <CODE>fftw_malloc_hook</CODE> and<CODE>fftw_free_hook</CODE> are pointers to functions, and they are normally<CODE>NULL</CODE>. If you set those variables to point to other functions,then FFTW will use your routines instead of <CODE>malloc</CODE> and<CODE>free</CODE>. <CODE>fftw_malloc_hook</CODE> must point to a <CODE>malloc</CODE>-likefunction, and <CODE>fftw_free_hook</CODE> must point to a <CODE>free</CODE>-likefunction.<H2><A NAME="SEC46">Thread safety</A></H2><P><A NAME="IDX198"></A><A NAME="IDX199"></A>Users writing multi-threaded programs must concern themselves with the<EM>thread safety</EM> of the libraries they use--that is, whether it issafe to call routines in parallel from multiple threads. FFTW can beused in such an environment, but some care must be taken because certainparts of FFTW use private global variables to share data between calls.In particular, the plan-creation functions share trigonometric tablesand accumulated <CODE>wisdom</CODE>. (Users should note that these commentsonly apply to programs using shared-memory threads. Parallelism usingMPI or forked processes involves a separate address-space and globalvariables for each process, and is not susceptible to problems of thissort.)<P>The central restriction of FFTW is that it is not safe to createmultiple plans in parallel. You must either create all of your plansfrom a single thread, or instead use a semaphore, mutex, or othermechanism to ensure that different threads don't attempt to create plansat the same time. The same restriction also holds for destruction ofplans and importing/forgetting <CODE>wisdom</CODE>. Once created, a plan maysafely be used in any thread.<P>The actual transform routines in FFTW (<CODE>fftw_one</CODE>, etcetera) arere-entrant and thread-safe, so it is fine to call them simultaneouslyfrom multiple threads. Another question arises, however--is it safe touse the <EM>same plan</EM> for multiple transforms in parallel? (It wouldbe unsafe if, for example, the plan were modified in some way by thetransform.) We address this question by defining an additional plannerflag, <CODE>FFTW_THREADSAFE</CODE>.<A NAME="IDX200"></A>When included in the flags for any of the plan-creation routines,<CODE>FFTW_THREADSAFE</CODE> guarantees that the resulting plan will beread-only and safe to use in parallel by multiple threads.<P><HR><P>Go to the <A HREF="fftw_1.html">first</A>, <A HREF="fftw_2.html">previous</A>, <A HREF="fftw_4.html">next</A>, <A HREF="fftw_10.html">last</A> section, <A HREF="fftw_toc.html">table of contents</A>.</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -