Chris@16: // Chris@16: // Copyright (c) 2000-2010 Chris@16: // Joerg Walter, Mathias Koch, David Bellot Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // The authors gratefully acknowledge the support of Chris@16: // GeNeSys mbH & Co. KG in producing this work. Chris@16: // Chris@16: Chris@16: #ifndef _BOOST_UBLAS_IO_ Chris@16: #define _BOOST_UBLAS_IO_ Chris@16: Chris@16: // Only forward definition required to define stream operations Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: namespace boost { namespace numeric { namespace ublas { Chris@16: Chris@16: /** \brief output stream operator for vector expressions Chris@16: * Chris@16: * Any vector expressions can be written to a standard output stream Chris@16: * as defined in the C++ standard library. For example: Chris@16: * \code Chris@16: * vector v1(3),v2(3); Chris@16: * for(size_t i=0; i<3; i++) Chris@16: * { Chris@16: * v1(i) = i+0.2; Chris@16: * v2(i) = i+0.3; Chris@16: * } Chris@16: * cout << v1+v2 << endl; Chris@16: * \endcode Chris@16: * will display the some of the 2 vectors like this: Chris@16: * \code Chris@16: * [3](0.5,2.5,4.5) Chris@16: * \endcode Chris@16: * Chris@16: * \param os is a standard basic output stream Chris@16: * \param v is a vector expression Chris@16: * \return a reference to the resulting output stream Chris@16: */ Chris@16: template Chris@16: // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. Chris@16: std::basic_ostream &operator << (std::basic_ostream &os, Chris@16: const vector_expression &v) { Chris@16: typedef typename VE::size_type size_type; Chris@16: size_type size = v ().size (); Chris@16: std::basic_ostringstream > s; Chris@16: s.flags (os.flags ()); Chris@16: s.imbue (os.getloc ()); Chris@16: s.precision (os.precision ()); Chris@16: s << '[' << size << "]("; Chris@16: if (size > 0) Chris@16: s << v () (0); Chris@16: for (size_type i = 1; i < size; ++ i) Chris@16: s << ',' << v () (i); Chris@16: s << ')'; Chris@16: return os << s.str ().c_str (); Chris@16: } Chris@16: Chris@16: /** \brief input stream operator for vectors Chris@16: * Chris@16: * This is used to feed in vectors with data stored as an ASCII representation Chris@16: * from a standard input stream. Chris@16: * Chris@16: * From a file or any valid stream, the format is: Chris@16: * \c [](,,...) like for example: Chris@16: * \code Chris@16: * [5](1,2.1,3.2,3.14,0.2) Chris@16: * \endcode Chris@16: * Chris@16: * You can use it like this Chris@16: * \code Chris@16: * my_input_stream >> my_vector; Chris@16: * \endcode Chris@16: * Chris@16: * You can only put data into a valid \c vector<> not a \c vector_expression Chris@16: * Chris@16: * \param is is a standard basic input stream Chris@16: * \param v is a vector Chris@16: * \return a reference to the resulting input stream Chris@16: */ Chris@16: template Chris@16: // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. Chris@16: std::basic_istream &operator >> (std::basic_istream &is, Chris@16: vector &v) { Chris@16: typedef typename vector::size_type size_type; Chris@16: E ch; Chris@16: size_type size; Chris@16: if (is >> ch && ch != '[') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (is >> size >> ch && ch != ']') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: vector s (size); Chris@16: if (is >> ch && ch != '(') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: for (size_type i = 0; i < size; i ++) { Chris@16: if (is >> s (i) >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: if (i < size - 1) Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: if (is >> ch && ch != ')') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } Chris@16: } Chris@16: if (! is.fail ()) Chris@16: v.swap (s); Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: /** \brief output stream operator for matrix expressions Chris@16: * Chris@16: * it outpus the content of a \f$(M \times N)\f$ matrix to a standard output Chris@16: * stream using the following format: Chris@16: * \c[,]((,,...,),...,(,,...,)) Chris@16: * Chris@16: * For example: Chris@16: * \code Chris@16: * matrix m(3,3) = scalar_matrix(3,3,1.0) - diagonal_matrix(3,3,1.0); Chris@16: * cout << m << endl; Chris@16: * \encode Chris@16: * will display Chris@16: * \code Chris@16: * [3,3]((0,1,1),(1,0,1),(1,1,0)) Chris@16: * \endcode Chris@16: * This output is made for storing and retrieving matrices in a simple way but you can Chris@16: * easily recognize the following: Chris@16: * \f[ \left( \begin{array}{ccc} 1 & 1 & 1\\ 1 & 1 & 1\\ 1 & 1 & 1 \end{array} \right) - \left( \begin{array}{ccc} 1 & 0 & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{array} \right) = \left( \begin{array}{ccc} 0 & 1 & 1\\ 1 & 0 & 1\\ 1 & 1 & 0 \end{array} \right) \f] Chris@16: * Chris@16: * \param os is a standard basic output stream Chris@16: * \param m is a matrix expression Chris@16: * \return a reference to the resulting output stream Chris@16: */ Chris@16: template Chris@16: // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. Chris@16: std::basic_ostream &operator << (std::basic_ostream &os, Chris@16: const matrix_expression &m) { Chris@16: typedef typename ME::size_type size_type; Chris@16: size_type size1 = m ().size1 (); Chris@16: size_type size2 = m ().size2 (); Chris@16: std::basic_ostringstream > s; Chris@16: s.flags (os.flags ()); Chris@16: s.imbue (os.getloc ()); Chris@16: s.precision (os.precision ()); Chris@16: s << '[' << size1 << ',' << size2 << "]("; Chris@16: if (size1 > 0) { Chris@16: s << '(' ; Chris@16: if (size2 > 0) Chris@16: s << m () (0, 0); Chris@16: for (size_type j = 1; j < size2; ++ j) Chris@16: s << ',' << m () (0, j); Chris@16: s << ')'; Chris@16: } Chris@16: for (size_type i = 1; i < size1; ++ i) { Chris@16: s << ",(" ; Chris@16: if (size2 > 0) Chris@16: s << m () (i, 0); Chris@16: for (size_type j = 1; j < size2; ++ j) Chris@16: s << ',' << m () (i, j); Chris@16: s << ')'; Chris@16: } Chris@16: s << ')'; Chris@16: return os << s.str ().c_str (); Chris@16: } Chris@16: Chris@16: /** \brief input stream operator for matrices Chris@16: * Chris@16: * This is used to feed in matrices with data stored as an ASCII representation Chris@16: * from a standard input stream. Chris@16: * Chris@16: * From a file or any valid standard stream, the format is: Chris@16: * \c[,]((,,...,),...,(,,...,)) Chris@16: * Chris@16: * You can use it like this Chris@16: * \code Chris@16: * my_input_stream >> my_matrix; Chris@16: * \endcode Chris@16: * Chris@16: * You can only put data into a valid \c matrix<> not a \c matrix_expression Chris@16: * Chris@16: * \param is is a standard basic input stream Chris@16: * \param m is a matrix Chris@16: * \return a reference to the resulting input stream Chris@16: */ Chris@16: template Chris@16: // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. Chris@16: std::basic_istream &operator >> (std::basic_istream &is, Chris@16: matrix &m) { Chris@16: typedef typename matrix::size_type size_type; Chris@16: E ch; Chris@16: size_type size1, size2; Chris@16: if (is >> ch && ch != '[') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (is >> size1 >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (is >> size2 >> ch && ch != ']') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: matrix s (size1, size2); Chris@16: if (is >> ch && ch != '(') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: for (size_type i = 0; i < size1; i ++) { Chris@16: if (is >> ch && ch != '(') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: for (size_type j = 0; j < size2; j ++) { Chris@16: if (is >> s (i, j) >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: if (j < size2 - 1) { Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: } Chris@16: if (is >> ch && ch != ')') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: if (is >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: if (i < size1 - 1) { Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: } Chris@16: if (is >> ch && ch != ')') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } Chris@16: } Chris@16: if (! is.fail ()) Chris@16: m.swap (s); Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: /** \brief special input stream operator for symmetric matrices Chris@16: * Chris@16: * This is used to feed in symmetric matrices with data stored as an ASCII Chris@16: * representation from a standard input stream. Chris@16: * Chris@16: * You can simply write your matrices in a file or any valid stream and read them again Chris@16: * at a later time with this function. The format is the following: Chris@16: * \code [,]((,,...,),...,(,,...,)) \endcode Chris@16: * Chris@16: * You can use it like this Chris@16: * \code Chris@16: * my_input_stream >> my_symmetric_matrix; Chris@16: * \endcode Chris@16: * Chris@16: * You can only put data into a valid \c symmetric_matrix<>, not in a \c matrix_expression Chris@16: * This function also checks that input data form a valid symmetric matrix Chris@16: * Chris@16: * \param is is a standard basic input stream Chris@16: * \param m is a \c symmetric_matrix Chris@16: * \return a reference to the resulting input stream Chris@16: */ Chris@16: template Chris@16: // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it. Chris@16: std::basic_istream &operator >> (std::basic_istream &is, Chris@16: symmetric_matrix &m) { Chris@16: typedef typename symmetric_matrix::size_type size_type; Chris@16: E ch; Chris@16: size_type size1, size2; Chris@16: MT value; Chris@16: if (is >> ch && ch != '[') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (is >> size1 >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: symmetric_matrix s (size1, size2); Chris@16: if (is >> ch && ch != '(') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } else if (! is.fail ()) { Chris@16: for (size_type i = 0; i < size1; i ++) { Chris@16: if (is >> ch && ch != '(') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: for (size_type j = 0; j < size2; j ++) { Chris@16: if (is >> value >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: if (j < size2 - 1) { Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: if (i <= j) { Chris@16: // this is the first time we read this element - set the value Chris@16: s(i,j) = value; Chris@16: } Chris@16: else if ( s(i,j) != value ) { Chris@16: // matrix is not symmetric Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: if (is >> ch && ch != ')') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: if (is >> ch && ch != ',') { Chris@16: is.putback (ch); Chris@16: if (i < size1 - 1) { Chris@16: is.setstate (std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: } Chris@16: } Chris@16: if (is >> ch && ch != ')') { Chris@16: is.putback (ch); Chris@16: is.setstate (std::ios_base::failbit); Chris@16: } Chris@16: } Chris@16: if (! is.fail ()) Chris@16: m.swap (s); Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: Chris@16: }}} Chris@16: Chris@16: #endif