typename boost::math::tools::promote_args<T_prob>::type categorical_logit_log(const std::vector<int>& ns, const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) { static const char* function("categorical_logit_log"); for (size_t k = 0; k < ns.size(); ++k) check_bounded(function, "categorical outcome out of support", ns[k], 1, beta.size()); check_finite(function, "log odds parameter", beta); if (!include_summand<propto, T_prob>::value) return 0.0; if (ns.size() == 0) return 0.0; Eigen::Matrix<T_prob, Eigen::Dynamic, 1> log_softmax_beta = log_softmax(beta); // FIXME: replace with more efficient sum() Eigen::Matrix<typename boost::math::tools::promote_args<T_prob>::type, Eigen::Dynamic, 1> results(ns.size()); for (size_t i = 0; i < ns.size(); ++i) results[i] = log_softmax_beta(ns[i] - 1); return sum(results); }
inline bool check_bounded(const char* function, const T_y& y, const T_low& low, const T_high& high, const char* name, T_result* result) { return check_bounded(function,y,low,high,name,result,default_policy()); }
typename boost::math::tools::promote_args<T_prob>::type categorical_logit_log(int n, const Eigen::Matrix<T_prob, Eigen::Dynamic, 1>& beta) { static const char* function("categorical_logit_log"); check_bounded(function, "categorical outcome out of support", n, 1, beta.size()); check_finite(function, "log odds parameter", beta); if (!include_summand<propto, T_prob>::value) return 0.0; // FIXME: wasteful vs. creating term (n-1) if not vectorized return beta(n-1) - log_sum_exp(beta); // == log_softmax(beta)(n-1); }