Stan Math Library  2.14.0
reverse mode automatic differentiation
lkj_cov_lpdf.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_PRIM_MAT_PROB_LKJ_COV_LPDF_HPP
2 #define STAN_MATH_PRIM_MAT_PROB_LKJ_COV_LPDF_HPP
3 
12 
13 namespace stan {
14  namespace math {
15 
16  // LKJ_cov(y|mu, sigma, eta) [ y covariance matrix (not correlation matrix)
17  // mu vector, sigma > 0 vector, eta > 0 ]
18  template <bool propto,
19  typename T_y, typename T_loc, typename T_scale, typename T_shape>
20  typename
21  boost::math::tools::promote_args<T_y, T_loc, T_scale, T_shape>::type
22  lkj_cov_lpdf(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
23  const Eigen::Matrix<T_loc, Eigen::Dynamic, 1>& mu,
24  const Eigen::Matrix<T_scale, Eigen::Dynamic, 1>& sigma,
25  const T_shape& eta) {
26  static const char* function("lkj_cov_lpdf");
27 
28  using boost::math::tools::promote_args;
29 
30  typename promote_args<T_y, T_loc, T_scale, T_shape>::type lp(0.0);
31  check_size_match(function,
32  "Rows of location parameter", mu.rows(),
33  "columns of scale parameter", sigma.rows());
34  check_square(function, "random variable", y);
35  check_size_match(function,
36  "Rows of random variable", y.rows(),
37  "rows of location parameter", mu.rows());
38  check_positive(function, "Shape parameter", eta);
39  check_finite(function, "Location parameter", mu);
40  check_finite(function, "Scale parameter", sigma);
41  for (int m = 0; m < y.rows(); ++m)
42  for (int n = 0; n < y.cols(); ++n)
43  check_finite(function, "Covariance matrix", y(m, n));
44 
45  const unsigned int K = y.rows();
46  const Eigen::Array<T_y, Eigen::Dynamic, 1> sds
47  = y.diagonal().array().sqrt();
48  for (unsigned int k = 0; k < K; k++) {
49  lp += lognormal_lpdf<propto>(sds(k), mu(k), sigma(k));
50  }
51  if (stan::is_constant<typename stan::scalar_type<T_shape> >::value
52  && eta == 1.0) {
53  // no need to rescale y into a correlation matrix
54  lp += lkj_corr_lpdf<propto, T_y, T_shape>(y, eta);
55  return lp;
56  }
57  Eigen::DiagonalMatrix<T_y, Eigen::Dynamic> D(K);
58  D.diagonal() = sds.inverse();
59  lp += lkj_corr_lpdf<propto, T_y, T_shape>(D * y * D, eta);
60  return lp;
61  }
62 
63  template <typename T_y, typename T_loc, typename T_scale, typename T_shape>
64  inline
65  typename
66  boost::math::tools::promote_args<T_y, T_loc, T_scale, T_shape>::type
67  lkj_cov_lpdf(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
68  const Eigen::Matrix<T_loc, Eigen::Dynamic, 1>& mu,
69  const Eigen::Matrix<T_scale, Eigen::Dynamic, 1>& sigma,
70  const T_shape& eta) {
71  return lkj_cov_lpdf<false>(y, mu, sigma, eta);
72  }
73 
74  // LKJ_Cov(y|mu, sigma, eta) [ y covariance matrix (not correlation matrix)
75  // mu scalar, sigma > 0 scalar, eta > 0 ]
76  template <bool propto,
77  typename T_y, typename T_loc, typename T_scale, typename T_shape>
78  typename
79  boost::math::tools::promote_args<T_y, T_loc, T_scale, T_shape>::type
80  lkj_cov_lpdf(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
81  const T_loc& mu,
82  const T_scale& sigma,
83  const T_shape& eta) {
84  static const char* function("lkj_cov_lpdf");
85 
86  using boost::math::tools::promote_args;
87 
88  typename promote_args<T_y, T_loc, T_scale, T_shape>::type lp(0.0);
89  check_positive(function, "Shape parameter", eta);
90  check_finite(function, "Location parameter", mu);
91  check_finite(function, "Scale parameter", sigma);
92 
93  const unsigned int K = y.rows();
94  const Eigen::Array<T_y, Eigen::Dynamic, 1> sds
95  = y.diagonal().array().sqrt();
96  for (unsigned int k = 0; k < K; k++) {
97  lp += lognormal_lpdf<propto>(sds(k), mu, sigma);
98  }
99  if (stan::is_constant<typename stan::scalar_type<T_shape> >::value
100  && eta == 1.0) {
101  // no need to rescale y into a correlation matrix
102  lp += lkj_corr_lpdf<propto>(y, eta);
103  return lp;
104  }
105  Eigen::DiagonalMatrix<T_y, Eigen::Dynamic> D(K);
106  D.diagonal() = sds.inverse();
107  lp += lkj_corr_lpdf<propto, T_y, T_shape>(D * y * D, eta);
108  return lp;
109  }
110 
111  template <typename T_y, typename T_loc, typename T_scale, typename T_shape>
112  inline
113  typename boost::math::tools::promote_args
114  <T_y, T_loc, T_scale, T_shape>::type
115  lkj_cov_lpdf(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y,
116  const T_loc& mu,
117  const T_scale& sigma,
118  const T_shape& eta) {
119  return lkj_cov_lpdf<false>(y, mu, sigma, eta);
120  }
121 
122  }
123 }
124 #endif
Metaprogramming struct to detect whether a given type is constant in the mathematical sense (not the ...
Definition: is_constant.hpp:22
Metaprogram structure to determine the base scalar type of a template argument.
Definition: scalar_type.hpp:33
void check_finite(const char *function, const char *name, const T_y &y)
Check if y is finite.
boost::math::tools::promote_args< T_y, T_loc, T_scale, T_shape >::type lkj_cov_lpdf(const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const Eigen::Matrix< T_loc, Eigen::Dynamic, 1 > &mu, const Eigen::Matrix< T_scale, Eigen::Dynamic, 1 > &sigma, const T_shape &eta)
void check_size_match(const char *function, const char *name_i, T_size1 i, const char *name_j, T_size2 j)
Check if the provided sizes match.
void check_square(const char *function, const char *name, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y)
Check if the specified matrix is square.
void check_positive(const char *function, const char *name, const T_y &y)
Check if y is positive.

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