numerics 0.1.0
Loading...
Searching...
No Matches
impl.hpp
Go to the documentation of this file.
1/// @file spectral/backends/fftw/impl.hpp
2/// @brief FFTW3 backend wrappers.
3/// Only included by src/spectral/fft.cpp.
4#pragma once
5
6#ifdef NUMERICS_HAS_FFTW
7 #include "spectral/fft.hpp"
8 #include <fftw3.h>
9 #include <stdexcept>
10
11namespace backends {
12namespace fftw {
13
14// std::complex<double> is layout-compatible with fftw_complex (double[2])
15inline fftw_complex* fc(num::CVector& v) {
16 return reinterpret_cast<fftw_complex*>(v.data());
17}
18inline const fftw_complex* fc(const num::CVector& v) {
19 return reinterpret_cast<const fftw_complex*>(v.data());
20}
21
22inline void fft(const num::CVector& in, num::CVector& out) {
23 fftw_plan p = fftw_plan_dft_1d(static_cast<int>(in.size()),
24 const_cast<fftw_complex*>(fc(in)),
25 fc(out),
26 FFTW_FORWARD,
27 FFTW_ESTIMATE);
28 fftw_execute(p);
29 fftw_destroy_plan(p);
30}
31
32inline void ifft(const num::CVector& in, num::CVector& out) {
33 fftw_plan p = fftw_plan_dft_1d(static_cast<int>(in.size()),
34 const_cast<fftw_complex*>(fc(in)),
35 fc(out),
36 FFTW_BACKWARD,
37 FFTW_ESTIMATE);
38 fftw_execute(p);
39 fftw_destroy_plan(p);
40}
41
42inline void rfft(const num::Vector& in, num::CVector& out) {
43 fftw_plan p = fftw_plan_dft_r2c_1d(static_cast<int>(in.size()),
44 const_cast<double*>(in.data()),
45 fc(out),
46 FFTW_ESTIMATE);
47 fftw_execute(p);
48 fftw_destroy_plan(p);
49}
50
51inline void irfft(const num::CVector& in, int n, num::Vector& out) {
52 fftw_plan p = fftw_plan_dft_c2r_1d(n,
53 const_cast<fftw_complex*>(fc(in)),
54 out.data(),
55 FFTW_ESTIMATE);
56 fftw_execute(p);
57 fftw_destroy_plan(p);
58}
59
60struct FFTPlanImpl {
61 fftw_plan plan;
62 int n;
63
64 FFTPlanImpl(int n_, bool forward)
65 : n(n_) {
66 // Allocate dummy arrays -- FFTW_MEASURE overwrites them during planning
67 num::CVector tmp_in(n_, num::cplx{0, 0}), tmp_out(n_, num::cplx{0, 0});
68 plan = fftw_plan_dft_1d(n_,
69 fc(tmp_in),
70 fc(tmp_out),
71 forward ? FFTW_FORWARD : FFTW_BACKWARD,
72 FFTW_MEASURE);
73 }
74
75 ~FFTPlanImpl() {
76 fftw_destroy_plan(plan);
77 }
78
79 void execute(const num::CVector& in, num::CVector& out) const {
80 fftw_execute_dft(plan,
81 const_cast<fftw_complex*>(fc(in)),
82 const_cast<fftw_complex*>(fc(out)));
83 }
84};
85
86} // namespace fftw
87} // namespace backends
88
89#endif // NUMERICS_HAS_FFTW
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:24
constexpr idx size() const noexcept
Definition vector.hpp:80
FFT interface with backend dispatch.
void ifft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Inverse complex DFT (unnormalised: result = n * true_inverse).
Definition fft.cpp:40
void fft(const CVector &in, CVector &out, FFTBackend b=default_fft_backend)
Forward complex DFT. out must be pre-allocated to in.size().
Definition fft.cpp:15
void irfft(const CVector &in, int n, Vector &out, FFTBackend b=default_fft_backend)
Complex-to-real inverse DFT (unnormalised).
Definition fft.cpp:88
constexpr FFTBackend fftw
Definition fft.hpp:43
void rfft(const Vector &in, CVector &out, FFTBackend b=default_fft_backend)
Real-to-complex forward DFT. out must be pre-allocated to n/2+1.
Definition fft.cpp:64
std::complex< real > cplx
Definition types.hpp:12