isce3  0.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
fftw3cxx.h
1 // fftw3cxx.hh version 1.2
2 /*
3  * Copyright (c) 2017 Gregory E. Allen
4  *
5  * This is free and unencumbered software released into the public domain.
6  *
7  * Anyone is free to copy, modify, publish, use, compile, sell, or
8  * distribute this software, either in source code form or as a compiled
9  * binary, for any purpose, commercial or non-commercial, and by any
10  * means.
11  *
12  * In jurisdictions that recognize copyright laws, the author or authors
13  * of this software dedicate any and all copyright interest in the
14  * software to the public domain. We make this dedication for the benefit
15  * of the public at large and to the detriment of our heirs and
16  * successors. We intend this dedication to be an overt act of
17  * relinquishment in perpetuity of all present and future rights to this
18  * software under copyright law.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  */
28 /*
29  * This file borrows significantly from fftw3.h, with the copyright below.
30  */
31 /*
32  * Copyright (c) 2003, 2007-14 Matteo Frigo
33  * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
34  *
35  * The following statement of license applies *only* to this header file,
36  * and *not* to the other files distributed with FFTW or derived therefrom:
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  *
42  * 1. Redistributions of source code must retain the above copyright
43  * notice, this list of conditions and the following disclaimer.
44  *
45  * 2. Redistributions in binary form must reproduce the above copyright
46  * notice, this list of conditions and the following disclaimer in the
47  * documentation and/or other materials provided with the distribution.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
50  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
53  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
55  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
57  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
58  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60  */
61 
62 #pragma once
63 
64 #include <stdexcept>
65 #include <complex>
66 #include <fftw3.h>
67 
68 //---
69 // Between fftw releases 3.2 and 3.3.5, several new API functions were added.
70 // We forward declare them here, so fftw3cxx works with any of these versions.
71 // If these functions were also declared in fftw3.h, no harm.
72 //---
73 
74 #define FFTW3CXX_DEFINE_FFTW330_NEW_API(X, R, C) \
75 FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
76 FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
77 FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
78 FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
79 FFTW_EXTERN R *X(alloc_real)(size_t n); \
80 FFTW_EXTERN C *X(alloc_complex)(size_t n); \
81 FFTW_EXTERN double X(cost)(const X(plan) p);
82 
83 #define FFTW3CXX_DEFINE_FFTW335_NEW_API(X, R, C) \
84 FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
85 FFTW_EXTERN int X(alignment_of)(R *p); \
86 FFTW_EXTERN void X(make_planner_thread_safe)(void);
87 
88 extern "C" {
89  FFTW3CXX_DEFINE_FFTW330_NEW_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
90  FFTW3CXX_DEFINE_FFTW330_NEW_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
91  FFTW3CXX_DEFINE_FFTW330_NEW_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
92  FFTW3CXX_DEFINE_FFTW335_NEW_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
93  FFTW3CXX_DEFINE_FFTW335_NEW_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
94  FFTW3CXX_DEFINE_FFTW335_NEW_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
95 }
96 
97 namespace isce3{
99  namespace fftw3cxx {
100 
101 //---
102 // Alias the fftw public API with a C++ templated-type style.
103 // e.g. fftw_plan becomes fftw<double>::plan
104 //---
105 
106 /*
107  Use a large macro in the style of fftw3.h
108 
109  X: name-mangling macro
110  R: real data type
111  C: complex data type
112 */
113 
114 #define FFTW3CXX_DEFINE_API(X, R, C) \
115 \
116 template<> \
117 struct fftw<R> { \
118  typedef X(plan) plan; \
119  typedef R real; \
120  typedef X(complex) complex; \
121  typedef X(iodim) iodim; \
122  typedef X(iodim64) iodim64; \
123  typedef X(r2r_kind) r2r_kind; \
124 \
125  static void execute(const plan p) \
126  { X(execute)(p); } \
127 \
128  static plan plan_dft(int rank, const int *n, \
129  C *in, C *out, int sign, unsigned flags) \
130  { return X(plan_dft)(rank, n, in, out, sign, flags); } \
131 \
132  static plan plan_dft_1d(int n, C *in, C *out, \
133  int sign, unsigned flags) \
134  { return X(plan_dft_1d)(n, in, out, sign, flags); } \
135  static plan plan_dft_2d(int n0, int n1, \
136  C *in, C *out, int sign, unsigned flags) \
137  { return X(plan_dft_2d)(n0, n1, in, out, sign, flags); } \
138  static plan plan_dft_3d(int n0, int n1, int n2, \
139  C *in, C *out, int sign, unsigned flags) \
140  { return X(plan_dft_3d)(n0, n1, n2, in, out, sign, flags); } \
141 \
142  static plan plan_many_dft(int rank, const int *n, int howmany, \
143  C *in, const int *inembed, int istride, int idist, \
144  C *out, const int *onembed, int ostride, int odist, \
145  int sign, unsigned flags) \
146  { return X(plan_many_dft)(rank, n, howmany, \
147  in, inembed, istride, idist, \
148  out, onembed, ostride, odist, sign, flags); } \
149 \
150  static plan plan_guru_dft(int rank, const iodim *dims, \
151  int howmany_rank, const iodim *howmany_dims, \
152  C *in, C *out, int sign, unsigned flags) \
153  { return X(plan_guru_dft)(rank, dims, \
154  howmany_rank, howmany_dims, in, out, sign, flags); } \
155  static plan plan_guru_split_dft(int rank, const iodim *dims, \
156  int howmany_rank, const iodim *howmany_dims, \
157  R *ri, R *ii, R *ro, R *io, unsigned flags) \
158  { return X(plan_guru_split_dft)(rank, dims, \
159  howmany_rank, howmany_dims, ri, ii, ro, io, flags); } \
160 \
161  static plan plan_guru64_dft(int rank, const iodim64 *dims, \
162  int howmany_rank, const iodim64 *howmany_dims,\
163  C *in, C *out, int sign, unsigned flags) \
164  { return X(plan_guru64_dft)(rank, dims, \
165  howmany_rank, howmany_dims, in, out, sign, flags); } \
166  static plan plan_guru64_split_dft(int rank, const iodim64 *dims, \
167  int howmany_rank, const iodim64 *howmany_dims, \
168  R *ri, R *ii, R *ro, R *io, unsigned flags) \
169  { return X(plan_guru64_split_dft)(rank, dims, \
170  howmany_rank, howmany_dims, ri, ii, ro, io, flags); } \
171 \
172  static void execute_dft(const plan p, C *in, C *out) \
173  { X(execute_dft)(p, in, out); } \
174  static void execute_split_dft(const plan p, R *ri, R *ii, \
175  R *ro, R *io) \
176  { X(execute_split_dft)(p, ri, ii, ro, io); } \
177 \
178  static plan plan_many_dft_r2c(int rank, const int *n, int howmany, \
179  R *in, const int *inembed, int istride, int idist, \
180  C *out, const int *onembed, int ostride, int odist, \
181  unsigned flags) \
182  { return X(plan_many_dft_r2c)(rank, n, howmany, \
183  in, inembed, istride, idist, \
184  out, onembed, ostride, odist, flags); } \
185 \
186  static plan plan_dft_r2c(int rank, const int *n, \
187  R *in, C *out, unsigned flags) \
188  { return X(plan_dft_r2c)(rank, n, in, out, flags); } \
189 \
190  static plan plan_dft_r2c_1d(int n, R *in, C *out, \
191  unsigned flags) \
192  { return X(plan_dft_r2c_1d)(n, in, out, flags); } \
193  static plan plan_dft_r2c_2d(int n0, int n1, \
194  R *in, C *out, unsigned flags) \
195  { return X(plan_dft_r2c_2d)(n0, n1, in, out, flags); } \
196  static plan plan_dft_r2c_3d(int n0, int n1, int n2, \
197  R *in, C *out, unsigned flags) \
198  { return X(plan_dft_r2c_3d)(n0, n1, n2, in, out, flags); } \
199 \
200  static plan plan_many_dft_c2r(int rank, const int *n, int howmany, \
201  C *in, const int *inembed, int istride, int idist, \
202  R *out, const int *onembed, int ostride, int odist, \
203  unsigned flags) \
204  { return X(plan_many_dft_c2r)(rank, n, howmany, \
205  in, inembed, istride, idist, \
206  out, onembed, ostride, odist, flags); } \
207 \
208  static plan plan_dft_c2r(int rank, const int *n, \
209  C *in, R *out, unsigned flags) \
210  { return X(plan_dft_c2r)(rank, n, in, out, flags); } \
211 \
212  static plan plan_dft_c2r_1d(int n, C *in, R *out, unsigned flags) \
213  { return X(plan_dft_c2r_1d)(n, in, out, flags); } \
214  static plan plan_dft_c2r_2d(int n0, int n1, \
215  C *in, R *out, unsigned flags) \
216  { return X(plan_dft_c2r_2d)(n0, n1, in, out, flags); } \
217  static plan plan_dft_c2r_3d(int n0, int n1, int n2, \
218  C *in, R *out, unsigned flags) \
219  { return X(plan_dft_c2r_3d)(n0, n1, n2, in, out, flags); } \
220 \
221  static plan plan_guru_dft_r2c(int rank, const iodim *dims, \
222  int howmany_rank, const iodim *howmany_dims, \
223  R *in, C *out, unsigned flags) \
224  { return X(plan_guru_dft_r2c)(rank, dims, \
225  howmany_rank, howmany_dims, in, out, flags); } \
226  static plan plan_guru_dft_c2r(int rank, const iodim *dims, \
227  int howmany_rank, const iodim *howmany_dims, \
228  C *in, R *out, unsigned flags) \
229  { return X(plan_guru_dft_c2r)(rank, dims, \
230  howmany_rank, howmany_dims, in, out, flags); } \
231 \
232  static plan plan_guru_split_dft_r2c( \
233  int rank, const iodim *dims, \
234  int howmany_rank, const iodim *howmany_dims, \
235  R *in, R *ro, R *io, unsigned flags) \
236  { return X(plan_guru_split_dft_r2c)(rank, dims, \
237  howmany_rank, howmany_dims, in, ro, io, flags); } \
238  static plan plan_guru_split_dft_c2r( \
239  int rank, const iodim *dims, \
240  int howmany_rank, const iodim *howmany_dims, \
241  R *ri, R *ii, R *out, unsigned flags) \
242  { return X(plan_guru_split_dft_c2r)(rank, dims, \
243  howmany_rank, howmany_dims, ri, ii, out, flags); } \
244 \
245  static plan plan_guru64_dft_r2c(int rank, const iodim64 *dims, \
246  int howmany_rank, const iodim64 *howmany_dims, \
247  R *in, C *out, unsigned flags) \
248  { return X(plan_guru64_dft_r2c)(rank, dims, \
249  howmany_rank, howmany_dims, in, out, flags); } \
250  static plan plan_guru64_dft_c2r(int rank, const iodim64 *dims, \
251  int howmany_rank, const iodim64 *howmany_dims, \
252  C *in, R *out, unsigned flags) \
253  { return X(plan_guru64_dft_c2r)(rank, dims, \
254  howmany_rank, howmany_dims, in, out, flags); } \
255 \
256  static plan plan_guru64_split_dft_r2c( \
257  int rank, const iodim64 *dims, \
258  int howmany_rank, const iodim64 *howmany_dims, \
259  R *in, R *ro, R *io, unsigned flags) \
260  { return X(plan_guru64_split_dft_r2c)(rank, dims, \
261  howmany_rank, howmany_dims, in, ro, io, flags); } \
262  static plan plan_guru64_split_dft_c2r( \
263  int rank, const iodim64 *dims, \
264  int howmany_rank, const iodim64 *howmany_dims, \
265  R *ri, R *ii, R *out, unsigned flags) \
266  { return X(plan_guru64_split_dft_c2r)(rank, dims, \
267  howmany_rank, howmany_dims, ri, ii, out, flags); } \
268 \
269  static void execute_dft_r2c(const plan p, R *in, C *out) \
270  { X(execute_dft_r2c)(p, in, out); } \
271  static void execute_dft_c2r(const plan p, C *in, R *out) \
272  { X(execute_dft_c2r)(p, in, out); } \
273 \
274  static void execute_split_dft_r2c(const plan p, \
275  R *in, R *ro, R *io) \
276  { X(execute_split_dft_r2c)(p, in, ro, io); } \
277  static void execute_split_dft_c2r(const plan p, \
278  R *ri, R *ii, R *out) \
279  { X(execute_split_dft_c2r)(p, ri, ii, out); } \
280 \
281  static plan plan_many_r2r(int rank, const int *n, int howmany, \
282  R *in, const int *inembed, int istride, int idist, \
283  R *out, const int *onembed, int ostride, int odist, \
284  const r2r_kind *kind, unsigned flags) \
285  { return X(plan_many_r2r)(rank, n, howmany, \
286  in, inembed, istride, idist, out, onembed, ostride, odist, \
287  kind, flags); } \
288 \
289  static plan plan_r2r(int rank, const int *n, R *in, R *out, \
290  const r2r_kind *kind, unsigned flags) \
291  { return X(plan_r2r)(rank, n, in, out, kind, flags); } \
292 \
293  static plan plan_r2r_1d(int n, R *in, R *out, \
294  r2r_kind kind, unsigned flags) \
295  { return X(plan_r2r_1d)(n, in, out, kind, flags); } \
296  static plan plan_r2r_2d(int n0, int n1, R *in, R *out, \
297  r2r_kind kind0, r2r_kind kind1, unsigned flags) \
298  { return X(plan_r2r_2d)(n0, n1, in, out, kind0, kind1, flags); } \
299  static plan plan_r2r_3d(int n0, int n1, int n2, \
300  R *in, R *out, \
301  r2r_kind kind0, r2r_kind kind1, r2r_kind kind2, unsigned flags) \
302  { return X(plan_r2r_3d)(n0, n1, n2, in, out, \
303  kind0, kind1, kind2, flags); } \
304 \
305  static plan plan_guru_r2r(int rank, const iodim *dims, \
306  int howmany_rank, const iodim *howmany_dims, \
307  R *in, R *out, const r2r_kind *kind, unsigned flags) \
308  { return X(plan_guru_r2r)(rank, dims, \
309  howmany_rank, howmany_dims, in, out, kind, flags); } \
310 \
311  static plan plan_guru64_r2r(int rank, const iodim64 *dims, \
312  int howmany_rank, const iodim64 *howmany_dims, \
313  R *in, R *out, const r2r_kind *kind, unsigned flags) \
314  { return X(plan_guru64_r2r)(rank, dims, \
315  howmany_rank, howmany_dims, in, out, kind, flags); } \
316 \
317  static void execute_r2r(const plan p, R *in, R *out) \
318  { X(execute_r2r)(p, in, out); } \
319 \
320  static void destroy_plan(plan p) { X(destroy_plan)(p); } \
321  static void forget_wisdom(void) { X(forget_wisdom)(); } \
322  static void cleanup(void) { X(cleanup)(); } \
323 \
324  static void set_timelimit(double t) \
325  { X(set_timelimit)(t); } \
326 \
327  static void plan_with_nthreads(int nthreads) \
328  { X(plan_with_nthreads)(nthreads); } \
329  static int init_threads(void) \
330  { return X(init_threads)(); } \
331  static void cleanup_threads(void) \
332  { X(cleanup_threads)(); } \
333  static void make_planner_thread_safe(void) \
334  { X(make_planner_thread_safe)(); } \
335 \
336  static int export_wisdom_to_filename(const char *filename) \
337  { return X(export_wisdom_to_filename)(filename); } \
338  static void export_wisdom_to_file(FILE *output_file) \
339  { X(export_wisdom_to_file)(output_file); } \
340  static char *export_wisdom_to_string(void) \
341  { return X(export_wisdom_to_string)(); } \
342  static void export_wisdom(void (*write_char)(char, void*), void *data) \
343  { X(export_wisdom)(write_char, data); } \
344 \
345  static int import_system_wisdom(void) \
346  { return X(import_system_wisdom)(); } \
347  static int import_wisdom_from_filename(const char *filename) \
348  { return X(import_wisdom_from_filename)(filename); } \
349  static int import_wisdom_from_file(FILE *input_file) \
350  { return X(import_wisdom_from_file)(input_file); } \
351  static int import_wisdom_from_string(const char *input_string) \
352  { return X(import_wisdom_from_string)(input_string); } \
353  static int import_wisdom(int (*read_char)(void*), void *data) \
354  { return X(import_wisdom)(read_char, data); } \
355 \
356  static void fprint_plan(const plan p, FILE *output_file) \
357  { X(fprint_plan)(p, output_file); } \
358  static void print_plan(const plan p) \
359  { X(print_plan)(p); } \
360  static char *sprint_plan(const plan p) \
361  { return X(sprint_plan)(p); } \
362 \
363  static void *malloc(size_t n) \
364  { return X(malloc)(n); } \
365  static R *alloc_real(size_t n) \
366  { return X(alloc_real)(n); } \
367  static C *alloc_complex(size_t n) \
368  { return X(alloc_complex)(n); } \
369  static void free(void *p) \
370  { X(free)(p); } \
371 \
372  static void flops(const plan p, \
373  double *add, double *mul, double *fmas) \
374  { X(flops)(p, add, mul, fmas); } \
375  static double estimate_cost(const plan p) \
376  { return X(estimate_cost)(p); } \
377  static double cost(const plan p) \
378  { return X(cost)(p); } \
379 \
380  static int alignment_of(R *p) \
381  { return X(alignment_of)(p); } \
382  static const char *version(void) \
383  { return X(version); } \
384  static const char *cc(void) \
385  { return X(cc); } \
386  static const char *codelet_optim(void) \
387  { return X(codelet_optim); } \
388 }; // struct fftw
389 
390 
391 template<typename T>
392 struct fftw {};
393 
394 // use the macro to define the differently typed APIs
395 FFTW3CXX_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
396 FFTW3CXX_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
397 FFTW3CXX_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
398 
399 // Quad float is a gcc extension and would need some attention.
400 // FFTW3CXX_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
401 
402 
403 //---
404 // A plan class using RAII and with inline methods
405 // that forward to the above fftw3cxx::fftw<T>:: API
406 // Supports both fftw's complex type and C++ std::complex.
407 //---
408 
409 template<typename T>
410 class plan {
411  public:
412  typedef plan<T> self_type;
413  typedef T R;
414  typedef typename fftw<T>::complex C;
415  typedef std::complex<T> SC;
416  typedef R real;
417  typedef C complex;
418  typedef SC std_complex;
419  typedef typename fftw<T>::iodim iodim;
420  typedef typename fftw<T>::iodim64 iodim64;
421  typedef typename fftw<T>::r2r_kind r2r_kind;
422 
423  plan(void): paux(0) {}
424  plan(typename fftw<T>::plan p): paux(new aux(p)) {}
425  plan(const self_type &other): paux(other.paux) { inc(); }
426  ~plan(void) { dec(); }
427  void swap(self_type &other)
428  { aux *tmp = other.paux; other.paux = paux; paux = tmp; }
429  self_type& operator=(self_type other)
430  { swap(other); return *this; }
431  void clear(void) { self_type t; *this = t; }
432  bool empty(void) const { return paux==0; }
433 
434  // What follows is most of the fftw3 API
435  // in the same order it appears in fftw3.h
436  // Plan creators are static named constructors and
437  // plan executors are methods
438 
439  void execute(void) const
440  { fftw<T>::execute(p()); }
441 
442  static self_type plan_dft(int rank, const int *n,
443  C *in, C *out, int sign, unsigned flags)
444  { return fftw<T>::plan_dft(rank, n, in, out, sign, flags); }
445  static self_type plan_dft(int rank, const int *n,
446  SC *in, SC *out, int sign, unsigned flags)
447  { return fftw<T>::plan_dft(rank, n, (C*)in, (C*)out, sign, flags); }
448 
449  static self_type plan_dft_1d(int n,
450  C *in, C *out, int sign, unsigned flags)
451  { return fftw<T>::plan_dft_1d(n, in, out, sign, flags); }
452  static self_type plan_dft_1d(int n,
453  SC *in, SC *out, int sign, unsigned flags)
454  { return fftw<T>::plan_dft_1d(n, (C*)in, (C*)out, sign, flags); }
455  static self_type plan_dft_2d(int n0, int n1,
456  C *in, C *out, int sign, unsigned flags)
457  { return fftw<T>::plan_dft_2d(n0, n1, in, out, sign, flags); }
458  static self_type plan_dft_2d(int n0, int n1,
459  SC *in, SC *out, int sign, unsigned flags)
460  { return fftw<T>::plan_dft_2d(n0, n1, (C*)in, (C*)out, sign, flags); }
461  static self_type plan_dft_3d(int n0, int n1, int n2,
462  C *in, C *out, int sign, unsigned flags)
463  { return fftw<T>::plan_dft_3d(n0, n1, n2, in, out, sign, flags); }
464  static self_type plan_dft_3d(int n0, int n1, int n2,
465  SC *in, SC *out, int sign, unsigned flags)
466  { return fftw<T>::plan_dft_3d(n0, n1, n2, (C*)in, (C*)out, sign, flags); }
467 
468  static self_type plan_many_dft(int rank, const int *n, int howmany,
469  C *in, const int *inembed, int istride, int idist,
470  C *out, const int *onembed, int ostride, int odist,
471  int sign, unsigned flags)
472  { return fftw<T>::plan_many_dft(rank, n, howmany,
473  in, inembed, istride, idist,
474  out, onembed, ostride, odist, sign, flags); }
475  static self_type plan_many_dft(int rank, const int *n, int howmany,
476  SC *in, const int *inembed, int istride, int idist,
477  SC *out, const int *onembed, int ostride, int odist,
478  int sign, unsigned flags)
479  { return fftw<T>::plan_many_dft(rank, n, howmany,
480  (C*)in, inembed, istride, idist,
481  (C*)out, onembed, ostride, odist, sign, flags); }
482 
483  static self_type plan_guru_dft(int rank, const iodim *dims,
484  int howmany_rank, const iodim *howmany_dims,
485  C *in, C *out, int sign, unsigned flags)
486  { return fftw<T>::plan_guru_dft(rank, dims,
487  howmany_rank, howmany_dims, in, out, sign, flags); }
488  static self_type plan_guru_dft(int rank, const iodim *dims,
489  int howmany_rank, const iodim *howmany_dims,
490  SC *in, SC *out, int sign, unsigned flags)
491  { return fftw<T>::plan_guru_dft(rank, dims,
492  howmany_rank, howmany_dims, (C*)in, (C*)out, sign, flags); }
493  static self_type plan_guru_split_dft(int rank, const iodim *dims,
494  int howmany_rank, const iodim *howmany_dims,
495  R *ri, R *ii, R *ro, R *io, unsigned flags)
496  { return fftw<T>::plan_guru_split_dft(rank, dims,
497  howmany_rank, howmany_dims, ri, ii, ro, io, flags); }
498 
499  static self_type plan_guru64_dft(int rank, const iodim64 *dims,
500  int howmany_rank, const iodim64 *howmany_dims,
501  C *in, C *out, int sign, unsigned flags)
502  { return fftw<T>::plan_guru64_dft(rank, dims,
503  howmany_rank, howmany_dims, in, out, sign, flags); }
504  static self_type plan_guru64_dft(int rank, const iodim64 *dims,
505  int howmany_rank, const iodim64 *howmany_dims,
506  SC *in, SC *out, int sign, unsigned flags)
507  { return fftw<T>::plan_guru64_dft(rank, dims,
508  howmany_rank, howmany_dims, (C*)in, (C*)out, sign, flags); }
509  static self_type plan_guru64_split_dft(int rank, const iodim64 *dims,
510  int howmany_rank, const iodim64 *howmany_dims,
511  R *ri, R *ii, R *ro, R *io, unsigned flags)
512  { return fftw<T>::plan_guru64_split_dft(rank, dims,
513  howmany_rank, howmany_dims, ri, ii, ro, io, flags); }
514 
515  void execute_dft(C *in, C *out) const
516  { fftw<T>::execute_dft(p(), in, out); }
517  void execute_dft(SC *in, SC *out) const
518  { fftw<T>::execute_dft(p(), (C*)in, (C*)out); }
519  void execute_split_dft(R *ri, R *ii, R *ro, R *io) const
520  { fftw<T>::execute_split_dft(p(), ri, ii, ro, io); }
521 
522  static self_type plan_many_dft_r2c(int rank, const int *n, int howmany,
523  R *in, const int *inembed, int istride, int idist,
524  C *out, const int *onembed, int ostride, int odist,
525  unsigned flags)
526  { return fftw<T>::plan_many_dft_r2c(rank, n, howmany,
527  in, inembed, istride, idist,
528  out, onembed, ostride, odist, flags); }
529  static self_type plan_many_dft_r2c(int rank, const int *n, int howmany,
530  R *in, const int *inembed, int istride, int idist,
531  SC *out, const int *onembed, int ostride, int odist,
532  unsigned flags)
533  { return fftw<T>::plan_many_dft_r2c(rank, n, howmany,
534  in, inembed, istride, idist,
535  (C*)out, onembed, ostride, odist, flags); }
536 
537  static self_type plan_dft_r2c(int rank, const int *n,
538  R *in, C *out, unsigned flags)
539  { return fftw<T>::plan_dft_r2c(rank, n, in, out, flags); }
540  static self_type plan_dft_r2c(int rank, const int *n,
541  R *in, SC *out, unsigned flags)
542  { return fftw<T>::plan_dft_r2c(rank, n, in, (C*)out, flags); }
543 
544  static self_type plan_dft_r2c_1d(int n, R *in, C *out,
545  unsigned flags)
546  { return fftw<T>::plan_dft_r2c_1d(n, in, out, flags); }
547  static self_type plan_dft_r2c_1d(int n, R *in, SC *out,
548  unsigned flags)
549  { return fftw<T>::plan_dft_r2c_1d(n, in, (C*)out, flags); }
550  static self_type plan_dft_r2c_2d(int n0, int n1,
551  R *in, C *out, unsigned flags)
552  { return fftw<T>::plan_dft_r2c_2d(n0, n1, in, out, flags); }
553  static self_type plan_dft_r2c_2d(int n0, int n1,
554  R *in, SC *out, unsigned flags)
555  { return fftw<T>::plan_dft_r2c_2d(n0, n1, in, (C*)out, flags); }
556  static self_type plan_dft_r2c_3d(int n0, int n1, int n2,
557  R *in, C *out, unsigned flags)
558  { return fftw<T>::plan_dft_r2c_3d(n0, n1, n2, in, out, flags); }
559  static self_type plan_dft_r2c_3d(int n0, int n1, int n2,
560  R *in, SC *out, unsigned flags)
561  { return fftw<T>::plan_dft_r2c_3d(n0, n1, n2, in, (C*)out, flags); }
562 
563  static self_type plan_many_dft_c2r(int rank, const int *n, int howmany,
564  C *in, const int *inembed, int istride, int idist,
565  R *out, const int *onembed, int ostride, int odist,
566  unsigned flags)
567  { return fftw<T>::plan_many_dft_c2r(rank, n, howmany,
568  in, inembed, istride, idist,
569  out, onembed, ostride, odist, flags); }
570  static self_type plan_many_dft_c2r(int rank, const int *n, int howmany,
571  SC *in, const int *inembed, int istride, int idist,
572  R *out, const int *onembed, int ostride, int odist,
573  unsigned flags)
574  { return fftw<T>::plan_many_dft_c2r(rank, n, howmany,
575  (C*)in, inembed, istride, idist,
576  out, onembed, ostride, odist, flags); }
577 
578  static self_type plan_dft_c2r(int rank, const int *n,
579  C *in, R *out, unsigned flags)
580  { return fftw<T>::plan_dft_c2r(rank, n, in, out, flags); }
581  static self_type plan_dft_c2r(int rank, const int *n,
582  SC *in, R *out, unsigned flags)
583  { return fftw<T>::plan_dft_c2r(rank, n, (C*)in, out, flags); }
584 
585  static self_type plan_dft_c2r_1d(int n, C *in, R *out, unsigned flags)
586  { return fftw<T>::plan_dft_c2r_1d(n, in, out, flags); }
587  static self_type plan_dft_c2r_1d(int n, SC *in, R *out, unsigned flags)
588  { return fftw<T>::plan_dft_c2r_1d(n, (C*)in, out, flags); }
589  static self_type plan_dft_c2r_2d(int n0, int n1,
590  C *in, R *out, unsigned flags)
591  { return fftw<T>::plan_dft_c2r_2d(n0, n1, in, out, flags); }
592  static self_type plan_dft_c2r_2d(int n0, int n1,
593  SC *in, R *out, unsigned flags)
594  { return fftw<T>::plan_dft_c2r_2d(n0, n1, (C*)in, out, flags); }
595  static self_type plan_dft_c2r_3d(int n0, int n1, int n2,
596  C *in, R *out, unsigned flags)
597  { return fftw<T>::plan_dft_c2r_3d(n0, n1, n2, in, out, flags); }
598  static self_type plan_dft_c2r_3d(int n0, int n1, int n2,
599  SC *in, R *out, unsigned flags)
600  { return fftw<T>::plan_dft_c2r_3d(n0, n1, n2, (C*)in, out, flags); }
601 
602  static self_type plan_guru_dft_r2c(int rank, const iodim *dims,
603  int howmany_rank, const iodim *howmany_dims,
604  R *in, C *out, unsigned flags)
605  { return fftw<T>::plan_guru_dft_r2c(rank, dims,
606  howmany_rank, howmany_dims, in, out, flags); }
607  static self_type plan_guru_dft_r2c(int rank, const iodim *dims,
608  int howmany_rank, const iodim *howmany_dims,
609  R *in, SC *out, unsigned flags)
610  { return fftw<T>::plan_guru_dft_r2c(rank, dims,
611  howmany_rank, howmany_dims, in, (C*)out, flags); }
612  static self_type plan_guru_dft_c2r(int rank, const iodim *dims,
613  int howmany_rank, const iodim *howmany_dims,
614  C *in, R *out, unsigned flags)
615  { return fftw<T>::plan_guru_dft_c2r(rank, dims,
616  howmany_rank, howmany_dims, in, out, flags); }
617  static self_type plan_guru_dft_c2r(int rank, const iodim *dims,
618  int howmany_rank, const iodim *howmany_dims,
619  SC *in, R *out, unsigned flags)
620  { return fftw<T>::plan_guru_dft_c2r(rank, dims,
621  howmany_rank, howmany_dims, (C*)in, out, flags); }
622 
623  static self_type plan_guru_split_dft_r2c(
624  int rank, const iodim *dims,
625  int howmany_rank, const iodim *howmany_dims,
626  R *in, R *ro, R *io, unsigned flags)
627  { return fftw<T>::plan_guru_split_dft_r2c(rank, dims,
628  howmany_rank, howmany_dims, in, ro, io, flags); }
629  static self_type plan_guru_split_dft_c2r(
630  int rank, const iodim *dims,
631  int howmany_rank, const iodim *howmany_dims,
632  R *ri, R *ii, R *out, unsigned flags)
633  { return fftw<T>::plan_guru_split_dft_c2r(rank, dims,
634  howmany_rank, howmany_dims, ri, ii, out, flags); }
635 
636  static self_type plan_guru64_dft_r2c(int rank, const iodim64 *dims,
637  int howmany_rank, const iodim64 *howmany_dims,
638  R *in, C *out, unsigned flags)
639  { return fftw<T>::plan_guru64_dft_r2c(rank, dims,
640  howmany_rank, howmany_dims, in, out, flags); }
641  static self_type plan_guru64_dft_r2c(int rank, const iodim64 *dims,
642  int howmany_rank, const iodim64 *howmany_dims,
643  R *in, SC *out, unsigned flags)
644  { return fftw<T>::plan_guru64_dft_r2c(rank, dims,
645  howmany_rank, howmany_dims, in, (C*)out, flags); }
646  static self_type plan_guru64_dft_c2r(int rank, const iodim64 *dims,
647  int howmany_rank, const iodim64 *howmany_dims,
648  C *in, R *out, unsigned flags)
649  { return fftw<T>::plan_guru64_dft_c2r(rank, dims,
650  howmany_rank, howmany_dims, in, out, flags); }
651  static self_type plan_guru64_dft_c2r(int rank, const iodim64 *dims,
652  int howmany_rank, const iodim64 *howmany_dims,
653  SC *in, R *out, unsigned flags)
654  { return fftw<T>::plan_guru64_dft_c2r(rank, dims,
655  howmany_rank, howmany_dims, (C*)in, out, flags); }
656 
657  static self_type plan_guru64_split_dft_r2c(
658  int rank, const iodim64 *dims,
659  int howmany_rank, const iodim64 *howmany_dims,
660  R *in, R *ro, R *io, unsigned flags)
661  { return fftw<T>::plan_guru64_split_dft_r2c(rank, dims,
662  howmany_rank, howmany_dims, in, ro, io, flags); }
663  static self_type plan_guru64_split_dft_c2r(
664  int rank, const iodim64 *dims,
665  int howmany_rank, const iodim64 *howmany_dims,
666  R *ri, R *ii, R *out, unsigned flags)
667  { return fftw<T>::plan_guru64_split_dft_c2r(rank, dims,
668  howmany_rank, howmany_dims, ri, ii, out, flags); }
669 
670  void execute_dft_r2c(R *in, C *out) const
671  { fftw<T>::execute_dft_r2c(p(), in, out); }
672  void execute_dft_r2c(R *in, SC *out) const
673  { fftw<T>::execute_dft_r2c(p(), in, (C*)out); }
674  void execute_dft_c2r(C *in, R *out) const
675  { fftw<T>::execute_dft_c2r(p(), in, out); }
676  void execute_dft_c2r(SC *in, R *out) const
677  { fftw<T>::execute_dft_c2r(p(), (C*)in, out); }
678 
679  void execute_split_dft_r2c(R *in, R *ro, R *io) const
680  { fftw<T>::execute_split_dft_r2c(p(), in, ro, io); }
681  void execute_split_dft_c2r(R *ri, R *ii, R *out) const
682  { fftw<T>::execute_split_dft_c2r(p(), ri, ii, out); }
683 
684  static self_type plan_many_r2r(int rank, const int *n, int howmany,
685  R *in, const int *inembed, int istride, int idist,
686  R *out, const int *onembed, int ostride, int odist,
687  const r2r_kind *kind, unsigned flags)
688  { return fftw<T>::plan_many_r2r(rank, n, howmany,
689  in, inembed, istride, idist, out, onembed, ostride, odist,
690  kind, flags); }
691 
692  static self_type plan_r2r(int rank, const int *n, R *in, R *out,
693  const r2r_kind *kind, unsigned flags)
694  { return fftw<T>::plan_r2r(rank, n, in, out, kind, flags); }
695 
696  static self_type plan_r2r_1d(int n, R *in, R *out,
697  r2r_kind kind, unsigned flags)
698  { return fftw<T>::plan_r2r_1d(n, in, out, kind, flags); }
699  static self_type plan_r2r_2d(int n0, int n1, R *in, R *out,
700  r2r_kind kind0, r2r_kind kind1, unsigned flags)
701  { return fftw<T>::plan_r2r_2d(n0, n1, in, out, kind0, kind1, flags); }
702  static self_type plan_r2r_3d(int n0, int n1, int n2,
703  R *in, R *out,
704  r2r_kind kind0, r2r_kind kind1, r2r_kind kind2, unsigned flags)
705  { return fftw<T>::plan_r2r_3d(n0, n1, n2, in, out,
706  kind0, kind1, kind2, flags); }
707 
708  static self_type plan_guru_r2r(int rank, const iodim *dims,
709  int howmany_rank, const iodim *howmany_dims,
710  R *in, R *out, const r2r_kind *kind, unsigned flags)
711  { return fftw<T>::plan_guru_r2r(rank, dims,
712  howmany_rank, howmany_dims, in, out, kind, flags); }
713 
714  static self_type plan_guru64_r2r(int rank, const iodim64 *dims,
715  int howmany_rank, const iodim64 *howmany_dims,
716  R *in, R *out, const r2r_kind *kind, unsigned flags)
717  { return fftw<T>::plan_guru64_r2r(rank, dims,
718  howmany_rank, howmany_dims, in, out, kind, flags); }
719 
720  void execute_r2r(R *in, R *out) const
721  { fftw<T>::execute_r2r(p(), in, out); }
722 
723  // This ends following the order of fftw3.h
724 
725  // additional plan methods
726  void fprint(FILE *output_file) const
727  { fftw<T>::fprint_plan(p(), output_file); }
728  void print(void) const
729  { fftw<T>::print_plan(p()); }
730  char *sprint(void) const
731  { return fftw<T>::sprint_plan(p()); }
732  void flops(double *add, double *mul, double *fmas) const
733  { fftw<T>::flops(p(), add, mul, fmas); }
734  double estimate_cost(void) const
735  { return fftw<T>::estimate_cost(p()); }
736  double cost(void) const
737  { return fftw<T>::cost(p()); }
738 
739  private:
740  class aux {
741  typename fftw<T>::plan p;
742  unsigned refcnt;
743  aux(typename fftw<T>::plan p_): p(p_), refcnt(1) {}
744  ~aux(void) { fftw<T>::destroy_plan(p); }
745  void inc(void) { ++refcnt; }
746  unsigned dec(void) { return --refcnt; }
747  friend class plan<T>;
748  };
749  aux *paux;
750  void inc(void) { if (paux) paux->inc(); }
751  void dec(void) { if (paux && !paux->dec()) { delete paux; paux = 0; } }
752  typename fftw<T>::plan p(void) const {
753  if (!paux) throw std::runtime_error("plan is not initialized");
754  return paux->p;
755  }
756 };
757 
758 //---
759 // Define template functions to put the remaining (non-plan) FFTW API
760 // directly into the fftw3cxx namespace.
761 // e.g. fftw3cxx::fftw<double>::forget_wisdom is fftw3cxx::forget_wisdom<double>
762 //---
763 
764 // The remainder appears in the same order as fftw3.h
765 
766 template<typename T>
767 inline void forget_wisdom(void)
769 template<typename T>
770 inline void cleanup(void)
771  { fftw<T>::cleanup(); }
772 
773 template<typename T>
774 inline void set_timelimit(double t)
775  { fftw<T>::set_timelimit(t); }
776 
777 template<typename T>
778 inline void plan_with_nthreads(int nthreads)
779  { fftw<T>::plan_with_nthreads(nthreads); }
780 template<typename T>
781 inline int init_threads(void)
782  { return fftw<T>::init_threads(); }
783 template<typename T>
784 inline void cleanup_threads(void)
785  { fftw<T>::cleanup_threads(); }
786 template<typename T>
787 inline void make_planner_thread_safe(void)
788  { fftw<T>::make_planner_thread_safe(); }
789 
790 template<typename T>
791 inline int export_wisdom_to_filename(const char *filename)
792  { return fftw<T>::export_wisdom_to_filename(filename); }
793 template<typename T>
794 inline void export_wisdom_to_file(FILE *output_file)
795  { fftw<T>::export_wisdom_to_file(output_file); }
796 template<typename T>
797 inline char *export_wisdom_to_string(void)
798  { return fftw<T>::export_wisdom_to_string(); }
799 template<typename T>
800 inline void export_wisdom(void (*write_char)(char, void*), void *data)
801  { fftw<T>::export_wisdom(write_char, data); }
802 
803 template<typename T>
804 inline int import_system_wisdom(void)
805  { return fftw<T>::import_system_wisdom(); }
806 template<typename T>
807 inline int import_wisdom_from_filename(const char *filename)
808  { return fftw<T>::import_wisdom_from_filename(filename); }
809 template<typename T>
810 inline int import_wisdom_from_file(FILE *input_file)
811  { return fftw<T>::import_wisdom_from_file(input_file); }
812 template<typename T>
813 inline int import_wisdom_from_string(const char *input_string)
814  { return fftw<T>::import_wisdom_from_string(input_string); }
815 template<typename T>
816 inline int import_wisdom(int (*read_char)(void*), void *data)
817  { return fftw<T>::import_wisdom(read_char, data); }
818 
819 template<typename T>
820 inline void *malloc(size_t n)
821  { return fftw<T>::malloc(n); }
822 template<typename T>
823 inline T *alloc_real(size_t n)
824  { return fftw<T>::alloc_real(n); }
825 template<typename T>
826 inline typename fftw<T>::complex *alloc_complex(size_t n)
827  { return fftw<T>::alloc_complex(n); }
828 template<typename T>
829 inline void free(void *p)
830  { fftw<T>::free(p); }
831 
832 template<typename T>
833 inline int alignment_of(T *p)
834  { return fftw<T>::alignment_of(p); }
835 template<typename T>
836 inline const char *version(void)
837  { return fftw<T>::version; }
838 template<typename T>
839 inline const char *cc(void)
840  { return fftw<T>::cc; }
841 template<typename T>
842 inline const char *codelet_optim(void)
843  { return fftw<T>::codelet_optim; }
844 
845 } // namespace fftw3cxx
846 } // namespace isce3
Definition: fftw3cxx.h:392
Definition: fftw3cxx.h:410

Generated for ISCE3.0 by doxygen 1.8.5.