1 #ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP__
32 template <
bool propto,
33 typename T_y,
typename T_loc,
typename T_covar,
35 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
37 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
38 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
40 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
51 using boost::math::tools::promote_args;
53 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
61 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
63 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
70 lp += NEG_LOG_SQRT_TWO_PI * y.rows();
73 lp -= L.diagonal().array().log().sum();
76 Eigen::Matrix<
typename
77 boost::math::tools::promote_args<T_y,T_loc>::type,
78 Eigen::Dynamic, 1> y_minus_mu(y.size());
79 for (
int i = 0; i < y.size(); i++)
80 y_minus_mu(i) = y(i)-mu(i);
81 Eigen::Matrix<
typename
82 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
95 template <
bool propto,
96 typename T_y,
typename T_loc,
typename T_covar>
98 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
100 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
101 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
102 return multi_normal_cholesky_log<propto>(y,mu,L,
106 template <
typename T_y,
typename T_loc,
typename T_covar,
109 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
111 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
112 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
114 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
117 template <
typename T_y,
typename T_loc,
typename T_covar>
119 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
121 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
122 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
123 return multi_normal_cholesky_log<false>(y,mu,L,
129 template <
bool propto,
130 typename T_y,
typename T_loc,
typename T_covar,
132 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
134 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
135 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
137 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
148 using boost::math::tools::promote_args;
150 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
158 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
160 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
167 lp += NEG_LOG_SQRT_TWO_PI * y.cols() * y.rows();
170 lp -= L.diagonal().array().log().sum() * y.rows();
173 Eigen::Matrix<T_loc, Eigen::Dynamic, Eigen::Dynamic> MU(y.rows(),y.cols());
177 Eigen::Matrix<typename boost::math::tools::promote_args<T_loc,T_y>::type,
178 Eigen::Dynamic,Eigen::Dynamic>
179 y_minus_MU(y.rows(), y.cols());
180 for (
int i = 0; i < y.size(); i++)
181 y_minus_MU(i) = y(i)-MU(i);
182 Eigen::Matrix<
typename
183 boost::math::tools::promote_args<T_loc,T_y>::type,
184 Eigen::Dynamic,Eigen::Dynamic>
185 z(y_minus_MU.transpose());
193 Eigen::Matrix<
typename
194 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
195 Eigen::Dynamic,Eigen::Dynamic>
203 template <
bool propto,
204 typename T_y,
typename T_loc,
typename T_covar>
206 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
208 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
209 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
210 return multi_normal_cholesky_log<propto>(y,mu,L,
214 template <
typename T_y,
typename T_loc,
typename T_covar,
217 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
219 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
220 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
222 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
225 template <
typename T_y,
typename T_loc,
typename T_covar>
227 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
229 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
230 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
231 return multi_normal_cholesky_log<false>(y,mu,L,
254 template <
bool propto,
255 typename T_y,
typename T_loc,
typename T_covar,
257 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
259 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
260 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
262 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
263 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
271 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
273 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
276 Eigen::LLT< Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> > LLT = Sigma.llt();
277 if (LLT.info() != Eigen::Success) {
278 lp = stan::math::policies::raise_domain_error<T_covar>(
function,
279 "Covariance matrix is not positive definite (%1%)",
283 Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> L(LLT.matrixL());
284 return multi_normal_cholesky_log<propto>(y,mu,L,Policy());
287 template <
bool propto,
288 typename T_y,
typename T_loc,
typename T_covar>
290 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
292 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
293 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
298 template <
typename T_y,
typename T_loc,
typename T_covar,
301 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
303 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
304 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
306 return multi_normal_log<false>(y,mu,Sigma,Policy());
310 template <
typename T_y,
typename T_loc,
typename T_covar>
312 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
314 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
315 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
322 template <
bool propto,
323 typename T_y,
typename T_loc,
typename T_covar,
325 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
327 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
328 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
330 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
331 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
339 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
341 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
343 Eigen::LLT< Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> > LLT = Sigma.llt();
344 if (LLT.info() != Eigen::Success) {
345 lp = stan::math::policies::raise_domain_error<T_covar>(
function,
346 "Sigma is not positive definite (%1%)",
350 Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> L(LLT.matrixL());
351 return multi_normal_cholesky_log<propto>(y,mu,L,Policy());
354 template <
bool propto,
355 typename T_y,
typename T_loc,
typename T_covar>
357 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
359 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
360 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
365 template <
typename T_y,
typename T_loc,
typename T_covar,
368 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
370 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
371 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
373 return multi_normal_log<false>(y,mu,Sigma,Policy());
376 template <
typename T_y,
typename T_loc,
typename T_covar>
378 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
380 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
381 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
internal::traits< Derived >::Index size_type
var dot_self(const Eigen::Matrix< var, R, C > &v)
Returns the dot product of a vector with itself.
bool check_symmetric(const char *function, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const char *name, T_result *result, const Policy &)
Return true if the specified matrix is symmetric.
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)
Eigen::Matrix< T, Eigen::Dynamic, 1 > columns_dot_self(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &x)
Returns the dot product of each column of a matrix with itself.
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.
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
Checks if the variable y is nan.
bool check_cov_matrix(const char *function, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const char *name, T_result *result, const Policy &)
Return true if the specified matrix is a valid covariance matrix.
double dot_self(const Eigen::Matrix< double, R, C > &v)
Returns the dot product of the specified vector with itself.
Eigen::Matrix< double, R, C > multiply(const Eigen::Matrix< double, R, C > &m, double c)
Return specified matrix multiplied by specified scalar.
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
Checks if the variable y is finite.
boost::math::policies::policy default_policy
Default error-handling policy from Boost.
bool check_size_match(const char *function, T_size1 i, T_size2 j, T_result *result, const Policy &)
boost::math::tools::promote_args< T_y, T_loc, T_covar >::type multi_normal_cholesky_log(const Eigen::Matrix< T_y, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< T_loc, Eigen::Dynamic, 1 > &mu, const Eigen::Matrix< T_covar, Eigen::Dynamic, Eigen::Dynamic > &L, const Policy &)
The log of the multivariate normal density for the given y, mu, and a Cholesky factor L of the varian...
boost::math::tools::promote_args< T_y, T_loc, T_covar >::type multi_normal_log(const Eigen::Matrix< T_y, Eigen::Dynamic, 1 > &y, const Eigen::Matrix< T_loc, Eigen::Dynamic, 1 > &mu, const Eigen::Matrix< T_covar, Eigen::Dynamic, Eigen::Dynamic > &Sigma, const Policy &)
The log of the multivariate normal density for the given y, mu, and variance matrix.
Probability, optimization and sampling library.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...