32 #ifndef MCKL_MATH_BETA_HPP 33 #define MCKL_MATH_BETA_HPP 46 inline double betai_acf(
double a,
double b,
double x)
48 constexpr
double eps = std::numeric_limits<double>::epsilon();
49 constexpr
double fpmin = std::numeric_limits<double>::min() / eps;
55 double d = 1 - qab * x / qap;
62 for (
int i = 0; i != 10000; ++i) {
65 double aa = m * (b - m) * x / ((qam + m2) * (a + m2));
76 aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
100 double mu = a / (a + b);
103 double t =
std::sqrt(a * b / ((a + b) * (a + b) * (a + b + 1)));
105 if (x > a / (a + b)) {
109 xu = std::min(1.0, std::max(mu + 10 * t, x + 5 * t));
114 xu = std::max(0.0, std::min(mu - 10 * t, x - 5 * t));
123 double ans = sum * (xu - x) *
127 return ans > 0 ? 1 - ans : -ans;
134 inline double betai(
double a,
double b,
double x)
136 if (a <= 0.0 || b <= 0.0) {
137 return mckl::const_nan<double>();
139 if (x < 0.0 || x > 1.0) {
140 return mckl::const_nan<double>();
142 if (!(x > 0 || x < 0)) {
145 if (!(x > 1 || x < 1)) {
148 if (a > 3000 && b > 3000) {
155 return x < (a + 1) / (a + b + 2) ?
162 inline double betaiinv(
double a,
double b,
double y)
175 if (a >= 1 && b >= 1) {
176 double z = (y < 0.5) ? y : 1 - y;
178 x = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;
182 double al = (x * x - 3) / 6;
183 double h = 2 / (1 / (2 * a - 1) + 1 / (2 * b - 1));
185 (1 / (2 * b - 1) - 1 / (2 * a - 1)) * (al + 5 / 6 - 2 / (3 * h));
193 x = y < t / w ?
std::pow(a * w * y, 1 / a) :
194 1 -
std::pow(b * w * (1 - y), 1 / b);
197 for (
int i = 0; i != 10; ++i) {
198 if (!(x > 0 || x < 0)) {
201 if (!(x > 1 || x < 1)) {
204 double err =
betai(a, b, x) - y;
207 x -= (t = u / (1 - 0.5 * std::min(1.0, u * (a1 / x - b1 / (1 - x)))));
212 x = 0.5 * (x + t + 1);
214 if (
std::abs(t) < eps * x && i > 0) {
224 #endif // MCKL_MATH_BETA_HPP void pow(std::size_t n, const float *a, const float *b, float *y)
static constexpr double gammap_approx_w[]
double betai(double a, double b, double x)
Regularized incomplete Beta function.
static constexpr std::size_t gammap_approx_n
double betai_acf(double a, double b, double x)
static constexpr double gammap_approx_y[]
void lgamma(std::size_t n, const float *a, float *y)
void log(std::size_t n, const float *a, float *y)
void abs(std::size_t n, const float *a, float *y)
double betai_approx(double a, double b, double x)
void sqrt(std::size_t n, const float *a, float *y)
void exp(std::size_t n, const float *a, float *y)
double betaiinv(double a, double b, double y)
Inverse regularized incomplete Beta function.