6#include <xtl/xcomplex.hpp>
8#include "../containers/xarray.hpp"
9#include "../core/xmath.hpp"
10#include "../core/xnoalias.hpp"
11#include "../generators/xbuilder.hpp"
12#include "../misc/xcomplex.hpp"
13#include "../views/xaxis_slice_iterator.hpp"
14#include "../views/xview.hpp"
15#include "./xtl_concepts.hpp"
23 template <xtl::complex_concept E>
24 inline auto radix2(E&& e)
26 using namespace xt::placeholders;
27 using namespace std::complex_literals;
28 using value_type =
typename std::decay_t<E>::value_type;
29 using precision =
typename value_type::value_type;
31 const bool powerOfTwo = !(N == 0) && !(N & (N - 1));
33 if (!powerOfTwo || N == 0)
36 XTENSOR_THROW(std::runtime_error,
"FFT Implementation requires power of 2");
38 auto pi = xt::numeric_constants<precision>::PI;
49 oneapi::tbb::parallel_invoke(
67 auto first_half = even + t;
68 auto second_half = even - t;
70 auto spectrum = xt::xtensor<value_type, 1>::from_shape({N});
78 auto transform_bluestein(E&& data)
80 using value_type =
typename std::decay_t<E>::value_type;
81 using precision =
typename value_type::value_type;
84 const std::size_t n = data.
size();
85 size_t m = std::ceil(std::log2(n * 2 + 1));
93 auto angles =
xt::eval(precision{3.141592653589793238463} * i / n);
94 auto j = std::complex<precision>(0, 1);
95 exp_table =
xt::exp(-angles * j);
110 auto xv = radix2(av);
111 auto yv = radix2(bv);
112 auto spectrum_k = xv * yv;
113 auto complex_args =
xt::conj(spectrum_k);
114 auto fft_res = radix2(complex_args);
128 inline auto fft(E&& e, std::ptrdiff_t axis = -1)
130 using value_type =
typename std::decay<E>::type::value_type;
131 if constexpr (xtl::is_complex<typename std::decay<E>::type::value_type>::value)
133 using precision =
typename value_type::value_type;
134 const auto saxis = xt::normalize_axis(e.dimension(), axis);
135 const size_t N = e.shape(saxis);
136 const bool powerOfTwo = !(N == 0) && !(N & (N - 1));
140 for (
auto iter = begin; iter != end; iter++)
144 xt::noalias(*iter) = detail::radix2(*iter);
148 xt::noalias(*iter) = detail::transform_bluestein(*iter);
155 return fft(
xt::cast<std::complex<value_type>>(e), axis);
160 inline auto ifft(E&& e, std::ptrdiff_t axis = -1)
162 if constexpr (xtl::is_complex<typename std::decay<E>::type::value_type>::value)
165 const std::size_t n = e.shape(axis);
168 XTENSOR_THROW(std::runtime_error,
"Cannot take the iFFT along an empty dimention");
171 auto fft_res = xt::fft::fft(complex_args, axis);
177 using value_type =
typename std::decay<E>::type::value_type;
178 return ifft(
xt::cast<std::complex<value_type>>(e), axis);
189 template <
typename E1,
typename E2>
190 auto convolve(E1&& xvec, E2&& yvec, std::ptrdiff_t axis = -1)
193 if (xvec.dimension() != yvec.dimension())
195 XTENSOR_THROW(std::runtime_error,
"Mismatched dimentions");
198 auto saxis = xt::normalize_axis(xvec.dimension(), axis);
199 if (xvec.shape(saxis) != yvec.shape(saxis))
201 XTENSOR_THROW(std::runtime_error,
"Mismatched lengths along slice axis");
204 const std::size_t n = xvec.shape(saxis);
206 auto xv = fft(xvec, axis);
207 auto yv = fft(yvec, axis);
213 for (
auto iter = begin_x; iter != end_x; iter++)
215 (*iter) = (*iter_y++) * (*iter);
218 auto outvec = ifft(xv, axis);
size_type size() const noexcept
Returns the number of element in the container.
auto cast(E &&e) noexcept -> detail::xfunction_type_t< typename detail::cast< R >::functor, E >
Element-wise static_cast.
auto exp(E &&e) noexcept -> detail::xfunction_type_t< math::exp_fun, E >
Natural exponential function.
auto pow(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::pow_fun, E1, E2 >
Power function.
auto conj(E &&e) noexcept
Return an xt::xfunction evaluating to the complex conjugate of the given expression.
auto eval(T &&t) -> std::enable_if_t< detail::is_container< std::decay_t< T > >::value, T && >
Force evaluation of xexpression.
auto flip(E &&e)
Reverse the order of elements in an xexpression along every axis.
standard mathematical functions for xexpressions
auto range(A start_val, B stop_val)
Select a range from start_val to stop_val (excluded).
auto arange(T start, T stop, S step=1) noexcept
Generates numbers evenly spaced within given half-open interval [start, stop).
xarray_container< uvector< T, A >, L, xt::svector< typename uvector< T, A >::size_type, 4, SA, true > > xarray
Alias template on xarray_container with default parameters for data container type and shape / stride...
xtensor_container< uvector< T, A >, N, L > xtensor
Alias template on xtensor_container with default parameters for data container type.
auto axis_slice_begin(E &&e)
Returns an iterator to the first element of the expression for axis 0.
auto view(E &&e, S &&... slices)
Constructs and returns a view on the specified xexpression.
auto axis_slice_end(E &&e)
Returns an iterator to the element following the last element of the expression for axis 0.
xarray< T, L > empty(const S &shape)
Create a xcontainer (xarray, xtensor or xtensor_fixed) with uninitialized values of with value_type T...