Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
multi_normal.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP
2 #define STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_HPP
3 
4 #include <boost/random/normal_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
7 #include <stan/agrad/rev.hpp>
12 #include <stan/meta/traits.hpp>
13 #include <stan/prob/constants.hpp>
14 #include <stan/prob/traits.hpp>
19 
20 namespace stan {
21 
22  namespace prob {
23 
24  template <bool propto,
25  typename T_y, typename T_loc, typename T_covar>
26  typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type
27  multi_normal_log(const T_y& y,
28  const T_loc& mu,
29  const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
30  static const char* function = "stan::prob::multi_normal_log(%1%)";
31  typedef typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type lp_type;
32  lp_type lp(0.0);
33 
40 
41  check_size_match(function,
42  Sigma.rows(), "Rows of covariance parameter",
43  Sigma.cols(), "columns of covariance parameter",
44  &lp);
45  check_positive(function, Sigma.rows(), "Covariance matrix rows", &lp);
46  check_symmetric(function, Sigma, "Covariance matrix", &lp);
47 
49  check_ldlt_factor(function,ldlt_Sigma,"LDLT_Factor of covariance parameter",&lp);
50 
51  VectorViewMvt<const T_y> y_vec(y);
52  VectorViewMvt<const T_loc> mu_vec(mu);
53  //size of std::vector of Eigen vectors
54  size_t size_vec = max_size_mvt(y, mu);
55 
56  //Check if every vector of the array has the same size
57  int size_y = y_vec[0].size();
58  int size_mu = mu_vec[0].size();
59  if (size_vec > 1) {
60  int size_y_old = size_y;
61  int size_y_new;
62  for (size_t i = 1, size_ = length_mvt(y); i < size_; i++) {
63  int size_y_new = y_vec[i].size();
64  check_size_match(function,
65  size_y_new, "Size of one of the vectors of the random variable",
66  size_y_old, "Size of another vector of the random variable",
67  &lp);
68  size_y_old = size_y_new;
69  }
70  int size_mu_old = size_mu;
71  int size_mu_new;
72  for (size_t i = 1, size_ = length_mvt(mu); i < size_; i++) {
73  int size_mu_new = mu_vec[i].size();
74  check_size_match(function,
75  size_mu_new, "Size of one of the vectors of the location variable",
76  size_mu_old, "Size of another vector of the location variable",
77  &lp);
78  size_mu_old = size_mu_new;
79  }
80  (void) size_y_old;
81  (void) size_y_new;
82  (void) size_mu_old;
83  (void) size_mu_new;
84  }
85 
86  check_size_match(function,
87  size_y, "Size of random variable",
88  size_mu, "size of location parameter",
89  &lp);
90  check_size_match(function,
91  size_y, "Size of random variable",
92  Sigma.rows(), "rows of covariance parameter",
93  &lp);
94  check_size_match(function,
95  size_y, "Size of random variable",
96  Sigma.cols(), "columns of covariance parameter",
97  &lp);
98 
99  for (size_t i = 0; i < size_vec; i++) {
100  check_finite(function, mu_vec[i], "Location parameter", &lp);
101  check_not_nan(function, y_vec[i], "Random variable", &lp);
102  }
103 
104  if (size_y == 0) //y_vec[0].size() == 0
105  return lp;
106 
108  lp += NEG_LOG_SQRT_TWO_PI * size_y * size_vec;
109 
111  lp -= 0.5 * log_determinant_ldlt(ldlt_Sigma) * size_vec;
112 
114  lp_type sum_lp_vec(0.0);
115  for (size_t i = 0; i < size_vec; i++) {
116  Eigen::Matrix<typename
117  boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type>::type,
118  Eigen::Dynamic, 1> y_minus_mu(size_y);
119  for (int j = 0; j < size_y; j++)
120  y_minus_mu(j) = y_vec[i](j)-mu_vec[i](j);
121  sum_lp_vec += trace_inv_quad_form_ldlt(ldlt_Sigma,y_minus_mu);
122  }
123  lp -= 0.5*sum_lp_vec;
124  }
125  return lp;
126  }
127 
128  template <typename T_y, typename T_loc, typename T_covar>
129  inline
130  typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type
131  multi_normal_log(const T_y& y,
132  const T_loc& mu,
133  const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
134  return multi_normal_log<false>(y,mu,Sigma);
135  }
136 
137  template <class RNG>
138  inline Eigen::VectorXd
139  multi_normal_rng(const Eigen::Matrix<double,Eigen::Dynamic,1>& mu,
140  const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& S,
141  RNG& rng) {
142  using boost::variate_generator;
143  using boost::normal_distribution;
144 
145  static const char* function = "stan::prob::multi_normal_rng(%1%)";
146 
150 
151  check_positive(function, S.rows(), "Covariance matrix rows", (double*)0);
152  check_symmetric(function, S, "Covariance matrix", (double*)0);
153  check_finite(function, mu, "Location parameter", (double*)0);
154 
155  variate_generator<RNG&, normal_distribution<> >
156  std_normal_rng(rng, normal_distribution<>(0,1));
157 
158  Eigen::VectorXd z(S.cols());
159  for(int i = 0; i < S.cols(); i++)
160  z(i) = std_normal_rng();
161 
162  return mu + S.llt().matrixL() * z;
163  }
164  }
165 }
166 
167 #endif
size_t max_size_mvt(const T1 &x1, const T2 &x2)
Definition: traits.hpp:575
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
Definition: traits.hpp:139
bool check_symmetric(const char *function, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const char *name, T_result *result)
Return true if the specified matrix is symmetric.
bool check_ldlt_factor(const char *function, stan::math::LDLT_factor< T, R, C > &A, const char *name, T_result *result)
Return true if the underlying matrix is positive definite.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Definition: traits.hpp:35
size_t length_mvt(const T &)
Definition: traits.hpp:561
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result)
Eigen::VectorXd multi_normal_rng(const Eigen::Matrix< double, Eigen::Dynamic, 1 > &mu, const Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > &S, RNG &rng)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
var log_determinant_ldlt(stan::math::LDLT_factor< var, R, C > &A)
size_t size_
Definition: dot_self.hpp:18
boost::math::tools::promote_args< typename scalar_type< T_y >::type, typename scalar_type< T_loc >::type, T_covar >::type multi_normal_log(const T_y &y, const T_loc &mu, const Eigen::Matrix< T_covar, Eigen::Dynamic, Eigen::Dynamic > &Sigma)
boost::enable_if_c< boost::is_same< T2, var >::value||boost::is_same< T3, var >::value, var >::type trace_inv_quad_form_ldlt(const stan::math::LDLT_factor< T2, R2, C2 > &A, const Eigen::Matrix< T3, R3, C3 > &B)
Compute the trace of an inverse quadratic form.

     [ Stan Home Page ] © 2011–2014, Stan Development Team.