14#ifndef XTENSOR_MATH_HPP 
   15#define XTENSOR_MATH_HPP 
   23#include <xtl/xcomplex.hpp> 
   24#include <xtl/xsequence.hpp> 
   25#include <xtl/xtype_traits.hpp> 
   27#include "../core/xeval.hpp" 
   28#include "../core/xoperation.hpp" 
   29#include "../core/xtensor_config.hpp" 
   30#include "../misc/xmanipulation.hpp" 
   31#include "../reducers/xaccumulator.hpp" 
   32#include "../reducers/xreducer.hpp" 
   33#include "../views/xslice.hpp" 
   34#include "../views/xstrided_view.hpp" 
   38    template <
class T = 
double>
 
   41        static constexpr T PI = 3.141592653589793238463;
 
   42        static constexpr T PI_2 = 1.57079632679489661923;
 
   43        static constexpr T PI_4 = 0.785398163397448309616;
 
   44        static constexpr T D_1_PI = 0.318309886183790671538;
 
   45        static constexpr T D_2_PI = 0.636619772367581343076;
 
   46        static constexpr T D_2_SQRTPI = 1.12837916709551257390;
 
   47        static constexpr T SQRT2 = 1.41421356237309504880;
 
   48        static constexpr T SQRT1_2 = 0.707106781186547524401;
 
   49        static constexpr T E = 2.71828182845904523536;
 
   50        static constexpr T LOG2E = 1.44269504088896340736;
 
   51        static constexpr T LOG10E = 0.434294481903251827651;
 
   52        static constexpr T LN2 = 0.693147180559945309417;
 
 
   59#define XTENSOR_UNSIGNED_ABS_FUNC(T)   \ 
   60    constexpr inline T abs(const T& x) \ 
   65#define XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, T) \ 
   66    constexpr inline bool FUNC_NAME(const T& ) noexcept      \ 
   71#define XTENSOR_INT_SPECIALIZATION(FUNC_NAME, RETURN_VAL)                   \ 
   72    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, char);           \ 
   73    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, short);          \ 
   74    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, int);            \ 
   75    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, long);           \ 
   76    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, long long);      \ 
   77    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned char);  \ 
   78    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned short); \ 
   79    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned int);   \ 
   80    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned long);  \ 
   81    XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned long long); 
   84#define XTENSOR_UNARY_MATH_FUNCTOR(NAME)              \ 
   88        constexpr auto operator()(const T& arg) const \ 
   94        constexpr auto simd_apply(const B& arg) const \ 
  101#define XTENSOR_UNARY_MATH_FUNCTOR_COMPLEX_REDUCING(NAME) \ 
  105        constexpr auto operator()(const T& arg) const     \ 
  111        constexpr auto simd_apply(const B& arg) const     \ 
  118#define XTENSOR_BINARY_MATH_FUNCTOR(NAME)                               \ 
  121        template <class T1, class T2>                                   \ 
  122        constexpr auto operator()(const T1& arg1, const T2& arg2) const \ 
  125            return NAME(arg1, arg2);                                    \ 
  128        constexpr auto simd_apply(const B& arg1, const B& arg2) const   \ 
  131            return NAME(arg1, arg2);                                    \ 
  135#define XTENSOR_TERNARY_MATH_FUNCTOR(NAME)                                              \ 
  138        template <class T1, class T2, class T3>                                         \ 
  139        constexpr auto operator()(const T1& arg1, const T2& arg2, const T3& arg3) const \ 
  142            return NAME(arg1, arg2, arg3);                                              \ 
  145        auto simd_apply(const B& arg1, const B& arg2, const B& arg3) const              \ 
  148            return NAME(arg1, arg2, arg3);                                              \ 
  188        using std::nearbyint;
 
  189        using std::remainder;
 
  207#if !defined(_MSC_VER) 
  218        using std::fpclassify;
 
  224        inline std::enable_if_t<xtl::is_arithmetic<T>::value, 
bool> 
isinf(
const T& t)
 
  226            return bool(std::isinf(t));
 
  230        inline std::enable_if_t<xtl::is_arithmetic<T>::value, 
bool> isnan(
const T& t)
 
  232            return bool(std::isnan(t));
 
  236        inline std::enable_if_t<xtl::is_arithmetic<T>::value, 
bool> isfinite(
const T& t)
 
  238            return bool(std::isfinite(t));
 
  244        inline bool isinf(
const std::complex<T>& c)
 
  246            return std::isinf(std::real(c)) || std::isinf(std::imag(c));
 
  250        inline bool isnan(
const std::complex<T>& c)
 
  252            return std::isnan(std::real(c)) || std::isnan(std::imag(c));
 
  256        inline bool isfinite(
const std::complex<T>& c)
 
  258            return !isinf(c) && !isnan(c);
 
  263#if defined(_WIN32) && defined(XTENSOR_USE_XSIMD) 
  283        XTENSOR_UNSIGNED_ABS_FUNC(
unsigned char)
 
  284        XTENSOR_UNSIGNED_ABS_FUNC(
unsigned short)
 
  285        XTENSOR_UNSIGNED_ABS_FUNC(
unsigned int)
 
  286        XTENSOR_UNSIGNED_ABS_FUNC(
unsigned long)
 
  287        XTENSOR_UNSIGNED_ABS_FUNC(
unsigned long long)
 
  290        XTENSOR_INT_SPECIALIZATION(isinf, 
false);
 
  291        XTENSOR_INT_SPECIALIZATION(isnan, 
false);
 
  292        XTENSOR_INT_SPECIALIZATION(isfinite, 
true);
 
  295        XTENSOR_UNARY_MATH_FUNCTOR_COMPLEX_REDUCING(abs);
 
  297        XTENSOR_UNARY_MATH_FUNCTOR(
fabs);
 
  298        XTENSOR_BINARY_MATH_FUNCTOR(
fmod);
 
  300        XTENSOR_TERNARY_MATH_FUNCTOR(
fma);
 
  301        XTENSOR_BINARY_MATH_FUNCTOR(
fmax);
 
  302        XTENSOR_BINARY_MATH_FUNCTOR(
fmin);
 
  303        XTENSOR_BINARY_MATH_FUNCTOR(
fdim);
 
  304        XTENSOR_UNARY_MATH_FUNCTOR(
exp);
 
  305        XTENSOR_UNARY_MATH_FUNCTOR(
exp2);
 
  307        XTENSOR_UNARY_MATH_FUNCTOR(
log);
 
  309        XTENSOR_UNARY_MATH_FUNCTOR(
log2);
 
  311        XTENSOR_BINARY_MATH_FUNCTOR(
pow);
 
  312        XTENSOR_UNARY_MATH_FUNCTOR(
sqrt);
 
  313        XTENSOR_UNARY_MATH_FUNCTOR(
cbrt);
 
  315        XTENSOR_UNARY_MATH_FUNCTOR(
sin);
 
  316        XTENSOR_UNARY_MATH_FUNCTOR(
cos);
 
  317        XTENSOR_UNARY_MATH_FUNCTOR(
tan);
 
  318        XTENSOR_UNARY_MATH_FUNCTOR(
asin);
 
  319        XTENSOR_UNARY_MATH_FUNCTOR(
acos);
 
  320        XTENSOR_UNARY_MATH_FUNCTOR(
atan);
 
  322        XTENSOR_UNARY_MATH_FUNCTOR(
sinh);
 
  323        XTENSOR_UNARY_MATH_FUNCTOR(
cosh);
 
  324        XTENSOR_UNARY_MATH_FUNCTOR(
tanh);
 
  328        XTENSOR_UNARY_MATH_FUNCTOR(
erf);
 
  329        XTENSOR_UNARY_MATH_FUNCTOR(
erfc);
 
  332        XTENSOR_UNARY_MATH_FUNCTOR(
ceil);
 
  337        XTENSOR_UNARY_MATH_FUNCTOR(
rint);
 
  338        XTENSOR_UNARY_MATH_FUNCTOR(isfinite);
 
  339        XTENSOR_UNARY_MATH_FUNCTOR(isinf);
 
  340        XTENSOR_UNARY_MATH_FUNCTOR(isnan);
 
  341        XTENSOR_UNARY_MATH_FUNCTOR(
conj);
 
  344#undef XTENSOR_UNARY_MATH_FUNCTOR 
  345#undef XTENSOR_BINARY_MATH_FUNCTOR 
  346#undef XTENSOR_TERNARY_MATH_FUNCTOR 
  347#undef XTENSOR_UNARY_MATH_FUNCTOR_COMPLEX_REDUCING 
  348#undef XTENSOR_UNSIGNED_ABS_FUNC 
  352        template <
class R, 
class T>
 
  353        std::enable_if_t<!has_iterator_interface<R>::value, R> fill_init(T init)
 
  358        template <
