numerics
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)), fc(out),
25 FFTW_FORWARD, FFTW_ESTIMATE);
26 fftw_execute(p);
27 fftw_destroy_plan(p);
28}
29
30inline void ifft(const num::CVector& in, num::CVector& out) {
31 fftw_plan p = fftw_plan_dft_1d(static_cast<int>(in.size()),
32 const_cast<fftw_complex*>(fc(in)), fc(out),
33 FFTW_BACKWARD, FFTW_ESTIMATE);
34 fftw_execute(p);
35 fftw_destroy_plan(p);
36}
37
38inline void rfft(const num::Vector& in, num::CVector& out) {
39 fftw_plan p = fftw_plan_dft_r2c_1d(static_cast<int>(in.size()),
40 const_cast<double*>(in.data()), fc(out),
41 FFTW_ESTIMATE);
42 fftw_execute(p);
43 fftw_destroy_plan(p);
44}
45
46inline void irfft(const num::CVector& in, int n, num::Vector& out) {
47 fftw_plan p = fftw_plan_dft_c2r_1d(n,
48 const_cast<fftw_complex*>(fc(in)), out.data(),
49 FFTW_ESTIMATE);
50 fftw_execute(p);
51 fftw_destroy_plan(p);
52}
53
54struct FFTPlanImpl {
55 fftw_plan plan;
56 int n;
57
58 FFTPlanImpl(int n_, bool forward) : n(n_) {
59 // Allocate dummy arrays -- FFTW_MEASURE overwrites them during planning
60 num::CVector tmp_in(n_, num::cplx{0, 0}), tmp_out(n_, num::cplx{0, 0});
61 plan = fftw_plan_dft_1d(n_, fc(tmp_in), fc(tmp_out),
62 forward ? FFTW_FORWARD : FFTW_BACKWARD,
63 FFTW_MEASURE);
64 }
65
66 ~FFTPlanImpl() { fftw_destroy_plan(plan); }
67
68 void execute(const num::CVector& in, num::CVector& out) const {
69 fftw_execute_dft(plan,
70 const_cast<fftw_complex*>(fc(in)),
71 const_cast<fftw_complex*>(fc(out)));
72 }
73};
74
75} // namespace fftw
76} // namespace backends
77
78#endif // NUMERICS_HAS_FFTW
Dense vector with optional GPU storage, templated over scalar type T.
Definition vector.hpp:23
constexpr idx size() const noexcept
Definition vector.hpp:77
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:31
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:61
constexpr FFTBackend fftw
Definition fft.hpp:36
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:46
std::complex< real > cplx
Definition types.hpp:12