Automatic Differentiation
 
Loading...
Searching...
No Matches
trigamma.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_FUN_TRIGAMMA_HPP
2#define STAN_MATH_PRIM_FUN_TRIGAMMA_HPP
3
12#include <cmath>
13
14// Reference:
15// BE Schneider,
16// Algorithm AS 121:
17// Trigamma Function,
18// Applied Statistics,
19// Volume 27, Number 1, pages 97-99, 1978.
20
21namespace stan {
22namespace math {
23
36template <typename T>
37inline T trigamma_impl(const T& x) {
38 double small = 0.0001;
39 double large = 5.0;
40 T value;
41 T y;
42 T z;
43
44 // bernoulli numbers
45 double b2 = inv(6.0);
46 double b4 = -inv(30.0);
47 double b6 = inv(42.0);
48 double b8 = -inv(30.0);
49
50 // negative integers and zero return positive infinity
51 // see http://mathworld.wolfram.com/PolygammaFunction.html
52 if (x <= 0.0 && floor(x) == x) {
53 value = positive_infinity();
54 return value;
55 }
56
57 // negative non-integers: use the reflection formula
58 // see http://mathworld.wolfram.com/PolygammaFunction.html
59 if (x <= 0 && floor(x) != x) {
60 value = -trigamma_impl(-x + 1.0) + square(pi() / sin(-pi() * x));
61 return value;
62 }
63
64 // small value approximation if x <= small.
65 if (x <= small) {
66 return inv_square(x);
67 }
68
69 // use recurrence relation until x >= large
70 // see http://mathworld.wolfram.com/PolygammaFunction.html
71 z = x;
72 value = 0.0;
73 while (z < large) {
74 value += inv_square(z);
75 z += 1.0;
76 }
77
78 // asymptotic expansion as a Laurent series if x >= large
79 // see http://en.wikipedia.org/wiki/Trigamma_function
80 y = inv_square(z);
81 value += 0.5 * y + (1.0 + y * (b2 + y * (b4 + y * (b6 + y * b8)))) / z;
82
83 return value;
84}
85
117inline double trigamma(double u) { return trigamma_impl(u); }
118
126inline double trigamma(int u) { return trigamma(static_cast<double>(u)); }
127
140 template <typename T>
141 static inline auto fun(const T& x) {
142 return trigamma(x);
143 }
144};
145
156template <typename T,
158inline auto trigamma(const T& x) {
160}
161
162} // namespace math
163} // namespace stan
164
165#endif
require_not_t< is_nonscalar_prim_or_rev_kernel_expression< std::decay_t< T > > > require_not_nonscalar_prim_or_rev_kernel_expression_t
Require type does not satisfy is_nonscalar_prim_or_rev_kernel_expression.
fvar< T > sin(const fvar< T > &x)
Definition sin.hpp:16
static constexpr double positive_infinity()
Return positive infinity.
fvar< T > inv_square(const fvar< T > &x)
T trigamma_impl(const T &x)
Return the trigamma function applied to the argument.
Definition trigamma.hpp:37
fvar< T > trigamma(const fvar< T > &u)
Return the value of the trigamma function at the specified argument (i.e., the second derivative of t...
Definition trigamma.hpp:25
fvar< T > floor(const fvar< T > &x)
Definition floor.hpp:13
static constexpr double pi()
Return the value of pi.
Definition constants.hpp:36
fvar< T > inv(const fvar< T > &x)
Definition inv.hpp:13
fvar< T > square(const fvar< T > &x)
Definition square.hpp:12
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Base template class for vectorization of unary scalar functions defined by a template class F to a sc...
static auto fun(const T &x)
Return the trigamma() function applied to the argument.
Definition trigamma.hpp:141
Structure to wrap trigamma() so it can be vectorized.
Definition trigamma.hpp:131