1 #ifndef STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP
2 #define STAN_MATH_PRIM_MAT_ERR_CHECK_CORR_MATRIX_HPP
3
4 #include <stan/math/prim/scal/err/domain_error.hpp>
5 #include <stan/math/prim/scal/err/check_positive_size.hpp>
6 #include <stan/math/prim/mat/err/check_pos_definite.hpp>
7 #include <stan/math/prim/mat/err/check_symmetric.hpp>
8 #include <stan/math/prim/scal/err/check_size_match.hpp>
9 #include <stan/math/prim/mat/err/constraint_tolerance.hpp>
10 #include <stan/math/prim/mat/fun/Eigen.hpp>
11 #include <stan/math/prim/mat/meta/index_type.hpp>
12 #include <stan/math/prim/scal/meta/error_index.hpp>
13 #include <sstream>
14 #include <string>
15
16 namespace stan {
17 namespace math {
18
19 /**
20 * Check if the specified matrix is a valid
21 * correlation matrix.
22 *
23 * A valid correlation matrix is symmetric, has a unit diagonal
24 * (all 1 values), and has all values between -1 and 1
25 * (inclusive).
26 *
27 * This function throws exceptions if the variable is not a valid
28 * correlation matrix.
29 *
30 * @tparam T_y Type of scalar
31 *
32 * @param function Name of the function this was called from
33 * @param name Name of the variable
34 * @param y Matrix to test
35 *
36 * @throw <code>std::invalid_argument</code> if the matrix is not square
37 * or if the matrix is 0x0
38 * @throw <code>std::domain_error</code> if the matrix is non-symmetric,
39 * diagonals not near 1, not positive definite, or any of the
40 * elements nan.
41 */
42 template <typename T_y>
check_corr_matrix(const char * function,const char * name,const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic> & y)43 inline void check_corr_matrix(
44 const char* function, const char* name,
45 const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y) {
46 using Eigen::Matrix;
47
48 typedef
49 typename index_type<Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic> >::type
50 size_t;
51
52 check_size_match(function, "Rows of correlation matrix", y.rows(),
53 "columns of correlation matrix", y.cols());
54 check_positive_size(function, name, "rows", y.rows());
55 check_symmetric(function, "y", y);
56
57 for (size_t k = 0; k < y.rows(); ++k) {
58 if (!(fabs(y(k, k) - 1.0) <= CONSTRAINT_TOLERANCE)) {
59 std::ostringstream msg;
60 msg << "is not a valid correlation matrix. " << name << "("
61 << stan::error_index::value + k << "," << stan::error_index::value + k
62 << ") is ";
63 std::string msg_str(msg.str());
64 domain_error(function, name, y(k, k), msg_str.c_str(),
65 ", but should be near 1.0");
66 }
67 }
68 check_pos_definite(function, "y", y);
69 }
70
71 } // namespace math
72 } // namespace stan
73 #endif
74