WPILibC++ 2024.3.2
erf.hpp
Go to the documentation of this file.
1/*################################################################################
2 ##
3 ## Copyright (C) 2016-2023 Keith O'Hara
4 ##
5 ## This file is part of the GCE-Math C++ library.
6 ##
7 ## Licensed under the Apache License, Version 2.0 (the "License");
8 ## you may not use this file except in compliance with the License.
9 ## You may obtain a copy of the License at
10 ##
11 ## http://www.apache.org/licenses/LICENSE-2.0
12 ##
13 ## Unless required by applicable law or agreed to in writing, software
14 ## distributed under the License is distributed on an "AS IS" BASIS,
15 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ## See the License for the specific language governing permissions and
17 ## limitations under the License.
18 ##
19 ################################################################################*/
20
21/*
22 * compile-time error function
23 */
24
25#ifndef _gcem_erf_HPP
26#define _gcem_erf_HPP
27
28#include <cmath>
29#include <type_traits>
30
31namespace gcem
32{
33
34namespace internal
35{
36
37// see
38// http://functions.wolfram.com/GammaBetaErf/Erf/10/01/0007/
39
40template<typename T>
41constexpr
42T
43erf_cf_large_recur(const T x, const int depth)
44noexcept
45{
46 return( depth < GCEM_ERF_MAX_ITER ? \
47 // if
48 x + 2*depth/erf_cf_large_recur(x,depth+1) :
49 // else
50 x );
51}
52
53template<typename T>
54constexpr
55T
57noexcept
58{
59 return( T(1) - T(2) * ( exp(-x*x) / T(GCEM_SQRT_PI) ) \
60 / erf_cf_large_recur(T(2)*x,1) );
61}
62
63// see
64// http://functions.wolfram.com/GammaBetaErf/Erf/10/01/0005/
65
66template<typename T>
67constexpr
68T
69erf_cf_small_recur(const T xx, const int depth)
70noexcept
71{
72 return( depth < GCEM_ERF_MAX_ITER ? \
73 // if
74 (2*depth - T(1)) - 2*xx \
75 + 4*depth*xx / erf_cf_small_recur(xx,depth+1) :
76 // else
77 (2*depth - T(1)) - 2*xx );
78}
79
80template<typename T>
81constexpr
82T
84noexcept
85{
86 return( T(2) * x * ( exp(-x*x) / T(GCEM_SQRT_PI) ) \
87 / erf_cf_small_recur(x*x,1) );
88}
89
90//
91
92template<typename T>
93constexpr
94T
95erf_begin(const T x)
96noexcept
97{
98 return( x > T(2.1) ? \
99 // if
101 // else
103}
104
105template<typename T>
106constexpr
107T
108erf_check(const T x)
109noexcept
110{
111 return( // NaN check
112 is_nan(x) ? \
114 // +/-Inf
115 is_posinf(x) ? \
116 T(1) :
117 is_neginf(x) ? \
118 - T(1) :
119 // indistinguishable from zero
120 GCLIM<T>::min() > abs(x) ? \
121 T(0) :
122 // else
123 x < T(0) ? \
124 - erf_begin(-x) :
125 erf_begin( x) );
126}
127
128}
129
130/**
131 * Compile-time Gaussian error function
132 *
133 * @param x a real-valued input.
134 * @return computes the Gaussian error function
135 * \f[ \text{erf}(x) = \frac{2}{\sqrt{\pi}} \int_0^x \exp( - t^2) dt \f]
136 * using a continued fraction representation:
137 * \f[ \text{erf}(x) = \frac{2x}{\sqrt{\pi}} \exp(-x^2) \dfrac{1}{1 - 2x^2 + \dfrac{4x^2}{3 - 2x^2 + \dfrac{8x^2}{5 - 2x^2 + \dfrac{12x^2}{7 - 2x^2 + \ddots}}}} \f]
138 */
139
140template<typename T>
141constexpr
142return_t<T>
143erf(const T x)
144noexcept
145{
147 return internal::erf_check( static_cast<return_t<T>>(x) );
148 } else {
149 return std::erf(x);
150 }
151}
152
153}
154
155#endif
#define GCEM_SQRT_PI
Definition: gcem_options.hpp:122
#define GCEM_ERF_MAX_ITER
Definition: gcem_options.hpp:137
constexpr FMT_INLINE auto is_constant_evaluated(bool default_value=false) noexcept -> bool
Definition: core.h:304
constexpr T erf_cf_small_recur(const T xx, const int depth) noexcept
Definition: erf.hpp:69
constexpr T erf_cf_small_main(const T x) noexcept
Definition: erf.hpp:83
constexpr bool is_nan(const T x) noexcept
Definition: is_nan.hpp:39
constexpr T erf_begin(const T x) noexcept
Definition: erf.hpp:95
constexpr bool is_posinf(const T x) noexcept
Definition: is_inf.hpp:84
constexpr T erf_cf_large_recur(const T x, const int depth) noexcept
Definition: erf.hpp:43
constexpr T erf_cf_large_main(const T x) noexcept
Definition: erf.hpp:56
constexpr bool is_neginf(const T x) noexcept
Definition: is_inf.hpp:37
constexpr T erf_check(const T x) noexcept
Definition: erf.hpp:108
Definition: is_even.hpp:29
constexpr T abs(const T x) noexcept
Compile-time absolute value function.
Definition: abs.hpp:40
constexpr return_t< T > erf(const T x) noexcept
Compile-time Gaussian error function.
Definition: erf.hpp:143
std::numeric_limits< T > GCLIM
Definition: gcem_options.hpp:74
typename std::conditional< std::is_integral< T >::value, double, T >::type return_t
Definition: gcem_options.hpp:77