1e78f53d1SNikolas Klauser // -*- C++ -*- 2e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 3e78f53d1SNikolas Klauser // 4e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 6e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e78f53d1SNikolas Klauser // 8e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 9e78f53d1SNikolas Klauser 10*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H 11*ce777190SNikolas Klauser #define _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H 12e78f53d1SNikolas Klauser 1373fbae83SNikolas Klauser #include <__cxx03/__config> 1473fbae83SNikolas Klauser #include <__cxx03/__math/copysign.h> 1573fbae83SNikolas Klauser #include <__cxx03/__math/traits.h> 1673fbae83SNikolas Klauser #include <__cxx03/__type_traits/enable_if.h> 1773fbae83SNikolas Klauser #include <__cxx03/__type_traits/is_integral.h> 1873fbae83SNikolas Klauser #include <__cxx03/limits> 19e78f53d1SNikolas Klauser 20e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21e78f53d1SNikolas Klauser # pragma GCC system_header 22e78f53d1SNikolas Klauser #endif 23e78f53d1SNikolas Klauser 24e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_STD 25e78f53d1SNikolas Klauser 26e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 17 27e78f53d1SNikolas Klauser 28e78f53d1SNikolas Klauser template <class _Real> 29e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _Real __hermite(unsigned __n, _Real __x) { 30e78f53d1SNikolas Klauser // The Hermite polynomial H_n(x). 31e78f53d1SNikolas Klauser // The implementation is based on the recurrence formula: H_{n+1}(x) = 2x H_n(x) - 2n H_{n-1}. 32e78f53d1SNikolas Klauser // Press, William H., et al. Numerical recipes 3rd edition: The art of scientific computing. 33e78f53d1SNikolas Klauser // Cambridge university press, 2007, p. 183. 34e78f53d1SNikolas Klauser 35e78f53d1SNikolas Klauser // NOLINTBEGIN(readability-identifier-naming) 36e78f53d1SNikolas Klauser if (__math::isnan(__x)) 37e78f53d1SNikolas Klauser return __x; 38e78f53d1SNikolas Klauser 39e78f53d1SNikolas Klauser _Real __H_0{1}; 40e78f53d1SNikolas Klauser if (__n == 0) 41e78f53d1SNikolas Klauser return __H_0; 42e78f53d1SNikolas Klauser 43e78f53d1SNikolas Klauser _Real __H_n_prev = __H_0; 44e78f53d1SNikolas Klauser _Real __H_n = 2 * __x; 45e78f53d1SNikolas Klauser for (unsigned __i = 1; __i < __n; ++__i) { 46e78f53d1SNikolas Klauser _Real __H_n_next = 2 * (__x * __H_n - __i * __H_n_prev); 47e78f53d1SNikolas Klauser __H_n_prev = __H_n; 48e78f53d1SNikolas Klauser __H_n = __H_n_next; 49e78f53d1SNikolas Klauser } 50e78f53d1SNikolas Klauser 51e78f53d1SNikolas Klauser if (!__math::isfinite(__H_n)) { 52e78f53d1SNikolas Klauser // Overflow occured. Two possible cases: 53e78f53d1SNikolas Klauser // n is odd: return infinity of the same sign as x. 54e78f53d1SNikolas Klauser // n is even: return +Inf 55e78f53d1SNikolas Klauser _Real __inf = std::numeric_limits<_Real>::infinity(); 56e78f53d1SNikolas Klauser return (__n & 1) ? __math::copysign(__inf, __x) : __inf; 57e78f53d1SNikolas Klauser } 58e78f53d1SNikolas Klauser return __H_n; 59e78f53d1SNikolas Klauser // NOLINTEND(readability-identifier-naming) 60e78f53d1SNikolas Klauser } 61e78f53d1SNikolas Klauser 62e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI double hermite(unsigned __n, double __x) { return std::__hermite(__n, __x); } 63e78f53d1SNikolas Klauser 64e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI float hermite(unsigned __n, float __x) { 65e78f53d1SNikolas Klauser // use double internally -- float is too prone to overflow! 66e78f53d1SNikolas Klauser return static_cast<float>(std::hermite(__n, static_cast<double>(__x))); 67e78f53d1SNikolas Klauser } 68e78f53d1SNikolas Klauser 69e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI long double hermite(unsigned __n, long double __x) { return std::__hermite(__n, __x); } 70e78f53d1SNikolas Klauser 71e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI float hermitef(unsigned __n, float __x) { return std::hermite(__n, __x); } 72e78f53d1SNikolas Klauser 73e78f53d1SNikolas Klauser inline _LIBCPP_HIDE_FROM_ABI long double hermitel(unsigned __n, long double __x) { return std::hermite(__n, __x); } 74e78f53d1SNikolas Klauser 75e78f53d1SNikolas Klauser template <class _Integer, std::enable_if_t<std::is_integral_v<_Integer>, int> = 0> 76e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI double hermite(unsigned __n, _Integer __x) { 77e78f53d1SNikolas Klauser return std::hermite(__n, static_cast<double>(__x)); 78e78f53d1SNikolas Klauser } 79e78f53d1SNikolas Klauser 80e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 81e78f53d1SNikolas Klauser 82e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_STD 83e78f53d1SNikolas Klauser 84*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H 85