Automatic Differentiation
 
Loading...
Searching...
No Matches
digamma.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_DIGAMMA_HPP
2#define STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_DIGAMMA_HPP
3#ifdef STAN_OPENCL
4
6#include <string>
7
8namespace stan {
9namespace math {
10namespace opencl_kernels {
11// \cond
12static constexpr const char* digamma_device_function
13 = "\n"
14 "#ifndef STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_DIGAMMA\n"
15 "#define STAN_MATH_OPENCL_KERNELS_DEVICE_FUNCTIONS_DIGAMMA\n" STRINGIFY(
16 // \endcond
25 double digamma(double x) {
26 double result = 0;
27 if (x <= -1) {
28 x = 1 - x;
29 double remainder = x - floor(x);
30 if (remainder > 0.5) {
31 remainder -= 1;
32 }
33 if (remainder == 0) {
34 return NAN;
35 }
36 result = M_PI / tan(M_PI * remainder);
37 }
38 if (x == 0) {
39 return NAN;
40 }
41 // in boost: x >= digamma_large_lim(t)
42 if (x > 10) {
43 // in boost: result += digamma_imp_large(x, t);
44 const double P[8]
45 = {0.083333333333333333333333333333333333333333333333333,
46 -0.0083333333333333333333333333333333333333333333333333,
47 0.003968253968253968253968253968253968253968253968254,
48 -0.0041666666666666666666666666666666666666666666666667,
49 0.0075757575757575757575757575757575757575757575757576,
50 -0.021092796092796092796092796092796092796092796092796,
51 0.083333333333333333333333333333333333333333333333333,
52 -0.44325980392156862745098039215686274509803921568627};
53 x -= 1;
54 result += log(x);
55 result += 1 / (2 * x);
56 double z = 1 / (x * x);
57 double tmp = P[7];
58 for (int i = 6; i >= 0; i--) {
59 tmp = tmp * z + P[i];
60 }
61 // tmp=boost::tools::evaluate_polynomial(P, z);
62 result -= z * tmp;
63 } else {
64 while (x > 2) {
65 x -= 1;
66 result += 1 / x;
67 }
68 while (x < 1) {
69 result -= 1 / x;
70 x += 1;
71 }
72 // in boost: result += digamma_imp_1_2(x, t);
73 const float Y = 0.99558162689208984F;
74
75 const double root1 = (double)1569415565 / 1073741824uL; // NOLINT
76 const double root2
77 = (double)381566830 / 1073741824uL / 1073741824uL; // NOLINT
78 const double root3
79 = 0.9016312093258695918615325266959189453125e-19;
80
81 const double P[6]
82 = {0.25479851061131551, -0.32555031186804491,
83 -0.65031853770896507, -0.28919126444774784,
84 -0.045251321448739056, -0.0020713321167745952};
85 const double Q[7] = {1.0,
86 2.0767117023730469,
87 1.4606242909763515,
88 0.43593529692665969,
89 0.054151797245674225,
90 0.0021284987017821144,
91 -0.55789841321675513e-6};
92 double g = x - root1 - root2 - root3;
93 double tmp = P[5];
94 for (int i = 4; i >= 0; i--) {
95 tmp = tmp * (x - 1) + P[i];
96 }
97 double tmp2 = Q[6];
98 for (int i = 5; i >= 0; i--) {
99 tmp2 = tmp2 * (x - 1) + Q[i];
100 }
101 // in boost: T r = tools::evaluate_polynomial(P, T(x-1)) /
102 // tools::evaluate_polynomial(Q, T(x-1));
103 double r = tmp / tmp2;
104 result += g * Y + g * r;
105 }
106 return result;
107 }
108 // \cond
109 ) "\n#endif\n"; // NOLINT
110// \endcond
111
112} // namespace opencl_kernels
113} // namespace math
114} // namespace stan
115
116#endif
117#endif
double digamma(double x)
Calculates the digamma function - derivative of logarithm of gamma.
Definition digamma.hpp:25
fvar< T > log(const fvar< T > &x)
Definition log.hpp:15
fvar< T > tan(const fvar< T > &x)
Definition tan.hpp:14
fvar< T > floor(const fvar< T > &x)
Definition floor.hpp:12
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
#define STRINGIFY(...)
Definition stringify.hpp:9