class R, 
class T>
 
  359        std::enable_if_t<has_iterator_interface<R>::value, R> fill_init(T init)
 
  362            std::fill(std::begin(result), std::end(result), init);
 
  367#define XTENSOR_REDUCER_FUNCTION(NAME, FUNCTOR, INIT_VALUE_TYPE, INIT)                                               \ 
  372        class EVS = DEFAULT_STRATEGY_REDUCERS,                                                                       \ 
  373        XTL_REQUIRES(std::negation<is_reducer_options<X>>, std::negation<xtl::is_integral<std::decay_t<X>>>)>        \ 
  374    inline auto NAME(E&& e, X&& axes, EVS es = EVS())                                                                \ 
  376        using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>;                \ 
  377        using functor_type = FUNCTOR;                                                                                \ 
  378        using init_value_fct = xt::const_value<init_value_type>;                                                     \ 
  380            make_xreducer_functor(functor_type(), init_value_fct(detail::fill_init<init_value_type>(INIT))),         \ 
  381            std::forward<E>(e),                                                                                      \ 
  382            std::forward<X>(axes),                                                                                   \ 
  391        class EVS = DEFAULT_STRATEGY_REDUCERS,                                                                       \ 
  392        XTL_REQUIRES(std::negation<is_reducer_options<X>>, xtl::is_integral<std::decay_t<X>>)>                       \ 
  393    inline auto NAME(E&& e, X axis, EVS es = EVS())                                                                  \ 
  395        return NAME(std::forward<E>(e), {axis}, es);                                                                 \ 
  398    template <class T = void, class E, class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)> \ 
  399    inline auto NAME(E&& e, EVS es = EVS())                                                                          \ 
  401        using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>;                \ 
  402        using functor_type = FUNCTOR;                                                                                \ 
  403        using init_value_fct = xt::const_value<init_value_type>;                                                     \ 
  405            make_xreducer_functor(functor_type(), init_value_fct(detail::fill_init<init_value_type>(INIT))),         \ 
  406            std::forward<E>(e),                                                                                      \ 
  411    template <class T = void, class E, class I, std::size_t N, class EVS = DEFAULT_STRATEGY_REDUCERS>                \ 
  412    inline auto NAME(E&& e, const I(&axes)[N], EVS es = EVS())                                                       \ 
  414        using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>;                \ 
  415        using functor_type = FUNCTOR;                                                                                \ 
  416        using init_value_fct = xt::const_value<init_value_type>;                                                     \ 
  418            make_xreducer_functor(functor_type(), init_value_fct(detail::fill_init<init_value_type>(INIT))),         \ 
  419            std::forward<E>(e),                                                                                      \ 
  443    inline auto abs(E&& e) 
noexcept -> detail::xfunction_type_t<math::abs_fun, E>
 
  445        return detail::make_xfunction<math::abs_fun>(std::forward<E>(e));
 
 
  458    inline auto fabs(E&& e) 
noexcept -> detail::xfunction_type_t<math::fabs_fun, E>
 
  460        return detail::make_xfunction<math::fabs_fun>(std::forward<E>(e));
 
 
  474    template <
