// Copyright 2006 John Maddock // Copyright 2024 Matt Borland // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt #ifndef BOOST_DECIMAL_DETAIL_CMATH_ASSOC_LAGUERRE_HPP #define BOOST_DECIMAL_DETAIL_CMATH_ASSOC_LAGUERRE_HPP #include #include #include #include #include #include #ifndef BOOST_DECIMAL_BUILD_MODULE #include #include #endif namespace boost { namespace decimal { namespace detail { template constexpr auto assoc_laguerre_next(const unsigned n, const unsigned l, const T1 x, const T2 Pl, const T3 Plm1) { using promoted_type = promote_args_t; return ((2 * n + l + 1 - static_cast(x)) * static_cast(Pl) - (n + l) * static_cast(Plm1)) / (n+1); } template constexpr auto assoc_laguerre_impl(const unsigned n, const unsigned m, const T x) BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { // Special cases: if(m == 0) { return boost::decimal::laguerre(n, x); } T p0 {UINT64_C(1)}; if(n == 0) { return p0; } T p1 {m + 1 - x}; unsigned c {1U}; while(c < n) { std::swap(p0, p1); p1 = static_cast(assoc_laguerre_next(c, m, x, p0, p1)); ++c; } return p1; } } //namespace detail BOOST_DECIMAL_EXPORT template constexpr auto assoc_laguerre(const unsigned n, const unsigned m, const T x) BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T) { using evaluation_type = detail::evaluation_type_t; return static_cast(detail::assoc_laguerre_impl(n, m, static_cast(x))); } } //namespace decimal } //namespace boost #endif //BOOST_DECIMAL_DETAIL_CMATH_ASSOC_LAGUERRE_HPP