/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay, Wolf Vollprecht and * * Martin Renou * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XSIMD_ESTRIN_HPP #define XSIMD_ESTRIN_HPP #include #include "../types/xsimd_types_include.hpp" namespace xsimd { namespace detail { template inline T coef() noexcept { using value_type = typename T::value_type; return T(caster_t(as_unsigned_integer_t(c)).f); } template struct estrin { T x; template inline T operator()(const Ts&... coefs) noexcept { return eval(coefs...); } private: inline T eval(const T& c0) noexcept { return c0; } inline T eval(const T& c0, const T& c1) noexcept { return fma(x, c1, c0); } template inline T eval(index_sequence, const Tuple& tuple) { return estrin{x * x}(std::get(tuple)...); } template inline T eval(const std::tuple& tuple) noexcept { return eval(make_index_sequence(), tuple); } template inline T eval(const std::tuple& tuple, const T& c0) noexcept { return eval(std::tuple_cat(tuple, std::make_tuple(eval(c0)))); } template inline T eval(const std::tuple& tuple, const T& c0, const T& c1) noexcept { return eval(std::tuple_cat(tuple, std::make_tuple(eval(c0, c1)))); } template inline T eval(const std::tuple& tuple, const T& c0, const T& c1, const Ts&... coefs) noexcept { return eval(std::tuple_cat(tuple, std::make_tuple(eval(c0, c1))), coefs...); } template inline T eval(const T& c0, const T& c1, const Ts&... coefs) noexcept { return eval(std::make_tuple(eval(c0, c1)), coefs...); } }; } /********** * estrin * **********/ template inline T estrin(const T& x) noexcept { return detail::estrin{x}(detail::coef()...); } } #endif