casacore
Loading...
Searching...
No Matches
FFTW.h
Go to the documentation of this file.
1// # Copyright (C) 1993,1994,1995,1997,1999,2000,2001
2// # Associated Universities, Inc. Washington DC, USA.
3// #
4// # This library is free software; you can redistribute it and/or modify it
5// # under the terms of the GNU Library General Public License as published by
6// # the Free Software Foundation; either version 2 of the License, or (at your
7// # option) any later version.
8// #
9// # This library is distributed in the hope that it will be useful, but WITHOUT
10// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12// # License for more details.
13// #
14// # You should have received a copy of the GNU Library General Public License
15// # along with this library; if not, write to the Free Software Foundation,
16// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
17// #
18// # Correspondence concerning AIPS++ should be addressed as follows:
19// # Internet email: casa-feedback@nrao.edu.
20// # Postal address: AIPS++ Project Office
21// # National Radio Astronomy Observatory
22// # 520 Edgemont Road
23// # Charlottesville, VA 22903-2475 USA
24
25#ifndef SCIMATH_FFTW_H
26#define SCIMATH_FFTW_H
27
28#include <casacore/casa/aips.h>
29#include <casacore/casa/Arrays/IPosition.h>
30
31#include <complex>
32#include <memory>
33#include <mutex>
34
35namespace casacore {
36
37// # Forward Declarations.
38class FFTWPlan;
39class FFTWPlanf;
40
41// <summary> C++ interface to the FFTWw library </summary>
42// <reviewed reviewer="NONE" date="" tests="" demos="">
43// </reviewed>
44// <synopsis>
45// This is a wrapper of FFTW3.
46// It is only active if FFTW3 was found during the build.
47// If not found, all functions won't do anything at all.
48//
49// The interface is such that the presence of FFTW3 is only visible
50// in the implementation. The header file does not need to know.
51// In this way external code using this class does not need to set HAVE_FFTW.
52// </synopsis>
53
54class FFTW {
55 public:
57
59
60 // overloaded interface to fftw[f]_plan...
61 void plan_r2c(const IPosition &size, float *in, std::complex<float> *out);
62 void plan_r2c(const IPosition &size, double *in, std::complex<double> *out);
63 void plan_c2r(const IPosition &size, std::complex<float> *in, float *out);
64 void plan_c2r(const IPosition &size, std::complex<double> *in, double *out);
65 void plan_c2c_forward(const IPosition &size, std::complex<double> *in);
66 void plan_c2c_forward(const IPosition &size, std::complex<float> *in);
67 void plan_c2c_backward(const IPosition &size, std::complex<double> *in);
68 void plan_c2c_backward(const IPosition &size, std::complex<float> *in);
69
70 // TODO These overloads do not use their parameters at all. This should
71 // be written to use an interface like plan_redft00().
72 // overloaded interface to fftw[f]_execute...
73 void r2c(const IPosition &size, float *in, std::complex<float> *out);
74 void r2c(const IPosition &size, double *in, std::complex<double> *out);
75 void c2r(const IPosition &size, std::complex<float> *in, float *out);
76 void c2r(const IPosition &size, std::complex<double> *in, double *out);
77 void c2c(const IPosition &size, std::complex<float> *in, bool forward);
78 void c2c(const IPosition &size, std::complex<double> *in, bool forward);
79
80 class Plan {
81 public:
82 ~Plan() noexcept;
83 Plan(const Plan &) = delete;
85 Plan &operator=(const Plan &) = delete;
86 Plan &operator=(Plan &&);
87
88 // Perform the FFT associated with this plan with the given
89 // in data, and store it in the given out data.
90 // <group>
91 void Execute(float *in, float *out);
92 void Execute(double *in, double *out);
93 // </group>
94 private:
95 friend FFTW;
96 Plan(FFTWPlan *plan);
97 Plan(FFTWPlanf *plan);
98 std::unique_ptr<FFTWPlan> _plan;
99 std::unique_ptr<FFTWPlanf> _planf;
100 };
101
102 static Plan plan_redft00(const IPosition &size, float *in, float *out);
103 static Plan plan_redft00(const IPosition &size, double *in, double *out);
104
105 private:
106 static void initialize_fftw();
107
108 std::unique_ptr<FFTWPlanf> itsPlanR2Cf;
109 std::unique_ptr<FFTWPlan> itsPlanR2C;
110
111 std::unique_ptr<FFTWPlanf> itsPlanC2Rf;
112 std::unique_ptr<FFTWPlan> itsPlanC2R;
113
114 std::unique_ptr<FFTWPlanf> itsPlanC2CFf; // forward
115 std::unique_ptr<FFTWPlan> itsPlanC2CF;
116
117 std::unique_ptr<FFTWPlanf> itsPlanC2CBf; // backward
118 std::unique_ptr<FFTWPlan> itsPlanC2CB;
119
120 std::unique_ptr<FFTWPlanf> itsPlanR2Rf;
121 std::unique_ptr<FFTWPlan> itsPlanR2R;
122
123 unsigned flags;
124
125 static bool is_initialized_fftw; // FFTW needs initialization
126 // only once per process,
127 // not once per object
128
129 // TODO this mutex does not make FFTW thread safe, because
130 // planning an FFT with FFTW is not thread safe either.
131 // So either the plan..() methods should take the mutex, or
132 // FFTW should leave synchronization fully to the user of
133 // this class: currently it's halfway in between.
134 static std::mutex theirMutex; // Initialization mutex
135};
136
137} // namespace casacore
138
139#endif
Plan(const Plan &)=delete
std::unique_ptr< FFTWPlan > _plan
Definition FFTW.h:98
std::unique_ptr< FFTWPlanf > _planf
Definition FFTW.h:99
void Execute(float *in, float *out)
Perform the FFT associated with this plan with the given in data, and store it in the given out data.
std::unique_ptr< FFTWPlan > itsPlanR2C
Definition FFTW.h:109
void plan_c2r(const IPosition &size, std::complex< double > *in, double *out)
std::unique_ptr< FFTWPlanf > itsPlanC2CBf
Definition FFTW.h:117
void plan_c2c_backward(const IPosition &size, std::complex< double > *in)
std::unique_ptr< FFTWPlanf > itsPlanR2Rf
Definition FFTW.h:120
void plan_c2c_forward(const IPosition &size, std::complex< float > *in)
std::unique_ptr< FFTWPlan > itsPlanC2CB
Definition FFTW.h:118
void r2c(const IPosition &size, double *in, std::complex< double > *out)
void c2c(const IPosition &size, std::complex< float > *in, bool forward)
void c2c(const IPosition &size, std::complex< double > *in, bool forward)
std::unique_ptr< FFTWPlan > itsPlanR2R
Definition FFTW.h:121
void plan_r2c(const IPosition &size, float *in, std::complex< float > *out)
overloaded interface to fftw[f]_plan...
unsigned flags
Definition FFTW.h:123
void plan_c2c_forward(const IPosition &size, std::complex< double > *in)
void r2c(const IPosition &size, float *in, std::complex< float > *out)
TODO These overloads do not use their parameters at all.
void plan_r2c(const IPosition &size, double *in, std::complex< double > *out)
std::unique_ptr< FFTWPlan > itsPlanC2R
Definition FFTW.h:112
void plan_c2c_backward(const IPosition &size, std::complex< float > *in)
void plan_c2r(const IPosition &size, std::complex< float > *in, float *out)
std::unique_ptr< FFTWPlanf > itsPlanR2Cf
Definition FFTW.h:108
static Plan plan_redft00(const IPosition &size, float *in, float *out)
static std::mutex theirMutex
only once per process, not once per object
Definition FFTW.h:134
std::unique_ptr< FFTWPlan > itsPlanC2CF
Definition FFTW.h:115
std::unique_ptr< FFTWPlanf > itsPlanC2Rf
Definition FFTW.h:111
void c2r(const IPosition &size, std::complex< double > *in, double *out)
void c2r(const IPosition &size, std::complex< float > *in, float *out)
std::unique_ptr< FFTWPlanf > itsPlanC2CFf
Definition FFTW.h:114
static void initialize_fftw()
static bool is_initialized_fftw
Definition FFTW.h:125
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
size_t size() const
Definition Block.h:566
Define real & complex conjugation for non-complex types and put comparisons into std namespace.
Definition Complex.h:344