inline bool check_corr_matrix(const char* function, const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y, const char* name, T_result* result, const Policy&) { if (!check_size_match(function, y.rows(), "Rows of correlation matrix", y.cols(), "columns of correlation matrix", result, Policy())) return false; if (!check_positive(function, y.rows(), "rows", result, Policy())) return false; if (!check_symmetric(function, y, "y", result, Policy())) return false; for (typename Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>::size_type k = 0; k < y.rows(); ++k) { if (fabs(y(k,k) - 1.0) > CONSTRAINT_TOLERANCE) { std::ostringstream message; message << name << " is not a valid correlation matrix. " << name << "(" << k << "," << k << ") is %1%, but should be near 1.0"; T_result tmp = policies::raise_domain_error<T_y>(function, message.str().c_str(), y(k,k), Policy()); if (result != 0) *result = tmp; return false; } } if (!check_pos_definite(function, y, "y", result, Policy())) return false; return true; }
inline bool check_cov_matrix(const std::string& function, const std::string& name, const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y) { check_size_match(function, "Rows of covariance matrix", y.rows(), "columns of covariance matrix", y.cols()); check_positive(function, "rows", y.rows()); check_symmetric(function, name, y); check_pos_definite(function, name, y); return true; }
inline bool check_cov_matrix(const char* function, const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic>& y, const char* name, T_result* result) { check_size_match(function, y.rows(), "Rows of covariance matrix", y.cols(), "columns of covariance matrix", result); check_positive(function, y.rows(), "rows", result); check_symmetric(function, y, name, result); check_pos_definite(function, y, name, result); return true; }
typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type multi_gp_log(const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y, const Eigen::Matrix <T_covar, Eigen::Dynamic, Eigen::Dynamic>& Sigma, const Eigen::Matrix<T_w, Eigen::Dynamic, 1>& w) { static const char* function("multi_gp_log"); typedef typename boost::math::tools::promote_args<T_y, T_covar, T_w>::type T_lp; T_lp lp(0.0); check_positive(function, "Kernel rows", Sigma.rows()); check_finite(function, "Kernel", Sigma); check_symmetric(function, "Kernel", Sigma); LDLT_factor<T_covar, Eigen::Dynamic, Eigen::Dynamic> ldlt_Sigma(Sigma); check_ldlt_factor(function, "LDLT_Factor of Sigma", ldlt_Sigma); check_size_match(function, "Size of random variable (rows y)", y.rows(), "Size of kernel scales (w)", w.size()); check_size_match(function, "Size of random variable", y.cols(), "rows of covariance parameter", Sigma.rows()); check_positive_finite(function, "Kernel scales", w); check_finite(function, "Random variable", y); if (y.rows() == 0) return lp; if (include_summand<propto>::value) { lp += NEG_LOG_SQRT_TWO_PI * y.rows() * y.cols(); } if (include_summand<propto, T_covar>::value) { lp -= 0.5 * log_determinant_ldlt(ldlt_Sigma) * y.rows(); } if (include_summand<propto, T_w>::value) { lp += (0.5 * y.cols()) * sum(log(w)); } if (include_summand<propto, T_y, T_w, T_covar>::value) { Eigen::Matrix<T_w, Eigen::Dynamic, Eigen::Dynamic> w_mat(w.asDiagonal()); Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic> yT(y.transpose()); lp -= 0.5 * trace_gen_inv_quad_form_ldlt(w_mat, ldlt_Sigma, yT); } return lp; }
inline void check_pos_definite(const char* function, const char* name, const Eigen::Matrix<T_y, -1, -1>& y) { check_symmetric(function, name, y); check_positive_size(function, name, "rows", y.rows()); if (y.rows() == 1 && !(y(0, 0) > CONSTRAINT_TOLERANCE)) domain_error(function, name, "is not positive definite.", ""); Eigen::LDLT<Eigen::MatrixXd> cholesky = value_of_rec(y).ldlt(); if (cholesky.info() != Eigen::Success || !cholesky.isPositive() || (cholesky.vectorD().array() <= 0.0).any()) domain_error(function, name, "is not positive definite.", ""); check_not_nan(function, name, y); }