1#ifndef STAN_MATH_PRIM_CONSTRAINT_SIMPLEX_CONSTRAIN_HPP
2#define STAN_MATH_PRIM_CONSTRAINT_SIMPLEX_CONSTRAIN_HPP
32template <
typename Vec, require_eigen_vector_t<Vec>* =
nullptr,
33 require_not_st_var<Vec>* =
nullptr>
36 const auto N = y.size();
51 for (
int i = N; i > 0; --i) {
52 double n =
static_cast<double>(i);
53 auto w = y_ref(i - 1) *
inv_sqrt(n * (n + 1));
56 z.coeffRef(i - 1) += sum_w;
57 z.coeffRef(i) -= w * n;
59 max_val =
fmax(max_val_old, z.coeff(i));
60 d = d *
exp(max_val_old - max_val) +
exp(z.coeff(i) - max_val);
61 max_val_old = max_val;
65 max_val =
fmax(max_val_old, z.coeff(0));
66 d = d *
exp(max_val_old - max_val) +
exp(z.coeff(0) - max_val);
68 z.array() = (z.array() - max_val).
exp() / d;
91template <
typename Vec,
typename Lp, require_eigen_vector_t<Vec>* =
nullptr,
92 require_not_st_var<Vec>* =
nullptr,
93 require_convertible_t<value_type_t<Vec>, Lp>* =
nullptr>
97 const auto N = y.size();
112 for (
int i = N; i > 0; --i) {
113 double n =
static_cast<double>(i);
114 auto w = y_ref(i - 1) *
inv_sqrt(n * (n + 1));
117 z.coeffRef(i - 1) += sum_w;
118 z.coeffRef(i) -= w * n;
120 max_val =
fmax(max_val_old, z.coeff(i));
121 d = d *
exp(max_val_old - max_val) +
exp(z.coeff(i) - max_val);
122 max_val_old = max_val;
126 max_val =
fmax(max_val_old, z.coeff(0));
127 d = d *
exp(max_val_old - max_val) +
exp(z.coeff(0) - max_val);
129 z.array() = (z.array() - max_val).
exp() / d;
132 lp += -(N + 1) * (max_val +
log(d)) + 0.5 *
log(N + 1);
147template <
typename T, require_std_vector_t<T>* =
nullptr>
166template <
typename T,
typename Lp, require_std_vector_t<T>* =
nullptr,
167 require_convertible_t<return_type_t<T>, Lp>* =
nullptr>
191template <
bool Jacobian,
typename Vec,
typename Lp,
194 if constexpr (Jacobian) {
require_t< std::is_convertible< std::decay_t< T >, std::decay_t< S > > > require_convertible_t
Require types T and S satisfies std::is_convertible.
typename value_type< T >::type value_type_t
Helper function for accessing underlying type.
static constexpr double negative_infinity()
Return negative infinity.
fvar< T > log(const fvar< T > &x)
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
fvar< T > fmax(const fvar< T > &x1, const fvar< T > &x2)
Return the greater of the two specified arguments.
plain_type_t< Vec > simplex_constrain(const Vec &y)
Return the simplex corresponding to the specified free vector.
fvar< T > inv_sqrt(const fvar< T > &x)
fvar< T > exp(const fvar< T > &x)
typename plain_type< T >::type plain_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...