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%)";
52 using boost::math::tools::promote_args;
54 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
57 y.size(),
"Size of random variable",
58 mu.size(),
"size of location parameter",
62 y.size(),
"Size of random variable",
63 L.rows(),
"rows of covariance parameter",
67 y.size(),
"Size of random variable",
68 L.cols(),
"columns of covariance parameter",
71 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
73 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
80 lp += NEG_LOG_SQRT_TWO_PI * y.rows();
83 Eigen::Matrix<T_covar,Eigen::Dynamic,1> L_log_diag = L.diagonal().array().log().matrix();
84 lp -=
sum(L_log_diag);
88 Eigen::Matrix<
typename
89 boost::math::tools::promote_args<T_y,T_loc>::type,
90 Eigen::Dynamic, 1> y_minus_mu(y.size());
91 for (
int i = 0; i < y.size(); i++)
92 y_minus_mu(i) = y(i)-mu(i);
93 Eigen::Matrix<
typename
94 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
107 template <
bool propto,
108 typename T_y,
typename T_loc,
typename T_covar>
110 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
112 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
113 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
114 return multi_normal_cholesky_log<propto>(y,mu,L,
118 template <
typename T_y,
typename T_loc,
typename T_covar,
121 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
123 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
124 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
126 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
129 template <
typename T_y,
typename T_loc,
typename T_covar>
131 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
133 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
134 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
135 return multi_normal_cholesky_log<false>(y,mu,L,
141 template <
bool propto,
142 typename T_y,
typename T_loc,
typename T_covar,
144 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
146 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
147 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
149 static const char*
function =
"stan::prob::multi_normal_cholesky_log(%1%)";
162 using boost::math::tools::promote_args;
164 typename promote_args<T_y,T_loc,T_covar>::type lp(0.0);
167 y.cols(),
"Columns of random variable",
168 mu.rows(),
"rows of location parameter",
172 y.cols(),
"Columns of random variable",
173 L.rows(),
"rows of covariance parameter",
177 y.cols(),
"Columns of random variable",
178 L.cols(),
"columns of covariance parameter",
181 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
183 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
190 lp += NEG_LOG_SQRT_TWO_PI * y.cols() * y.rows();
193 Eigen::Matrix<T_covar,Eigen::Dynamic,1> L_log_diag = L.diagonal().array().log().matrix();
194 lp -=
sum(L_log_diag) * y.rows();
198 Eigen::Matrix<T_loc, Eigen::Dynamic, Eigen::Dynamic> MU(y.rows(),y.cols());
202 Eigen::Matrix<
typename
203 boost::math::tools::promote_args<T_loc,T_y>::type,
204 Eigen::Dynamic,Eigen::Dynamic>
205 y_minus_MU(y.rows(), y.cols());
206 for (
int i = 0; i < y.size(); i++)
207 y_minus_MU(i) = y(i)-MU(i);
209 Eigen::Matrix<
typename
210 boost::math::tools::promote_args<T_loc,T_y>::type,
211 Eigen::Dynamic,Eigen::Dynamic>
212 z(y_minus_MU.transpose());
220 Eigen::Matrix<
typename
221 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
222 Eigen::Dynamic,Eigen::Dynamic>
230 template <
bool propto,
231 typename T_y,
typename T_loc,
typename T_covar>
233 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
235 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
236 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
237 return multi_normal_cholesky_log<propto>(y,mu,L,
241 template <
typename T_y,
typename T_loc,
typename T_covar,
244 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
246 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
247 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L,
249 return multi_normal_cholesky_log<false>(y,mu,L,Policy());
252 template <
typename T_y,
typename T_loc,
typename T_covar>
254 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
256 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
257 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& L) {
258 return multi_normal_cholesky_log<false>(y,mu,L,
281 template <
bool propto,
282 typename T_y,
typename T_loc,
typename T_covar,
284 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
286 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
287 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
289 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
290 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
303 Sigma.rows(),
"Rows of covariance parameter",
304 Sigma.cols(),
"columns of covariance parameter",
307 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
309 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
314 y.size(),
"Size of random variable",
315 mu.size(),
"size of location parameter",
319 y.size(),
"Size of random variable",
320 Sigma.rows(),
"rows of covariance parameter",
324 y.size(),
"Size of random variable",
325 Sigma.cols(),
"columns of covariance parameter",
328 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
330 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
337 lp += NEG_LOG_SQRT_TWO_PI * y.rows();
344 Eigen::Matrix<
typename
345 boost::math::tools::promote_args<T_y,T_loc>::type,
346 Eigen::Dynamic, 1> y_minus_mu(y.size());
347 for (
int i = 0; i < y.size(); i++)
348 y_minus_mu(i) = y(i)-mu(i);
349 Eigen::Matrix<
typename
350 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
351 Eigen::Dynamic, 1> Sinv_y_minus_mu(
mdivide_left(Sigma,y_minus_mu));
352 lp -= 0.5 *
dot_product(y_minus_mu,Sinv_y_minus_mu);
357 template <
bool propto,
358 typename T_y,
typename T_loc,
typename T_covar>
360 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
362 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
363 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
368 template <
typename T_y,
typename T_loc,
typename T_covar,
371 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
373 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
374 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
376 return multi_normal_log<false>(y,mu,Sigma,Policy());
380 template <
typename T_y,
typename T_loc,
typename T_covar>
382 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
384 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
385 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
392 template <
bool propto,
393 typename T_y,
typename T_loc,
typename T_covar,
395 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
397 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
398 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
400 static const char*
function =
"stan::prob::multi_normal_log(%1%)";
401 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
415 Sigma.rows(),
"Rows of covariance matrix",
416 Sigma.cols(),
"columns of covariance matrix",
419 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
421 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
426 y.cols(),
"Columns of random variable",
427 mu.rows(),
"rows of location parameter",
431 y.cols(),
"Columns of random variable",
432 Sigma.rows(),
"rows of covariance parameter",
436 y.cols(),
"Columns of random variable",
437 Sigma.cols(),
"columns of covariance parameter",
440 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
442 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
449 lp += NEG_LOG_SQRT_TWO_PI * y.cols() * y.rows();
456 Eigen::Matrix<T_loc, Eigen::Dynamic, Eigen::Dynamic> MU(y.rows(),y.cols());
460 Eigen::Matrix<
typename
461 boost::math::tools::promote_args<T_loc,T_y>::type,
462 Eigen::Dynamic,Eigen::Dynamic> y_minus_MU(y.rows(), y.cols());
464 for (
int i = 0; i < y.size(); i++)
465 y_minus_MU(i) = y(i)-MU(i);
467 Eigen::Matrix<
typename
468 boost::math::tools::promote_args<T_loc,T_y>::type,
469 Eigen::Dynamic,Eigen::Dynamic> z(y_minus_MU.transpose());
477 Eigen::Matrix<
typename
478 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
479 Eigen::Dynamic,Eigen::Dynamic> Sinv_y_minus_mu(
mdivide_left(Sigma,z));
486 template <
bool propto,
487 typename T_y,
typename T_loc,
typename T_covar>
489 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
491 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
492 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
497 template <
typename T_y,
typename T_loc,
typename T_covar,
500 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
502 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
503 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
505 return multi_normal_log<false>(y,mu,Sigma,Policy());
508 template <
typename T_y,
typename T_loc,
typename T_covar>
510 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
512 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
513 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
517 template <
bool propto,
518 typename T_y,
typename T_loc,
typename T_covar,
520 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
522 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
523 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
525 static const char*
function =
"stan::prob::multi_normal_prec_log(%1%)";
526 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
540 Sigma.rows(),
"Rows of covariance parameter",
541 Sigma.cols(),
"columns of covariance parameter",
544 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
546 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
551 y.size(),
"Size of random variable",
552 mu.size(),
"size of location parameter",
556 y.size(),
"Size of random variable",
557 Sigma.rows(),
"rows of covariance parameter",
561 y.size(),
"Size of random variable",
562 Sigma.cols(),
"columns of covariance parameter",
565 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
567 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
574 lp += NEG_LOG_SQRT_TWO_PI * y.rows();
580 Eigen::Matrix<
typename
581 boost::math::tools::promote_args<T_y,T_loc>::type,
582 Eigen::Dynamic, 1> y_minus_mu(y.size());
583 for (
int i = 0; i < y.size(); i++)
584 y_minus_mu(i) = y(i)-mu(i);
585 Eigen::Matrix<
typename
586 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
587 Eigen::Dynamic, 1> Sinv_y_minus_mu(
multiply(Sigma,y_minus_mu));
588 lp -= 0.5 *
dot_product(y_minus_mu,Sinv_y_minus_mu);
593 template <
bool propto,
594 typename T_y,
typename T_loc,
typename T_covar>
596 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
598 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
599 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
604 template <
typename T_y,
typename T_loc,
typename T_covar,
607 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
609 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
610 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
612 return multi_normal_prec_log<false>(y,mu,Sigma,Policy());
616 template <
typename T_y,
typename T_loc,
typename T_covar>
618 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
620 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
621 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
628 template <
bool propto,
629 typename T_y,
typename T_loc,
typename T_covar,
631 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
633 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
634 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
636 static const char*
function =
"stan::prob::multi_normal_prec_log(%1%)";
637 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type lp(0.0);
651 Sigma.rows(),
"Rows of covariance matrix",
652 Sigma.cols(),
"columns of covariance matrix",
655 if (!
check_positive(
function, Sigma.rows(),
"Covariance matrix rows", &lp, Policy()))
657 if (!
check_symmetric(
function, Sigma,
"Covariance matrix", &lp, Policy()))
662 y.cols(),
"Columns of random variable",
663 mu.rows(),
"rows of location parameter",
667 y.cols(),
"Columns of random variable",
668 Sigma.rows(),
"rows of covariance parameter",
672 y.cols(),
"Columns of random variable",
673 Sigma.cols(),
"columns of covariance parameter",
676 if (!
check_finite(
function, mu,
"Location parameter", &lp, Policy()))
678 if (!
check_not_nan(
function, y,
"Random variable", &lp, Policy()))
685 lp += NEG_LOG_SQRT_TWO_PI * y.cols() * y.rows();
692 Eigen::Matrix<T_loc, Eigen::Dynamic, Eigen::Dynamic> MU(y.rows(),y.cols());
696 Eigen::Matrix<
typename
697 boost::math::tools::promote_args<T_loc,T_y>::type,
698 Eigen::Dynamic,Eigen::Dynamic> y_minus_MU(y.rows(), y.cols());
700 for (
int i = 0; i < y.size(); i++)
701 y_minus_MU(i) = y(i)-MU(i);
703 Eigen::Matrix<
typename
704 boost::math::tools::promote_args<T_loc,T_y>::type,
705 Eigen::Dynamic,Eigen::Dynamic> z(y_minus_MU.transpose());
713 Eigen::Matrix<
typename
714 boost::math::tools::promote_args<T_covar,T_loc,T_y>::type,
715 Eigen::Dynamic,Eigen::Dynamic> Sinv_y_minus_mu(
multiply(Sigma,z));
722 template <
bool propto,
723 typename T_y,
typename T_loc,
typename T_covar>
725 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
727 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
728 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
733 template <
typename T_y,
typename T_loc,
typename T_covar,
736 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
738 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
739 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma,
741 return multi_normal_prec_log<false>(y,mu,Sigma,Policy());
744 template <
typename T_y,
typename T_loc,
typename T_covar>
746 typename boost::math::tools::promote_args<T_y,T_loc,T_covar>::type
748 const Eigen::Matrix<T_loc,Eigen::Dynamic,1>& mu,
749 const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {