diff --git a/include/boost/numeric/ublas/io.hpp b/include/boost/numeric/ublas/io.hpp index 8ba186e1..88f7f174 100644 --- a/include/boost/numeric/ublas/io.hpp +++ b/include/boost/numeric/ublas/io.hpp @@ -174,6 +174,79 @@ namespace boost { namespace numeric { namespace ublas { return is; } + // Special input operator for symmetrix_matrix + template + // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. + std::basic_istream &operator >> (std::basic_istream &is, + symmetric_matrix &m) { + typedef typename symmetric_matrix::size_type size_type; + E ch; + size_type size1, size2; + MT value; + if (is >> ch && ch != '[') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + } else if (is >> size1 >> ch && ch != ',') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square + is.putback (ch); + is.setstate (std::ios_base::failbit); + } else if (! is.fail ()) { + symmetric_matrix s (size1, size2); + if (is >> ch && ch != '(') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + } else if (! is.fail ()) { + for (size_type i = 0; i < size1; i ++) { + if (is >> ch && ch != '(') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + break; + } + for (size_type j = 0; j < size2; j ++) { + if (is >> value >> ch && ch != ',') { + is.putback (ch); + if (j < size2 - 1) { + is.setstate (std::ios_base::failbit); + break; + } + } + if (i <= j) { + // this is the first time we read this element - set the value + s(i,j) = value; + } + else if ( s(i,j) != value ) { + // matrix is not symmetric + is.setstate (std::ios_base::failbit); + break; + } + } + if (is >> ch && ch != ')') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + break; + } + if (is >> ch && ch != ',') { + is.putback (ch); + if (i < size1 - 1) { + is.setstate (std::ios_base::failbit); + break; + } + } + } + if (is >> ch && ch != ')') { + is.putback (ch); + is.setstate (std::ios_base::failbit); + } + } + if (! is.fail ()) + m.swap (s); + } + return is; + } + + }}} #endif