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