8#ifndef STAN_MATH_PRIM_FUN_LOG_MODIFIED_BESSEL_FIRST_KIND_HPP
9#define STAN_MATH_PRIM_FUN_LOG_MODIFIED_BESSEL_FIRST_KIND_HPP
25#include <boost/math/tools/rational.hpp>
45template <
typename T1,
typename T2,
46 require_all_stan_scalar_t<T1, T2>* =
nullptr>
48 const T1 v,
const T2 z) {
49 check_not_nan(
"log_modified_bessel_first_kind",
"first argument (order)", v);
50 check_not_nan(
"log_modified_bessel_first_kind",
"second argument (variable)",
53 "second argument (variable)", z);
55 "first argument (order)", v, -1);
57 using boost::math::tools::evaluate_polynomial;
94 static constexpr double P[15]
95 = {1.00000000000000000e+00, 2.49999999999999909e-01,
96 2.77777777777782257e-02, 1.73611111111023792e-03,
97 6.94444444453352521e-05, 1.92901234513219920e-06,
98 3.93675991102510739e-08, 6.15118672704439289e-10,
99 7.59407002058973446e-12, 7.59389793369836367e-14,
100 6.27767773636292611e-16, 4.34709704153272287e-18,
101 2.63417742690109154e-20, 1.13943037744822825e-22,
102 9.07926920085624812e-25};
104 +
log(evaluate_polynomial(P, 0.25 *
square(z))));
110 static constexpr double P[22]
111 = {3.98942280401425088e-01, 4.98677850604961985e-02,
112 2.80506233928312623e-02, 2.92211225166047873e-02,
113 4.44207299493659561e-02, 1.30970574605856719e-01,
114 -3.35052280231727022e+00, 2.33025711583514727e+02,
115 -1.13366350697172355e+04, 4.24057674317867331e+05,
116 -1.23157028595698731e+07, 2.80231938155267516e+08,
117 -5.01883999713777929e+09, 7.08029243015109113e+10,
118 -7.84261082124811106e+11, 6.76825737854096565e+12,
119 -4.49034849696138065e+13, 2.24155239966958995e+14,
120 -8.13426467865659318e+14, 2.02391097391687777e+15,
121 -3.08675715295370878e+15, 2.17587543863819074e+15};
126 static constexpr double P[5]
127 = {3.98942280401432905e-01, 4.98677850491434560e-02,
128 2.80506308916506102e-02, 2.92179096853915176e-02,
129 4.53371208762579442e-02};
140 static constexpr double P[13]
141 = {8.333333333333333803e-02, 6.944444444444341983e-03,
142 3.472222222225921045e-04, 1.157407407354987232e-05,
143 2.755731926254790268e-07, 4.920949692800671435e-09,
144 6.834657311305621830e-11, 7.593969849687574339e-13,
145 6.904822652741917551e-15, 5.220157095351373194e-17,
146 3.410720494727771276e-19, 1.625212890947171108e-21,
147 1.332898928162290861e-23};
149 T Q[3] = {1, 0.5, evaluate_polynomial(P, a)};
156 static constexpr double P[22]
157 = {3.989422804014406054e-01, -1.496033551613111533e-01,
158 -4.675104253598537322e-02, -4.090895951581637791e-02,
159 -5.719036414430205390e-02, -1.528189554374492735e-01,
160 3.458284470977172076e+00, -2.426181371595021021e+02,
161 1.178785865993440669e+04, -4.404655582443487334e+05,
162 1.277677779341446497e+07, -2.903390398236656519e+08,
163 5.192386898222206474e+09, -7.313784438967834057e+10,
164 8.087824484994859552e+11, -6.967602516005787001e+12,
165 4.614040809616582764e+13, -2.298849639457172489e+14,
166 8.325554073334618015e+14, -2.067285045778906105e+15,
167 3.146401654361325073e+15, -2.213318202179221945e+15};
172 static constexpr double P[5]
173 = {3.989422804014314820e-01, -1.496033551467584157e-01,
174 -4.675105322571775911e-02, -4.090421597376992892e-02,
175 -5.843630344778927582e-02};
180 T lim =
pow((
square(v) + 2.5) / (2 * z), 3) / 24;
201 T lcons = (2.0 + v) * log_half_z;
216 lcons += 2 * log_half_z;
220 }
while (out > old_out || out < old_out);
234template <
typename T1,
typename T2, require_any_container_t<T1, T2>* =
nullptr>
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
fvar< T > multiply_log(const fvar< T > &x1, const fvar< T > &x2)
void check_nonnegative(const char *function, const char *name, const T_y &y)
Check if y is non-negative.
static constexpr double EPSILON
Smallest positive value.
auto pow(const T1 &x1, const T2 &x2)
fvar< T > log(const fvar< T > &x)
return_type_t< T1, T2, double > log_modified_bessel_first_kind(const T1 v, const T2 z)
static constexpr double NEGATIVE_INFTY
Negative infinity.
static constexpr double LOG_TWO
The natural logarithm of 2, .
void check_greater_or_equal(const char *function, const char *name, const T_y &y, const T_low &low, Idxs... idxs)
Throw an exception if y is not greater or equal than low.
fvar< T > log1p_exp(const fvar< T > &x)
fvar< T > sqrt(const fvar< T > &x)
fvar< T > log1p(const fvar< T > &x)
fvar< T > lgamma(const fvar< T > &x)
Return the natural logarithm of the gamma function applied to the specified argument.
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
static constexpr double TWO_PI
Twice the value of , .
int is_inf(const fvar< T > &x)
Returns 1 if the input's value is infinite and 0 otherwise.
auto apply_scalar_binary(const T1 &x, const T2 &y, const F &f)
Base template function for vectorization of binary scalar functions defined by applying a functor to ...
fvar< T > inv(const fvar< T > &x)
static constexpr double INFTY
Positive infinity.
fvar< T > square(const fvar< T > &x)
fvar< T > log_sum_exp(const fvar< T > &x1, const fvar< T > &x2)
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...