JayBeams  0.1
Another project to have fun coding.
traits.hpp
Go to the documentation of this file.
1 #ifndef jb_fftw_traits_hpp
2 #define jb_fftw_traits_hpp
3 
4 #include <fftw3.h>
5 #include <complex>
6 #include <vector>
7 
8 namespace jb {
9 namespace fftw {
10 
11 /**
12  * Wrap fftw_* types and operations to treat floating point values generically.
13  *
14  * Type traits to handle single-precision (float / fftwf_*),
15  * double-precision (double / fftw_*) and quad-precision
16  * (long double / fftwl_*) generically in C++ code.
17  *
18  * @tparam precision_t the type of floating point value, must be
19  * either float, double or long double.
20  */
21 template <typename precision_t>
22 struct traits;
23 
24 /**
25  * Wrap the FFTW types and functions for double precision float point numbers
26  */
27 template <>
28 struct traits<double> {
29  //@{
30  /**
31  * @name type traits
32  */
33  /// The type used to represent floating point numbers
34  typedef double precision_type;
35  /// The type used to represent complex numbers in the C++ standard library
36  typedef ::std::complex<double> std_complex_type;
37  /// The type used to represent complex numbers in FFTW
38  typedef ::fftw_complex fftw_complex_type;
39  /// The type used to represent execution plans in FFTW
40  typedef ::fftw_plan fftw_plan_type;
41  //@}
42 
43  /**
44  * Allocate a properly aligned (for SIMD acceleration) block of memory
45  *
46  * @param n the number of bytes to allocate
47  * @returns a block for at least @a n bytes
48  */
49  static void* allocate(std::size_t n) {
50  return ::fftw_malloc(n);
51  }
52 
53  /**
54  * Release a block of memory allocated with allocate()
55  *
56  * @param buffer the block to release
57  */
58  static void release(void* buffer) {
59  ::fftw_free(buffer);
60  }
61 
62  /**
63  * Execute an existing plan for a given input and output
64  *
65  * FFTW requires, but does not check that the input and output have
66  * the same alignment and sizes defined in the original plan.
67  *
68  * @param p the execution plan
69  * @param in the input vector (or array)
70  * @param out the output data (or array)
71  */
72  static void execute_plan(
73  fftw_plan_type const p, fftw_complex_type const* in,
74  fftw_complex_type* out) {
75  ::fftw_execute_dft(p, const_cast<fftw_complex_type*>(in), out);
76  }
77 
78  /**
79  * Execute an existing plan for a given input and output
80  *
81  * FFTW requires, but does not check that the input and output have
82  * the same alignment and sizes defined in the original plan.
83  *
84  * @param p the execution plan
85  * @param in the input vector (or array)
86  * @param out the output vector (or array)
87  */
88  static void execute_plan(
89  fftw_plan_type const p, precision_type const* in,
90  fftw_complex_type* out) {
91  ::fftw_execute_dft_r2c(p, const_cast<precision_type*>(in), out);
92  }
93 
94  /**
95  * Execute an existing plan for a given input and output
96  *
97  * FFTW requires, but does not check that the input and output have
98  * the same alignment and sizes defined in the original plan.
99  *
100  * @param p the execution plan
101  * @param in the input vector (or array)
102  * @param out the output vector (or array), can be the same as the input
103  */
104  static void execute_plan(
105  fftw_plan_type const p, fftw_complex_type const* in,
106  precision_type* out) {
107  ::fftw_execute_dft_c2r(p, const_cast<fftw_complex_type*>(in), out);
108  }
109 
110  /**
111  * Create an execution plan to compute the DFT based on the input
112  * and output exemplars
113  *
114  * @returns the execution plan
115  * @param size the size of the input and output vectors
116  * @param in the input vector
117  * @param out the output vector
118  * @param flags control the algorithm choices in FFTW
119  */
120  static fftw_plan_type create_forward_plan(
121  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
122  int flags) {
123  return ::fftw_plan_dft_1d(
124  size, const_cast<fftw_complex_type*>(in), out, FFTW_FORWARD, flags);
125  }
126 
127  /**
128  * Create an execution to compute the inverse DFT based on the input
129  * and output exemplars
130  *
131  * @returns the execution plan
132  * @param size the size of the input and output vectors
133  * @param in the input vector
134  * @param out the output vector
135  * @param flags control the algorithm choices in FFTW
136  */
137  static fftw_plan_type create_backward_plan(
138  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
139  int flags) {
140  return ::fftw_plan_dft_1d(
141  size, const_cast<fftw_complex_type*>(in), out, FFTW_BACKWARD, flags);
142  }
143 
144  /**
145  * Create an execution to compute the DFT based on the input
146  * and output exemplars
147  *
148  * @returns the execution plan
149  * @param size the size of the input and output vectors
150  * @param in the input vector
151  * @param out the output vector
152  * @param flags control the algorithm choices in FFTW
153  */
154  static fftw_plan_type create_plan(
155  std::size_t size, precision_type const* in, fftw_complex_type* out,
156  int flags) {
157  return ::fftw_plan_dft_r2c_1d(
158  size, const_cast<precision_type*>(in), out, flags);
159  }
160 
161  /**
162  * Create an execution to compute the inverse DFT based on the input
163  * and output exemplars
164  *
165  * @returns the execution plan
166  * @param size the size of the input and output vectors
167  * @param in the input vector
168  * @param out the output vector
169  * @param flags control the algorithm choices in FFTW
170  */
171  static fftw_plan_type create_plan(
172  std::size_t size, fftw_complex_type const* in, precision_type* out,
173  int flags) {
174  return ::fftw_plan_dft_c2r_1d(
175  size, const_cast<fftw_complex_type*>(in), out, flags);
176  }
177 
178  /**
179  * Create an execution to compute the DFT of many vectors based on the input
180  * and output exemplars
181  *
182  * @returns the execution plan
183  * @param howmany how many timeseries in the arrays
184  * @param size the size of the input and output vectors
185  * @param in the input array must be of size @a howmany*size
186  * @param out the output array must be of size @a howmany*size
187  * @param flags control the algorithm choices in FFTW
188  */
189  static fftw_plan_type create_forward_plan_many(
190  int howmany, std::size_t size, fftw_complex_type const* in,
191  fftw_complex_type* out, int flags) {
192  int const rank = 1;
193  int const n[rank] = {static_cast<int>(size)};
194  int const istride = 1;
195  int const ostride = 1;
196  int const* inembed = nullptr;
197  int const* onembed = nullptr;
198  int const idist = n[0];
199  int const odist = n[0];
200  return ::fftw_plan_many_dft(
201  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
202  idist, out, onembed, ostride, odist, FFTW_FORWARD, flags);
203  }
204 
205  /**
206  * Create an execution to compute the inverse DFT of many vectors
207  * based on the input and output exemplars
208  *
209  * @returns the execution plan
210  * @param howmany how many timeseries in the arrays
211  * @param size the size of the input and output vectors
212  * @param in the input array must be of size @a howmany*size
213  * @param out the output array must be of size @a howmany*size
214  * @param flags control the algorithm choices in FFTW
215  */
216  static fftw_plan_type create_backward_plan_many(
217  int howmany, std::size_t size, fftw_complex_type const* in,
218  fftw_complex_type* out, int flags) {
219  int const rank = 1;
220  int const n[rank] = {static_cast<int>(size)};
221  int const istride = 1;
222  int const ostride = 1;
223  int const* inembed = nullptr;
224  int const* onembed = nullptr;
225  int const idist = n[0];
226  int const odist = n[0];
227  return ::fftw_plan_many_dft(
228  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
229  idist, out, onembed, ostride, odist, FFTW_BACKWARD, flags);
230  }
231 
232  /**
233  * Create an execution to compute the DFT of many vectors based on
234  * the input and output exemplars
235  *
236  * @returns the execution plan
237  * @param howmany how many timeseries in the arrays
238  * @param size the size of the input and output vectors
239  * @param in the input array must be of size @a howmany*size
240  * @param out the output array must be of size @a howmany*size
241  * @param flags control the algorithm choices in FFTW
242  */
243  static fftw_plan_type create_plan_many(
244  int howmany, std::size_t size, precision_type const* in,
245  fftw_complex_type* out, unsigned flags) {
246  int const rank = 1;
247  int const n[rank] = {static_cast<int>(size)};
248  int const istride = 1;
249  int const ostride = 1;
250  int const* inembed = nullptr;
251  int const* onembed = nullptr;
252  int const idist = n[0];
253  int const odist = n[0];
254  return ::fftw_plan_many_dft_r2c(
255  rank, n, howmany, const_cast<precision_type*>(in), inembed, istride,
256  idist, out, onembed, ostride, odist, flags);
257  }
258 
259  /**
260  * Create an execution to compute the inverse DFT of many vectors based on
261  * the input and output exemplars
262  *
263  * @returns the execution plan
264  * @param howmany how many timeseries in the arrays
265  * @param size the size of the input and output vectors
266  * @param in the input array must be of size @a howmany*size
267  * @param out the output array must be of size @a howmany*size
268  * @param flags control the algorithm choices in FFTW
269  */
270  static fftw_plan_type create_plan_many(
271  int howmany, std::size_t size, fftw_complex_type const* in,
272  precision_type* out, int flags) {
273  int const rank = 1;
274  int const n[rank] = {static_cast<int>(size)};
275  int const istride = 1;
276  int const ostride = 1;
277  int const* inembed = nullptr;
278  int const* onembed = nullptr;
279  int const idist = n[0];
280  int const odist = n[0];
281  return ::fftw_plan_many_dft_c2r(
282  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
283  idist, out, onembed, ostride, odist, flags);
284  }
285 
286  /**
287  * Destroy an execution plan
288  *
289  * @param p the plan to destroy
290  */
291  static void destroy_plan(fftw_plan_type p) {
292  ::fftw_destroy_plan(p);
293  }
294 };
295 
296 /**
297  * Wrap the FFTW types and functions for single precision float point numbers
298  */
299 template <>
300 struct traits<float> {
301  //@{
302  /**
303  * @name type traits
304  */
305  /// The type used to represent floating point numbers
306  typedef float precision_type;
307  /// The type used to represent complex numbers in the C++ standard library
308  typedef std::complex<float> std_complex_type;
309  /// The type used to represent complex numbers in FFTW
310  typedef ::fftwf_complex fftw_complex_type;
311  /// The type used to represent execution plans in FFTW
312  typedef ::fftwf_plan fftw_plan_type;
313  //@}
314 
315  /**
316  * Allocate a properly aligned (for SIMD acceleration) block of memory
317  *
318  * @param n the number of bytes to allocate
319  * @returns a block for at least @a n bytes
320  */
321  static void* allocate(std::size_t n) {
322  return ::fftwf_malloc(n);
323  }
324 
325  /**
326  * Release a block of memory allocated with allocate()
327  *
328  * @param buffer the block to release
329  */
330  static void release(void* buffer) {
331  ::fftwf_free(buffer);
332  }
333 
334  /**
335  * Execute an existing plan for a given input and output
336  *
337  * FFTW requires, but does not check that the input and output have
338  * the same alignment and sizes defined in the original plan.
339  *
340  * @param p the execution plan
341  * @param in the input vector (or array)
342  * @param out the output data (or array)
343  */
344  static void execute_plan(
345  fftw_plan_type const p, fftw_complex_type const* in,
346  fftw_complex_type* out) {
347  ::fftwf_execute_dft(p, const_cast<fftw_complex_type*>(in), out);
348  }
349 
350  /**
351  * Execute an existing plan for a given input and output
352  *
353  * FFTW requires, but does not check that the input and output have
354  * the same alignment and sizes defined in the original plan.
355  *
356  * @param p the execution plan
357  * @param in the input vector (or array)
358  * @param out the output vector (or array)
359  */
360  static void execute_plan(
361  fftw_plan_type const p, precision_type const* in,
362  fftw_complex_type* out) {
363  ::fftwf_execute_dft_r2c(p, const_cast<precision_type*>(in), out);
364  }
365 
366  /**
367  * Execute an existing plan for a given input and output
368  *
369  * FFTW requires, but does not check that the input and output have
370  * the same alignment and sizes defined in the original plan.
371  *
372  * @param p the execution plan
373  * @param in the input vector (or array)
374  * @param out the output vector (or array), can be the same as the input
375  */
376  static void execute_plan(
377  fftw_plan_type const p, fftw_complex_type const* in,
378  precision_type* out) {
379  ::fftwf_execute_dft_c2r(p, const_cast<fftw_complex_type*>(in), out);
380  }
381 
382  /**
383  * Create an execution plan to compute the DFT based on the input
384  * and output exemplars
385  *
386  * @returns the execution plan
387  * @param size the size of the input and output vectors
388  * @param in the input vector
389  * @param out the output vector
390  * @param flags control the algorithm choices in FFTW
391  */
392  static fftw_plan_type create_forward_plan(
393  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
394  int flags) {
395  return ::fftwf_plan_dft_1d(
396  size, const_cast<fftw_complex_type*>(in), out, FFTW_FORWARD, flags);
397  }
398 
399  /**
400  * Create an execution to compute the inverse DFT based on the input
401  * and output exemplars
402  *
403  * @returns the execution plan
404  * @param size the size of the input and output vectors
405  * @param in the input vector
406  * @param out the output vector
407  * @param flags control the algorithm choices in FFTW
408  */
409  static fftw_plan_type create_backward_plan(
410  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
411  int flags) {
412  return ::fftwf_plan_dft_1d(
413  size, const_cast<fftw_complex_type*>(in), out, FFTW_BACKWARD, flags);
414  }
415 
416  /**
417  * Create an execution to compute the DFT based on the input
418  * and output exemplars
419  *
420  * @returns the execution plan
421  * @param size the size of the input and output vectors
422  * @param in the input vector
423  * @param out the output vector
424  * @param flags control the algorithm choices in FFTW
425  */
426  static fftw_plan_type create_plan(
427  std::size_t size, precision_type const* in, fftw_complex_type* out,
428  int flags) {
429  return ::fftwf_plan_dft_r2c_1d(
430  size, const_cast<precision_type*>(in), out, flags);
431  }
432 
433  /**
434  * Create an execution to compute the inverse DFT based on the input
435  * and output exemplars
436  *
437  * @returns the execution plan
438  * @param size the size of the input and output vectors
439  * @param in the input vector
440  * @param out the output vector
441  * @param flags control the algorithm choices in FFTW
442  */
443  static fftw_plan_type create_plan(
444  std::size_t size, fftw_complex_type const* in, precision_type* out,
445  int flags) {
446  return ::fftwf_plan_dft_c2r_1d(
447  size, const_cast<fftw_complex_type*>(in), out, flags);
448  }
449 
450  /**
451  * Create an execution to compute the DFT of many vectors based on the input
452  * and output exemplars
453  *
454  * @returns the execution plan
455  * @param howmany how many timeseries in the arrays
456  * @param size the size of the input and output vectors
457  * @param in the input array must be of size @a howmany*size
458  * @param out the output array must be of size @a howmany*size
459  * @param flags control the algorithm choices in FFTW
460  */
461  static fftw_plan_type create_forward_plan_many(
462  int howmany, std::size_t size, fftw_complex_type const* in,
463  fftw_complex_type* out, int flags) {
464  int const rank = 1;
465  int const n[rank] = {static_cast<int>(size)};
466  int const istride = 1;
467  int const ostride = 1;
468  int const* inembed = nullptr;
469  int const* onembed = nullptr;
470  int const idist = n[0];
471  int const odist = n[0];
472  return ::fftwf_plan_many_dft(
473  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
474  idist, out, onembed, ostride, odist, FFTW_FORWARD, flags);
475  }
476 
477  /**
478  * Create an execution to compute the inverse DFT of many vectors
479  * based on the input and output exemplars
480  *
481  * @returns the execution plan
482  * @param howmany how many timeseries in the arrays
483  * @param size the size of the input and output vectors
484  * @param in the input array must be of size @a howmany*size
485  * @param out the output array must be of size @a howmany*size
486  * @param flags control the algorithm choices in FFTW
487  */
488  static fftw_plan_type create_backward_plan_many(
489  int howmany, std::size_t size, fftw_complex_type const* in,
490  fftw_complex_type* out, int flags) {
491  int const rank = 1;
492  int const n[rank] = {static_cast<int>(size)};
493  int const istride = 1;
494  int const ostride = 1;
495  int const* inembed = nullptr;
496  int const* onembed = nullptr;
497  int const idist = n[0];
498  int const odist = n[0];
499  return ::fftwf_plan_many_dft(
500  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
501  idist, out, onembed, ostride, odist, FFTW_BACKWARD, flags);
502  }
503 
504  /**
505  * Create an execution to compute the DFT of many vectors based on
506  * the input and output exemplars
507  *
508  * @returns the execution plan
509  * @param howmany how many timeseries in the arrays
510  * @param size the size of the input and output vectors
511  * @param in the input array must be of size @a howmany*size
512  * @param out the output array must be of size @a howmany*size
513  * @param flags control the algorithm choices in FFTW
514  */
515  static fftw_plan_type create_plan_many(
516  int howmany, std::size_t size, precision_type const* in,
517  fftw_complex_type* out, unsigned flags) {
518  int const rank = 1;
519  int const n[rank] = {static_cast<int>(size)};
520  int const istride = 1;
521  int const ostride = 1;
522  int const* inembed = nullptr;
523  int const* onembed = nullptr;
524  int const idist = n[0];
525  int const odist = n[0];
526  return ::fftwf_plan_many_dft_r2c(
527  rank, n, howmany, const_cast<precision_type*>(in), inembed, istride,
528  idist, out, onembed, ostride, odist, flags);
529  }
530 
531  /**
532  * Create an execution to compute the inverse DFT of many vectors based on
533  * the input and output exemplars
534  *
535  * @returns the execution plan
536  * @param howmany how many timeseries in the arrays
537  * @param size the size of the input and output vectors
538  * @param in the input array must be of size @a howmany*size
539  * @param out the output array must be of size @a howmany*size
540  * @param flags control the algorithm choices in FFTW
541  */
542  static fftw_plan_type create_plan_many(
543  int howmany, std::size_t size, fftw_complex_type const* in,
544  precision_type* out, int flags) {
545  int const rank = 1;
546  int const n[rank] = {static_cast<int>(size)};
547  int const istride = 1;
548  int const ostride = 1;
549  int const* inembed = nullptr;
550  int const* onembed = nullptr;
551  int const idist = n[0];
552  int const odist = n[0];
553  return ::fftwf_plan_many_dft_c2r(
554  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
555  idist, out, onembed, ostride, odist, flags);
556  }
557 
558  /**
559  * Destroy an execution plan
560  *
561  * @param p the plan to destroy
562  */
563  static void destroy_plan(fftw_plan_type p) {
564  ::fftwf_destroy_plan(p);
565  }
566 };
567 
568 /**
569  * Wrap the FFTW types and functions for quad precision float point numbers
570  */
571 template <>
572 struct traits<long double> {
573  //@{
574  /**
575  * @name type traits
576  */
577  /// The type used to represent floating point numbers
578  typedef long double precision_type;
579  /// The type used to represent complex numbers in the C++ standard library
580  typedef ::std::complex<double> std_complex_type;
581  /// The type used to represent complex numbers in FFTW
582  typedef ::fftwl_complex fftw_complex_type;
583  /// The type used to represent execution plans in FFTW
584  typedef ::fftwl_plan fftw_plan_type;
585 
586  //@}
587 
588  /**
589  * Allocate a properly aligned (for SIMD acceleration) block of memory
590  *
591  * @param n the number of bytes to allocate
592  * @returns a block for at least @a n bytes
593  */
594  static void* allocate(std::size_t n) {
595  return ::fftwl_malloc(n);
596  }
597 
598  /**
599  * Release a block of memory allocated with allocate()
600  *
601  * @param buffer the block to release
602  */
603  static void release(void* buffer) {
604  ::fftwl_free(buffer);
605  }
606 
607  /**
608  * Execute an existing plan for a given input and output
609  *
610  * FFTW requires, but does not check that the input and output have
611  * the same alignment and sizes defined in the original plan.
612  *
613  * @param p the execution plan
614  * @param in the input vector (or array)
615  * @param out the output data (or array)
616  */
617  static void execute_plan(
618  fftw_plan_type const p, fftw_complex_type const* in,
619  fftw_complex_type* out) {
620  ::fftwl_execute_dft(p, const_cast<fftw_complex_type*>(in), out);
621  }
622 
623  /**
624  * Execute an existing plan for a given input and output
625  *
626  * FFTW requires, but does not check that the input and output have
627  * the same alignment and sizes defined in the original plan.
628  *
629  * @param p the execution plan
630  * @param in the input vector (or array)
631  * @param out the output vector (or array)
632  */
633  static void execute_plan(
634  fftw_plan_type const p, precision_type const* in,
635  fftw_complex_type* out) {
636  ::fftwl_execute_dft_r2c(p, const_cast<precision_type*>(in), out);
637  }
638 
639  /**
640  * Execute an existing plan for a given input and output
641  *
642  * FFTW requires, but does not check that the input and output have
643  * the same alignment and sizes defined in the original plan.
644  *
645  * @param p the execution plan
646  * @param in the input vector (or array)
647  * @param out the output vector (or array), can be the same as the input
648  */
649  static void execute_plan(
650  fftw_plan_type const p, fftw_complex_type const* in,
651  precision_type* out) {
652  ::fftwl_execute_dft_c2r(p, const_cast<fftw_complex_type*>(in), out);
653  }
654 
655  /**
656  * Create an execution plan to compute the DFT based on the input
657  * and output exemplars
658  *
659  * @returns the execution plan
660  * @param size the size of the input and output vectors
661  * @param in the input vector
662  * @param out the output vector
663  * @param flags control the algorithm choices in FFTW
664  */
665  static fftw_plan_type create_forward_plan(
666  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
667  int flags) {
668  return ::fftwl_plan_dft_1d(
669  size, const_cast<fftw_complex_type*>(in), out, FFTW_FORWARD, flags);
670  }
671 
672  /**
673  * Create an execution to compute the inverse DFT based on the input
674  * and output exemplars
675  *
676  * @returns the execution plan
677  * @param size the size of the input and output vectors
678  * @param in the input vector
679  * @param out the output vector
680  * @param flags control the algorithm choices in FFTW
681  */
682  static fftw_plan_type create_backward_plan(
683  std::size_t size, fftw_complex_type const* in, fftw_complex_type* out,
684  int flags) {
685  return ::fftwl_plan_dft_1d(
686  size, const_cast<fftw_complex_type*>(in), out, FFTW_BACKWARD, flags);
687  }
688 
689  /**
690  * Create an execution to compute the DFT based on the input
691  * and output exemplars
692  *
693  * @returns the execution plan
694  * @param size the size of the input and output vectors
695  * @param in the input vector
696  * @param out the output vector
697  * @param flags control the algorithm choices in FFTW
698  */
699  static fftw_plan_type create_plan(
700  std::size_t size, precision_type const* in, fftw_complex_type* out,
701  int flags) {
702  return ::fftwl_plan_dft_r2c_1d(
703  size, const_cast<precision_type*>(in), out, flags);
704  }
705 
706  /**
707  * Create an execution to compute the inverse DFT based on the input
708  * and output exemplars
709  *
710  * @returns the execution plan
711  * @param size the size of the input and output vectors
712  * @param in the input vector
713  * @param out the output vector
714  * @param flags control the algorithm choices in FFTW
715  */
716  static fftw_plan_type create_plan(
717  std::size_t size, fftw_complex_type const* in, precision_type* out,
718  int flags) {
719  return ::fftwl_plan_dft_c2r_1d(
720  size, const_cast<fftw_complex_type*>(in), out, flags);
721  }
722 
723  /**
724  * Create an execution to compute the DFT of many vectors based on the input
725  * and output exemplars
726  *
727  * @returns the execution plan
728  * @param howmany how many timeseries in the arrays
729  * @param size the size of the input and output vectors
730  * @param in the input array must be of size @a howmany*size
731  * @param out the output array must be of size @a howmany*size
732  * @param flags control the algorithm choices in FFTW
733  */
734  static fftw_plan_type create_forward_plan_many(
735  int howmany, std::size_t size, fftw_complex_type const* in,
736  fftw_complex_type* out, int flags) {
737  int const rank = 1;
738  int const n[rank] = {static_cast<int>(size)};
739  int const istride = 1;
740  int const ostride = 1;
741  int const* inembed = nullptr;
742  int const* onembed = nullptr;
743  int const idist = n[0];
744  int const odist = n[0];
745  return ::fftwl_plan_many_dft(
746  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
747  idist, out, onembed, ostride, odist, FFTW_FORWARD, flags);
748  }
749 
750  /**
751  * Create an execution to compute the inverse DFT of many vectors
752  * based on the input and output exemplars
753  *
754  * @returns the execution plan
755  * @param howmany how many timeseries in the arrays
756  * @param size the size of the input and output vectors
757  * @param in the input array must be of size @a howmany*size
758  * @param out the output array must be of size @a howmany*size
759  * @param flags control the algorithm choices in FFTW
760  */
761  static fftw_plan_type create_backward_plan_many(
762  int howmany, std::size_t size, fftw_complex_type const* in,
763  fftw_complex_type* out, int flags) {
764  int const rank = 1;
765  int const n[rank] = {static_cast<int>(size)};
766  int const istride = 1;
767  int const ostride = 1;
768  int const* inembed = nullptr;
769  int const* onembed = nullptr;
770  int const idist = n[0];
771  int const odist = n[0];
772  return ::fftwl_plan_many_dft(
773  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
774  idist, out, onembed, ostride, odist, FFTW_BACKWARD, flags);
775  }
776 
777  /**
778  * Create an execution to compute the DFT of many vectors based on
779  * the input and output exemplars
780  *
781  * @returns the execution plan
782  * @param howmany how many timeseries in the arrays
783  * @param size the size of the input and output vectors
784  * @param in the input array must be of size @a howmany*size
785  * @param out the output array must be of size @a howmany*size
786  * @param flags control the algorithm choices in FFTW
787  */
788  static fftw_plan_type create_plan_many(
789  int howmany, std::size_t size, precision_type const* in,
790  fftw_complex_type* out, unsigned flags) {
791  int const rank = 1;
792  int const n[rank] = {static_cast<int>(size)};
793  int const istride = 1;
794  int const ostride = 1;
795  int const* inembed = nullptr;
796  int const* onembed = nullptr;
797  int const idist = n[0];
798  int const odist = n[0];
799  return ::fftwl_plan_many_dft_r2c(
800  rank, n, howmany, const_cast<precision_type*>(in), inembed, istride,
801  idist, out, onembed, ostride, odist, flags);
802  }
803 
804  /**
805  * Create an execution to compute the inverse DFT of many vectors based on
806  * the input and output exemplars
807  *
808  * @returns the execution plan
809  * @param howmany how many timeseries in the arrays
810  * @param size the size of the input and output vectors
811  * @param in the input array must be of size @a howmany*size
812  * @param out the output array must be of size @a howmany*size
813  * @param flags control the algorithm choices in FFTW
814  */
815  static fftw_plan_type create_plan_many(
816  int howmany, std::size_t size, fftw_complex_type const* in,
817  precision_type* out, int flags) {
818  int const rank = 1;
819  int const n[rank] = {static_cast<int>(size)};
820  int const istride = 1;
821  int const ostride = 1;
822  int const* inembed = nullptr;
823  int const* onembed = nullptr;
824  int const idist = n[0];
825  int const odist = n[0];
826  return ::fftwl_plan_many_dft_c2r(
827  rank, n, howmany, const_cast<fftw_complex_type*>(in), inembed, istride,
828  idist, out, onembed, ostride, odist, flags);
829  }
830 
831  /**
832  * Destroy an execution plan
833  *
834  * @param p the plan to destroy
835  */
836  static void destroy_plan(fftw_plan_type p) {
837  ::fftwl_destroy_plan(p);
838  }
839 };
840 
841 /**
842  * Define traits for std::complex<T> in terms of the traits for T.
843  *
844  * The traits for a std::complex type are the same as the traits for the
845  * underlying precision of the complex type instantiation. The
846  * objective is to simplify/normalize the interface into FFTW3, so all
847  * uses of FFTW look similar in C++.
848  */
849 template <typename T>
850 struct traits<std::complex<T>> : public traits<T> {};
851 
852 } // namespace fftw
853 } // namespace jb
854 
855 #endif // jb_fftw_traits_hpp
static void * allocate(std::size_t n)
Allocate a properly aligned (for SIMD acceleration) block of memory.
Definition: traits.hpp:49
static fftw_plan_type create_backward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:488
static void * allocate(std::size_t n)
Allocate a properly aligned (for SIMD acceleration) block of memory.
Definition: traits.hpp:594
Wrap fftw_* types and operations to treat floating point values generically.
Definition: traits.hpp:22
static fftw_plan_type create_backward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:761
static void destroy_plan(fftw_plan_type p)
Destroy an execution plan.
Definition: traits.hpp:836
static fftw_plan_type create_forward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution plan to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:392
static fftw_plan_type create_plan_many(int howmany, std::size_t size, precision_type const *in, fftw_complex_type *out, unsigned flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:243
static fftw_plan_type create_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:815
static fftw_plan_type create_forward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:461
static void destroy_plan(fftw_plan_type p)
Destroy an execution plan.
Definition: traits.hpp:291
static fftw_plan_type create_plan(std::size_t size, precision_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:426
static fftw_plan_type create_backward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:682
long double precision_type
The type used to represent floating point numbers.
Definition: traits.hpp:578
static fftw_plan_type create_forward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:189
STL namespace.
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:72
static fftw_plan_type create_forward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:734
static fftw_plan_type create_forward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution plan to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:120
static fftw_plan_type create_plan_many(int howmany, std::size_t size, precision_type const *in, fftw_complex_type *out, unsigned flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:515
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, precision_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:649
static fftw_plan_type create_backward_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:216
static fftw_plan_type create_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:270
double precision_type
The type used to represent floating point numbers.
Definition: traits.hpp:34
::fftw_plan fftw_plan_type
The type used to represent execution plans in FFTW.
Definition: traits.hpp:40
static fftw_plan_type create_forward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution plan to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:665
::fftw_complex fftw_complex_type
The type used to represent complex numbers in FFTW.
Definition: traits.hpp:38
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:617
static void execute_plan(fftw_plan_type const p, precision_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:360
static fftw_plan_type create_plan(std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:716
static void release(void *buffer)
Release a block of memory allocated with allocate()
Definition: traits.hpp:603
static void release(void *buffer)
Release a block of memory allocated with allocate()
Definition: traits.hpp:330
::fftwf_plan fftw_plan_type
The type used to represent execution plans in FFTW.
Definition: traits.hpp:312
static void release(void *buffer)
Release a block of memory allocated with allocate()
Definition: traits.hpp:58
static void execute_plan(fftw_plan_type const p, precision_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:633
static void execute_plan(fftw_plan_type const p, precision_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:88
static fftw_plan_type create_plan(std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:171
::fftwl_complex fftw_complex_type
The type used to represent complex numbers in FFTW.
Definition: traits.hpp:582
static fftw_plan_type create_plan(std::size_t size, precision_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:699
::fftwl_plan fftw_plan_type
The type used to represent execution plans in FFTW.
Definition: traits.hpp:584
static fftw_plan_type create_plan(std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:443
static fftw_plan_type create_plan_many(int howmany, std::size_t size, fftw_complex_type const *in, precision_type *out, int flags)
Create an execution to compute the inverse DFT of many vectors based on the input and output exemplar...
Definition: traits.hpp:542
static fftw_plan_type create_plan_many(int howmany, std::size_t size, precision_type const *in, fftw_complex_type *out, unsigned flags)
Create an execution to compute the DFT of many vectors based on the input and output exemplars...
Definition: traits.hpp:788
static void destroy_plan(fftw_plan_type p)
Destroy an execution plan.
Definition: traits.hpp:563
static fftw_plan_type create_backward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:409
::std::complex< double > std_complex_type
The type used to represent complex numbers in the C++ standard library.
Definition: traits.hpp:580
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, precision_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:104
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, precision_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:376
static void execute_plan(fftw_plan_type const p, fftw_complex_type const *in, fftw_complex_type *out)
Execute an existing plan for a given input and output.
Definition: traits.hpp:344
std::complex< float > std_complex_type
The type used to represent complex numbers in the C++ standard library.
Definition: traits.hpp:308
static void * allocate(std::size_t n)
Allocate a properly aligned (for SIMD acceleration) block of memory.
Definition: traits.hpp:321
float precision_type
The type used to represent floating point numbers.
Definition: traits.hpp:306
static fftw_plan_type create_plan(std::size_t size, precision_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the DFT based on the input and output exemplars.
Definition: traits.hpp:154
::fftwf_complex fftw_complex_type
The type used to represent complex numbers in FFTW.
Definition: traits.hpp:310
::std::complex< double > std_complex_type
The type used to represent complex numbers in the C++ standard library.
Definition: traits.hpp:36
static fftw_plan_type create_backward_plan(std::size_t size, fftw_complex_type const *in, fftw_complex_type *out, int flags)
Create an execution to compute the inverse DFT based on the input and output exemplars.
Definition: traits.hpp:137
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7