Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
inv_wishart.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__INV_WISHART_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__CONTINUOUS__INV_WISHART_HPP__
3 
7 #include <stan/prob/traits.hpp>
8 #include <stan/meta/traits.hpp>
9 #include <stan/agrad/agrad.hpp>
10 #include <stan/agrad/matrix.hpp>
13 
14 namespace stan {
15  namespace prob {
16  // InvWishart(Sigma|n,Omega) [W, S symmetric, non-neg, definite;
17  // W.dims() = S.dims();
18  // n > S.rows() - 1]
46  template <bool propto,
47  typename T_y, typename T_dof, typename T_scale,
48  class Policy>
49  typename boost::math::tools::promote_args<T_y,T_dof,T_scale>::type
50  inv_wishart_log(const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& W,
51  const T_dof& nu,
52  const Eigen::Matrix<T_scale,Eigen::Dynamic,Eigen::Dynamic>& S,
53  const Policy&) {
54  static const char* function = "stan::prob::inv_wishart_log(%1%)";
55 
58  using boost::math::tools::promote_args;
59 
61  typename promote_args<T_y,T_dof,T_scale>::type lp(0.0);
62  if(!check_greater(function, nu, k-1, "Degrees of freedom parameter",
63  &lp, Policy()))
64  return lp;
65  if (!check_size_match(function,
66  W.rows(), "Rows of random variable",
67  W.cols(), "columns of random variable",
68  &lp, Policy()))
69  return lp;
70  if (!check_size_match(function,
71  S.rows(), "Rows of scale parameter",
72  S.cols(), "columns of scale parameter",
73  &lp, Policy()))
74  return lp;
75  if (!check_size_match(function,
76  W.rows(), "Rows of random variable",
77  S.rows(), "columns of scale parameter",
78  &lp, Policy()))
79  return lp;
80  // FIXME: domain checks
81 
82  Eigen::LLT< Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic> > LLT_W = W.llt();
83  if (LLT_W.info() != Eigen::Success) {
84  lp = stan::math::policies::raise_domain_error<T_y>(function,
85  "W is not positive definite (%1%)",
86  0,Policy());
87  return lp;
88  }
89  Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic> L = LLT_W.matrixL();
90 
94  using stan::math::lmgamma;
96 
98  lp -= lmgamma(k, 0.5 * nu);
100 // lp += nu * S.llt().matrixLLT().diagonal().array().log().sum();
101  lp += 0.5 * nu * log_determinant(S);
102  }
104  lp -= (nu + k + 1.0) * L.diagonal().array().log().sum();
105  }
108  Eigen::Matrix<T_y,Eigen::Dynamic,1> W_inv_vec = Eigen::Map<
109  const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic> >(
110  &L(0), L.size(), 1);
111  Eigen::Matrix<T_scale,Eigen::Dynamic,1> S_vec = Eigen::Map<
112  const Eigen::Matrix<T_scale,Eigen::Dynamic,Eigen::Dynamic> >(
113  &S(0), S.size(), 1);
114  lp -= 0.5 * dot_product(S_vec, W_inv_vec); // trace(S * W^-1)
115  }
117  lp += nu * k * NEG_LOG_TWO_OVER_TWO;
118  return lp;
119  }
120 
121  template <bool propto,
122  typename T_y, typename T_dof, typename T_scale>
123  inline
124  typename boost::math::tools::promote_args<T_y,T_dof,T_scale>::type
125  inv_wishart_log(const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& W,
126  const T_dof& nu,
127  const Eigen::Matrix<T_scale,Eigen::Dynamic,Eigen::Dynamic>& S) {
128  return inv_wishart_log<propto>(W,nu,S,stan::math::default_policy());
129  }
130 
131 
132  template <typename T_y, typename T_dof, typename T_scale,
133  class Policy>
134  inline
135  typename boost::math::tools::promote_args<T_y,T_dof,T_scale>::type
136  inv_wishart_log(const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& W,
137  const T_dof& nu,
138  const Eigen::Matrix<T_scale,Eigen::Dynamic,Eigen::Dynamic>& S,
139  const Policy&) {
140  return inv_wishart_log<false>(W,nu,S,Policy());
141  }
142 
143 
144  template <typename T_y, typename T_dof, typename T_scale>
145  inline
146  typename boost::math::tools::promote_args<T_y,T_dof,T_scale>::type
147  inv_wishart_log(const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& W,
148  const T_dof& nu,
149  const Eigen::Matrix<T_scale,Eigen::Dynamic,Eigen::Dynamic>& S) {
150  return inv_wishart_log<false>(W,nu,S,stan::math::default_policy());
151  }
152 
153  template <class RNG>
154  inline Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>
155  inv_wishart_rng(const double nu,
156  const Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>& S,
157  RNG& rng) {
158 
159  Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> S_inv(S.rows(), S.cols());
160  S_inv = Eigen::MatrixXd::Identity(S.cols(),S.cols());
161  S_inv = S.ldlt().solve(S_inv);
162 
163  return wishart_rng(nu, S_inv, rng).inverse();
164  }
165  }
166 }
167 #endif

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