30 #ifndef STAN_MATH_PRIM_MAT_PROB_WIENER_LPDF_HPP 31 #define STAN_MATH_PRIM_MAT_PROB_WIENER_LPDF_HPP 45 #include <boost/math/distributions.hpp> 71 template <
bool propto,
typename T_y,
typename T_alpha,
typename T_tau,
72 typename T_beta,
typename T_delta>
74 const T_y&
y,
const T_alpha& alpha,
const T_tau& tau,
const T_beta&
beta,
75 const T_delta&
delta) {
76 static const char*
function =
"wiener_lpdf";
82 static const double WIENER_ERR = 0.000001;
83 static const double PI_TIMES_WIENER_ERR =
pi() * WIENER_ERR;
84 static const double LOG_PI_LOG_WIENER_ERR =
LOG_PI +
log(WIENER_ERR);
85 static const double TWO_TIMES_SQRT_2_TIMES_SQRT_PI_TIMES_WIENER_ERR
87 static const double LOG_TWO_OVER_TWO_PLUS_LOG_SQRT_PI
89 static const double SQUARE_PI_OVER_TWO =
square(
pi()) * 0.5;
90 static const double TWO_TIMES_LOG_SQRT_PI = 2.0 *
LOG_SQRT_PI;
92 if (
size_zero(y, alpha, beta, tau, delta))
97 T_return_type lp(0.0);
113 alpha,
"A-priori bias", beta,
"Nondecision time", tau,
114 "Drift rate", delta);
127 for (
size_t i = 0;
i < N_y_tau; ++
i) {
128 if (y_vec[
i] <= tau_vec[
i]) {
129 std::stringstream
msg;
130 msg <<
", but must be greater than nondecision time = " << tau_vec[
i];
132 domain_error(
function,
"Random variable", y_vec[i],
" = ",
140 for (
size_t i = 0;
i < N;
i++) {
143 T_return_type
x = (y_vec[
i] - tau_vec[
i]) / alpha2;
144 T_return_type kl, ks,
tmp = 0;
146 T_return_type sqrt_x =
sqrt(x);
147 T_return_type log_x =
log(x);
148 T_return_type one_over_pi_times_sqrt_x = 1.0 /
pi() * sqrt_x;
152 if (PI_TIMES_WIENER_ERR * x < 1) {
154 kl =
sqrt(-2.0 *
SQRT_PI * (LOG_PI_LOG_WIENER_ERR + log_x)) / sqrt_x;
156 kl = (kl > one_over_pi_times_sqrt_x) ? kl : one_over_pi_times_sqrt_x;
158 kl = one_over_pi_times_sqrt_x;
162 T_return_type tmp_expr0
163 = TWO_TIMES_SQRT_2_TIMES_SQRT_PI_TIMES_WIENER_ERR * sqrt_x;
166 ks = 2.0 + sqrt_x *
sqrt(-2 *
log(tmp_expr0));
168 T_return_type sqrt_x_plus_one = sqrt_x + 1.0;
169 ks = (ks > sqrt_x_plus_one) ? ks : sqrt_x_plus_one;
175 T_return_type tmp_expr1 = (K - 1.0) / 2.0;
176 T_return_type tmp_expr2 =
ceil(tmp_expr1);
177 for (k = -
floor(tmp_expr1); k <= tmp_expr2; k++)
178 tmp += (one_minus_beta + 2.0 * k)
179 *
exp(-(
square(one_minus_beta + 2.0 * k)) * 0.5 / x);
180 tmp =
log(tmp) - LOG_TWO_OVER_TWO_PLUS_LOG_SQRT_PI - 1.5 * log_x;
183 for (k = 1; k <=
K; ++k)
184 tmp += k *
exp(-(
square(k)) * (SQUARE_PI_OVER_TWO * x))
185 *
sin(k *
pi() * one_minus_beta);
186 tmp =
log(tmp) + TWO_TIMES_LOG_SQRT_PI;
190 lp += delta_vec[
i] * alpha_vec[
i] * one_minus_beta
191 -
square(delta_vec[i]) * x * alpha2 / 2.0 -
log(alpha2) +
tmp;
196 template <
typename T_y,
typename T_alpha,
typename T_tau,
typename T_beta,
200 const T_beta&
beta,
const T_delta&
delta) {
201 return wiener_lpdf<false>(
y, alpha, tau,
beta,
delta);
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
T max(const caf::Proxy< T > &a, T b)
void check_finite(const char *function, const char *name, const T_y &y)
fvar< T > sqrt(const fvar< T > &x)
void check_bounded(const char *function, const char *name, const T_y &y, const T_low &low, const T_high &high)
fvar< T > log(const fvar< T > &x)
fvar< T > square(const fvar< T > &x)
const double SQRT_2_TIMES_SQRT_PI
fvar< T > sin(const fvar< T > &x)
fvar< T > exp(const fvar< T > &x)
void check_not_nan(const char *function, const char *name, const T_y &y)
return_type< T_y, T_alpha, T_tau, T_beta, T_delta >::type wiener_lpdf(const T_y &y, const T_alpha &alpha, const T_tau &tau, const T_beta &beta, const T_delta &delta)
size_t max_size(const T1 &x1, const T2 &x2)
void domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
fvar< T > floor(const fvar< T > &x)
void check_positive(const char *function, const char *name, const T_y &y)
void check_consistent_sizes(const char *function, const char *name1, const T1 &x1, const char *name2, const T2 &x2)
fvar< T > ceil(const fvar< T > &x)