Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
multi_normal_prec.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_PREC_HPP
2 #define STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__MULTI_NORMAL_PREC_HPP
3 
4 #include <stan/agrad/rev.hpp>
13 #include <stan/math/matrix/log.hpp>
19 #include <stan/math/matrix/sum.hpp>
22 #include <stan/meta/traits.hpp>
23 #include <stan/prob/constants.hpp>
24 #include <stan/prob/traits.hpp>
26 
27 namespace stan {
28 
29  namespace prob {
30 
31  template <bool propto,
32  typename T_y, typename T_loc, typename T_covar>
33  typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type
34  multi_normal_prec_log(const T_y& y,
35  const T_loc& mu,
36  const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
37  static const char* function = "stan::prob::multi_normal_prec_log(%1%)";
38  typedef typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type lp_type;
39  lp_type lp(0.0);
40 
46  using stan::math::sum;
51 
52  check_size_match(function,
53  Sigma.rows(), "Rows of precision parameter",
54  Sigma.cols(), "columns of precision parameter",
55  &lp);
56  check_positive(function, Sigma.rows(), "Precision matrix rows", &lp);
57  check_symmetric(function, Sigma, "Precision matrix", &lp);
58 
59  LDLT_factor<T_covar,Eigen::Dynamic,Eigen::Dynamic> ldlt_Sigma(Sigma);
60  check_ldlt_factor(function,ldlt_Sigma,
61  "LDLT_Factor of precision parameter",&lp);
62 
63  using Eigen::Matrix;
64  using Eigen::Dynamic;
65  using std::vector;
66  VectorViewMvt<const T_y> y_vec(y);
67  VectorViewMvt<const T_loc> mu_vec(mu);
68  //size of std::vector of Eigen vectors
69  size_t size_vec = max_size_mvt(y, mu);
70 
71 
72  //Check if every vector of the array has the same size
73  int size_y = y_vec[0].size();
74  int size_mu = mu_vec[0].size();
75  if (size_vec > 1) {
76  int size_y_old = size_y;
77  int size_y_new;
78  for (size_t i = 1, size_ = length_mvt(y); i < size_; i++) {
79  int size_y_new = y_vec[i].size();
80  check_size_match(function,
81  size_y_new, "Size of one of the vectors of the random variable",
82  size_y_old, "Size of another vector of the random variable",
83  &lp);
84  size_y_old = size_y_new;
85  }
86  int size_mu_old = size_mu;
87  int size_mu_new;
88  for (size_t i = 1, size_ = length_mvt(mu); i < size_; i++) {
89  int size_mu_new = mu_vec[i].size();
90  check_size_match(function,
91  size_mu_new, "Size of one of the vectors of the location variable",
92  size_mu_old, "Size of another vector of the location variable",
93  &lp);
94  size_mu_old = size_mu_new;
95  }
96  (void) size_y_old;
97  (void) size_y_new;
98  (void) size_mu_old;
99  (void) size_mu_new;
100  }
101 
102  check_size_match(function,
103  size_y, "Size of random variable",
104  size_mu, "size of location parameter",
105  &lp);
106  check_size_match(function,
107  size_y, "Size of random variable",
108  Sigma.rows(), "rows of covariance parameter",
109  &lp);
110  check_size_match(function,
111  size_y, "Size of random variable",
112  Sigma.cols(), "columns of covariance parameter",
113  &lp);
114 
115  for (size_t i = 0; i < size_vec; i++) {
116  check_finite(function, mu_vec[i], "Location parameter", &lp);
117  check_not_nan(function, y_vec[i], "Random variable", &lp);
118  }
119 
120  if (size_y == 0) //y_vec[0].size() == 0
121  return lp;
122 
124  lp += 0.5 * log_determinant_ldlt(ldlt_Sigma) * size_vec;
125 
127  lp += NEG_LOG_SQRT_TWO_PI * size_y * size_vec;
128 
130  lp_type sum_lp_vec(0.0);
131  for (size_t i = 0; i < size_vec; i++) {
132  Matrix<typename
133  boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type>::type,
134  Dynamic, 1> y_minus_mu(size_y);
135  for (int j = 0; j < size_y; j++)
136  y_minus_mu(j) = y_vec[i](j)-mu_vec[i](j);
137  sum_lp_vec += trace_quad_form(Sigma,y_minus_mu);
138  }
139  lp -= 0.5*sum_lp_vec;
140  }
141  return lp;
142  }
143 
144  template <typename T_y, typename T_loc, typename T_covar>
145  inline
146  typename boost::math::tools::promote_args<typename scalar_type<T_y>::type, typename scalar_type<T_loc>::type, T_covar>::type
147  multi_normal_prec_log(const T_y& y,
148  const T_loc& mu,
149  const Eigen::Matrix<T_covar,Eigen::Dynamic,Eigen::Dynamic>& Sigma) {
150  return multi_normal_prec_log<false>(y,mu,Sigma);
151  }
152 
153  }
154 }
155 #endif
156 
size_t max_size_mvt(const T1 &x1, const T2 &x2)
Definition: traits.hpp:575
boost::math::tools::promote_args< typename scalar_type< T_y >::type, typename scalar_type< T_loc >::type, T_covar >::type multi_normal_prec_log(const T_y &y, const T_loc &mu, const Eigen::Matrix< T_covar, Eigen::Dynamic, Eigen::Dynamic > &Sigma)
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
stan::agrad::fvar< T > trace_quad_form(const Eigen::Matrix< stan::agrad::fvar< T >, RA, CA > &A, const Eigen::Matrix< stan::agrad::fvar< T >, RB, CB > &B)
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
double trace_quad_form(const Eigen::Matrix< double, RA, CA > &A, const Eigen::Matrix< double, RB, CB > &B)
Compute trace(B^T A B).
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)
double sum(std::vector< double > &x)
Definition: sum.hpp:10
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
T log_determinant_ldlt(stan::math::LDLT_factor< T, R, C > &A)

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