class E1, 
class E2>
 
  475    inline auto fmod(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::fmod_fun, E1, E2>
 
  477        return detail::make_xfunction<math::fmod_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  491    template <
class E1, 
class E2>
 
  492    inline auto remainder(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::remainder_fun, E1, E2>
 
  494        return detail::make_xfunction<math::remainder_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  509    template <
class E1, 
class E2, 
class E3>
 
  510    inline auto fma(E1&& e1, E2&& e2, E3&& e3) 
noexcept -> detail::xfunction_type_t<math::fma_fun, E1, E2, E3>
 
  512        return detail::make_xfunction<math::fma_fun>(
 
  513            std::forward<E1>(e1),
 
  514            std::forward<E2>(e2),
 
 
  530    template <
class E1, 
class E2>
 
  531    inline auto fmax(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::fmax_fun, E1, E2>
 
  533        return detail::make_xfunction<math::fmax_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  547    template <
class E1, 
class E2>
 
  548    inline auto fmin(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::fmin_fun, E1, E2>
 
  550        return detail::make_xfunction<math::fmin_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  564    template <
class E1, 
class E2>
 
  565    inline auto fdim(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::fdim_fun, E1, E2>
 
  567        return detail::make_xfunction<math::fdim_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  572        template <
class T = 
void>
 
  575            template <
class A1, 
class A2>
 
  576            constexpr auto operator()(
const A1& t1, 
const A2& t2) 
const noexcept 
  578                return xtl::select(t1 < t2, t1, t2);
 
  581            template <
class A1, 
class A2>
 
  582            constexpr auto simd_apply(
const A1& t1, 
const A2& t2) 
const noexcept 
  584                return xt_simd::select(t1 < t2, t1, t2);
 
 
  588        template <
class T = 
void>
 
  591            template <
class A1, 
class A2>
 
  592            constexpr auto operator()(
const A1& t1, 
const A2& t2) 
const noexcept 
  594                return xtl::select(t1 > t2, t1, t2);
 
  597            template <
class A1, 
class A2>
 
  598            constexpr auto simd_apply(
const A1& t1, 
const A2& t2) 
const noexcept 
  600                return xt_simd::select(t1 > t2, t1, t2);
 
 
  606            template <
class A1, 
class A2, 
class A3>
 
  607            constexpr auto operator()(
const A1& v, 
const A2& lo, 
const A3& hi)
 const 
  609                return xtl::select(v < lo, lo, xtl::select(hi < v, hi, v));
 
  612            template <
class A1, 
class A2, 
class A3>
 
  613            constexpr auto simd_apply(
const A1& v, 
const A2& lo, 
const A3& hi)
 const 
  615                return xt_simd::select(v < lo, lo, xt_simd::select(hi < v, hi, v));
 
 
  621            template <class A, std::enable_if_t<xtl::is_integral<A>::value, 
int> = 0>
 
  622            constexpr double operator()(
const A& a) 
const noexcept 
  624                return a * xt::numeric_constants<double>::PI / 180.0;
 
  627            template <class A, std::enable_if_t<std::is_floating_point<A>::value, 
int> = 0>
 
  628            constexpr auto operator()(
const A& a) 
const noexcept 
  630                return a * xt::numeric_constants<A>::PI / A(180.0);
 
  633            template <class A, std::enable_if_t<xtl::is_integral<A>::value, 
int> = 0>
 
  634            constexpr double simd_apply(
const A& a) 
const noexcept 
  636                return a * xt::numeric_constants<double>::PI / 180.0;
 
  639            template <class A, std::enable_if_t<std::is_floating_point<A>::value, 
int> = 0>
 
  640            constexpr auto simd_apply(
const A& a) 
const noexcept 
  642                return a * xt::numeric_constants<A>::PI / A(180.0);
 
 
  648            template <class A, std::enable_if_t<xtl::is_integral<A>::value, 
int> = 0>
 
  649            constexpr double operator()(
const A& a) 
const noexcept 
  651                return a * 180.0 / xt::numeric_constants<double>::PI;
 
  654            template <class A, std::enable_if_t<std::is_floating_point<A>::value, 
int> = 0>
 
  655            constexpr auto operator()(
const A& a) 
const noexcept 
  657                return a * A(180.0) / xt::numeric_constants<A>::PI;
 
  660            template <class A, std::enable_if_t<xtl::is_integral<A>::value, 
int> = 0>
 
  661            constexpr double simd_apply(
const A& a) 
const noexcept 
  663                return a * 180.0 / xt::numeric_constants<double>::PI;
 
  666            template <class A, std::enable_if_t<std::is_floating_point<A>::value, 
int> = 0>
 
  667            constexpr auto simd_apply(
const A& a) 
const noexcept 
  669                return a * A(180.0) / xt::numeric_constants<A>::PI;
 
 
  684    inline auto deg2rad(E&& e) 
noexcept -> detail::xfunction_type_t<math::deg2rad, E>
 
  686        return detail::make_xfunction<math::deg2rad>(std::forward<E>(e));
 
 
  699    inline auto radians(E&& e) 
noexcept -> detail::xfunction_type_t<math::deg2rad, E>
 
  701        return detail::make_xfunction<math::deg2rad>(std::forward<E>(e));
 
 
  714    inline auto rad2deg(E&& e) 
noexcept -> detail::xfunction_type_t<math::rad2deg, E>
 
  716        return detail::make_xfunction<math::rad2deg>(std::forward<E>(e));
 
 
  729    inline auto degrees(E&& e) 
noexcept -> detail::xfunction_type_t<math::rad2deg, E>
 
  731        return detail::make_xfunction<math::rad2deg>(std::forward<E>(e));
 
 
  744    template <
class E1, 
class E2>
 
  745    inline auto maximum(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::maximum<void>, E1, E2>
 
  747        return detail::make_xfunction<math::maximum<void>>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  760    template <
class E1, 
class E2>
 
  761    inline auto minimum(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::minimum<void>, E1, E2>
 
  763        return detail::make_xfunction<math::minimum<void>>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
  777    XTENSOR_REDUCER_FUNCTION(
 
  780        typename std::decay_t<E>::value_type,
 
  781        std::numeric_limits<xvalue_type_t<std::decay_t<E>>>::lowest()
 
  795    XTENSOR_REDUCER_FUNCTION(
 
  798        typename std::decay_t<E>::value_type,
 
  799        std::numeric_limits<xvalue_type_t<std::decay_t<E>>>::max()
 
  814    template <class E1, class E2, class E3>
 
  815    inline auto 
clip(E1&& e1, E2&& lo, E3&& hi) noexcept
 
  816        -> detail::xfunction_type_t<math::clamp_fun, E1, E2, E3>
 
  818        return detail::make_xfunction<math::clamp_fun>(
 
  819            std::forward<E1>(e1),
 
  820            std::forward<E2>(lo),
 
 
  830            template <
class XT = T>
 
  831            static constexpr std::enable_if_t<xtl::is_signed<XT>::value, T> run(T x)
 
  833                return std::isnan(x) ? std::numeric_limits<T>::quiet_NaN()
 
  834                       : x == 0      ? T(copysign(T(0), x))
 
  835                                     : T(copysign(T(1), x));
 
  838            template <
class XT = T>
 
  839            static constexpr std::enable_if_t<xtl::is_complex<XT>::value, T> run(T x)
 
  842                    sign_impl<typename T::value_type>::run(
 
  843                        (x.real() != 
typename T::value_type(0)) ? x.real() : x.imag()
 
  849            template <
class XT = T>
 
  850            static constexpr std::enable_if_t<std::is_unsigned<XT>::value, T> run(T x)
 
 
  859            constexpr auto operator()(
const T& x)
 const 
  861                return sign_impl<T>::run(x);
 
 
  877    inline auto sign(E&& e) 
noexcept -> detail::xfunction_type_t<math::sign_fun, E>
 
  879        return detail::make_xfunction<math::sign_fun>(std::forward<E>(e));
 
 
  900    inline auto exp(E&& e) 
noexcept -> detail::xfunction_type_t<math::exp_fun, E>
 
  902        return detail::make_xfunction<math::exp_fun>(std::forward<E>(e));
 
 
  915    inline auto exp2(E&& e) 
noexcept -> detail::xfunction_type_t<math::exp2_fun, E>
 
  917        return detail::make_xfunction<math::exp2_fun>(std::forward<E>(e));
 
 
  930    inline auto expm1(E&& e) 
noexcept -> detail::xfunction_type_t<math::expm1_fun, E>
 
  932        return detail::make_xfunction<math::expm1_fun>(std::forward<E>(e));
 
 
  945    inline auto log(E&& e) 
noexcept -> detail::xfunction_type_t<math::log_fun, E>
 
  947        return detail::make_xfunction<math::log_fun>(std::forward<E>(e));
 
 
  960    inline auto log10(E&& e) 
noexcept -> detail::xfunction_type_t<math::log10_fun, E>
 
  962        return detail::make_xfunction<math::log10_fun>(std::forward<E>(e));
 
 
  975    inline auto log2(E&& e) 
noexcept -> detail::xfunction_type_t<math::log2_fun, E>
 
  977        return detail::make_xfunction<math::log2_fun>(std::forward<E>(e));
 
 
  990    inline auto log1p(E&& e) 
noexcept -> detail::xfunction_type_t<math::log1p_fun, E>
 
  992        return detail::make_xfunction<math::log1p_fun>(std::forward<E>(e));
 
 
 1014    template <
class E1, 
class E2>
 
 1015    inline auto pow(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::pow_fun, E1, E2>
 
 1017        return detail::make_xfunction<math::pow_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
 1022        template <
class F, 
class... T, 
typename = 
decltype(std::declval<F>()(std::declval<T>()...))>
 
 1023        std::true_type supports_test(
const F&, 
const T&...);
 
 1024        std::false_type supports_test(...);
 
 1026        template <
class... T>
 
 1029        template <
class F, 
class... T>
 
 1030        struct supports<F(T...)> : decltype(supports_test(std::declval<F>(), std::declval<T>()...))
 
 1037            explicit lambda_adapt(F&& lmbd)
 
 1038                : m_lambda(std::move(lmbd))
 
 1042            template <
class... T>
 
 1043            auto operator()(T... args)
 const 
 1045                return m_lambda(args...);
 
 1048            template <
class... T, XTL_REQUIRES(detail::supports<F(T...)>)>
 
 1049            auto simd_apply(T... args)
 const 
 1051                return m_lambda(args...);
 
 1084    template <
class F, 
class... E>
 
 1087        using xfunction_type = 
typename detail::xfunction_type<detail::lambda_adapt<F>, E...>::type;
 
 1088        return xfunction_type(detail::lambda_adapt<F>(std::forward<F>(lambda)), std::forward<E>(args)...);
 
 
 1092#if (defined(_MSC_VER) && _MSC_VER < 1910) || (defined(__GNUC__) && __GNUC__ < 5) 
 1093#define XTENSOR_DISABLE_LAMBDA_FCT 
 1096#ifdef XTENSOR_DISABLE_LAMBDA_FCT 
 1100        auto operator()(T x) 
const -> 
decltype(x * x)
 
 1109        auto operator()(T x) 
const -> 
decltype(x * x * x)
 
 1128#ifdef XTENSOR_DISABLE_LAMBDA_FCT 
 1131        auto fnct = [](
auto x) -> 
decltype(x * x)
 
 
 1151#ifdef XTENSOR_DISABLE_LAMBDA_FCT 
 1154        auto fnct = [](
auto x) -> 
decltype(x * x * x)
 
 
 1162#undef XTENSOR_DISABLE_LAMBDA_FCT 
 1167        template <std::
size_t N>
 
 1170        template <std::
size_t N>
 
 1174            auto operator()(T v) 
const -> 
decltype(v * v)
 
 1176                T temp = pow_impl<N / 2>{}(v);
 
 1177                return temp * temp * pow_impl<N & 1>{}(v);
 
 1185            auto operator()(T v) 
const -> T
 
 1195            auto operator()(T ) 
const -> T
 
 1219    template <std::
size_t N, 
class E>
 
 1220    inline auto pow(E&& e) 
noexcept 
 1222        static_assert(N > 0, 
"integer power cannot be negative");
 
 
 1236    inline auto sqrt(E&& e) 
noexcept -> detail::xfunction_type_t<math::sqrt_fun, E>
 
 1238        return detail::make_xfunction<math::sqrt_fun>(std::forward<E>(e));
 
 
 1251    inline auto cbrt(E&& e) 
noexcept -> detail::xfunction_type_t<math::cbrt_fun, E>
 
 1253        return detail::make_xfunction<math::cbrt_fun>(std::forward<E>(e));
 
 
 1268    template <
class E1, 
class E2>
 
 1269    inline auto hypot(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::hypot_fun, E1, E2>
 
 1271        return detail::make_xfunction<math::hypot_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
 1292    inline auto sin(E&& e) 
noexcept -> detail::xfunction_type_t<math::sin_fun, E>
 
 1294        return detail::make_xfunction<math::sin_fun>(std::forward<E>(e));
 
 
 1307    inline auto cos(E&& e) 
noexcept -> detail::xfunction_type_t<math::cos_fun, E>
 
 1309        return detail::make_xfunction<math::cos_fun>(std::forward<E>(e));
 
 
 1322    inline auto tan(E&& e) 
noexcept -> detail::xfunction_type_t<math::tan_fun, E>
 
 1324        return detail::make_xfunction<math::tan_fun>(std::forward<E>(e));
 
 
 1337    inline auto asin(E&& e) 
noexcept -> detail::xfunction_type_t<math::asin_fun, E>
 
 1339        return detail::make_xfunction<math::asin_fun>(std::forward<E>(e));
 
 
 1352    inline auto acos(E&& e) 
noexcept -> detail::xfunction_type_t<math::acos_fun, E>
 
 1354        return detail::make_xfunction<math::acos_fun>(std::forward<E>(e));
 
 
 1367    inline auto atan(E&& e) 
noexcept -> detail::xfunction_type_t<math::atan_fun, E>
 
 1369        return detail::make_xfunction<math::atan_fun>(std::forward<E>(e));
 
 
 1384    template <
class E1, 
class E2>
 
 1385    inline auto atan2(E1&& e1, E2&& e2) 
noexcept -> detail::xfunction_type_t<math::atan2_fun, E1, E2>
 
 1387        return detail::make_xfunction<math::atan2_fun>(std::forward<E1>(e1), std::forward<E2>(e2));
 
 
 1408    inline auto sinh(E&& e) 
noexcept -> detail::xfunction_type_t<math::sinh_fun, E>
 
 1410        return detail::make_xfunction<math::sinh_fun>(std::forward<E>(e));
 
 
 1423    inline auto cosh(E&& e) 
noexcept -> detail::xfunction_type_t<math::cosh_fun, E>
 
 1425        return detail::make_xfunction<math::cosh_fun>(std::forward<E>(e));
 
 
 1438    inline auto tanh(E&& e) 
noexcept -> detail::xfunction_type_t<math::tanh_fun, E>
 
 1440        return detail::make_xfunction<math::tanh_fun>(std::forward<E>(e));
 
 
 1453    inline auto asinh(E&& e) 
noexcept -> detail::xfunction_type_t<math::asinh_fun, E>
 
 1455        return detail::make_xfunction<math::asinh_fun>(std::forward<E>(e));
 
 
 1468    inline auto acosh(E&& e) 
noexcept -> detail::xfunction_type_t<math::acosh_fun, E>
 
 1470        return detail::make_xfunction<math::acosh_fun>(std::forward<E>(e));
 
 
 1483    inline auto atanh(E&& e) 
noexcept -> detail::xfunction_type_t<math::atanh_fun, E>
 
 1485        return detail::make_xfunction<math::atanh_fun>(std::forward<E>(e));
 
 
 1506    inline auto erf(E&& e) 
noexcept -> detail::xfunction_type_t<math::erf_fun, E>
 
 1508        return detail::make_xfunction<math::erf_fun>(std::forward<E>(e));
 
 
 1521    inline auto erfc(E&& e) 
noexcept -> detail::xfunction_type_t<math::erfc_fun, E>
 
 1523        return detail::make_xfunction<math::erfc_fun>(std::forward<E>(e));
 
 
 1536    inline auto tgamma(E&& e) 
noexcept -> detail::xfunction_type_t<math::tgamma_fun, E>
 
 1538        return detail::make_xfunction<math::tgamma_fun>(std::forward<E>(e));
 
 
 1551    inline auto lgamma(E&& e) 
noexcept -> detail::xfunction_type_t<math::lgamma_fun, E>
 
 1553        return detail::make_xfunction<math::lgamma_fun>(std::forward<E>(e));
 
 
 1574    inline auto ceil(E&& e) 
noexcept -> detail::xfunction_type_t<math::ceil_fun, E>
 
 1576        return detail::make_xfunction<math::ceil_fun>(std::forward<E>(e));
 
 
 1589    inline auto floor(E&& e) 
noexcept -> detail::xfunction_type_t<math::floor_fun, E>
 
 1591        return detail::make_xfunction<math::floor_fun>(std::forward<E>(e));
 
 
 1604    inline auto trunc(E&& e) 
noexcept -> detail::xfunction_type_t<math::trunc_fun, E>
 
 1606        return detail::make_xfunction<math::trunc_fun>(std::forward<E>(e));
 
 
 1620    inline auto round(E&& e) 
noexcept -> detail::xfunction_type_t<math::round_fun, E>
 
 1622        return detail::make_xfunction<math::round_fun>(std::forward<E>(e));
 
 
 1636    inline auto nearbyint(E&& e) 
noexcept -> detail::xfunction_type_t<math::nearbyint_fun, E>
 
 1638        return detail::make_xfunction<math::nearbyint_fun>(std::forward<E>(e));
 
 
 1652    inline auto rint(E&& e) 
noexcept -> detail::xfunction_type_t<math::rint_fun, E>
 
 1654        return detail::make_xfunction<math::rint_fun>(std::forward<E>(e));
 
 
 1675    inline auto isfinite(E&& e) 
noexcept -> detail::xfunction_type_t<math::isfinite_fun, E>
 
 1677        return detail::make_xfunction<math::isfinite_fun>(std::forward<E>(e));
 
 
 1690    inline auto isinf(E&& e) 
noexcept -> detail::xfunction_type_t<math::isinf_fun, E>
 
 1692        return detail::make_xfunction<math::isinf_fun>(std::forward<E>(e));
 
 
 1705    inline auto isnan(E&& e) 
noexcept -> detail::xfunction_type_t<math::isnan_fun, E>
 
 1707        return detail::make_xfunction<math::isnan_fun>(std::forward<E>(e));
 
 
 1712        template <
class FUNCTOR, 
class T, std::size_t... Is>
 
 1713        inline auto get_functor(T&& args, std::index_sequence<Is...>)
 
 1715            return FUNCTOR(std::get<Is>(args)...);
 
 1718        template <
class F, 
class... A, 
class... E>
 
 1719        inline auto make_xfunction(std::tuple<A...>&& f_args, E&&... e) 
noexcept 
 1721            using functor_type = F;
 
 1722            using expression_tag = xexpression_tag_t<E...>;
 
 1723            using type = select_xfunction_expression_t<expression_tag, functor_type, const_xclosure_t<E>...>;
 
 1724            auto functor = get_functor<functor_type>(
 
 1725                std::forward<std::tuple<A...>>(f_args),
 
 1726                std::make_index_sequence<
sizeof...(A)>{}
 
 1728            return type(std::move(functor), std::forward<E>(e)...);
 
 1733            using result_type = bool;
 
 1735            isclose(
double rtol, 
double atol, 
bool equal_nan)
 
 1738                , m_equal_nan(equal_nan)
 
 1742            template <
class A1, 
class A2>
 
 1743            bool operator()(
const A1& a, 
const A2& b)
 const 
 1745                using internal_type = xtl::promote_type_t<A1, A2, double>;
 
 1746                if (math::isnan(a) && math::isnan(b))
 
 1750                if (math::isinf(a) && math::isinf(b))
 
 1755                auto d = math::abs(internal_type(a) - internal_type(b));
 
 1758                                   * double((std::max)(math::abs(internal_type(a)), math::abs(internal_type(b)))
 
 1785    template <
class E1, 
class E2>
 
 1787    isclose(E1&& e1, E2&& e2, 
double rtol = 1e-05, 
double atol = 1e-08, 
bool equal_nan = 
false) noexcept
 
 1789        return detail::make_xfunction<detail::isclose>(
 
 1790            std::make_tuple(rtol, atol, equal_nan),
 
 1791            std::forward<E1>(e1),
 
 1792            std::forward<E2>(e2)
 
 
 1809    template <
class E1, 
class E2>
 
 1810    inline auto allclose(E1&& e1, E2&& e2, 
double rtol = 1e-05, 
double atol = 1e-08) noexcept
 
 1812        return xt::all(
isclose(std::forward<E1>(e1), std::forward<E2>(e2), rtol, atol));
 
 
 1838    XTENSOR_REDUCER_FUNCTION(
sum, detail::plus, 
typename std::decay_t<E>::value_type, 0)
 
 1858    XTENSOR_REDUCER_FUNCTION(
prod, detail::multiplies, typename std::decay_t<E>::value_type, 1)
 
 1862        template <
class T, 
class S, 
class ST>
 
 1863        inline auto mean_division(S&& s, ST e_size)
 
 1865            using value_type = 
typename std::conditional_t<std::is_same<T, void>::value, double, T>;
 
 1867            value_type div = s.size() != ST(0) ? 
static_cast<value_type
>(e_size / s.size()) : value_type(0);
 
 1868            return std::move(s) / std::move(div);
 
 1878        inline auto mean(E&& e, X&& axes, 
const D& ddof, EVS es)
 
 1882            using size_type = 
typename std::decay_t<E>::size_type;
 
 1883            const size_type size = e.size();
 
 1884            XTENSOR_ASSERT(
static_cast<size_type
>(ddof) <= size);
 
 1885            auto s = 
sum<T>(std::forward<E>(e), std::forward<X>(axes), es);
 
 1886            return mean_division<T>(std::move(s), size - 
static_cast<size_type
>(ddof));
 
 1889        template <
class T, 
class E, 
class I, std::
size_t N, 
class D, 
class EVS>
 
 1890        inline auto mean(E&& e, 
const I (&axes)[N], 
const D& ddof, EVS es)
 
 1892            using size_type = 
typename std::decay_t<E>::size_type;
 
 1893            const size_type size = e.size();
 
 1894            XTENSOR_ASSERT(
static_cast<size_type
>(ddof) <= size);
 
 1895            auto s = 
sum<T>(std::forward<E>(e), axes, es);
 
 1896            return mean_division<T>(std::move(s), size - 
static_cast<size_type
>(ddof));
 
 1899        template <
class T, 
class E, 
class D, 
class EVS, XTL_REQUIRES(is_reducer_options<EVS>, xtl::is_
integral<D>)>
 
 1900        inline auto mean_noaxis(E&& e, 
const D& ddof, EVS es)
 
 1902            using value_type = 
typename std::conditional_t<std::is_same<T, void>::value, double, T>;
 
 1903            using size_type = 
typename std::decay_t<E>::size_type;
 
 1904            const size_type size = e.size();
 
 1905            XTENSOR_ASSERT(
static_cast<size_type
>(ddof) <= size);
 
 1906            auto s = 
sum<T>(std::forward<E>(e), es);
 
 1907            return std::move(s) / 
static_cast<value_type
>((size - 
static_cast<size_type
>(ddof)));
 
 1930        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 1931        XTL_REQUIRES(std::negation<is_reducer_options<X>>)>
 
 1932    inline auto mean(E&& e, X&& axes, EVS es = EVS())
 
 1934        return detail::mean<T>(std::forward<E>(e), std::forward<X>(axes), 0u, es);
 
 
 1937    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 1938    inline auto mean(E&& e, EVS es = EVS())
 
 1940        return detail::mean_noaxis<T>(std::forward<E>(e), 0u, es);
 
 1943    template <
class T = 
void, 
class E, 
class I, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 1944    inline auto mean(E&& e, 
const I (&axes)[N], EVS es = EVS())
 
 1946        return detail::mean<T>(std::forward<E>(e), axes, 0u, es);
 
 1971        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 1973    inline auto average(E&& e, W&& weights, X&& axes, EVS ev = EVS())
 
 1975        xindex_type_t<typename std::decay_t<E>::shape_type> broadcast_shape;
 
 1976        xt::resize_container(broadcast_shape, e.dimension());
 
 1977        auto ax = normalize_axis(e, axes);
 
 1978        if (weights.dimension() == 1)
 
 1980            if (weights.size() != e.shape()[ax[0]])
 
 1982                XTENSOR_THROW(std::runtime_error, 
"Weights need to have the same shape as expression at axes.");
 
 1985            std::fill(broadcast_shape.begin(), broadcast_shape.end(), std::size_t(1));
 
 1986            broadcast_shape[ax[0]] = weights.size();
 
 1994                    "Weights with dim > 1 need to have the same shape as expression." 
 1998            std::copy(e.shape().begin(), e.shape().end(), broadcast_shape.begin());
 
 2001        constexpr layout_type L = default_assignable_layout(std::decay_t<W>::static_layout);
 
 2002        auto weights_view = reshape_view<L>(std::forward<W>(weights), std::move(broadcast_shape));
 
 2003        auto scl = 
sum<T>(weights_view, ax, xt::evaluation_strategy::immediate);
 
 2004        return sum<T>(std::forward<E>(e) * std::move(weights_view), std::move(ax), ev) / std::move(scl);
 
 
 2012        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2013        XTL_REQUIRES(is_reducer_options<EVS>, xtl::is_integral<X>)>
 
 2014    inline auto average(E&& e, W&& weights, X axis, EVS ev = EVS())
 
 2016        return average(std::forward<E>(e), std::forward<W>(weights), {axis}, std::forward<EVS>(ev));
 
 2019    template <
class T = 
void, 
class E, 
class W, 
class X, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2020    inline auto average(E&& e, W&& weights, 
const X (&axes)[N], EVS ev = EVS())
 
 2023        using ax_t = std::array<std::size_t, N>;
 
 2024        return average<T>(std::forward<E>(e), std::forward<W>(weights), xt::forward_normalize<ax_t>(e, axes), ev);
 
 2027    template <
class T = 
void, 
class E, 
class W, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2028    inline auto average(E&& e, W&& weights, EVS ev = EVS())
 
 2030        if (weights.dimension() != e.dimension()
 
 2031            || !std::equal(weights.shape().begin(), weights.shape().end(), e.shape().begin()))
 
 2033            XTENSOR_THROW(std::runtime_error, 
"Weights need to have the same shape as expression.");
 
 2036        auto div = 
sum<T>(weights, evaluation_strategy::immediate)();
 
 2037        auto s = 
sum<T>(std::forward<E>(e) * std::forward<W>(weights), ev) / std::move(div);
 
 2041    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2042    inline auto average(E&& e, EVS ev = EVS())
 
 2049        template <
typename E>
 
 2050        std::enable_if_t<std::is_lvalue_reference<E>::value, E> shared_forward(E e) 
noexcept 
 2055        template <
typename E>
 
 2056        std::enable_if_t<!std::is_lvalue_reference<E>::value, xshared_expression<E>> shared_forward(E e) 
noexcept 
 2066        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2068    inline auto variance(E&& e, 
const D& ddof, EVS es = EVS())
 
 2070        auto cached_mean = 
mean<T>(e, es)();
 
 2071        return detail::mean_noaxis<T>(
square(std::forward<E>(e) - std::move(cached_mean)), ddof, es);
 
 2074    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2075    inline auto variance(E&& e, EVS es = EVS())
 
 2077        return variance<T>(std::forward<E>(e), 0u, es);
 
 2080    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2081    inline auto stddev(E&& e, EVS es = EVS())
 
 2083        return sqrt(variance<T>(std::forward<E>(e), es));
 
 2115        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2117    inline auto variance(E&& e, X&& axes, 
const D& ddof, EVS es = EVS())
 
 2119        decltype(
auto) sc = detail::shared_forward<E>(e);
 
 2121        auto axes_copy = axes;
 
 2123        auto inner_mean = 
eval(
mean<T>(sc, std::move(axes_copy), evaluation_strategy::immediate));
 
 2129        using tmp_shape_t = get_strides_t<typename std::decay_t<E>::shape_type>;
 
 2130        tmp_shape_t keep_dim_shape = xtl::forward_sequence<tmp_shape_t, 
decltype(e.shape())>(e.shape());
 
 2131        for (
const auto& el : axes)
 
 2133            keep_dim_shape[el] = 1u;
 
 2136        auto mrv = reshape_view<XTENSOR_DEFAULT_LAYOUT>(std::move(inner_mean), std::move(keep_dim_shape));
 
 2137        return detail::mean<T>(
square(sc - std::move(mrv)), std::forward<X>(axes), ddof, es);
 
 
 2144        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2145        XTL_REQUIRES(std::negation<is_reducer_options<X>>, std::negation<xtl::is_integral<std::decay_t<X>>>, is_reducer_options<EVS>)>
 
 2146    inline auto variance(E&& e, X&& axes, EVS es = EVS())
 
 2148        return variance<T>(std::forward<E>(e), std::forward<X>(axes), 0u, es);
 
 2176        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2178    inline auto stddev(E&& e, X&& axes, EVS es = EVS())
 
 2180        return sqrt(variance<T>(std::forward<E>(e), std::forward<X>(axes), es));
 
 
 2183    template <
class T = 
void, 
class E, 
class A, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2184    inline auto stddev(E&& e, 
const A (&axes)[N], EVS es = EVS())
 
 2188            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2198        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2200    inline auto variance(E&& e, 
const A (&axes)[N], EVS es = EVS())
 
 2204            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2209    template <
class T = 
void, 
class E, 
class A, std::
size_t N, 
class D, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2210    inline auto variance(E&& e, 
const A (&axes)[N], 
const D& ddof, EVS es = EVS())
 
 2214            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2230    template <
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2235        using value_type = 
typename std::decay_t<E>::value_type;
 
 2236        using result_type = std::array<value_type, 2>;
 
 2239        auto reduce_func = [](
auto r, 
const auto& v)
 
 2241            r[0] = (min) (r[0], v);
 
 2242            r[1] = (max) (r[1], v);
 
 2246        auto init_func = init_value_fct(
 
 2247            result_type{std::numeric_limits<value_type>::max(), std::numeric_limits<value_type>::lowest()}
 
 2250        auto merge_func = [](
auto r, 
const auto& s)
 
 2252            r[0] = (min) (r[0], s[0]);
 
 2253            r[1] = (max) (r[1], s[1]);
 
 2257            make_xreducer_functor(std::move(reduce_func), std::move(init_func), std::move(merge_func)),
 
 
 2282    template <
class T = 
void, 
class E>
 
 2283    inline auto cumsum(E&& e, std::ptrdiff_t axis)
 
 2285        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2287            make_xaccumulator_functor(detail::plus(), detail::accumulator_identity<init_value_type>()),
 
 
 2293    template <
class T = 
void, 
class E>
 
 2294    inline auto cumsum(E&& e)
 
 2296        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2298            make_xaccumulator_functor(detail::plus(), detail::accumulator_identity<init_value_type>()),
 
 2317    template <
class T = 
void, 
class E>
 
 2320        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2322            make_xaccumulator_functor(detail::multiplies(), detail::accumulator_identity<init_value_type>()),
 
 
 2328    template <
class T = 
void, 
class E>
 
 2331        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2333            make_xaccumulator_functor(detail::multiplies(), detail::accumulator_identity<init_value_type>()),
 
 2344        struct nan_to_num_functor
 
 2347            inline auto operator()(
const A& a)
 const 
 2357                        return std::numeric_limits<A>::lowest();
 
 2361                        return (std::numeric_limits<A>::max)();
 
 2370            template <
class T, 
class U>
 
 2371            constexpr auto operator()(
const T lhs, 
const U rhs)
 const 
 2374                return math::isnan(lhs)
 
 2376                           : (math::isnan(rhs) ? lhs
 
 2377                                               : std::common_type_t<T, U>(
 
 2378                                                   detail::make_xfunction<math::minimum<void>>(lhs, rhs)
 
 2385            template <
class T, 
class U>
 
 2386            constexpr auto operator()(
const T lhs, 
const U rhs)
 const 
 2389                return math::isnan(lhs)
 
 2391                           : (math::isnan(rhs) ? lhs
 
 2392                                               : std::common_type_t<T, U>(
 
 2393                                                   detail::make_xfunction<math::maximum<void>>(lhs, rhs)
 
 2400            template <
class T, 
class U>
 
 2401            constexpr auto operator()(
const T lhs, 
const U rhs)
 const 
 2403                return !math::isnan(rhs) ? lhs + rhs : lhs;
 
 2407        struct nan_multiplies
 
 2409            template <
class T, 
class U>
 
 2410            constexpr auto operator()(
const T lhs, 
const U rhs)
 const 
 2412                return !math::isnan(rhs) ? lhs * rhs : lhs;
 
 2416        template <
class T, 
int V>
 
 2419            using value_type = T;
 
 2420            using result_type = T;
 
 2422            constexpr result_type operator()(
const value_type lhs)
 const 
 2424                return math::isnan(lhs) ? result_type(V) : lhs;
 
 2446        return detail::make_xfunction<detail::nan_to_num_functor>(std::forward<E>(e));
 
 
 2462    XTENSOR_REDUCER_FUNCTION(
nanmin, detail::nan_min, 
typename std::decay_t<E>::value_type, std::nan(
"0"))
 
 2477    XTENSOR_REDUCER_FUNCTION(
nanmax, detail::nan_max, typename std::decay_t<E>::value_type, std::nan(
"0"))
 
 2494    XTENSOR_REDUCER_FUNCTION(
nansum, detail::nan_plus, typename std::decay_t<E>::value_type, 0)
 
 2511    XTENSOR_REDUCER_FUNCTION(
nanprod, detail::nan_multiplies, typename std::decay_t<E>::value_type, 1)
 
 2513#define COUNT_NON_ZEROS_CONTENT                                                             \ 
 2514    using value_type = typename std::decay_t<E>::value_type;                                \ 
 2515    using result_type = xt::detail::xreducer_size_type_t<value_type>;                       \ 
 2516    using init_value_fct = xt::const_value<result_type>;                                    \ 
 2518    auto init_fct = init_value_fct(0);                                                      \ 
 2520    auto reduce_fct = [](const auto& lhs, const auto& rhs)                                  \ 
 2522        using value_t = xt::detail::xreducer_temporary_type_t<std::decay_t<decltype(rhs)>>; \ 
 2523        using result_t = std::decay_t<decltype(lhs)>;                                       \ 
 2525        return (rhs != value_t(0)) ? lhs + result_t(1) : lhs;                               \ 
 2527    auto merge_func = detail::plus(); 
 2529    template <
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2530    inline auto count_nonzero(E&& e, EVS es = EVS())
 
 2532        COUNT_NON_ZEROS_CONTENT;
 
 2534            make_xreducer_functor(std::move(reduce_fct), std::move(init_fct), std::move(merge_func)),
 
 2543        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2544        XTL_REQUIRES(std::negation<is_reducer_options<X>>, std::negation<xtl::is_integral<X>>)>
 
 2545    inline auto count_nonzero(E&& e, X&& axes, EVS es = EVS())
 
 2547        COUNT_NON_ZEROS_CONTENT;
 
 2549            make_xreducer_functor(std::move(reduce_fct), std::move(init_fct), std::move(merge_func)),
 
 2551            std::forward<X>(axes),
 
 2559        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2561    inline auto count_nonzero(E&& e, X axis, EVS es = EVS())
 
 2563        return count_nonzero(std::forward<E>(e), {axis}, es);
 
 2566    template <
class E, 
class I, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2567    inline auto count_nonzero(E&& e, 
const I (&axes)[N], EVS es = EVS())
 
 2569        COUNT_NON_ZEROS_CONTENT;
 
 2571            make_xreducer_functor(std::move(reduce_fct), std::move(init_fct), std::move(merge_func)),
 
 2578#undef COUNT_NON_ZEROS_CONTENT 
 2580    template <
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2581    inline auto count_nonnan(E&& e, EVS es = EVS())
 
 2583        return xt::count_nonzero(!
xt::isnan(std::forward<E>(e)), es);
 
 2589        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2591    inline auto count_nonnan(E&& e, X&& axes, EVS es = EVS())
 
 2593        return xt::count_nonzero(!
xt::isnan(std::forward<E>(e)), std::forward<X>(axes), es);
 
 2599        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2601    inline auto count_nonnan(E&& e, X&& axes, EVS es = EVS())
 
 2603        return xt::count_nonzero(!
xt::isnan(std::forward<E>(e)), {axes}, es);
 
 2606    template <
class E, 
class I, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2607    inline auto count_nonnan(E&& e, 
const I (&axes)[N], EVS es = EVS())
 
 2609        return xt::count_nonzero(!
xt::isnan(std::forward<E>(e)), axes, es);
 
 2626    template <
class T = 
void, 
class E>
 
 2629        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2631            make_xaccumulator_functor(detail::nan_plus(), detail::nan_init<init_value_type, 0>()),
 
 
 2637    template <
class T = 
void, 
class E>
 
 2640        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2642            make_xaccumulator_functor(detail::nan_plus(), detail::nan_init<init_value_type, 0>()),
 
 2661    template <
class T = 
void, 
class E>
 
 2664        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2666            make_xaccumulator_functor(detail::nan_multiplies(), detail::nan_init<init_value_type, 1>()),
 
 
 2672    template <
class T = 
void, 
class E>
 
 2675        using init_value_type = std::conditional_t<std::is_same<T, void>::value, 
typename std::decay_t<E>::value_type, T>;
 
 2677            make_xaccumulator_functor(detail::nan_multiplies(), detail::nan_init<init_value_type, 1>()),
 
 2687            template <
class Arg>
 
 2688            inline void operator()(
 
 2690                const std::size_t& n,
 
 2696                for (std::size_t i = 0; i < n; ++i)
 
 2698                    slice2[saxis] = 
range(xnone(), ad.shape()[saxis] - 1);
 
 2705        struct diff_impl<bool>
 
 2707            template <
class Arg>
 
 2708            inline void operator()(
 
 2710                const std::size_t& n,
 
 2716                for (std::size_t i = 0; i < n; ++i)
 
 2718                    slice2[saxis] = 
range(xnone(), ad.shape()[saxis] - 1);
 
 2744        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2746    inline auto nanmean(E&& e, X&& axes, EVS es = EVS())
 
 2748        decltype(
auto) sc = detail::shared_forward<E>(e);
 
 2750        auto axes_copy = axes;
 
 2751        using value_type = 
typename std::conditional_t<std::is_same<T, void>::value, double, T>;
 
 2752        using sum_type = 
typename std::conditional_t<
 
 2753            std::is_same<T, void>::value,
 
 2754            typename std::common_type_t<typename std::decay_t<E>::value_type, value_type>,
 
 
 2762    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2763    inline auto nanmean(E&& e, EVS es = EVS())
 
 2765        decltype(
auto) sc = detail::shared_forward<E>(e);
 
 2766        using value_type = 
typename std::conditional_t<std::is_same<T, void>::value, double, T>;
 
 2767        using sum_type = 
typename std::conditional_t<
 
 2768            std::is_same<T, void>::value,
 
 2769            typename std::common_type_t<typename std::decay_t<E>::value_type, value_type>,
 
 2774    template <
class T = 
void, 
class E, 
class I, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2775    inline auto nanmean(E&& e, 
const I (&axes)[N], EVS es = EVS())
 
 2779            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2784    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2785    inline auto nanvar(E&& e, EVS es = EVS())
 
 2787        decltype(
auto) sc = detail::shared_forward<E>(e);
 
 2791    template <
class T = 
void, 
class E, 
class EVS = DEFAULT_STRATEGY_REDUCERS, XTL_REQUIRES(is_reducer_options<EVS>)>
 
 2792    inline auto nanstd(E&& e, EVS es = EVS())
 
 2794        return sqrt(nanvar<T>(std::forward<E>(e), es));
 
 2821        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2823    inline auto nanvar(E&& e, X&& axes, EVS es = EVS())
 
 2825        decltype(
auto) sc = detail::shared_forward<E>(e);
 
 2827        auto axes_copy = axes;
 
 2828        using result_type = 
typename std::conditional_t<std::is_same<T, void>::value, double, T>;
 
 2835        using tmp_shape_t = get_strides_t<typename std::decay_t<E>::shape_type>;
 
 2836        tmp_shape_t keep_dim_shape = xtl::forward_sequence<tmp_shape_t, 
decltype(e.shape())>(e.shape());
 
 2837        for (
const auto& el : axes)
 
 2839            keep_dim_shape[el] = 1;
 
 2841        auto mrv = reshape_view<XTENSOR_DEFAULT_LAYOUT>(std::move(inner_mean), std::move(keep_dim_shape));
 
 
 2869        class EVS = DEFAULT_STRATEGY_REDUCERS,
 
 2870        XTL_REQUIRES(std::negation<is_reducer_options<X>>)>
 
 2871    inline auto nanstd(E&& e, X&& axes, EVS es = EVS())
 
 2873        return sqrt(nanvar<T>(std::forward<E>(e), std::forward<X>(axes), es));
 
 
 2876    template <
class T = 
void, 
class E, 
class A, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2877    inline auto nanstd(E&& e, 
const A (&axes)[N], EVS es = EVS())
 
 2881            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2886    template <
class T = 
void, 
class E, 
class A, std::
size_t N, 
class EVS = DEFAULT_STRATEGY_REDUCERS>
 
 2887    inline auto nanvar(E&& e, 
const A (&axes)[N], EVS es = EVS())
 
 2891            xtl::forward_sequence<std::array<std::size_t, N>, 
decltype(axes)>(axes),
 
 2910        typename std::decay_t<T>::temporary_type ad = a.
derived_cast();
 
 2911        std::size_t saxis = normalize_axis(ad.dimension(), axis);
 
 2914            if (n != std::size_t(0))
 
 2918                slice1[saxis] = 
range(1, xnone());
 
 2920                detail::diff_impl<typename T::value_type> impl;
 
 2921                impl(ad, n, slice1, slice2, saxis);
 
 2926            auto shape = ad.shape();
 
 2927            shape[saxis] = std::size_t(0);
 
 
 2948        std::size_t saxis = normalize_axis(yd.dimension(), axis);
 
 2952        slice1[saxis] = 
range(1, xnone());
 
 2953        slice2[saxis] = 
range(xnone(), yd.shape()[saxis] - 1);
 
 2957        return eval(
sum(trap, {saxis}));
 
 
 2971    template <
class T, 
class E>
 
 2976        decltype(
diff(x)) dx;
 
 2978        std::size_t saxis = normalize_axis(yd.dimension(), axis);
 
 2980        if (xd.dimension() == 1)
 
 2983            typename std::decay_t<
decltype(yd)>::shape_type shape;
 
 2984            resize_container(shape, yd.dimension());
 
 2985            std::fill(shape.begin(), shape.end(), 1);
 
 2986            shape[saxis] = dx.shape()[0];
 
 2991            dx = 
diff(x, 1, axis);
 
 2996        slice1[saxis] = 
range(1, xnone());
 
 2997        slice2[saxis] = 
range(xnone(), yd.shape()[saxis] - 1);
 
 3001        return eval(
sum(trap, {saxis}));
 
 
 3016    template <
class E1, 
class E2, 
class E3, 
typename T>
 
 3017    inline auto interp(
const E1& x, 
const E2& xp, 
const E3& fp, T left, T right)
 
 3019        using size_type = common_size_type_t<E1, E2, E3>;
 
 3020        using value_type = 
typename E3::value_type;
 
 3023        XTENSOR_ASSERT(xp.dimension() == 1);
 
 3024        XTENSOR_ASSERT(std::is_sorted(x.cbegin(), x.cend()));
 
 3025        XTENSOR_ASSERT(std::is_sorted(xp.cbegin(), xp.cend()));
 
 3028        auto f = xtensor<value_type, 1>::from_shape(x.shape());
 
 3034        for (; i < x.size(); ++i)
 
 3040            f[i] = 
static_cast<value_type
>(left);
 
 3045        size_type imax = x.size();
 
 3048        for (; imax > 0; --imax)
 
 3050            if (x[imax - 1] < xp[xp.size() - 1])
 
 3054            f[imax - 1] = 
static_cast<value_type
>(right);
 
 3071        for (; i <= imax; ++i)
 
 3074            while (x[i] > xp[ip])
 
 3079            double dfp = 
static_cast<double>(fp[ip] - fp[ip - 1]);
 
 3080            double dxp = 
static_cast<double>(xp[ip] - xp[ip - 1]);
 
 3081            double dx = 
static_cast<double>(x[i] - xp[ip - 1]);
 
 3083            f[i] = fp[ip - 1] + 
static_cast<value_type
>(dfp / dxp * dx);
 
 
 3091        template <
class E1, 
class E2>
 
 3092        auto calculate_discontinuity(E1&& discontinuity, E2&&)
 
 3094            return discontinuity;
 
 3098        auto calculate_discontinuity(xt::placeholders::xtuph, E2&& period)
 
 3100            return 0.5 * period;
 
 3103        template <
class E1, 
class E2>
 
 3105        calculate_interval(E2&& period, 
typename std::enable_if<std::is_integral<E1>::value, E1>::type* = 0)
 
 3107            auto interval_high = 0.5 * period;
 
 3108            uint64_t 
remainder = 
static_cast<uint64_t
>(period) % 2;
 
 3109            auto boundary_ambiguous = (
remainder == 0);
 
 3110            return std::make_tuple(interval_high, boundary_ambiguous);
 
 3113        template <
class E1, 
class E2>
 
 3115        calculate_interval(E2&& period, 
typename std::enable_if<std::is_floating_point<E1>::value, E1>::type* = 0)
 
 3117            auto interval_high = 0.5 * period;
 
 3118            auto boundary_ambiguous = 
true;
 
 3119            return std::make_tuple(interval_high, boundary_ambiguous);
 
 3136    template <
class E1, 
class E2 = xt::placeholders::xtuph, 
class E3 = 
double>
 
 3139        E2 discontinuity = xnone(),
 
 3140        std::ptrdiff_t axis = -1,
 
 3141        E3 period = 2.0 * xt::numeric_constants<double>::PI
 
 3144        auto discont = detail::calculate_discontinuity(discontinuity, period);
 
 3145        using value_type = 
typename std::decay_t<E1>::value_type;
 
 3146        std::size_t saxis = normalize_axis(p.dimension(), axis);
 
 3147        auto dd = 
diff(p, 1, axis);
 
 3149        slice[saxis] = 
range(1, xnone());
 
 3150        auto interval_tuple = detail::calculate_interval<value_type>(period);
 
 3151        auto interval_high = std::get<0>(interval_tuple);
 
 3152        auto boundary_ambiguous = std::get<1>(interval_tuple);
 
 3153        auto interval_low = -interval_high;
 
 3155        if (boundary_ambiguous)
 
 3161            ddmod = 
xt::where(boolmap, interval_high, ddmod);
 
 3163        auto ph_correct = 
xt::eval(ddmod - dd);
 
 3167                                  + 
xt::cumsum(ph_correct, 
static_cast<std::ptrdiff_t
>(saxis));
 
 
 3181    template <
class E1, 
class E2, 
class E3>
 
 3182    inline auto interp(
const E1& x, 
const E2& xp, 
const E3& fp)
 
 3184        return interp(x, xp, fp, fp[0], fp[fp.size() - 1]);
 
 
 3194    inline auto cov(
const E1& x, 
const E1& y = E1())
 
 3196        using value_type = 
typename E1::value_type;
 
 3198        if (y.dimension() == 0)
 
 3201            using size_type = std::decay_t<
decltype(s[0])>;
 
 3202            if (x.dimension() == 1)
 
 3206                covar(0, 0) = std::inner_product(x_norm.begin(), x_norm.end(), x_norm.begin(), 0.0)
 
 3207                              / value_type(s[0] - 1);
 
 3211            XTENSOR_ASSERT(x.dimension() == 2);
 
 3215            m.reshape({m.shape()[0], 1});
 
 3216            auto x_norm = x - m;
 
 3217            for (size_type i = 0; i < s[0]; i++)
 
 3220                for (size_type j = i; j < s[0]; j++)
 
 3223                    covar(j, i) = std::inner_product(xi.begin(), xi.end(), xj.begin(), 0.0)
 
 3224                                  / value_type(s[1] - 1);
 
 
 3240    namespace convolve_mode
 
 3253        template <
class E1, 
class E2>
 
 3256            using value_type = 
typename std::decay<E1>::type::value_type;
 
 3258            const std::size_t na = e1.size();
 
 3259            const std::size_t nv = e2.size();
 
 3260            const std::size_t n = na - nv + 1;
 
 3262            for (std::size_t i = 0; i < n; i++)
 
 3264                for (std::size_t j = 0; j < nv; j++)
 
 3266                    out(i) += e1(j) * e2(j + i);
 
 3272        template <
class E1, 
class E2>
 
 3273        inline auto convolve_impl(E1&& e1, E2&& e2, convolve_mode::full)
 
 3275            using value_type = 
typename std::decay<E1>::type::value_type;
 
 3277            const std::size_t na = e1.size();
 
 3278            const std::size_t nv = e2.size();
 
 3279            const std::size_t n = na + nv - 1;
 
 3281            for (std::size_t i = 0; i < n; i++)
 
 3283                const std::size_t jmn = (i >= nv - 1) ? i - (nv - 1) : 0;
 
 3284                const std::size_t jmx = (i < na - 1) ? i : na - 1;
 
 3285                for (std::size_t j = jmn; j <= jmx; ++j)
 
 3287                    out(i) += e1(j) * e2(i - j);
 
 3304    template <
class E1, 
class E2, 
class E3>
 
 3305    inline auto convolve(E1&& a, E2&& v, E3 mode)
 
 3307        if (a.dimension() != 1 || v.dimension() != 1)
 
 3309            XTENSOR_THROW(std::runtime_error, 
"Invalid dimentions convolution arguments must be 1D expressions");
 
 3312        XTENSOR_ASSERT(a.size() > 0 && v.size() > 0);
 
 3315        if (a.size() < v.size())
 
 3317            return detail::convolve_impl(std::forward<E2>(v), std::forward<E1>(a), mode);
 
 3321            return detail::convolve_impl(std::forward<E1>(a), std::forward<E2>(v), mode);
 
Base class for xexpressions.
derived_type & derived_cast() &noexcept
Returns a reference to the actual derived type of the xexpression.
auto cumprod(E &&e, std::ptrdiff_t axis)
Cumulative product.
auto cumsum(E &&e, std::ptrdiff_t axis)
Cumulative sum.
auto fma(E1 &&e1, E2 &&e2, E3 &&e3) noexcept -> detail::xfunction_type_t< math::fma_fun, E1, E2, E3 >
Fused multiply-add operation.
auto deg2rad(E &&e) noexcept -> detail::xfunction_type_t< math::deg2rad, E >
Convert angles from degrees to radians.
auto amax(E &&e, X &&axes, EVS es=EVS())
Maximum element along given axis.
auto remainder(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::remainder_fun, E1, E2 >
Signed remainder of the division operation.
auto degrees(E &&e) noexcept -> detail::xfunction_type_t< math::rad2deg, E >
Convert angles from radians to degrees.
auto interp(const E1 &x, const E2 &xp, const E3 &fp, T left, T right)
Returns the one-dimensional piecewise linear interpolant to a function with given discrete data point...
auto fmod(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::fmod_fun, E1, E2 >
Remainder of the floating point division operation.
auto abs(E &&e) noexcept -> detail::xfunction_type_t< math::abs_fun, E >
Absolute value function.
auto fabs(E &&e) noexcept -> detail::xfunction_type_t< math::fabs_fun, E >
Absolute value function.
auto minimum(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::minimum< void >, E1, E2 >
Elementwise minimum.
auto maximum(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::maximum< void >, E1, E2 >
Elementwise maximum.
auto fmax(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::fmax_fun, E1, E2 >
Maximum function.
auto clip(E1 &&e1, E2 &&lo, E3 &&hi) noexcept -> detail::xfunction_type_t< math::clamp_fun, E1, E2, E3 >
Clip values between hi and lo.
auto radians(E &&e) noexcept -> detail::xfunction_type_t< math::deg2rad, E >
Convert angles from degrees to radians.
auto fdim(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::fdim_fun, E1, E2 >
Positive difference function.
auto amin(E &&e, X &&axes, EVS es=EVS())
Minimum element along given axis.
auto rad2deg(E &&e) noexcept -> detail::xfunction_type_t< math::rad2deg, E >
Convert angles from radians to degrees.
auto fmin(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::fmin_fun, E1, E2 >
Minimum function.
auto sign(E &&e) noexcept -> detail::xfunction_type_t< math::sign_fun, E >
Returns an element-wise indication of the sign of a number.
auto unwrap(E1 &&p, E2 discontinuity=xnone(), std::ptrdiff_t axis=-1, E3 period=2.0 *xt::numeric_constants< double >::PI)
Unwrap by taking the complement of large deltas with respect to the period.
auto cast(E &&e) noexcept -> detail::xfunction_type_t< typename detail::cast< R >::functor, E >
Element-wise static_cast.
auto allclose(E1 &&e1, E2 &&e2, double rtol=1e-05, double atol=1e-08) noexcept
Check if all elements in e1 are close to the corresponding elements in e2.
auto isfinite(E &&e) noexcept -> detail::xfunction_type_t< math::isfinite_fun, E >
finite value check
auto isnan(E &&e) noexcept -> detail::xfunction_type_t< math::isnan_fun, E >
NaN check.
auto isclose(E1 &&e1, E2 &&e2, double rtol=1e-05, double atol=1e-08, bool equal_nan=false) noexcept
Element-wise closeness detection.
auto isinf(E &&e) noexcept -> detail::xfunction_type_t< math::isinf_fun, E >
infinity check
auto not_equal(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< detail::not_equal_to, E1, E2 >
Element-wise inequality.
auto equal(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< detail::equal_to, E1, E2 >
Element-wise equality.
auto greater(E1 &&e1, E2 &&e2) noexcept -> decltype(std::forward< E1 >(e1) > std::forward< E2 >(e2))
Greater than.
auto lgamma(E &&e) noexcept -> detail::xfunction_type_t< math::lgamma_fun, E >
Natural logarithm of the gamma function.
auto erfc(E &&e) noexcept -> detail::xfunction_type_t< math::erfc_fun, E >
Complementary error function.
auto erf(E &&e) noexcept -> detail::xfunction_type_t< math::erf_fun, E >
Error function.
auto tgamma(E &&e) noexcept -> detail::xfunction_type_t< math::tgamma_fun, E >
Gamma function.
auto log1p(E &&e) noexcept -> detail::xfunction_type_t< math::log1p_fun, E >
Natural logarithm of one plus function.
auto expm1(E &&e) noexcept -> detail::xfunction_type_t< math::expm1_fun, E >
Natural exponential minus one function.
auto exp2(E &&e) noexcept -> detail::xfunction_type_t< math::exp2_fun, E >
Base 2 exponential function.
auto log(E &&e) noexcept -> detail::xfunction_type_t< math::log_fun, E >
Natural logarithm function.
auto log2(E &&e) noexcept -> detail::xfunction_type_t< math::log2_fun, E >
Base 2 logarithm function.
auto exp(E &&e) noexcept -> detail::xfunction_type_t< math::exp_fun, E >
Natural exponential function.
auto log10(E &&e) noexcept -> detail::xfunction_type_t< math::log10_fun, E >
Base 10 logarithm function.
auto asinh(E &&e) noexcept -> detail::xfunction_type_t< math::asinh_fun, E >
Inverse hyperbolic sine function.
auto tanh(E &&e) noexcept -> detail::xfunction_type_t< math::tanh_fun, E >
Hyperbolic tangent function.
auto cosh(E &&e) noexcept -> detail::xfunction_type_t< math::cosh_fun, E >
Hyperbolic cosine function.
auto sinh(E &&e) noexcept -> detail::xfunction_type_t< math::sinh_fun, E >
Hyperbolic sine function.
auto acosh(E &&e) noexcept -> detail::xfunction_type_t< math::acosh_fun, E >
Inverse hyperbolic cosine function.
auto atanh(E &&e) noexcept -> detail::xfunction_type_t< math::atanh_fun, E >
Inverse hyperbolic tangent function.
auto where(E1 &&e1, E2 &&e2, E3 &&e3) noexcept -> detail::xfunction_type_t< detail::conditional_ternary, E1, E2, E3 >
Ternary selection.
auto nanmax(E &&e, X &&axes, EVS es=EVS())
Maximum element along given axes, ignoring NaNs.
auto nancumsum(E &&e, std::ptrdiff_t axis)
Cumulative sum, replacing nan with 0.
auto nancumprod(E &&e, std::ptrdiff_t axis)
Cumulative product, replacing nan with 1.
auto nanmean(E &&e, X &&axes, EVS es=EVS())
Mean of elements over given axes, excluding NaNs.
auto nanmin(E &&e, X &&axes, EVS es=EVS())
Minimum element over given axes, ignoring NaNs.
auto nanprod(E &&e, X &&axes, EVS es=EVS())
Product of elements over given axes, replacing NaN with 1.
auto nansum(E &&e, X &&axes, EVS es=EVS())
Sum of elements over given axes, replacing NaN with 0.
auto nan_to_num(E &&e)
Convert nan or +/- inf to numbers.
auto ceil(E &&e) noexcept -> detail::xfunction_type_t< math::ceil_fun, E >
ceil function.
auto trunc(E &&e) noexcept -> detail::xfunction_type_t< math::trunc_fun, E >
trunc function.
auto nearbyint(E &&e) noexcept -> detail::xfunction_type_t< math::nearbyint_fun, E >
nearbyint function.
auto floor(E &&e) noexcept -> detail::xfunction_type_t< math::floor_fun, E >
floor function.
auto round(E &&e) noexcept -> detail::xfunction_type_t< math::round_fun, E >
round function.
auto rint(E &&e) noexcept -> detail::xfunction_type_t< math::rint_fun, E >
rint function.
auto cube(E1 &&e1) noexcept
Cube power function, equivalent to e1 * e1 * e1.
auto sqrt(E &&e) noexcept -> detail::xfunction_type_t< math::sqrt_fun, E >
Square root function.
auto square(E1 &&e1) noexcept
Square power function, equivalent to e1 * e1.
auto pow(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::pow_fun, E1, E2 >
Power function.
auto hypot(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::hypot_fun, E1, E2 >
Hypotenuse function.
auto cbrt(E &&e) noexcept -> detail::xfunction_type_t< math::cbrt_fun, E >
Cubic root function.
auto sum(E &&e, X &&axes, EVS es=EVS())
Sum of elements over given axes.
auto prod(E &&e, X &&axes, EVS es=EVS())
Product of elements over given axes.
auto trapz(const xexpression< T > &y, double dx=1.0, std::ptrdiff_t axis=-1)
Integrate along the given axis using the composite trapezoidal rule.
auto diff(const xexpression< T > &a, std::size_t n=1, std::ptrdiff_t axis=-1)
Calculate the n-th discrete difference along the given axis.
auto minmax(E &&e, EVS es=EVS())
Minimum and maximum among the elements of an array or expression.
auto average(E &&e, W &&weights, X &&axes, EVS ev=EVS())
Average of elements over given axes using weights.
auto mean(E &&e, X &&axes, EVS es=EVS())
Mean of elements over given axes.
auto atan(E &&e) noexcept -> detail::xfunction_type_t< math::atan_fun, E >
Arctangent function.
auto atan2(E1 &&e1, E2 &&e2) noexcept -> detail::xfunction_type_t< math::atan2_fun, E1, E2 >
Artangent function, using signs to determine quadrants.
auto asin(E &&e) noexcept -> detail::xfunction_type_t< math::asin_fun, E >
Arcsine function.
auto cos(E &&e) noexcept -> detail::xfunction_type_t< math::cos_fun, E >
Cosine function.
auto sin(E &&e) noexcept -> detail::xfunction_type_t< math::sin_fun, E >
Sine function.
auto tan(E &&e) noexcept -> detail::xfunction_type_t< math::tan_fun, E >
Tangent function.
auto acos(E &&e) noexcept -> detail::xfunction_type_t< math::acos_fun, E >
Arccosine 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 transpose(E &&e) noexcept
Returns a transpose view by reversing the dimensions of xexpression e.
bool same_shape(const S1 &s1, const S2 &s2) noexcept
Check if two objects have the same shape.
standard mathematical functions for xexpressions
auto stack(std::tuple< CT... > &&t, std::size_t axis=0)
Stack xexpressions along axis.
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).
auto all() noexcept
Returns a slice representing a full dimension, to be used as an argument of view function.
std::vector< xstrided_slice< std::ptrdiff_t > > xstrided_slice_vector
vector of slices used to build a xstrided_view
auto make_lambda_xfunction(F &&lambda, E &&... args)
Create a xfunction from a lambda.
auto reduce(F &&f, E &&e, X &&axes, EVS &&options=EVS())
Returns an xexpression applying the specified reducing function to an expression over the given axes.
auto zeros(S shape) noexcept
Returns an xexpression containing zeros of the specified shape.
auto accumulate(F &&f, E &&e, EVS evaluation_strategy=EVS())
Accumulate and flatten array NOTE This function is not lazy!
xtensor_container< uvector< T, A >, N, L > xtensor
Alias template on xtensor_container with default parameters for data container type.
auto diagonal(E &&arr, int offset=0, std::size_t axis_1=0, std::size_t axis_2=1)
Returns the elements on the diagonal of arr If arr has more than two dimensions, then the axes specif...
xshared_expression< E > make_xshared(xexpression< E > &&expr)
Helper function to create shared expression from any xexpression.
auto strided_view(E &&e, S &&shape, X &&stride, std::size_t offset=0, layout_type layout=L) noexcept
Construct a strided view from an xexpression, shape, strides and offset.
auto diag(E &&arr, int k=0)
xexpression with values of arr on the diagonal, zeroes otherwise
auto xtuple(Types &&... args)
Creates tuples from arguments for concatenate and stack.
auto cov(const E1 &x, const E1 &y=E1())
Returns the covariance matrix.