Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

io.hpp

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2000-2010
00003 //  Joerg Walter, Mathias Koch, David Bellot
00004 //
00005 //  Distributed under the Boost Software License, Version 1.0. (See
00006 //  accompanying file LICENSE_1_0.txt or copy at
00007 //  http://www.boost.org/LICENSE_1_0.txt)
00008 //
00009 //  The authors gratefully acknowledge the support of
00010 //  GeNeSys mbH & Co. KG in producing this work.
00011 //
00012 
00013 #ifndef _BOOST_UBLAS_IO_
00014 #define _BOOST_UBLAS_IO_
00015 
00016 // Only forward definition required to define stream operations
00017 #include <iosfwd>
00018 #include <sstream>
00019 #include <boost/numeric/ublas/matrix_expression.hpp>
00020 
00021 
00022 namespace boost { namespace numeric { namespace ublas {
00023 
00046     template<class E, class T, class VE>
00047     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
00048     std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
00049                                            const vector_expression<VE> &v) {
00050         typedef typename VE::size_type size_type;
00051         size_type size = v ().size ();
00052         std::basic_ostringstream<E, T, std::allocator<E> > s;
00053         s.flags (os.flags ());
00054         s.imbue (os.getloc ());
00055         s.precision (os.precision ());
00056         s << '[' << size << "](";
00057         if (size > 0)
00058             s << v () (0);
00059         for (size_type i = 1; i < size; ++ i)
00060             s << ',' << v () (i);
00061         s << ')';
00062         return os << s.str ().c_str ();
00063     }
00064 
00087     template<class E, class T, class VT, class VA>
00088     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
00089     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
00090                                            vector<VT, VA> &v) {
00091         typedef typename vector<VT, VA>::size_type size_type;
00092         E ch;
00093         size_type size;
00094         if (is >> ch && ch != '[') {
00095             is.putback (ch);
00096             is.setstate (std::ios_base::failbit);
00097         } else if (is >> size >> ch && ch != ']') {
00098             is.putback (ch);
00099             is.setstate (std::ios_base::failbit);
00100         } else if (! is.fail ()) {
00101             vector<VT, VA> s (size);
00102             if (is >> ch && ch != '(') {
00103                 is.putback (ch);
00104                 is.setstate (std::ios_base::failbit);
00105             } else if (! is.fail ()) {
00106                 for (size_type i = 0; i < size; i ++) {
00107                     if (is >> s (i) >> ch && ch != ',') {
00108                         is.putback (ch);
00109                         if (i < size - 1)
00110                             is.setstate (std::ios_base::failbit);
00111                         break;
00112                     }
00113                 }
00114                 if (is >> ch && ch != ')') {
00115                     is.putback (ch);
00116                     is.setstate (std::ios_base::failbit);
00117                 }
00118             }
00119             if (! is.fail ())
00120                 v.swap (s);
00121         }
00122         return is;
00123     }
00124 
00148     template<class E, class T, class ME>
00149     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
00150     std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
00151                                            const matrix_expression<ME> &m) {
00152         typedef typename ME::size_type size_type;
00153         size_type size1 = m ().size1 ();
00154         size_type size2 = m ().size2 ();
00155         std::basic_ostringstream<E, T, std::allocator<E> > s;
00156         s.flags (os.flags ());
00157         s.imbue (os.getloc ());
00158         s.precision (os.precision ());
00159         s << '[' << size1 << ',' << size2 << "](";
00160         if (size1 > 0) {
00161             s << '(' ;
00162             if (size2 > 0)
00163                 s << m () (0, 0);
00164             for (size_type j = 1; j < size2; ++ j)
00165                 s << ',' << m () (0, j);
00166             s << ')';
00167         }
00168         for (size_type i = 1; i < size1; ++ i) {
00169             s << ",(" ;
00170             if (size2 > 0)
00171                 s << m () (i, 0);
00172             for (size_type j = 1; j < size2; ++ j)
00173                 s << ',' << m () (i, j);
00174             s << ')';
00175         }
00176         s << ')';
00177         return os << s.str ().c_str ();
00178     }
00179 
00199     template<class E, class T, class MT, class MF, class MA>
00200     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
00201     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
00202                                            matrix<MT, MF, MA> &m) {
00203         typedef typename matrix<MT, MF, MA>::size_type size_type;
00204         E ch;
00205         size_type size1, size2;
00206         if (is >> ch && ch != '[') {
00207             is.putback (ch);
00208             is.setstate (std::ios_base::failbit);
00209         } else if (is >> size1 >> ch && ch != ',') {
00210             is.putback (ch);
00211             is.setstate (std::ios_base::failbit);
00212         } else if (is >> size2 >> ch && ch != ']') {
00213             is.putback (ch);
00214             is.setstate (std::ios_base::failbit);
00215         } else if (! is.fail ()) {
00216             matrix<MT, MF, MA> s (size1, size2);
00217             if (is >> ch && ch != '(') {
00218                 is.putback (ch);
00219                 is.setstate (std::ios_base::failbit);
00220             } else if (! is.fail ()) {
00221                 for (size_type i = 0; i < size1; i ++) {
00222                     if (is >> ch && ch != '(') {
00223                         is.putback (ch);
00224                         is.setstate (std::ios_base::failbit);
00225                         break;
00226                     }
00227                     for (size_type j = 0; j < size2; j ++) {
00228                         if (is >> s (i, j) >> ch && ch != ',') {
00229                             is.putback (ch);
00230                             if (j < size2 - 1) {
00231                                 is.setstate (std::ios_base::failbit);
00232                                 break;
00233                             }
00234                         }
00235                     }
00236                     if (is >> ch && ch != ')') {
00237                         is.putback (ch);
00238                         is.setstate (std::ios_base::failbit);
00239                         break;
00240                     }
00241                     if (is >> ch && ch != ',') {
00242                        is.putback (ch);
00243                        if (i < size1 - 1) {
00244                             is.setstate (std::ios_base::failbit);
00245                             break;
00246                        }
00247                     }
00248                 }
00249                 if (is >> ch && ch != ')') {
00250                     is.putback (ch);
00251                     is.setstate (std::ios_base::failbit);
00252                 }
00253             }
00254             if (! is.fail ())
00255                 m.swap (s);
00256         }
00257         return is;
00258     }
00259 
00281     template<class E, class T, class MT, class MF1, class MF2, class MA>
00282     // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
00283     std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
00284                                            symmetric_matrix<MT, MF1, MF2, MA> &m) {
00285         typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type;
00286         E ch;
00287         size_type size1, size2;
00288         MT value;
00289         if (is >> ch && ch != '[') {
00290             is.putback (ch);
00291             is.setstate (std::ios_base::failbit);
00292         } else if (is >> size1 >> ch && ch != ',') {
00293             is.putback (ch);
00294             is.setstate (std::ios_base::failbit);
00295         } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square
00296             is.putback (ch);
00297             is.setstate (std::ios_base::failbit);
00298         } else if (! is.fail ()) {
00299             symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2);
00300             if (is >> ch && ch != '(') {
00301                 is.putback (ch);
00302                 is.setstate (std::ios_base::failbit);
00303              } else if (! is.fail ()) {
00304                 for (size_type i = 0; i < size1; i ++) {
00305                     if (is >> ch && ch != '(') {
00306                         is.putback (ch);
00307                         is.setstate (std::ios_base::failbit);
00308                         break;
00309                     }
00310                     for (size_type j = 0; j < size2; j ++) {
00311                         if (is >> value >> ch && ch != ',') {
00312                             is.putback (ch);
00313                             if (j < size2 - 1) {
00314                                 is.setstate (std::ios_base::failbit);
00315                                 break;
00316                             }
00317                         }
00318                         if (i <= j) { 
00319                              // this is the first time we read this element - set the value
00320                             s(i,j) = value;
00321                         }
00322                         else if ( s(i,j) != value ) {
00323                             // matrix is not symmetric
00324                             is.setstate (std::ios_base::failbit);
00325                             break;
00326                         }
00327                      }
00328                      if (is >> ch && ch != ')') {
00329                          is.putback (ch);
00330                          is.setstate (std::ios_base::failbit);
00331                          break;
00332                      }
00333                      if (is >> ch && ch != ',') {
00334                         is.putback (ch);
00335                         if (i < size1 - 1) {
00336                              is.setstate (std::ios_base::failbit);
00337                              break;
00338                         }
00339                      }
00340                 }
00341                 if (is >> ch && ch != ')') {
00342                     is.putback (ch);
00343                     is.setstate (std::ios_base::failbit);
00344                 }
00345             }
00346             if (! is.fail ())
00347                 m.swap (s);
00348         }
00349         return is;
00350     }
00351  
00352 
00353 }}}
00354 
00355 #endif