NumCpp  2.16.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Loading...
Searching...
No Matches
ifft.hpp
Go to the documentation of this file.
1
28#pragma once
29
30#include <complex>
31
35#include "NumCpp/Core/Types.hpp"
37#include "NumCpp/NdArray.hpp"
38
39namespace nc::fft
40{
41 namespace detail
42 {
43 //===========================================================================
44 // Method Description:
50 inline NdArray<std::complex<double>> ifft_internal(const NdArray<std::complex<double>>& x, uint32 n)
51 {
52 if (n == 0)
53 {
54 return {};
55 }
56
58
60 result.end(),
61 [&](auto& resultElement)
62 {
63 const auto m = static_cast<double>(&resultElement - result.data());
64 const auto minusTwoPiKOverN = constants::twoPi * m / static_cast<double>(n);
65 resultElement = std::complex<double>{ 0., 0. };
66 for (auto k = 0u; k < std::min(n, x.size()); ++k)
67 {
68 const auto angle = minusTwoPiKOverN * static_cast<double>(k);
69 resultElement += (x[k] * std::polar(1., angle));
70 }
71
73 });
74
75 return result;
76 }
77 } // namespace detail
78
79 //===========================================================================
80 // Method Description:
91 template<typename dtype>
92 NdArray<std::complex<double>> ifft(const NdArray<dtype>& inArray, uint32 inN, Axis inAxis = Axis::NONE)
93 {
95
96 switch (inAxis)
97 {
98 case Axis::NONE:
99 {
100 const auto data = nc::complex<dtype, double>(inArray);
101 return detail::ifft_internal(data, inN);
102 }
103 case Axis::COL:
104 {
105 auto data = nc::complex<dtype, double>(inArray);
106 const auto& shape = inArray.shape();
107 auto result = NdArray<std::complex<double>>(shape.rows, inN);
108 const auto dataColSlice = data.cSlice();
109 const auto resultColSlice = result.cSlice();
110
111 for (uint32 row = 0; row < data.numRows(); ++row)
112 {
113 const auto rowData = data(row, dataColSlice);
114 const auto rowResult = detail::ifft_internal(rowData, inN);
115 result.put(row, resultColSlice, rowResult);
116 }
117
118 return result;
119 }
120 case Axis::ROW:
121 {
122 return ifft(inArray.transpose(), inN, Axis::COL).transpose();
123 }
124 default:
125 {
126 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
127 return {};
128 }
129 }
130 }
131
132 //===========================================================================
133 // Method Description:
143 template<typename dtype>
144 NdArray<std::complex<double>> ifft(const NdArray<dtype>& inArray, Axis inAxis = Axis::NONE)
145 {
147
148 switch (inAxis)
149 {
150 case Axis::NONE:
151 {
152 return ifft(inArray, inArray.size(), inAxis);
153 }
154 case Axis::COL:
155 {
156 return ifft(inArray, inArray.numCols(), inAxis);
157 }
158 case Axis::ROW:
159 {
160 return ifft(inArray, inArray.numRows(), inAxis);
161 }
162 default:
163 {
164 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
165 return {};
166 }
167 }
168 }
169
170 //============================================================================
171 // Method Description:
182 template<typename dtype>
184 ifft(const NdArray<std::complex<dtype>>& inArray, uint32 inN, Axis inAxis = Axis::NONE)
185 {
187
188 switch (inAxis)
189 {
190 case Axis::NONE:
191 {
192 const auto data = nc::complex<dtype, double>(inArray);
193 return detail::ifft_internal(data, inN);
194 }
195 case Axis::COL:
196 {
197 const auto data = nc::complex<dtype, double>(inArray);
198 const auto& shape = inArray.shape();
199 auto result = NdArray<std::complex<double>>(shape.rows, inN);
200 const auto dataColSlice = data.cSlice();
201 const auto resultColSlice = result.cSlice();
202
203 for (uint32 row = 0; row < data.numRows(); ++row)
204 {
205 const auto rowData = data(row, dataColSlice);
206 const auto rowResult = detail::ifft_internal(rowData, inN);
207 result.put(row, resultColSlice, rowResult);
208 }
209
210 return result;
211 }
212 case Axis::ROW:
213 {
214 return ifft(inArray.transpose(), inN, Axis::COL).transpose();
215 }
216 default:
217 {
218 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
219 return {};
220 }
221 }
222 }
223
224 //============================================================================
225 // Method Description:
235 template<typename dtype>
236 NdArray<std::complex<double>> ifft(const NdArray<std::complex<dtype>>& inArray, Axis inAxis = Axis::NONE)
237 {
239
240 switch (inAxis)
241 {
242 case Axis::NONE:
243 {
244 return ifft(inArray, inArray.size(), inAxis);
245 }
246 case Axis::COL:
247 {
248 return ifft(inArray, inArray.numCols(), inAxis);
249 }
250 case Axis::ROW:
251 {
252 return ifft(inArray, inArray.numRows(), inAxis);
253 }
254 default:
255 {
256 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
257 return {};
258 }
259 }
260 }
261} // namespace nc::fft
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition Error.hpp:37
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition StaticAsserts.hpp:39
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition NdArrayCore.hpp:139
size_type size() const noexcept
Definition NdArrayCore.hpp:4600
self_type transpose() const
Definition NdArrayCore.hpp:4959
size_type numCols() const noexcept
Definition NdArrayCore.hpp:3541
const Shape & shape() const noexcept
Definition NdArrayCore.hpp:4587
size_type numRows() const noexcept
Definition NdArrayCore.hpp:3553
Slice cSlice(index_type inStartIdx=0, size_type inStepSize=1) const
Definition NdArrayCore.hpp:1008
uint32 rows
Definition Core/shape.hpp:44
NdArray< std::complex< double > > ifft_internal(const NdArray< std::complex< double > > &x, uint32 n)
Definition ifft.hpp:50
Definition FFT/FFT.hpp:40
NdArray< std::complex< double > > ifft(const NdArray< dtype > &inArray, uint32 inN, Axis inAxis=Axis::NONE)
Definition ifft.hpp:92
void for_each(InputIt first, InputIt last, UnaryFunction f)
Definition StlAlgorithms.hpp:225
Axis
Enum To describe an axis.
Definition Enums.hpp:36
auto angle(const std::complex< dtype > &inValue)
Definition angle.hpp:48
NdArray< dtype > arange(dtype inStart, dtype inStop, dtype inStep=1)
Definition arange.hpp:59
Shape shape(const NdArray< dtype > &inArray) noexcept
Definition Functions/shape.hpp:42
std::uint32_t uint32
Definition Types.hpp:40