1 #ifndef STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_CHOLESKY_HPP
2 #define STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_CHOLESKY_HPP
4 #include <boost/random/normal_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
7 #include <boost/random/normal_distribution.hpp>
8 #include <boost/random/variate_generator.hpp>
50 template <
bool propto,
51 typename T_y,
typename T_loc,
typename T_covar>
52 typename boost::math::tools::promote_args<typename scalar_type<T_y>::type,
typename scalar_type<T_loc>::type, T_covar>::type
55 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
56 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
57 typedef typename boost::math::tools::promote_args<typename scalar_type<T_y>::type,
typename scalar_type<T_loc>::type, T_covar>::type lp_type;
76 int size_y = y_vec[0].size();
77 int size_mu = mu_vec[0].size();
79 int size_y_old = size_y;
82 int size_y_new = y_vec[i].size();
84 size_y_new,
"Size of one of the vectors of the random variable",
85 size_y_old,
"Size of another vector of the random variable",
87 size_y_old = size_y_new;
89 int size_mu_old = size_mu;
92 int size_mu_new = mu_vec[i].size();
94 size_mu_new,
"Size of one of the vectors of the location variable",
95 size_mu_old,
"Size of another vector of the location variable",
97 size_mu_old = size_mu_new;
106 size_y,
"Size of random variable",
107 size_mu,
"size of location parameter",
110 size_y,
"Size of random variable",
111 L.rows(),
"rows of covariance parameter",
114 size_y,
"Size of random variable",
115 L.cols(),
"columns of covariance parameter",
118 for (
size_t i = 0; i < size_vec; i++) {
119 check_finite(
function, mu_vec[i],
"Location parameter", &lp);
127 lp += NEG_LOG_SQRT_TWO_PI * size_y * size_vec;
130 lp -= L.diagonal().array().log().sum() * size_vec;
133 lp_type sum_lp_vec(0.0);
134 for (
size_t i = 0; i < size_vec; i++) {
135 Eigen::Matrix<
typename
136 boost::math::tools::promote_args<typename scalar_type<T_y>::type,
typename scalar_type<T_loc>::type>::type,
137 Eigen::Dynamic, 1> y_minus_mu(size_y);
138 for (
int j = 0; j < size_y; j++)
139 y_minus_mu(j) = y_vec[i](j)-mu_vec[i](j);
140 Eigen::Matrix<
typename
141 boost::math::tools::promote_args<T_covar,typename scalar_type<T_loc>::type,
typename scalar_type<T_y>::type>::type,
151 lp -= 0.5*sum_lp_vec;
156 template <
typename T_y,
typename T_loc,
typename T_covar>
158 typename boost::math::tools::promote_args<typename scalar_type<T_y>::type,
typename scalar_type<T_loc>::type, T_covar>::type
161 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
162 return multi_normal_cholesky_log<false>(y,mu,L);
166 inline Eigen::VectorXd
168 const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& S,
170 using boost::variate_generator;
171 using boost::normal_distribution;
173 static const char*
function =
"stan::prob::multi_normal_cholesky_rng(%1%)";
177 check_finite(
function, mu,
"Location parameter", (
double*)0);
179 variate_generator<RNG&, normal_distribution<> >
180 std_normal_rng(rng, normal_distribution<>(0,1));
182 Eigen::VectorXd z(S.cols());
183 for(
int i = 0; i < S.cols(); i++)
184 z(i) = std_normal_rng();
Eigen::Matrix< typename boost::math::tools::promote_args< T1, T2 >::type, R1, C2 > mdivide_left_tri_low(const Eigen::Matrix< T1, R1, C1 > &A, const Eigen::Matrix< T2, R2, C2 > &b)
fvar< T > dot_self(const Eigen::Matrix< fvar< T >, R, C > &v)
double dot_self(const std::vector< double > &x)
Eigen::VectorXd multi_normal_cholesky_rng(const Eigen::Matrix< double, Eigen::Dynamic, 1 > &mu, const Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > &S, RNG &rng)
size_t max_size_mvt(const T1 &x1, const T2 &x2)
boost::math::tools::promote_args< typename scalar_type< T_y >::type, typename scalar_type< T_loc >::type, T_covar >::type multi_normal_cholesky_log(const T_y &y, const T_loc &mu, const Eigen::Matrix< T_covar, Eigen::Dynamic, Eigen::Dynamic > &L)
The log of the multivariate normal density for the given y, mu, and a Cholesky factor L of the varian...
bool check_size_match(const char *function, T_size1 i, const char *name_i, T_size2 j, const char *name_j, T_result *result)
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is finite.
scalar_type_helper< is_vector< T >::value, T >::type type
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Eigen::Matrix< typename boost::math::tools::promote_args< T1, T2 >::type, R, C > subtract(const Eigen::Matrix< T1, R, C > &m1, const Eigen::Matrix< T2, R, C > &m2)
Return the result of subtracting the second specified matrix from the first specified matrix...
size_t length_mvt(const T &)
double sum(std::vector< double > &x)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
boost::enable_if_c< boost::is_arithmetic< T >::value, Eigen::Matrix< double, R, C > >::type multiply(const Eigen::Matrix< double, R, C > &m, T c)
Return specified matrix multiplied by specified scalar.
Eigen::Matrix< fvar< T >, R1, C1 > mdivide_left_tri_low(const Eigen::Matrix< fvar< T >, R1, C1 > &A, const Eigen::Matrix< fvar< T >, R2, C2 > &b)