6#include <xtl/xcomplex.hpp>
8#include <xtensor/xarray.hpp>
9#include <xtensor/xaxis_slice_iterator.hpp>
10#include <xtensor/xbuilder.hpp>
11#include <xtensor/xcomplex.hpp>
12#include <xtensor/xmath.hpp>
13#include <xtensor/xnoalias.hpp>
14#include <xtensor/xview.hpp>
24 typename std::enable_if<xtl::is_complex<typename std::decay<E>::type::value_type>::value,
bool>::type =
true>
25 inline auto radix2(E&& e)
27 using namespace xt::placeholders;
28 using namespace std::complex_literals;
29 using value_type =
typename std::decay_t<E>::value_type;
30 using precision =
typename value_type::value_type;
32 const bool powerOfTwo = !(N == 0) && !(N & (N - 1));
37 XTENSOR_THROW(std::runtime_error,
"FFT Implementation requires power of 2");
50 oneapi::tbb::parallel_invoke(
79 auto transform_bluestein(E&& data)
81 using value_type =
typename std::decay_t<E>::value_type;
82 using precision =
typename value_type::value_type;
85 const std::size_t
n = data.size();
86 size_t m = std::ceil(std::log2(
n * 2 + 1));
95 auto j = std::complex<precision>(0, 1);
111 auto xv = radix2(
av);
112 auto yv = radix2(
bv);
130 typename std::enable_if<xtl::is_complex<typename std::decay<E>::type::value_type>::value,
bool>::type =
true>
131 inline auto fft(E&&
e, std::ptrdiff_t axis = -1)
133 using value_type =
typename std::decay_t<E>::value_type;
134 using precision =
typename value_type::value_type;
135 const auto saxis = xt::normalize_axis(
e.dimension(), axis);
136 const size_t N =
e.shape(
saxis);
137 const bool powerOfTwo = !(N == 0) && !(N & (N - 1));
145 xt::noalias(*
iter) = detail::radix2(*
iter);
149 xt::noalias(*
iter) = detail::transform_bluestein(*
iter);
163 typename std::enable_if<!xtl::is_complex<typename std::decay<E>::type::value_type>::value,
bool>::type =
true>
164 inline auto fft(E&&
e, std::ptrdiff_t axis = -1)
166 using value_type =
typename std::decay<E>::type::value_type;
167 return fft(
xt::cast<std::complex<value_type>>(
e), axis);
172 typename std::enable_if<xtl::is_complex<typename std::decay<E>::type::value_type>::value,
bool>::type =
true>
173 auto ifft(E&&
e, std::ptrdiff_t axis = -1)
176 const std::size_t
n =
e.shape(axis);
179 XTENSOR_THROW(std::runtime_error,
"Cannot take the iFFT along an empty dimention");
189 typename std::enable_if<!xtl::is_complex<typename std::decay<E>::type::value_type>::value,
bool>::type =
true>
190 inline auto ifft(E&&
e, std::ptrdiff_t axis = -1)
192 using value_type =
typename std::decay<E>::type::value_type;
193 return ifft(
xt::cast<std::complex<value_type>>(
e), axis);
203 template <
typename E1,
typename E2>
204 auto convolve(
E1&&
xvec,
E2&&
yvec, std::ptrdiff_t axis = -1)
207 if (
xvec.dimension() !=
yvec.dimension())
209 XTENSOR_THROW(std::runtime_error,
"Mismatched dimentions");
212 auto saxis = xt::normalize_axis(
xvec.dimension(), axis);
215 XTENSOR_THROW(std::runtime_error,
"Mismatched lengths along slice axis");
220 auto xv = fft(
xvec, axis);
221 auto yv = fft(
yvec, axis);
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 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.