isce3 0.25.0
Loading...
Searching...
No Matches
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) \
75FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
76FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
77FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
78FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
79FFTW_EXTERN R *X(alloc_real)(size_t n); \
80FFTW_EXTERN C *X(alloc_complex)(size_t n); \
81FFTW_EXTERN double X(cost)(const X(plan) p);
82
83#define FFTW3CXX_DEFINE_FFTW335_NEW_API(X, R, C) \
84FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
85FFTW_EXTERN int X(alignment_of)(R *p); \
86FFTW_EXTERN void X(make_planner_thread_safe)(void);
87
88extern "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
97namespace 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\
116template<> \
117struct 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
391template<typename T>
392struct fftw {};
393
394// use the macro to define the differently typed APIs
395FFTW3CXX_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
396FFTW3CXX_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
397FFTW3CXX_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
409template<typename T>
410class 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
766template<typename T>
767inline void forget_wisdom(void)
769template<typename T>
770inline void cleanup(void)
771 { fftw<T>::cleanup(); }
772
773template<typename T>
774inline void set_timelimit(double t)
775 { fftw<T>::set_timelimit(t); }
776
777template<typename T>
778inline void plan_with_nthreads(int nthreads)
779 { fftw<T>::plan_with_nthreads(nthreads); }
780template<typename T>
781inline int init_threads(void)
782 { return fftw<T>::init_threads(); }
783template<typename T>
784inline void cleanup_threads(void)
786template<typename T>
787inline void make_planner_thread_safe(void)
789
790template<typename T>
791inline int export_wisdom_to_filename(const char *filename)
792 { return fftw<T>::export_wisdom_to_filename(filename); }
793template<typename T>
794inline void export_wisdom_to_file(FILE *output_file)
795 { fftw<T>::export_wisdom_to_file(output_file); }
796template<typename T>
797inline char *export_wisdom_to_string(void)
799template<typename T>
800inline void export_wisdom(void (*write_char)(char, void*), void *data)
801 { fftw<T>::export_wisdom(write_char, data); }
802
803template<typename T>
804inline int import_system_wisdom(void)
806template<typename T>
807inline int import_wisdom_from_filename(const char *filename)
808 { return fftw<T>::import_wisdom_from_filename(filename); }
809template<typename T>
810inline int import_wisdom_from_file(FILE *input_file)
811 { return fftw<T>::import_wisdom_from_file(input_file); }
812template<typename T>
813inline int import_wisdom_from_string(const char *input_string)
814 { return fftw<T>::import_wisdom_from_string(input_string); }
815template<typename T>
816inline int import_wisdom(int (*read_char)(void*), void *data)
817 { return fftw<T>::import_wisdom(read_char, data); }
818
819template<typename T>
820inline void *malloc(size_t n)
821 { return fftw<T>::malloc(n); }
822template<typename T>
823inline T *alloc_real(size_t n)
824 { return fftw<T>::alloc_real(n); }
825template<typename T>
826inline typename fftw<T>::complex *alloc_complex(size_t n)
827 { return fftw<T>::alloc_complex(n); }
828template<typename T>
829inline void free(void *p)
830 { fftw<T>::free(p); }
831
832template<typename T>
833inline int alignment_of(T *p)
834 { return fftw<T>::alignment_of(p); }
835template<typename T>
836inline const char *version(void)
837 { return fftw<T>::version; }
838template<typename T>
839inline const char *cc(void)
840 { return fftw<T>::cc; }
841template<typename T>
842inline const char *codelet_optim(void)
843 { return fftw<T>::codelet_optim; }
844
845} // namespace fftw3cxx
846} // namespace isce3
The isce3::fftw3cxx namespace.
Definition fftw3cxx.h:99
The isce3::io namespace.
Definition Constants.h:14
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5
Definition fftw3cxx.h:392

Generated for ISCE3.0 by doxygen 1.13.2.