1 #ifndef STAN_MATH_PRIM_MAT_ERR_CHECK_SYMMETRIC_HPP
2 #define STAN_MATH_PRIM_MAT_ERR_CHECK_SYMMETRIC_HPP
3
4 #include <stan/math/prim/scal/err/domain_error.hpp>
5 #include <stan/math/prim/mat/err/check_square.hpp>
6 #include <stan/math/prim/mat/err/constraint_tolerance.hpp>
7 #include <stan/math/prim/mat/fun/Eigen.hpp>
8 #include <stan/math/prim/mat/meta/index_type.hpp>
9 #include <stan/math/prim/mat/fun/value_of.hpp>
10 #include <stan/math/prim/scal/meta/error_index.hpp>
11 #include <sstream>
12 #include <string>
13
14 namespace stan {
15 namespace math {
16
17 /**
18 * Check if the specified matrix is symmetric.
19 *
20 * The error message is either 0 or 1 indexed, specified by
21 * <code>stan::error_index::value</code>.
22 *
23 * @tparam T_y Type of scalar.
24 *
25 * @param function Function name (for error messages)
26 * @param name Variable name (for error messages)
27 * @param y Matrix to test
28 *
29 * @throw <code>std::invalid_argument</code> if the matrix is not square.
30 * @throw <code>std::domain_error</code> if any element not on the
31 * main diagonal is <code>NaN</code>
32 */
33 template <typename T_y>
check_symmetric(const char * function,const char * name,const Eigen::Matrix<T_y,Eigen::Dynamic,Eigen::Dynamic> & y)34 inline void check_symmetric(
35 const char* function, const char* name,
36 const Eigen::Matrix<T_y, Eigen::Dynamic, Eigen::Dynamic>& y) {
37 check_square(function, name, y);
38
39 using Eigen::Dynamic;
40 using Eigen::Matrix;
41 using std::fabs;
42
43 typedef typename index_type<Matrix<T_y, Dynamic, Dynamic> >::type size_type;
44
45 size_type k = y.rows();
46 if (k == 1)
47 return;
48 for (size_type m = 0; m < k; ++m) {
49 for (size_type n = m + 1; n < k; ++n) {
50 if (!(fabs(value_of(y(m, n)) - value_of(y(n, m)))
51 <= CONSTRAINT_TOLERANCE)) {
52 std::ostringstream msg1;
53 msg1 << "is not symmetric. " << name << "["
54 << stan::error_index::value + m << ","
55 << stan::error_index::value + n << "] = ";
56 std::string msg1_str(msg1.str());
57 std::ostringstream msg2;
58 msg2 << ", but " << name << "[" << stan::error_index::value + n << ","
59 << stan::error_index::value + m << "] = " << y(n, m);
60 std::string msg2_str(msg2.str());
61 domain_error(function, name, y(m, n), msg1_str.c_str(),
62 msg2_str.c_str());
63 }
64 }
65 }
66 }
67
68 } // namespace math
69 } // namespace stan
70 #endif
71