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