1 /* -*- C -*- */
2 /*
3  * Copyright (c) 1997-1999 Massachusetts Institute of Technology
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20 
21 /* fftw.h -- system-wide definitions */
22 /* $Id: fftw.h,v 1.1.1.1 2004/11/10 16:07:38 rbd Exp $ */
23 
24 #ifndef FFTW_H
25 #define FFTW_H
26 
27 #include <stdlib.h>
28 #include <stdio.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif				/* __cplusplus */
33 
34 /* Define for using single precision */
35 /*
36  * If you can, use configure --enable-float instead of changing this
37  * flag directly
38  */
39 /* #undef FFTW_ENABLE_FLOAT */
40 
41 /* our real numbers */
42 #ifdef FFTW_ENABLE_FLOAT
43 typedef float fftw_real;
44 #else
45 typedef double fftw_real;
46 #endif
47 
48 /*********************************************
49  * Complex numbers and operations
50  *********************************************/
51 typedef struct {
52      fftw_real re, im;
53 } fftw_complex;
54 
55 #define c_re(c)  ((c).re)
56 #define c_im(c)  ((c).im)
57 
58 typedef enum {
59      FFTW_FORWARD = -1, FFTW_BACKWARD = 1
60 } fftw_direction;
61 
62 /* backward compatibility with FFTW-1.3 */
63 typedef fftw_complex FFTW_COMPLEX;
64 typedef fftw_real FFTW_REAL;
65 
66 #ifndef FFTW_1_0_COMPATIBILITY
67 #define FFTW_1_0_COMPATIBILITY 0
68 #endif
69 
70 #if FFTW_1_0_COMPATIBILITY
71 /* backward compatibility with FFTW-1.0 */
72 #define REAL fftw_real
73 #define COMPLEX fftw_complex
74 #endif
75 
76 /*********************************************
77  * Success or failure status
78  *********************************************/
79 
80 typedef enum {
81      FFTW_SUCCESS = 0, FFTW_FAILURE = -1
82 } fftw_status;
83 
84 /*********************************************
85  *              Codelets
86  *********************************************/
87 typedef void (fftw_notw_codelet)
88      (const fftw_complex *, fftw_complex *, int, int);
89 typedef void (fftw_twiddle_codelet)
90      (fftw_complex *, const fftw_complex *, int,
91       int, int);
92 typedef void (fftw_generic_codelet)
93      (fftw_complex *, const fftw_complex *, int,
94       int, int, int);
95 typedef void (fftw_real2hc_codelet)
96      (const fftw_real *, fftw_real *, fftw_real *,
97       int, int, int);
98 typedef void (fftw_hc2real_codelet)
99      (const fftw_real *, const fftw_real *,
100       fftw_real *, int, int, int);
101 typedef void (fftw_hc2hc_codelet)
102      (fftw_real *, const fftw_complex *,
103       int, int, int);
104 typedef void (fftw_rgeneric_codelet)
105      (fftw_real *, const fftw_complex *, int,
106       int, int, int);
107 
108 /*********************************************
109  *     Configurations
110  *********************************************/
111 /*
112  * A configuration is a database of all known codelets
113  */
114 
115 enum fftw_node_type {
116      FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER,
117      FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC
118 };
119 
120 /* description of a codelet */
121 typedef struct {
122      const char *name;		/* name of the codelet */
123      void (*codelet) ();	/* pointer to the codelet itself */
124      int size;			/* size of the codelet */
125      fftw_direction dir;	/* direction */
126      enum fftw_node_type type;	/* TWIDDLE or NO_TWIDDLE */
127      int signature;		/* unique id */
128      int ntwiddle;		/* number of twiddle factors */
129      const int *twiddle_order;	/*
130                                  * array that determines the order
131                                  * in which the codelet expects
132                                  * the twiddle factors
133                                  */
134 } fftw_codelet_desc;
135 
136 /* On Win32, you need to do funny things to access global variables
137    in shared libraries.  Thanks to Andrew Sterian for this hack. */
138 #if defined(__WIN32__) || defined(WIN32) || defined(_WINDOWS)
139 #  if defined(BUILD_FFTW_DLL)
140 #    define DL_IMPORT(type) __declspec(dllexport) type
141 #  elif defined(USE_FFTW_DLL)
142 #    define DL_IMPORT(type) __declspec(dllimport) type
143 #  else
144 #    define DL_IMPORT(type) type
145 #  endif
146 #else
147 #  define DL_IMPORT(type) type
148 #endif
149 
150 extern DL_IMPORT(const char *) fftw_version;
151 
152 /*****************************
153  *        Plans
154  *****************************/
155 /*
156  * A plan is a sequence of reductions to compute a FFT of
157  * a given size.  At each step, the FFT algorithm can:
158  *
159  * 1) apply a notw codelet, or
160  * 2) recurse and apply a twiddle codelet, or
161  * 3) apply the generic codelet.
162  */
163 
164 /* structure that contains twiddle factors */
165 typedef struct fftw_twiddle_struct {
166      int n;
167      const fftw_codelet_desc *cdesc;
168      fftw_complex *twarray;
169      struct fftw_twiddle_struct *next;
170      int refcnt;
171 } fftw_twiddle;
172 
173 typedef struct fftw_rader_data_struct {
174      struct fftw_plan_struct *plan;
175      fftw_complex *omega;
176      int g, ginv;
177      int p, flags, refcount;
178      struct fftw_rader_data_struct *next;
179      fftw_codelet_desc *cdesc;
180 } fftw_rader_data;
181 
182 typedef void (fftw_rader_codelet)
183      (fftw_complex *, const fftw_complex *, int,
184       int, int, fftw_rader_data *);
185 
186 /* structure that holds all the data needed for a given step */
187 typedef struct fftw_plan_node_struct {
188      enum fftw_node_type type;
189 
190      union {
191           /* nodes of type FFTW_NOTW */
192           struct {
193                int size;
194                fftw_notw_codelet *codelet;
195                const fftw_codelet_desc *codelet_desc;
196           } notw;
197 
198           /* nodes of type FFTW_TWIDDLE */
199           struct {
200                int size;
201                fftw_twiddle_codelet *codelet;
202                fftw_twiddle *tw;
203                struct fftw_plan_node_struct *recurse;
204                const fftw_codelet_desc *codelet_desc;
205           } twiddle;
206 
207           /* nodes of type FFTW_GENERIC */
208           struct {
209                int size;
210                fftw_generic_codelet *codelet;
211                fftw_twiddle *tw;
212                struct fftw_plan_node_struct *recurse;
213           } generic;
214 
215           /* nodes of type FFTW_RADER */
216           struct {
217                int size;
218                fftw_rader_codelet *codelet;
219                fftw_rader_data *rader_data;
220                fftw_twiddle *tw;
221                struct fftw_plan_node_struct *recurse;
222           } rader;
223 
224           /* nodes of type FFTW_REAL2HC */
225           struct {
226                int size;
227                fftw_real2hc_codelet *codelet;
228                const fftw_codelet_desc *codelet_desc;
229           } real2hc;
230 
231           /* nodes of type FFTW_HC2REAL */
232           struct {
233                int size;
234                fftw_hc2real_codelet *codelet;
235                const fftw_codelet_desc *codelet_desc;
236           } hc2real;
237 
238           /* nodes of type FFTW_HC2HC */
239           struct {
240                int size;
241                fftw_direction dir;
242                fftw_hc2hc_codelet *codelet;
243                fftw_twiddle *tw;
244                struct fftw_plan_node_struct *recurse;
245                const fftw_codelet_desc *codelet_desc;
246           } hc2hc;
247 
248           /* nodes of type FFTW_RGENERIC */
249           struct {
250                int size;
251                fftw_direction dir;
252                fftw_rgeneric_codelet *codelet;
253                fftw_twiddle *tw;
254                struct fftw_plan_node_struct *recurse;
255           } rgeneric;
256      } nodeu;
257 
258      int refcnt;
259 } fftw_plan_node;
260 
261 struct fftw_plan_struct {
262      int n;
263      int refcnt;
264      fftw_direction dir;
265      int flags;
266      int wisdom_signature;
267      enum fftw_node_type wisdom_type;
268      struct fftw_plan_struct *next;
269      fftw_plan_node *root;
270      double cost;
271 };
272 
273 /* a plan is just an array of instructions */
274 typedef struct fftw_plan_struct *fftw_plan;
275 
276 /* flags for the planner */
277 #define  FFTW_ESTIMATE (0)
278 #define  FFTW_MEASURE  (1)
279 
280 #define FFTW_OUT_OF_PLACE (0)
281 #define FFTW_IN_PLACE (8)
282 #define FFTW_USE_WISDOM (16)
283 
284 #define FFTW_THREADSAFE (128)  /* guarantee plan is read-only so that the
285                                   same plan can be used in parallel by
286                                   multiple threads */
287 
288 #define FFTWND_FORCE_BUFFERED (256)	/* internal, undocumented flag */
289 
290 extern fftw_plan fftw_create_plan_specific(int n, fftw_direction dir,
291                                            int flags,
292                                            fftw_complex *in, int istride,
293                                          fftw_complex *out, int ostride);
294 #define FFTW_HAS_PLAN_SPECIFIC
295 extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags);
296 extern void fftw_print_plan(fftw_plan plan);
297 extern void fftw_destroy_plan(fftw_plan plan);
298 extern void fftw(fftw_plan plan, int howmany, fftw_complex *in, int istride,
299                  int idist, fftw_complex *out, int ostride, int odist);
300 extern void fftw_one(fftw_plan plan, fftw_complex *in, fftw_complex *out);
301 extern void fftw_die(const char *s);
302 extern void *fftw_malloc(size_t n);
303 extern void fftw_free(void *p);
304 extern void fftw_check_memory_leaks(void);
305 extern void fftw_print_max_memory_usage(void);
306 
307 typedef void *(*fftw_malloc_type_function) (size_t n);
308 typedef void  (*fftw_free_type_function) (void *p);
309 typedef void  (*fftw_die_type_function) (const char *errString);
310 extern DL_IMPORT(fftw_malloc_type_function) fftw_malloc_hook;
311 extern DL_IMPORT(fftw_free_type_function) fftw_free_hook;
312 extern DL_IMPORT(fftw_die_type_function) fftw_die_hook;
313 
314 extern size_t fftw_sizeof_fftw_real(void);
315 
316 /* Wisdom: */
317 /*
318  * define this symbol so that users know we are using a version of FFTW
319  * with wisdom
320  */
321 #define FFTW_HAS_WISDOM
322 extern void fftw_forget_wisdom(void);
323 extern void fftw_export_wisdom(void (*emitter) (char c, void *), void *data);
324 extern fftw_status fftw_import_wisdom(int (*g) (void *), void *data);
325 extern void fftw_export_wisdom_to_file(FILE *output_file);
326 extern fftw_status fftw_import_wisdom_from_file(FILE *input_file);
327 extern char *fftw_export_wisdom_to_string(void);
328 extern fftw_status fftw_import_wisdom_from_string(const char *input_string);
329 
330 /*
331  * define symbol so we know this function is available (it is not in
332  * older FFTWs)
333  */
334 #define FFTW_HAS_FPRINT_PLAN
335 extern void fftw_fprint_plan(FILE *f, fftw_plan plan);
336 
337 /*****************************
338  *    N-dimensional code
339  *****************************/
340 typedef struct {
341      int is_in_place;		/* 1 if for in-place FFTs, 0 otherwise */
342 
343      int rank;			/*
344                                  * the rank (number of dimensions) of the
345                                  * array to be FFTed
346                                  */
347      int *n;			/*
348                                  * the dimensions of the array to the
349                                  * FFTed
350                                  */
351      fftw_direction dir;
352 
353      int *n_before;		/*
354                                  * n_before[i] = product of n[j] for j < i
355                                  */
356      int *n_after;		/* n_after[i] = product of n[j] for j > i */
357 
358      fftw_plan *plans;		/* 1d fftw plans for each dimension */
359 
360      int nbuffers, nwork;
361      fftw_complex *work;	/*
362                                  * work array big enough to hold
363                                  * nbuffers+1 of the largest dimension
364                                  * (has nwork elements)
365                                  */
366 } fftwnd_data;
367 
368 typedef fftwnd_data *fftwnd_plan;
369 
370 /* Initializing the FFTWND plan: */
371 extern fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir,
372                                       int flags);
373 extern fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz,
374                                       fftw_direction dir, int flags);
375 extern fftwnd_plan fftwnd_create_plan(int rank, const int *n,
376                                       fftw_direction dir,
377                                       int flags);
378 
379 extern fftwnd_plan fftw2d_create_plan_specific(int nx, int ny,
380                                                fftw_direction dir,
381                                                int flags,
382                                            fftw_complex *in, int istride,
383                                          fftw_complex *out, int ostride);
384 extern fftwnd_plan fftw3d_create_plan_specific(int nx, int ny, int nz,
385                                            fftw_direction dir, int flags,
386                                            fftw_complex *in, int istride,
387                                          fftw_complex *out, int ostride);
388 extern fftwnd_plan fftwnd_create_plan_specific(int rank, const int *n,
389                                                fftw_direction dir,
390                                                int flags,
391                                            fftw_complex *in, int istride,
392                                          fftw_complex *out, int ostride);
393 
394 /* Freeing the FFTWND plan: */
395 extern void fftwnd_destroy_plan(fftwnd_plan plan);
396 
397 /* Printing the plan: */
398 extern void fftwnd_fprint_plan(FILE *f, fftwnd_plan p);
399 extern void fftwnd_print_plan(fftwnd_plan p);
400 #define FFTWND_HAS_PRINT_PLAN
401 
402 /* Computing the N-Dimensional FFT */
403 extern void fftwnd(fftwnd_plan plan, int howmany,
404                    fftw_complex *in, int istride, int idist,
405                    fftw_complex *out, int ostride, int odist);
406 extern void fftwnd_one(fftwnd_plan p, fftw_complex *in, fftw_complex *out);
407 
408 #ifdef __cplusplus
409 }                               /* extern "C" */
410 
411 #endif				/* __cplusplus */
412 #endif				/* FFTW_H */
413