WPILibC++ 2023.4.3
incomplete_beta.hpp
Go to the documentation of this file.
1/*################################################################################
2 ##
3 ## Copyright (C) 2016-2022 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 incomplete beta function
23 *
24 * see eq. 18.5.17a in the Handbook of Continued Fractions for Special Functions
25 */
26
27#ifndef _gcem_incomplete_beta_HPP
28#define _gcem_incomplete_beta_HPP
29
30namespace internal
31{
32
33template<typename T>
34constexpr T incomplete_beta_cf(const T a, const T b, const T z, const T c_j, const T d_j, const T f_j, const int depth) noexcept;
35
36//
37// coefficients; see eq. 18.5.17b
38
39template<typename T>
40constexpr
41T
42incomplete_beta_coef_even(const T a, const T b, const T z, const int k)
43noexcept
44{
45 return( -z*(a + k)*(a + b + k)/( (a + 2*k)*(a + 2*k + T(1)) ) );
46}
47
48template<typename T>
49constexpr
50T
51incomplete_beta_coef_odd(const T a, const T b, const T z, const int k)
52noexcept
53{
54 return( z*k*(b - k)/((a + 2*k - T(1))*(a + 2*k)) );
55}
56
57template<typename T>
58constexpr
59T
60incomplete_beta_coef(const T a, const T b, const T z, const int depth)
61noexcept
62{
63 return( !is_odd(depth) ? incomplete_beta_coef_even(a,b,z,depth/2) :
64 incomplete_beta_coef_odd(a,b,z,(depth+1)/2) );
65}
66
67//
68// update formulae for the modified Lentz method
69
70template<typename T>
71constexpr
72T
73incomplete_beta_c_update(const T a, const T b, const T z, const T c_j, const int depth)
74noexcept
75{
76 return( T(1) + incomplete_beta_coef(a,b,z,depth)/c_j );
77}
78
79template<typename T>
80constexpr
81T
82incomplete_beta_d_update(const T a, const T b, const T z, const T d_j, const int depth)
83noexcept
84{
85 return( T(1) / (T(1) + incomplete_beta_coef(a,b,z,depth)*d_j) );
86}
87
88//
89// convergence-type condition
90
91template<typename T>
92constexpr
93T
94incomplete_beta_decision(const T a, const T b, const T z, const T c_j, const T d_j, const T f_j, const int depth)
95noexcept
96{
97 return( // tolerance check
98 abs(c_j*d_j - T(1)) < GCEM_INCML_BETA_TOL ? f_j*c_j*d_j :
99 // max_iter check
100 depth < GCEM_INCML_BETA_MAX_ITER ? \
101 // if
102 incomplete_beta_cf(a,b,z,c_j,d_j,f_j*c_j*d_j,depth+1) :
103 // else
104 f_j*c_j*d_j );
105}
106
107template<typename T>
108constexpr
109T
110incomplete_beta_cf(const T a, const T b, const T z, const T c_j, const T d_j, const T f_j, const int depth)
111noexcept
112{
113 return incomplete_beta_decision(a,b,z,
114 incomplete_beta_c_update(a,b,z,c_j,depth),
115 incomplete_beta_d_update(a,b,z,d_j,depth),
116 f_j,depth);
117}
118
119//
120// x^a (1-x)^{b} / (a beta(a,b)) * cf
121
122template<typename T>
123constexpr
124T
125incomplete_beta_begin(const T a, const T b, const T z)
126noexcept
127{
128 return ( (exp(a*log(z) + b*log(T(1)-z) - lbeta(a,b)) / a) * \
129 incomplete_beta_cf(a,b,z,T(1),
130 incomplete_beta_d_update(a,b,z,T(1),0),
131 incomplete_beta_d_update(a,b,z,T(1),0),1)
132 );
133}
134
135template<typename T>
136constexpr
137T
138incomplete_beta_check(const T a, const T b, const T z)
139noexcept
140{
141 return( // NaN check
142 any_nan(a, b, z) ? \
143 GCLIM<T>::quiet_NaN() :
144 // indistinguishable from zero
145 GCLIM<T>::min() > z ? \
146 T(0) :
147 // parameter check for performance
148 (a + T(1))/(a + b + T(2)) > z ? \
150 T(1) - incomplete_beta_begin(b,a,T(1) - z) );
151}
152
153template<typename T1, typename T2, typename T3, typename TC = common_return_t<T1,T2,T3>>
154constexpr
155TC
156incomplete_beta_type_check(const T1 a, const T2 b, const T3 p)
157noexcept
158{
159 return incomplete_beta_check(static_cast<TC>(a),
160 static_cast<TC>(b),
161 static_cast<TC>(p));
162}
163
164}
165
166/**
167 * Compile-time regularized incomplete beta function
168 *
169 * @param a a real-valued, non-negative input.
170 * @param b a real-valued, non-negative input.
171 * @param z a real-valued, non-negative input.
172 *
173 * @return computes the regularized incomplete beta function,
174 * \f[ \frac{\text{B}(z;\alpha,\beta)}{\text{B}(\alpha,\beta)} = \frac{1}{\text{B}(\alpha,\beta)}\int_0^z t^{a-1} (1-t)^{\beta-1} dt \f]
175 * using a continued fraction representation, found in the Handbook of Continued Fractions for Special Functions, and a modified Lentz method.
176 * \f[ \frac{\text{B}(z;\alpha,\beta)}{\text{B}(\alpha,\beta)} = \frac{z^{\alpha} (1-t)^{\beta}}{\alpha \text{B}(\alpha,\beta)} \dfrac{a_1}{1 + \dfrac{a_2}{1 + \dfrac{a_3}{1 + \dfrac{a_4}{1 + \ddots}}}} \f]
177 * where \f$ a_1 = 1 \f$ and
178 * \f[ a_{2m+2} = - \frac{(\alpha + m)(\alpha + \beta + m)}{(\alpha + 2m)(\alpha + 2m + 1)}, \ m \geq 0 \f]
179 * \f[ a_{2m+1} = \frac{m(\beta - m)}{(\alpha + 2m - 1)(\alpha + 2m)}, \ m \geq 1 \f]
180 * The Lentz method works as follows: let \f$ f_j \f$ denote the value of the continued fraction up to the first \f$ j \f$ terms; \f$ f_j \f$ is updated as follows:
181 * \f[ c_j = 1 + a_j / c_{j-1}, \ \ d_j = 1 / (1 + a_j d_{j-1}) \f]
182 * \f[ f_j = c_j d_j f_{j-1} \f]
183 */
184
185template<typename T1, typename T2, typename T3>
186constexpr
187common_return_t<T1,T2,T3>
188incomplete_beta(const T1 a, const T2 b, const T3 z)
189noexcept
190{
192}
193
194#endif
#define GCEM_INCML_BETA_TOL
Definition: gcem_options.hpp:161
#define GCEM_INCML_BETA_MAX_ITER
Definition: gcem_options.hpp:165
UnitType abs(const UnitType x) noexcept
Compute absolute value.
Definition: math.h:721
dimensionless::scalar_t log(const ScalarUnit x) noexcept
Compute natural logarithm.
Definition: math.h:349
constexpr common_return_t< T1, T2, T3 > incomplete_beta(const T1 a, const T2 b, const T3 z) noexcept
Compile-time regularized incomplete beta function.
Definition: incomplete_beta.hpp:188
constexpr common_return_t< T1, T2 > lbeta(const T1 a, const T2 b) noexcept
Compile-time log-beta function.
Definition: lbeta.hpp:36
constexpr common_t< T1, T2 > min(const T1 x, const T2 y) noexcept
Compile-time pairwise minimum function.
Definition: min.hpp:35
Definition: Eigen_Colamd.h:50
constexpr T incomplete_beta_begin(const T a, const T b, const T z) noexcept
Definition: incomplete_beta.hpp:125
constexpr T incomplete_beta_decision(const T a, const T b, const T z, const T c_j, const T d_j, const T f_j, const int depth) noexcept
Definition: incomplete_beta.hpp:94
constexpr T incomplete_beta_coef(const T a, const T b, const T z, const int depth) noexcept
Definition: incomplete_beta.hpp:60
constexpr T incomplete_beta_d_update(const T a, const T b, const T z, const T d_j, const int depth) noexcept
Definition: incomplete_beta.hpp:82
constexpr TC incomplete_beta_type_check(const T1 a, const T2 b, const T3 p) noexcept
Definition: incomplete_beta.hpp:156
constexpr T incomplete_beta_coef_odd(const T a, const T b, const T z, const int k) noexcept
Definition: incomplete_beta.hpp:51
constexpr bool is_odd(const llint_t x) noexcept
Definition: is_odd.hpp:33
constexpr T incomplete_beta_coef_even(const T a, const T b, const T z, const int k) noexcept
Definition: incomplete_beta.hpp:42
constexpr T incomplete_beta_check(const T a, const T b, const T z) noexcept
Definition: incomplete_beta.hpp:138
constexpr T incomplete_beta_cf(const T a, const T b, const T z, const T c_j, const T d_j, const T f_j, const int depth) noexcept
Definition: incomplete_beta.hpp:110
constexpr T incomplete_beta_c_update(const T a, const T b, const T z, const T c_j, const int depth) noexcept
Definition: incomplete_beta.hpp:73
constexpr bool any_nan(const T1 x, const T2 y) noexcept
Definition: is_nan.hpp:45
b
Definition: data.h:44