1#ifndef STAN_MATH_PRIM_PROB_CATEGORICAL_LOGIT_LPMF_HPP
2#define STAN_MATH_PRIM_PROB_CATEGORICAL_LOGIT_LPMF_HPP
35template <
bool propto,
typename T_prob, require_col_vector_t<T_prob>* =
nullptr>
37 static constexpr const char* function =
"categorical_logit_lpmf";
38 check_bounded(function,
"categorical outcome out of support", n, 1,
43 if constexpr (is_constant_v<T_prob>) {
46 check_greater(function,
"log odds parameter", beta_ref.maxCoeff(),
59 if constexpr (is_constant_v<T_prob>) {
60 int num_infty = (beta_ref.array() ==
INFTY).count();
62 return beta_ref.coeff(n - 1) ==
INFTY ? -std::log(num_infty)
68 return beta_ref.coeff(n - 1)
95template <
bool propto,
typename T_prob, require_col_vector_t<T_prob>* =
nullptr>
98 static constexpr const char* function =
"categorical_logit_lpmf";
100 check_bounded(function,
"categorical outcome out of support", ns, 1,
105 if (beta_ref.size() == 0) {
110 if constexpr (is_constant_v<T_prob>) {
113 check_greater(function,
"log odds parameter", beta_ref.maxCoeff(),
130 if constexpr (is_constant_v<T_prob>) {
131 int num_infty = (beta_ref.array() ==
INFTY).count();
135 if (beta_ref.coeff(n - 1) !=
INFTY) {
138 lp -= std::log(num_infty);
147 Eigen::Matrix<return_type_t<T_prob>, Eigen::Dynamic, 1>
results(ns.size());
148 for (
size_t i = 0; i < ns.size(); ++i) {
149 results[i] = log_softmax_beta(ns[i] - 1);
154template <
typename T_n,
typename T_prob, require_st_
integral<T_n>* =
nullptr,
155 require_col_vector_t<T_prob>* =
nullptr>
157 const T_prob&
beta) {
158 return categorical_logit_lpmf<false>(ns,
beta);
return_type_t< T_prob > categorical_logit_lpmf(int n, const T_prob &beta)
Categorical log PMF in log-odds parametrization.
results_cl< T_results... > results(T_results &&... results)
Deduces types for constructing results_cl object.
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
void check_bounded(const char *function, const char *name, const T_y &y, const T_low &low, const T_high &high)
Check if the value is between the low and high values, inclusively.
static constexpr double NEGATIVE_INFTY
Negative infinity.
void check_finite(const char *function, const char *name, const T_y &y)
Return true if all values in y are finite.
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
auto log_softmax(T &&x)
Return the log softmax of each vector in a container of fvar values.
auto sum(const std::vector< T > &m)
Return the sum of the entries of the specified standard vector.
ref_type_t< T && > to_ref(T &&a)
This evaluates expensive Eigen expressions.
fvar< T > beta(const fvar< T > &x1, const fvar< T > &x2)
Return fvar with the beta function applied to the specified arguments and its gradient.
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.
static constexpr double INFTY
Positive infinity.
fvar< T > log_sum_exp(const fvar< T > &x1, const fvar< T > &x2)
typename ref_type_if< true, T >::type ref_type_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...