Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:34

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H
0011 #define _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H
0012 
0013 #include <__cxx03/__config>
0014 #include <__cxx03/__math/copysign.h>
0015 #include <__cxx03/__math/traits.h>
0016 #include <__cxx03/__type_traits/enable_if.h>
0017 #include <__cxx03/__type_traits/is_integral.h>
0018 #include <__cxx03/limits>
0019 
0020 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0021 #  pragma GCC system_header
0022 #endif
0023 
0024 _LIBCPP_BEGIN_NAMESPACE_STD
0025 
0026 #if _LIBCPP_STD_VER >= 17
0027 
0028 template <class _Real>
0029 _LIBCPP_HIDE_FROM_ABI _Real __hermite(unsigned __n, _Real __x) {
0030   // The Hermite polynomial H_n(x).
0031   // The implementation is based on the recurrence formula: H_{n+1}(x) = 2x H_n(x) - 2n H_{n-1}.
0032   // Press, William H., et al. Numerical recipes 3rd edition: The art of scientific computing.
0033   // Cambridge university press, 2007, p. 183.
0034 
0035   // NOLINTBEGIN(readability-identifier-naming)
0036   if (__math::isnan(__x))
0037     return __x;
0038 
0039   _Real __H_0{1};
0040   if (__n == 0)
0041     return __H_0;
0042 
0043   _Real __H_n_prev = __H_0;
0044   _Real __H_n      = 2 * __x;
0045   for (unsigned __i = 1; __i < __n; ++__i) {
0046     _Real __H_n_next = 2 * (__x * __H_n - __i * __H_n_prev);
0047     __H_n_prev       = __H_n;
0048     __H_n            = __H_n_next;
0049   }
0050 
0051   if (!__math::isfinite(__H_n)) {
0052     // Overflow occured. Two possible cases:
0053     //    n is odd:  return infinity of the same sign as x.
0054     //    n is even: return +Inf
0055     _Real __inf = std::numeric_limits<_Real>::infinity();
0056     return (__n & 1) ? __math::copysign(__inf, __x) : __inf;
0057   }
0058   return __H_n;
0059   // NOLINTEND(readability-identifier-naming)
0060 }
0061 
0062 inline _LIBCPP_HIDE_FROM_ABI double hermite(unsigned __n, double __x) { return std::__hermite(__n, __x); }
0063 
0064 inline _LIBCPP_HIDE_FROM_ABI float hermite(unsigned __n, float __x) {
0065   // use double internally -- float is too prone to overflow!
0066   return static_cast<float>(std::hermite(__n, static_cast<double>(__x)));
0067 }
0068 
0069 inline _LIBCPP_HIDE_FROM_ABI long double hermite(unsigned __n, long double __x) { return std::__hermite(__n, __x); }
0070 
0071 inline _LIBCPP_HIDE_FROM_ABI float hermitef(unsigned __n, float __x) { return std::hermite(__n, __x); }
0072 
0073 inline _LIBCPP_HIDE_FROM_ABI long double hermitel(unsigned __n, long double __x) { return std::hermite(__n, __x); }
0074 
0075 template <class _Integer, std::enable_if_t<std::is_integral_v<_Integer>, int> = 0>
0076 _LIBCPP_HIDE_FROM_ABI double hermite(unsigned __n, _Integer __x) {
0077   return std::hermite(__n, static_cast<double>(__x));
0078 }
0079 
0080 #endif // _LIBCPP_STD_VER >= 17
0081 
0082 _LIBCPP_END_NAMESPACE_STD
0083 
0084 #endif // _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H