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