10#ifndef XTENSOR_COMPLEX_HPP
11#define XTENSOR_COMPLEX_HPP
16#include <xtl/xcomplex.hpp>
18#include "xtensor/xbuilder.hpp"
19#include "xtensor/xexpression.hpp"
20#include "xtensor/xoffset_view.hpp"
36 decltype(
auto)
real(E&& e)
noexcept;
39 decltype(
auto)
imag(E&& e)
noexcept;
47 template <
bool iscomplex = true>
51 inline static auto real(E&& e)
noexcept
53 using real_type =
typename std::decay_t<E>::value_type::value_type;
54 return xoffset_view<xclosure_t<E>, real_type, 0>(std::forward<E>(e));
58 inline static auto imag(E&& e)
noexcept
60 using real_type =
typename std::decay_t<E>::value_type::value_type;
61 return xoffset_view<xclosure_t<E>, real_type,
sizeof(real_type)>(std::forward<E>(e));
66 struct complex_helper<false>
69 inline static decltype(
auto) real(E&& e)
noexcept
71 return std::forward<E>(e);
75 inline static auto imag(E&& e)
noexcept
77 return zeros<typename std::decay_t<E>::value_type>(e.shape());
81 template <
bool isexpression = true>
82 struct complex_expression_helper
85 inline static decltype(
auto) real(E&& e)
noexcept
87 return detail::complex_helper<xtl::is_complex<typename std::decay_t<E>::value_type>::value>::real(
93 inline static decltype(
auto) imag(E&& e)
noexcept
95 return detail::complex_helper<xtl::is_complex<typename std::decay_t<E>::value_type>::value>::imag(
102 struct complex_expression_helper<false>
105 inline static decltype(
auto) real(E&& e)
noexcept
107 return xtl::forward_real(std::forward<E>(e));
111 inline static decltype(
auto) imag(E&& e)
noexcept
113 return xtl::forward_imag(std::forward<E>(e));
128 inline decltype(
auto)
real(E&&
e)
noexcept
130 return detail::complex_expression_helper<is_xexpression<std::decay_t<E>>::value>
::real(std::forward<E>(
e
144 inline decltype(
auto)
imag(E&&
e)
noexcept
146 return detail::complex_expression_helper<is_xexpression<std::decay_t<E>>::value>
::imag(std::forward<E>(
e
150#define UNARY_COMPLEX_FUNCTOR(NS, NAME) \
154 constexpr auto operator()(const T& t) const \
161 constexpr auto simd_apply(const B& t) const \
173 constexpr std::complex<T> conj_impl(
const std::complex<T>& c)
175 return std::complex<T>(c.real(), -c.imag());
179 constexpr std::complex<T> conj_impl(
const T& real)
181 return std::complex<T>(real, 0);
184#ifdef XTENSOR_USE_XSIMD
185 template <
class T,
class A>
186 xsimd::complex_batch_type_t<xsimd::batch<T, A>> conj_impl(
const xsimd::batch<T, A>& z)
188 return xsimd::conj(z);
193 UNARY_COMPLEX_FUNCTOR(std,
norm);
194 UNARY_COMPLEX_FUNCTOR(std, arg);
195 UNARY_COMPLEX_FUNCTOR(detail, conj_impl);
198#undef UNARY_COMPLEX_FUNCTOR
211 return type(functor(), std::forward<E>(
e));
221 inline auto arg(E&&
e)
noexcept
225 return type(functor(), std::forward<E>(
e));
240 using value_type = xtl::complex_value_type_t<typename std::decay_t<E>::value_type>;
261 return type(functor(), std::forward<E>(
e));
decltype(auto) imag(E &&e) noexcept
Return an xt::xexpression representing the imaginary part of the given expression.
decltype(auto) real(E &&e) noexcept
Return an xt::xexpression representing the real part of the given expression.
auto conj(E &&e) noexcept
Return an xt::xfunction evaluating to the complex conjugate of the given expression.
auto arg(E &&e) noexcept
Calculates the phase angle (in radians) elementwise for the complex numbers in e.
auto angle(E &&e, bool deg=false) noexcept
Calculates the phase angle elementwise for the complex numbers in e.
auto norm(E &&e) noexcept
Calculates the squared magnitude elementwise for the complex numbers in e.
standard mathematical functions for xexpressions