1 #ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP__
29 template <
bool propto,
30 typename T_y,
typename T_loc,
typename T_covar,
32 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
34 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
35 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
37 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
48 using boost::math::tools::promote_args;
50 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
58 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
60 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
67 lp += NEG_LOG_SQRT_TWO_PI * y.rows();
70 lp -= L.diagonal().array().log().sum();
73 Eigen::Matrix<
typename
74 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
83 template <
bool propto,
84 typename T_y,
typename T_loc,
typename T_covar>
86 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
88 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
89 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
90 return multi_normal_cholesky_log<propto>(y,mu,L,
94 template <
typename T_y,
typename T_loc,
typename T_covar,
97 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
99 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
100 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
102 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
105 template <
typename T_y,
typename T_loc,
typename T_covar>
107 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
109 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
110 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
111 return multi_normal_cholesky_log<false>(y,mu,L,
117 template <
bool propto,
118 typename T_y,
typename T_loc,
typename T_covar,
120 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
122 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
123 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
125 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
136 using boost::math::tools::promote_args;
138 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
146 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
148 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
155 lp += NEG_LOG_SQRT_TWO_PI * y.cols() * y.rows();
158 lp -= L.diagonal().array().log().sum() * y.rows();
161 Eigen::Matrix<T_loc, Eigen::Dynamic, Eigen::Dynamic> MU(y.rows(),y.cols());
165 Eigen::Matrix<
typename
166 boost::math::tools::promote_args<T_loc,T_y>::type,
167 Eigen::Dynamic,Eigen::Dynamic>
170 Eigen::Matrix<
typename
171 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
172 Eigen::Dynamic,Eigen::Dynamic>
180 template <
bool propto,
181 typename T_y,
typename T_loc,
typename T_covar>
183 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
185 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
186 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
187 return multi_normal_cholesky_log<propto>(y,mu,L,
191 template <
typename T_y,
typename T_loc,
typename T_covar,
194 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
196 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
197 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
199 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
202 template <
typename T_y,
typename T_loc,
typename T_covar>
204 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
206 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
207 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
208 return multi_normal_cholesky_log<false>(y,mu,L,
231 template <
bool propto,
232 typename T_y,
typename T_loc,
typename T_covar,
234 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
236 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
237 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
239 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
240 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
248 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
250 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
252 Eigen::LLT< Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> > LLT = Sigma.llt();
253 if (LLT.info() != Eigen::Success) {
254 lp = stan::math::policies::raise_domain_error<T_covar>(
function,
255 "Covariance matrix is not positive definite (%1%)",
259 Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> L(LLT.matrixL());
260 return multi_normal_cholesky_log<propto>(y,mu,L,Policy());
263 template <
bool propto,
264 typename T_y,
typename T_loc,
typename T_covar>
266 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
268 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
269 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
274 template <
typename T_y,
typename T_loc,
typename T_covar,
277 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
279 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
280 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
282 return multi_normal_log<false>(y,mu,Sigma,Policy());
286 template <
typename T_y,
typename T_loc,
typename T_covar>
288 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
290 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
291 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
298 template <
bool propto,
299 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 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
307 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
315 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
317 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
319 Eigen::LLT< Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> > LLT = Sigma.llt();
320 if (LLT.info() != Eigen::Success) {
321 lp = stan::math::policies::raise_domain_error<T_covar>(
function,
322 "Sigma is not positive definite (%1%)",
326 Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic> L(LLT.matrixL());
327 return multi_normal_cholesky_log<propto>(y,mu,L,Policy());
330 template <
bool propto,
331 typename T_y,
typename T_loc,
typename T_covar>
333 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
335 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
336 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
341 template <
typename T_y,
typename T_loc,
typename T_covar,
344 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
346 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
347 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
349 return multi_normal_log<false>(y,mu,Sigma,Policy());
352 template <
typename T_y,
typename T_loc,
typename T_covar>
354 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
356 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
357 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {