NiHu  2.0
spectral_interpolate.cpp
Go to the documentation of this file.
1 
7 #include "spectral_interpolate.h"
8 
9 namespace NiHu
10 {
11 namespace fmm
12 {
13 
15 {
16  destroy();
17 }
18 
20  : m_Nto(Nto)
21  , m_Nfrom(Nfrom)
22  , m_dft_plan(nullptr)
23  , m_idft_plan(nullptr)
24 {
25  init();
26 }
27 
29  : m_Nto(0)
30  , m_Nfrom(0)
31  , m_dft_plan(nullptr)
32  , m_idft_plan(nullptr)
33 {
34  *this = rhs;
35 }
36 
38  : m_Nto (rhs.m_Nto)
39  , m_Nfrom (rhs.m_Nfrom)
40  , m_dft_plan (rhs.m_dft_plan)
41  , m_idft_plan (rhs.m_idft_plan)
42  , m_in_spec (std::move(rhs.m_in_spec))
43  , m_in (std::move(rhs.m_in))
44  , m_out (std::move(rhs.m_out))
45  , m_out_spec (std::move(rhs.m_out_spec))
46 {
47  rhs.m_idft_plan = nullptr;
48  rhs.m_dft_plan = nullptr;
49 }
50 
52 {
53  if (this == &rhs)
54  return *this;
55 
56  destroy();
57 
58  m_Nfrom = rhs.m_Nfrom;
59  m_Nto = rhs.m_Nto;
60 
61  init();
62 
63  return *this;
64 }
65 
67 {
68  if (this == &rhs)
69  return *this;
70 
71  destroy();
72 
73  m_Nfrom = rhs.m_Nfrom;
74  m_Nto = rhs.m_Nto;
75 
76  m_idft_plan = rhs.m_idft_plan;
77  m_dft_plan = rhs.m_dft_plan;
78 
79  m_in_spec = std::move(rhs.m_in_spec);
80  m_in = std::move(rhs.m_in);
81  m_out = std::move(rhs.m_out);
82  m_out_spec = std::move(rhs.m_out_spec);
83 
84  rhs.m_idft_plan = nullptr;
85  rhs.m_dft_plan = nullptr;
86 
87  return *this;
88 }
89 
92 {
93  // check argument
94  if (from.rows() != 2 * (2 * m_Nfrom) + 1)
95  throw std::runtime_error("Invalid size of idft input vector");
96 
97  // idft with Nfrom size
98  fftw_execute_dft(m_idft_plan, (fftw_complex *)from.data(),
99  (fftw_complex *)m_in.data());
100  m_in /= std::complex<double>(double(2 * (2 * m_Nfrom) + 1));
101 
102 
103  // padding or truncating (m_out has been cleared by init() )
104  size_t L = std::min(m_Nfrom, m_Nto);
105  m_out.head(L + 1) = m_in.head(L + 1);
106  m_out.tail(L) = m_in.tail(L);
107 
108  // dft with Nto size
109  fftw_execute_dft(m_dft_plan, (fftw_complex *)m_out.data(),
110  (fftw_complex *)m_out_spec.data());
111 
112  return m_out_spec;
113 }
114 
115 void spectral_interpolate::init()
116 {
117  m_in_spec.resize(2 * (2 * m_Nfrom) + 1, 1);
118  m_in.resize(2 * (2 * m_Nfrom) + 1, 1);
119  m_out.resize(2 * (2 * m_Nto) + 1, 1);
120  m_out_spec.resize(2 * (2 * m_Nto) + 1, 1);
121 
122  m_idft_plan = fftw_plan_dft_1d(2 * (2 * int(m_Nfrom)) + 1,
123  (fftw_complex *)m_in_spec.data(),
124  (fftw_complex *)m_in.data(), FFTW_BACKWARD, FFTW_MEASURE);
125 
126  m_dft_plan = fftw_plan_dft_1d(2 * (2 * int(m_Nto)) + 1,
127  (fftw_complex *)m_out.data(),
128  (fftw_complex *)m_out_spec.data(), FFTW_FORWARD, FFTW_MEASURE);
129 
130  m_out.setZero();
131 }
132 
133 void spectral_interpolate::destroy()
134 {
135  if (m_dft_plan != nullptr)
136  {
137  fftw_destroy_plan(m_dft_plan);
138  m_dft_plan = nullptr;
139  }
140  if (m_idft_plan != nullptr)
141  {
142  fftw_destroy_plan(m_idft_plan);
143  m_dft_plan = nullptr;
144  }
145 }
146 
147 } // end of namespace fmm
148 } // namespace NiHu
NiHu::fmm::spectral_interpolate::cvector_t
Eigen::Matrix< std::complex< double >, Eigen::Dynamic, 1 > cvector_t
the spectrum type
Definition: spectral_interpolate.h:24
NiHu::fmm::spectral_interpolate::operator=
spectral_interpolate & operator=(spectral_interpolate const &rhs)
assign operator
Definition: spectral_interpolate.cpp:51
spectral_interpolate.h
Interface of class NiHu::fmm::spectral_interpolate.
NiHu::fmm::spectral_interpolate::spectral_interpolate
spectral_interpolate(size_t Nto=0, size_t Nfrom=0)
constructor
Definition: spectral_interpolate.cpp:19
NiHu::fmm::spectral_interpolate::interpolate
const cvector_t & interpolate(cvector_t const &from) const
interpolate a spectrum
Definition: spectral_interpolate.cpp:91
NiHu::fmm::spectral_interpolate::~spectral_interpolate
~spectral_interpolate()
destructor
Definition: spectral_interpolate.cpp:14
NiHu::fmm::spectral_interpolate
class performing spectral interpolation
Definition: spectral_interpolate.h:20