1#ifndef STAN_MATH_PRIM_PROB_WIENER5_LPDF_HPP
2#define STAN_MATH_PRIM_PROB_WIENER5_LPDF_HPP
29template <
typename T_y,
typename T_a,
typename T_v,
typename T_w,
typename T_sv>
32 const auto one_m_w = 1.0 - w;
33 const auto neg_v = -v;
34 const auto sv_sqr =
square(sv);
35 const auto one_plus_svsqr_y = 1 + sv_sqr * y;
36 const auto two_avw = 2.0 * a * neg_v * one_m_w;
37 const auto two_log_a = 2.0 *
log(a);
39 (sv_sqr *
square(a * one_m_w) - two_avw -
square(neg_v) * y) / 2.0
41 - two_log_a - 0.5 *
log(one_plus_svsqr_y));
60template <
bool Density,
GradientCalc GradW,
typename T_y,
typename T_a,
61 typename T_w,
typename T_err>
63 T_err error)
noexcept {
64 const auto two_error = 2.0 * error;
65 const auto y_asq = y /
square(a);
66 const auto two_log_a = 2.0 *
log(a);
67 const auto log_y_asq =
log(y) - two_log_a;
68 const auto one_m_w = 1.0 - w;
70 constexpr auto n_1_factor = Density ? 2.0 : 3.0;
71 const auto n_1 = (
sqrt(n_1_factor * y_asq) + one_m_w) / 2.0;
72 auto u_eps = (Density || GradW)
76 const auto arg_mult = (Density || GradW) ? 1 : 3;
77 const auto arg = -arg_mult * y_asq * (u_eps -
sqrt(-2.0 * u_eps - 2.0));
79 const auto n_2 = (
arg > 0) ? GradW ? 0.5 * (
sqrt(
arg) + one_m_w)
100template <
typename T_y,
typename T_a,
typename T_w,
typename T_err>
102 T_err error)
noexcept {
103 const auto y_asq = y /
square(a);
104 const auto log_y_asq =
log(y) - 2.0 *
log(a);
105 static constexpr double PI_SQUARED =
pi() *
pi();
106 auto n_1 = 1.0 / (
pi() *
sqrt(y_asq));
107 const auto two_log_piy = -2.0 * (
LOG_PI + log_y_asq + error);
109 = (two_log_piy >= 0) ?
sqrt(two_log_piy / (PI_SQUARED * y_asq)) : 0.0;
128template <
GradientCalc GradW,
typename T_y,
typename T_a,
typename T_w,
132 T_err error)
noexcept {
133 const auto y_asq = y /
square(a);
134 const auto log_y_asq =
log(y) - 2.0 *
log(a);
135 static constexpr double PI_SQUARED =
pi() *
pi();
136 static constexpr auto n_1_factor = GradW ? 2.0 : 3.0;
137 auto n_1 =
sqrt(n_1_factor / y_asq) /
pi();
138 const auto two_error = 2.0 * error;
140 = GradW ?
log(4.0) -
log(9.0) + 2.0 *
LOG_PI + 3.0 * log_y_asq + two_error
141 :
log(3.0) -
log(5.0) +
LOG_PI + 2.0 * log_y_asq + error;
142 const auto u_eps =
fmin(-1, u_eps_arg);
143 if constexpr (GradW) {
144 const auto arg = -(u_eps -
sqrt(-2.0 * u_eps - 2.0));
149 = -(2.0 / PI_SQUARED / y_asq) * (u_eps -
sqrt(-2.0 * u_eps - 2.0));
173template <
bool Density,
GradientCalc GradW,
typename T_y,
typename T_a,
174 typename T_w,
typename T_nsmall,
typename T_nlarge>
176 T_nsmall&& n_terms_small_t,
177 T_nlarge&& n_terms_large_t)
noexcept {
180 const auto y_asq = y /
square(a);
181 const auto one_m_w = 1.0 - w;
182 const bool small_n_terms_small_t
183 = Density ? (2.0 * n_terms_small_t <= n_terms_large_t)
184 : (2.0 * n_terms_small_t < n_terms_large_t);
185 const auto scaling = small_n_terms_small_t ?
inv(2.0 * y_asq) : y_asq / 2.0;
189 if (small_n_terms_small_t) {
190 constexpr double mult = Density ? 1.0 : 3.0;
191 if constexpr (GradW) {
192 for (
auto k = n_terms_small_t; k >= 1; k--) {
193 const auto w_plus_2_k = one_m_w + 2.0 * k;
194 const auto w_minus_2_k = one_m_w - 2.0 * k;
195 const auto square_w_plus_2_k_minus_offset =
square(w_plus_2_k) - y_asq;
196 if (square_w_plus_2_k_minus_offset > 0) {
197 const auto summand_plus =
log(square_w_plus_2_k_minus_offset)
198 -
square(w_plus_2_k) * scaling;
200 }
else if (square_w_plus_2_k_minus_offset < 0) {
201 const auto summand_plus =
log(-square_w_plus_2_k_minus_offset)
202 -
square(w_plus_2_k) * scaling;
205 const auto square_w_minus_2_k_minus_offset
206 =
square(w_minus_2_k) - y_asq;
207 if (square_w_minus_2_k_minus_offset > 0) {
208 const auto summand_minus =
log(square_w_minus_2_k_minus_offset)
209 -
square(w_minus_2_k) * scaling;
211 }
else if (square_w_minus_2_k_minus_offset < 0) {
212 const auto summand_minus =
log(-square_w_minus_2_k_minus_offset)
213 -
square(w_minus_2_k) * scaling;
217 const auto square_w_minus_offset =
square(one_m_w) - y_asq;
218 if (square_w_minus_offset > 0) {
220 =
log(square_w_minus_offset) -
square(one_m_w) * scaling;
222 }
else if (square_w_minus_offset < 0) {
224 =
log(-square_w_minus_offset) -
square(one_m_w) * scaling;
228 for (
auto k = n_terms_small_t; k >= 1; k--) {
229 const auto w_plus_2_k = one_m_w + 2.0 * k;
230 const auto w_minus_2_k = one_m_w - 2.0 * k;
231 const auto summand_plus
232 = mult *
log(w_plus_2_k) -
square(w_plus_2_k) * scaling;
234 const auto summand_minus
235 = mult *
log(-w_minus_2_k) -
square(w_minus_2_k) * scaling;
237 fminus = summand_minus;
240 }
else if (fminus > summand_minus) {
241 fminus = fminus +
log1p_exp(summand_minus - fminus);
243 fminus = summand_minus +
log1p_exp(fminus - summand_minus);
246 const auto new_val = mult *
log(one_m_w) -
square(one_m_w) * scaling;
250 constexpr double mult = (Density ? 1.0 : (GradW ? 2.0 : 3.0));
251 for (
auto k = n_terms_large_t; k >= 1; k--) {
252 const auto pi_k = k *
pi();
253 const auto check = (GradW) ?
cos(pi_k * one_m_w) :
sin(pi_k * one_m_w);
256 fplus, mult *
log(k) -
square(pi_k) * scaling +
log(check));
257 }
else if ((GradW && check < 0) || !GradW) {
259 fminus, mult *
log(k) -
square(pi_k) * scaling +
log(-check));
263 current_sign = (fplus < fminus) ? -1 : 1;
265 return std::make_pair(fminus, current_sign);
267 return std::make_pair(fplus, current_sign);
268 }
else if (fplus > fminus) {
269 return std::make_pair(
log_diff_exp(fplus, fminus), current_sign);
270 }
else if (fplus < fminus) {
271 return std::make_pair(
log_diff_exp(fminus, fplus), current_sign);
298template <
bool NaturalScale =
false,
typename T_y,
typename T_a,
typename T_w,
299 typename T_v,
typename T_sv,
typename T_err>
301 const T_w& w,
const T_sv& sv,
302 T_err log_err =
log(1
e-12)) noexcept {
304 const auto log_error = (log_err - log_error_term);
305 const auto n_terms_small_t
306 = wiener5_n_terms_small_t<GradientCalc::ON, GradientCalc::OFF>(y, a, w,
308 const auto n_terms_large_t
311 auto res = wiener5_log_sum_exp<GradientCalc::ON, GradientCalc::OFF>(
312 y, a, w, n_terms_small_t, n_terms_large_t)
314 if (2 * n_terms_small_t <= n_terms_large_t) {
316 - 1.5 * (
log(y) - 2.0 *
log(a)) + res;
317 return NaturalScale ?
exp(log_density) : log_density;
319 auto log_density = log_error_term + res +
LOG_PI;
320 return NaturalScale ?
exp(log_density) : log_density;
345template <
bool WrtLog =
false,
typename T_y,
typename T_a,
typename T_w,
346 typename T_v,
typename T_sv,
typename T_err>
348 const T_w& w,
const T_sv& sv,
349 T_err log_err =
log(1
e-12)) noexcept {
350 const auto two_log_a = 2.0 *
log(a);
351 const auto log_y_asq =
log(y) - two_log_a;
353 const auto one_m_w = 1.0 - w;
354 const auto neg_v = -v;
355 const auto sv_sqr =
square(sv);
356 const auto one_plus_svsqr_y = 1 + sv_sqr * y;
357 const auto density_part_one
360 + sv_sqr * (1.0 - (2.0 * a * neg_v * one_m_w)) +
square(neg_v))
361 /
square(one_plus_svsqr_y);
362 const auto log_error = (log_err - log_error_term) + two_log_a;
363 const auto n_terms_small_t
364 = wiener5_n_terms_small_t<GradientCalc::OFF, GradientCalc::OFF>(
366 const auto n_terms_large_t
367 = wiener5_gradient_large_reaction_time_terms<GradientCalc::OFF>(
369 auto wiener_res = wiener5_log_sum_exp<GradientCalc::OFF, GradientCalc::OFF>(
370 y, a, w, n_terms_small_t, n_terms_large_t);
371 auto&& result = wiener_res.first;
372 auto&& newsign = wiener_res.second;
373 const auto error_log_density
375 const auto log_density = wiener5_density<GradientCalc::OFF>(
376 y, a, v, w, sv, log_err - error_log_density);
377 if (2.0 * n_terms_small_t < n_terms_large_t) {
379 = density_part_one - 1.5 / y
382 - 3.5 * log_y_asq + result - log_density);
383 return WrtLog ? ans *
exp(log_density) : ans;
385 auto ans = density_part_one
388 + result - log_density);
389 return WrtLog ? ans *
exp(log_density) : ans;
414template <
bool WrtLog =
false,
typename T_y,
typename T_a,
typename T_w,
415 typename T_v,
typename T_sv,
typename T_err>
417 const T_w& w,
const T_sv& sv,
418 T_err log_err =
log(1
e-12)) noexcept {
419 const auto two_log_a = 2.0 *
log(a);
421 const auto one_m_w = 1.0 - w;
422 const auto sv_sqr =
square(sv);
423 const auto one_plus_svsqr_y = 1.0 + sv_sqr * y;
424 const auto density_part_one
425 = (v * one_m_w + sv_sqr *
square(one_m_w) * a) / one_plus_svsqr_y;
427 = log_err - log_error_term + 3.0 *
log(a) -
log(y) -
LOG_TWO;
429 const auto n_terms_small_t
430 = wiener5_n_terms_small_t<GradientCalc::OFF, GradientCalc::OFF>(
432 const auto n_terms_large_t
433 = wiener5_gradient_large_reaction_time_terms<GradientCalc::OFF>(
435 auto wiener_res = wiener5_log_sum_exp<GradientCalc::OFF, GradientCalc::OFF>(
436 y, a, w, n_terms_small_t, n_terms_large_t);
437 auto&& result = wiener_res.first;
438 auto&& newsign = wiener_res.second;
439 const auto log_error_log_density =
log(
440 fmax(
fabs(density_part_one + 1.0 / a),
fabs(density_part_one - 2.0 / a)));
441 const auto log_density = wiener5_density<GradientCalc::OFF>(
442 y, a, v, w, sv, log_err - log_error_log_density);
443 if (2.0 * n_terms_small_t < n_terms_large_t) {
444 auto ans = density_part_one + 1.0 / a
447 + 2.0 * two_log_a + log_error_term + result
449 return WrtLog ? ans *
exp(log_density) : ans;
451 auto ans = density_part_one - 2.0 / a
454 + result - log_density);
455 return WrtLog ? ans *
exp(log_density) : ans;
480template <
bool WrtLog =
false,
typename T_y,
typename T_a,
typename T_w,
481 typename T_v,
typename T_sv,
typename T_err>
483 const T_w& w,
const T_sv& sv,
484 T_err log_err =
log(1
e-12)) noexcept {
485 auto ans = (a * (1 - w) - v * y) / (1.0 +
square(sv) * y);
486 if constexpr (WrtLog) {
487 return ans * wiener5_density<true>(y, a, v, w, sv, log_err);
514template <
bool WrtLog =
false,
typename T_y,
typename T_a,
typename T_w,
515 typename T_v,
typename T_sv,
typename T_err>
517 const T_w& w,
const T_sv& sv,
518 T_err log_err =
log(1
e-12)) noexcept {
519 const auto two_log_a = 2.0 *
log(a);
520 const auto log_y_asq =
log(y) - two_log_a;
522 const auto one_m_w = 1.0 - w;
523 const auto sv_sqr =
square(sv);
524 const auto one_plus_svsqr_y = 1.0 + sv_sqr * y;
525 const auto density_part_one
526 = (v * a + sv_sqr *
square(a) * one_m_w) / one_plus_svsqr_y;
527 const auto log_error = (log_err - log_error_term);
529 const auto n_terms_small_t
530 = wiener5_n_terms_small_t<GradientCalc::OFF, GradientCalc::ON>(y, a, w,
532 const auto n_terms_large_t
533 = wiener5_gradient_large_reaction_time_terms<GradientCalc::ON>(y, a, w,
535 auto wiener_res = wiener5_log_sum_exp<GradientCalc::OFF, GradientCalc::ON>(
536 y, a, w, n_terms_small_t, n_terms_large_t);
537 auto&& result = wiener_res.first;
538 auto&& newsign = wiener_res.second;
539 const auto log_density = wiener5_density<GradientCalc::OFF>(
540 y, a, v, w, sv, log_err -
log(
fabs(density_part_one)));
541 if (2.0 * n_terms_small_t < n_terms_large_t) {
542 auto ans = -(density_part_one
544 *
exp(result - (log_density - log_error_term)
546 return WrtLog ? ans *
exp(log_density) : ans;
551 *
exp(result - (log_density - log_error_term) + 2.0 *
LOG_PI));
552 return WrtLog ? ans *
exp(log_density) : ans;
577template <
bool WrtLog =
false,
typename T_y,
typename T_a,
typename T_w,
578 typename T_v,
typename T_sv,
typename T_err>
580 const T_w& w,
const T_sv& sv,
581 T_err log_err =
log(1
e-12)) noexcept {
582 const auto one_plus_svsqr_y = 1.0 +
square(sv) * y;
583 const auto one_m_w = 1.0 - w;
584 const auto neg_v = -v;
585 const auto t1 = -y / one_plus_svsqr_y;
586 const auto t2 = (
square(a * one_m_w) + 2.0 * a * neg_v * one_m_w * y
588 /
square(one_plus_svsqr_y);
589 const auto ans = sv * (t1 + t2);
590 return WrtLog ? ans * wiener5_density<true>(y, a, v, w, sv, log_err) : ans;
603template <
size_t NestedIndex,
typename Scalar1,
typename Scalar2>
619template <
size_t NestedIndex,
typename Scalar,
typename... TArgs>
620inline void assign_err(std::tuple<TArgs...>& args_tuple, Scalar err) {
621 std::get<NestedIndex>(args_tuple) = err;
641template <
int ErrIndex,
size_t NestedIndex = 0,
643 typename F,
typename T_err,
typename... ArgsTupleT>
645 ArgsTupleT&&... args_tuple) {
646 auto result = functor(args_tuple...);
647 auto log_fabs_result = LogResult ?
log(
fabs(result)) :
fabs(result);
648 if (log_fabs_result < log_err) {
649 log_fabs_result =
is_inf(log_fabs_result) ? 0 : log_fabs_result;
650 auto err_args_tuple = std::make_tuple(args_tuple...);
651 const auto new_error = GradW7 ? log_err + log_fabs_result +
LOG_TWO
652 : log_err + log_fabs_result;
653 if constexpr (NestedIndex != -1) {
654 assign_err<NestedIndex>(std::get<ErrIndex>(err_args_tuple), new_error);
657 =
math::apply([](
auto&& func,
auto&&... args) {
return func(args...); },
658 err_args_tuple, functor);
686template <
bool propto =
false,
typename T_y,
typename T_a,
typename T_t0,
687 typename T_w,
typename T_v,
typename T_sv>
688inline auto wiener_lpdf(
const T_y& y,
const T_a& a,
const T_t0& t0,
689 const T_w& w,
const T_v& v,
const T_sv& sv,
690 const double& precision_derivatives = 1
e-4) {
703 T_t0_ref t0_ref = t0;
706 T_sv_ref sv_ref = sv;
720 static constexpr const char* function_name =
"wiener5_lpdf";
723 "Boundary separation", a,
"Drift rate", v,
724 "A-priori bias", w,
"Nondecision time", t0,
725 "Inter-trial variability in drift rate", sv);
729 check_less(function_name,
"A-priori bias", w_val, 1);
732 check_finite(function_name,
"Nondecision time", t0_val);
735 check_finite(function_name,
"Inter-trial variability in drift rate", sv_val);
740 const size_t N =
max_size(y, a, t0, w, v, sv);
751 const size_t N_y_t0 =
max_size(y, t0);
753 for (
size_t i = 0; i < N_y_t0; ++i) {
754 if (y_vec[i] <= t0_vec[i]) {
755 std::stringstream msg;
756 msg <<
", but must be greater than nondecision time = " << t0_vec[i];
757 std::string msg_str(msg.str());
764 const auto log_error_density =
log(1
e-6);
765 const auto log_error_derivative =
log(precision_derivatives);
766 const double log_error_absolute_val =
log(1
e-12);
767 const T_partials_return log_error_absolute = log_error_absolute_val;
768 T_partials_return log_density = 0.0;
772 const double LOG_FOUR = std::log(4.0);
775 for (
size_t i = 0; i < N; i++) {
780 const auto y_value = y_vec.val(i);
781 const auto a_value = a_vec.val(i);
782 const auto t0_value = t0_vec.val(i);
783 const auto w_value = w_vec.val(i);
784 const auto v_value = v_vec.val(i);
785 const auto sv_value = sv_vec.val(i);
789 return internal::wiener5_density<GradientCalc::OFF>(args...);
791 log_error_density -
LOG_TWO, y_value - t0_value, a_value, v_value,
792 w_value, sv_value, log_error_absolute);
794 log_density += l_density;
796 const auto new_est_err = l_density + log_error_derivative - LOG_FOUR;
805 return internal::wiener5_grad_t<GradientCalc::OFF>(args...);
807 new_est_err, y_value - t0_value, a_value, v_value, w_value,
808 sv_value, log_error_absolute);
811 if constexpr (is_autodiff_v<T_y>) {
812 partials<0>(ops_partials)[i] = deriv_y;
814 if constexpr (is_autodiff_v<T_a>) {
815 partials<1>(ops_partials)[i]
819 return internal::wiener5_grad_a<GradientCalc::OFF>(args...);
821 new_est_err, y_value - t0_value, a_value, v_value, w_value,
822 sv_value, log_error_absolute);
824 if constexpr (is_autodiff_v<T_t0>) {
825 partials<2>(ops_partials)[i] = -deriv_y;
827 if constexpr (is_autodiff_v<T_w>) {
828 partials<3>(ops_partials)[i]
832 return internal::wiener5_grad_w<GradientCalc::OFF>(args...);
834 new_est_err, y_value - t0_value, a_value, v_value, w_value,
835 sv_value, log_error_absolute);
837 if constexpr (is_autodiff_v<T_v>) {
838 partials<4>(ops_partials)[i]
839 = internal::wiener5_grad_v<GradientCalc::OFF>(
840 y_value - t0_value, a_value, v_value, w_value, sv_value,
841 log_error_absolute_val);
843 if constexpr (is_autodiff_v<T_sv>) {
844 partials<5>(ops_partials)[i]
845 = internal::wiener5_grad_sv<GradientCalc::OFF>(
846 y_value - t0_value, a_value, v_value, w_value, sv_value,
847 log_error_absolute_val);
850 return ops_partials.build(log_density);
scalar_seq_view provides a uniform sequence-like wrapper around either a scalar or a sequence of scal...
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
auto wiener5_density(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the wiener5 density.
auto wiener5_grad_v(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the derivative of the wiener5 density w.r.t.
auto wiener5_log_sum_exp(T_y &&y, T_a &&a, T_w &&w, T_nsmall &&n_terms_small_t, T_nlarge &&n_terms_large_t) noexcept
Calculate the 'result' term and its sign for a wiener5 density or gradient.
auto estimate_with_err_check(F &&functor, T_err &&log_err, ArgsTupleT &&... args_tuple)
Utility function for estimating a function with a given set of arguments, checking the result against...
auto wiener5_gradient_large_reaction_time_terms(T_y &&y, T_a &&a, T_w &&w, T_err error) noexcept
Calculate the 'n_terms_large_t' term for a wiener5 gradient.
auto wiener5_density_large_reaction_time_terms(T_y &&y, T_a &&a, T_w &&w, T_err error) noexcept
Calculate the 'n_terms_large_t' term for a wiener5 density.
auto wiener5_grad_t(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the derivative of the wiener5 density w.r.t.
auto wiener5_grad_w(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the derivative of the wiener5 density w.r.t.
void assign_err(Scalar1 arg, Scalar2 err)
Utility function for replacing a value with a specified error value.
auto wiener5_grad_a(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the derivative of the wiener5 density w.r.t.
auto wiener5_grad_sv(const T_y &y, const T_a &a, const T_v &v, const T_w &w, const T_sv &sv, T_err log_err=log(1e-12)) noexcept
Calculate the derivative of the wiener5 density w.r.t.
auto wiener5_n_terms_small_t(T_y &&y, T_a &&a, T_w &&w, T_err error) noexcept
Calculate the 'n_terms_small_t' term for a wiener5 density or gradient.
auto wiener5_compute_log_error_term(T_y &&y, T_a &&a, T_v &&v, T_w &&w, T_sv &&sv) noexcept
Calculate the 'log_error_term' term for a wiener5 density or gradient.
fvar< T > sin(const fvar< T > &x)
void check_nonnegative(const char *function, const char *name, const T_y &y)
Check if y is non-negative.
bool size_zero(const T &x)
Returns 1 if input is of length 0, returns 0 otherwise.
fvar< T > fmin(const fvar< T > &x1, const fvar< T > &x2)
static constexpr double e()
Return the base of the natural logarithm.
fvar< T > arg(const std::complex< fvar< T > > &z)
Return the phase angle of the complex argument.
T eval(T &&arg)
Inputs which have a plain_type equal to the own time are forwarded unmodified (for Eigen expressions ...
fvar< T > log(const fvar< T > &x)
static constexpr double NEGATIVE_INFTY
Negative infinity.
void throw_domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw a domain error with a consistently formatted message.
static constexpr double LOG_TWO
The natural logarithm of 2, .
fvar< T > log1p_exp(const fvar< T > &x)
auto as_value_column_array_or_scalar(T &&a)
Extract the value from an object and for eigen vectors and std::vectors convert to an eigen column ar...
void check_consistent_sizes(const char *)
Trivial no input case, this function is a no-op.
fvar< T > sqrt(const fvar< T > &x)
static constexpr double LOG_SQRT_PI
The natural logarithm of the square root of , .
static constexpr double LOG_PI
The natural logarithm of , .
void check_finite(const char *function, const char *name, const T_y &y)
Return true if all values in y are finite.
fvar< T > fmax(const fvar< T > &x1, const fvar< T > &x2)
Return the greater of the two specified arguments.
fvar< T > log_diff_exp(const fvar< T > &x1, const fvar< T > &x2)
fvar< T > cos(const fvar< T > &x)
static constexpr double pi()
Return the value of pi.
auto wiener_lpdf(const T_y &y, const T_a &a, const T_t0 &t0, const T_w &w, const T_v &v, const T_sv &sv, const double &precision_derivatives=1e-4)
Log-density function for the 5-parameter Wiener density.
int is_inf(const fvar< T > &x)
Returns 1 if the input's value is infinite and 0 otherwise.
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
void check_less(const char *function, const char *name, const T_y &y, const T_high &high, Idxs... idxs)
Throw an exception if y is not strictly less than high.
fvar< T > ceil(const fvar< T > &x)
int64_t max_size(const T1 &x1, const Ts &... xs)
Calculate the size of the largest input.
void check_greater(const char *function, const char *name, const T_y &y, const T_low &low, Idxs... idxs)
Throw an exception if y is not strictly greater than low.
fvar< T > inv(const fvar< T > &x)
auto make_partials_propagator(Ops &&... ops)
Construct an partials_propagator.
constexpr decltype(auto) apply(F &&f, Tuple &&t, PreArgs &&... pre_args)
void check_positive_finite(const char *function, const char *name, const T_y &y)
Check if y is positive and finite.
fvar< T > fabs(const fvar< T > &x)
fvar< T > square(const fvar< T > &x)
fvar< T > log_sum_exp(const fvar< T > &x1, const fvar< T > &x2)
fvar< T > exp(const fvar< T > &x)
typename ref_type_if< true, T >::type ref_type_t
typename partials_return_type< Args... >::type partials_return_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...