Automatic Differentiation
 
Loading...
Searching...
No Matches
inv_Phi.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_INV_PHI_HPP
2#define STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_INV_PHI_HPP
3#ifdef STAN_OPENCL
4
6#include <string>
7
8namespace stan {
9namespace math {
10namespace opencl_kernels {
11// \cond
12static constexpr const char* inv_phi_device_function
13 = "\n"
14 "#ifndef STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_INV_PHI\n"
15 "#define STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_INV_PHI\n" STRINGIFY(
16 // \endcond
23 inline double inv_Phi(double p) {
24 if (p < 8e-311) {
25 return -INFINITY;
26 }
27 if (p == 1) {
28 return INFINITY;
29 }
30
31 const double a[6] = {-3.969683028665376e+01, 2.209460984245205e+02,
32 -2.759285104469687e+02, 1.383577518672690e+02,
33 -3.066479806614716e+01, 2.506628277459239e+00};
34 const double b[5] = {-5.447609879822406e+01, 1.615858368580409e+02,
35 -1.556989798598866e+02, 6.680131188771972e+01,
36 -1.328068155288572e+01};
37 const double c[6] = {-7.784894002430293e-03, -3.223964580411365e-01,
38 -2.400758277161838e+00, -2.549732539343734e+00,
39 4.374664141464968e+00, 2.938163982698783e+00};
40 const double d[4] = {7.784695709041462e-03, 3.224671290700398e-01,
41 2.445134137142996e+00, 3.754408661907416e+00};
42
43 const double p_low = 0.02425;
44 const double p_high = 0.97575;
45
46 double x;
47 if ((p_low <= p) && (p <= p_high)) {
48 double q = p - 0.5;
49 double r = q * q;
50 x = (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r
51 + a[5])
52 * q
53 / (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4])
54 * r
55 + 1.0);
56 } else if (p < p_low) {
57 double q = sqrt(-2.0 * log(p));
58 x = (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q
59 + c[5])
60 / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1.0);
61 } else {
62 double q = sqrt(-2.0 * log1m(p));
63 x = -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q
64 + c[5])
65 / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1.0);
66 }
67
68 if (x < 37.6) { // gradient blows up past here
69 double e = Phi(x) - p;
70 double u = e * sqrt(2.0 * M_PI) * exp(0.5 * x * x);
71 x -= u / (1.0 + 0.5 * x * u);
72 }
73
74 return x;
75 }
76 // \cond
77 ) "\n#endif\n"; // NOLINT
78// \endcond
79
80} // namespace opencl_kernels
81} // namespace math
82} // namespace stan
83
84#endif
85#endif
double log1m(double a)
Calculates the natural logarithm of one minus the specified value.
Definition log1m.hpp:28
double Phi(double x)
Return the Phi function applied to the specified argument.
Definition Phi.hpp:23
double inv_Phi(double p)
Return the inv_Phi function applied to the specified argument.
Definition inv_Phi.hpp:23
static constexpr double e()
Return the base of the natural logarithm.
Definition constants.hpp:20
fvar< T > log(const fvar< T > &x)
Definition log.hpp:18
fvar< T > sqrt(const fvar< T > &x)
Definition sqrt.hpp:18
fvar< T > exp(const fvar< T > &x)
Definition exp.hpp:15
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
#define STRINGIFY(...)
Definition stringify.hpp:9