io.hpp
Go to the documentation of this file.
1 /*!
2  * \brief Input and output of vectors and matrices
3  *
4  * \author O. Krause
5  * \date 2013
6  *
7  *
8  * \par Copyright 1995-2015 Shark Development Team
9  *
10  * <BR><HR>
11  * This file is part of Shark.
12  * <http://image.diku.dk/shark/>
13  *
14  * Shark is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as published
16  * by the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * Shark is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 #ifndef REMORA_IO_HPP
29 #define REMORA_IO_HPP
30 
31 // Only forward definition required to define stream operations
32 #include <iosfwd>
33 #include <sstream>
34 #include "expression_types.hpp"
35 
36 
37 namespace remora{
38 
39  /** \brief output stream operator for vector expressions
40  *
41  * Any vector expressions can be written to a standard output stream
42  * as defined in the C++ standard library. For example:
43  * \code
44  * vector<float> v1(3),v2(3);
45  * for(size_t i=0; i<3; i++)
46  * {
47  * v1(i) = i+0.2;
48  * v2(i) = i+0.3;
49  * }
50  * cout << v1+v2 << endl;
51  * \endcode
52  * will display the some of the 2 vectors like this:
53  * \code
54  * [3](0.5,2.5,4.5)
55  * \endcode
56  *
57  * \param os is a standard basic output stream
58  * \param vec is a vector expression
59  * \return a reference to the resulting output stream
60  */
61  template<class E, class T, class VE>
62  // This function seems to be big. So we do not let the compiler inline it.
63  std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
64  const vector_expression<VE, cpu_tag> &vec) {
65  auto&& v = eval_block(vec);
66  typedef typename VE::size_type size_type;
67  size_type size = v.size ();
68  std::basic_ostringstream<E, T, std::allocator<E> > s;
69  s.flags (os.flags ());
70  s.imbue (os.getloc ());
71  s.precision (os.precision ());
72  s << '[' << size << "](";
73  if (size > 0)
74  s << v(0);
75  for (size_type i = 1; i < size; ++ i)
76  s << ',' << v(i);
77  s << ')';
78  return os << s.str ().c_str ();
79  }
80 
81  /** \brief output stream operator for matrix expressions
82  *
83  * it outputs the content of a \f$ (M \times N) \f$ matrix to a standard output
84  * stream using the following format:
85  * \c [ (rows),)(columns)](((m00),(m01),...,(m0N)),...,((mM0),(mM1),...,(mMN)))
86  *
87  * For example:
88  * \code
89  * matrix<float> m(3,3) = scalar_matrix<float>(3,3,1.0) - diagonal_matrix<float>(3,3,1.0);
90  * cout << m << endl;
91  * \encode
92  * will display
93  * \code
94  * [3,3]((0,1,1),(1,0,1),(1,1,0))
95  * \endcode
96  * This output is made for storing and retrieving matrices in a simple way but you can
97  * easily recognize the following:
98  * \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]
99  *
100  * \param os is a standard basic output stream
101  * \param mat is a matrix expression
102  * \return a reference to the resulting output stream
103  */
104  template<class E, class T, class ME>
105  // This function seems to be big. So we do not let the compiler inline it.
106  std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
107  const matrix_expression<ME, cpu_tag> &mat) {
108  auto&& m=eval_block(mat);
109  typedef typename ME::size_type size_type;
110  size_type size1 = m.size1 ();
111  size_type size2 = m.size2 ();
112  std::basic_ostringstream<E, T, std::allocator<E> > s;
113  s.flags (os.flags ());
114  s.imbue (os.getloc ());
115  s.precision (os.precision ());
116  s << '[' << size1 << ',' << size2 << "](";
117  if (size1 > 0) {
118  s << '(' ;
119  if (size2 > 0)
120  s << m(0, 0);
121  for (size_type j = 1; j < size2; ++ j)
122  s << ',' << m(0, j);
123  s << ')';
124  }
125  for (size_type i = 1; i < size1; ++ i) {
126  s << ",(" ;
127  if (size2 > 0)
128  s << m(i, 0);
129  for (size_type j = 1; j < size2; ++ j)
130  s << ',' << m(i, j);
131  s << ')';
132  }
133  s << ')';
134  return os << s.str().c_str ();
135  }
136 }
137 
138 #endif