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