1#ifndef STAN_MATH_PRIM_PROB_HMM_LATENT_RNG_HPP
2#define STAN_MATH_PRIM_PROB_HMM_LATENT_RNG_HPP
8#include <boost/random.hpp>
41template <
typename T_omega,
typename T_Gamma,
typename T_rho,
class RNG,
42 require_all_eigen_t<T_omega, T_Gamma>* =
nullptr,
43 require_eigen_col_vector_t<T_rho>* =
nullptr>
45 const T_Gamma& Gamma,
const T_rho& rho,
47 int n_states = log_omegas.rows();
48 int n_transitions = log_omegas.cols() - 1;
50 Eigen::MatrixXd omegas =
value_of(log_omegas).array().exp();
53 hmm_check(log_omegas, Gamma_dbl, rho_dbl,
"hmm_latent_rng");
55 Eigen::MatrixXd alphas(n_states, n_transitions + 1);
56 alphas.col(0) = omegas.col(0).cwiseProduct(rho_dbl);
57 alphas.col(0) /= alphas.col(0).maxCoeff();
59 for (
int n = 0; n < n_transitions; ++n) {
61 = omegas.col(n + 1).cwiseProduct(Gamma_dbl.transpose() * alphas.col(n));
62 alphas.col(n + 1) /= alphas.col(n + 1).maxCoeff();
65 Eigen::VectorXd
beta = Eigen::VectorXd::Ones(n_states);
68 std::vector<int> hidden_states(n_transitions + 1);
69 std::vector<double> probs(n_states);
70 Eigen::Map<Eigen::VectorXd> probs_vec(probs.data(), n_states);
71 probs_vec = alphas.col(n_transitions) / alphas.col(n_transitions).sum();
72 boost::random::discrete_distribution<> cat_hidden(probs);
75 for (
int n = n_transitions; n-- > 0;) {
80 probs_vec = alphas.col(n).cwiseProduct(Gamma_dbl.col(last_hs))
81 *
beta(last_hs) * omegas(last_hs, n + 1);
83 probs_vec /= probs_vec.sum();
87 boost::random::discrete_distribution<> cat_hidden(probs);
91 beta = Gamma_dbl * (omegas.col(n + 1).cwiseProduct(
beta));
std::vector< int > hmm_latent_rng(const T_omega &log_omegas, const T_Gamma &Gamma, const T_rho &rho, RNG &rng)
For a hidden Markov model with observation y, hidden state x, and parameters theta,...
T value_of(const fvar< T > &v)
Return the value of the specified variable.
void hmm_check(const T_omega &log_omegas, const T_Gamma &Gamma, const T_rho &rho, const char *function)
Check arguments for hidden Markov model functions with a discrete latent state (lpdf,...
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.
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 ...