NumCpp  2.16.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
Loading...
Searching...
No Matches
FFT/FFT.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>> fft_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 k = static_cast<double>(&resultElement - result.data());
64 const auto minusTwoPiKOverN = -constants::twoPi * k / static_cast<double>(n);
65 resultElement = std::complex<double>{ 0., 0. };
66 for (auto m = 0u; m < std::min(n, x.size()); ++m)
67 {
68 const auto angle = minusTwoPiKOverN * static_cast<double>(m);
69 resultElement += (x[m] * std::polar(1., angle));
70 }
71 });
72
73 return result;
74 }
75 } // namespace detail
76
77 //===========================================================================
78 // Method Description:
89 template<typename dtype>
90 NdArray<std::complex<double>> fft(const NdArray<dtype>& inArray, uint32 inN, Axis inAxis = Axis::NONE)
91 {
93
94 switch (inAxis)
95 {
96 case Axis::NONE:
97 {
98 const auto data = nc::complex<dtype, double>(inArray);
99 return detail::fft_internal(data, inN);
100 }
101 case Axis::COL:
102 {
103 auto data = nc::complex<dtype, double>(inArray);
104 const auto& shape = inArray.shape();
105 auto result = NdArray<std::complex<double>>(shape.rows, inN);
106 const auto dataColSlice = data.cSlice();
107 const auto resultColSlice = result.cSlice();
108
109 for (uint32 row = 0; row < data.numRows(); ++row)
110 {
111 const auto rowData = data(row, dataColSlice);
112 const auto rowResult = detail::fft_internal(rowData, inN);
113 result.put(row, resultColSlice, rowResult);
114 }
115
116 return result;
117 }
118 case Axis::ROW:
119 {
120 return fft(inArray.transpose(), inN, Axis::COL).transpose();
121 }
122 default:
123 {
124 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
125 return {};
126 }
127 }
128 }
129
130 //===========================================================================
131 // Method Description:
141 template<typename dtype>
142 NdArray<std::complex<double>> fft(const NdArray<dtype>& inArray, Axis inAxis = Axis::NONE)
143 {
145
146 switch (inAxis)
147 {
148 case Axis::NONE:
149 {
150 return fft(inArray, inArray.size(), inAxis);
151 }
152 case Axis::COL:
153 {
154 return fft(inArray, inArray.numCols(), inAxis);
155 }
156 case Axis::ROW:
157 {
158 return fft(inArray, inArray.numRows(), inAxis);
159 }
160 default:
161 {
162 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
163 return {};
164 }
165 }
166 }
167
168 //============================================================================
169 // Method Description:
180 template<typename dtype>
181 NdArray<std::complex<double>> fft(const NdArray<std::complex<dtype>>& inArray, uint32 inN, Axis inAxis = Axis::NONE)
182 {
184
185 switch (inAxis)
186 {
187 case Axis::NONE:
188 {
189 const auto data = nc::complex<dtype, double>(inArray);
190 return detail::fft_internal(data, inN);
191 }
192 case Axis::COL:
193 {
194 const auto data = nc::complex<dtype, double>(inArray);
195 const auto& shape = inArray.shape();
196 auto result = NdArray<std::complex<double>>(shape.rows, inN);
197 const auto dataColSlice = data.cSlice();
198 const auto resultColSlice = result.cSlice();
199
200 for (uint32 row = 0; row < data.numRows(); ++row)
201 {
202 const auto rowData = data(row, dataColSlice);
203 const auto rowResult = detail::fft_internal(rowData, inN);
204 result.put(row, resultColSlice, rowResult);
205 }
206
207 return result;
208 }
209 case Axis::ROW:
210 {
211 return fft(inArray.transpose(), inN, Axis::COL).transpose();
212 }
213 default:
214 {
215 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
216 return {};
217 }
218 }
219 }
220
221 //============================================================================
222 // Method Description:
232 template<typename dtype>
233 NdArray<std::complex<double>> fft(const NdArray<std::complex<dtype>>& inArray, Axis inAxis = Axis::NONE)
234 {
236
237 switch (inAxis)
238 {
239 case Axis::NONE:
240 {
241 return fft(inArray, inArray.size(), inAxis);
242 }
243 case Axis::COL:
244 {
245 return fft(inArray, inArray.numCols(), inAxis);
246 }
247 case Axis::ROW:
248 {
249 return fft(inArray, inArray.numRows(), inAxis);
250 }
251 default:
252 {
253 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
254 return {};
255 }
256 }
257 }
258} // 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 > > fft_internal(const NdArray< std::complex< double > > &x, uint32 n)
Definition FFT/FFT.hpp:50
Definition FFT/FFT.hpp:40
NdArray< std::complex< double > > fft(const NdArray< dtype > &inArray, uint32 inN, Axis inAxis=Axis::NONE)
Definition FFT/FFT.hpp:90
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