]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/numeric/ublas/include/boost/numeric/ublas/io.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / numeric / ublas / include / boost / numeric / ublas / io.hpp
1 //
2 // Copyright (c) 2000-2010
3 // Joerg Walter, Mathias Koch, David Bellot
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // The authors gratefully acknowledge the support of
10 // GeNeSys mbH & Co. KG in producing this work.
11 //
12
13 #ifndef _BOOST_UBLAS_IO_
14 #define _BOOST_UBLAS_IO_
15
16 // Only forward definition required to define stream operations
17 #include <iosfwd>
18 #include <sstream>
19 #include <boost/numeric/ublas/matrix_expression.hpp>
20
21
22 namespace boost { namespace numeric { namespace ublas {
23
24 /** \brief output stream operator for vector expressions
25 *
26 * Any vector expressions can be written to a standard output stream
27 * as defined in the C++ standard library. For example:
28 * \code
29 * vector<float> v1(3),v2(3);
30 * for(size_t i=0; i<3; i++)
31 * {
32 * v1(i) = i+0.2;
33 * v2(i) = i+0.3;
34 * }
35 * cout << v1+v2 << endl;
36 * \endcode
37 * will display the some of the 2 vectors like this:
38 * \code
39 * [3](0.5,2.5,4.5)
40 * \endcode
41 *
42 * \param os is a standard basic output stream
43 * \param v is a vector expression
44 * \return a reference to the resulting output stream
45 */
46 template<class E, class T, class VE>
47 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
48 std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
49 const vector_expression<VE> &v) {
50 typedef typename VE::size_type size_type;
51 size_type size = v ().size ();
52 std::basic_ostringstream<E, T, std::allocator<E> > s;
53 s.flags (os.flags ());
54 s.imbue (os.getloc ());
55 s.precision (os.precision ());
56 s << '[' << size << "](";
57 if (size > 0)
58 s << v () (0);
59 for (size_type i = 1; i < size; ++ i)
60 s << ',' << v () (i);
61 s << ')';
62 return os << s.str ().c_str ();
63 }
64
65 /** \brief input stream operator for vectors
66 *
67 * This is used to feed in vectors with data stored as an ASCII representation
68 * from a standard input stream.
69 *
70 * From a file or any valid stream, the format is:
71 * \c [<vector size>](<data1>,<data2>,...<dataN>) like for example:
72 * \code
73 * [5](1,2.1,3.2,3.14,0.2)
74 * \endcode
75 *
76 * You can use it like this
77 * \code
78 * my_input_stream >> my_vector;
79 * \endcode
80 *
81 * You can only put data into a valid \c vector<> not a \c vector_expression
82 *
83 * \param is is a standard basic input stream
84 * \param v is a vector
85 * \return a reference to the resulting input stream
86 */
87 template<class E, class T, class VT, class VA>
88 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
89 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
90 vector<VT, VA> &v) {
91 typedef typename vector<VT, VA>::size_type size_type;
92 E ch;
93 size_type size;
94 if (is >> ch && ch != '[') {
95 is.putback (ch);
96 is.setstate (std::ios_base::failbit);
97 } else if (is >> size >> ch && ch != ']') {
98 is.putback (ch);
99 is.setstate (std::ios_base::failbit);
100 } else if (! is.fail ()) {
101 vector<VT, VA> s (size);
102 if (is >> ch && ch != '(') {
103 is.putback (ch);
104 is.setstate (std::ios_base::failbit);
105 } else if (! is.fail ()) {
106 for (size_type i = 0; i < size; i ++) {
107 if (is >> s (i) >> ch && ch != ',') {
108 is.putback (ch);
109 if (i < size - 1)
110 is.setstate (std::ios_base::failbit);
111 break;
112 }
113 }
114 if (is >> ch && ch != ')') {
115 is.putback (ch);
116 is.setstate (std::ios_base::failbit);
117 }
118 }
119 if (! is.fail ())
120 v.swap (s);
121 }
122 return is;
123 }
124
125 /** \brief output stream operator for matrix expressions
126 *
127 * it outpus the content of a \f$(M \times N)\f$ matrix to a standard output
128 * stream using the following format:
129 * \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
130 *
131 * For example:
132 * \code
133 * matrix<float> m(3,3) = scalar_matrix<float>(3,3,1.0) - diagonal_matrix<float>(3,3,1.0);
134 * cout << m << endl;
135 * \encode
136 * will display
137 * \code
138 * [3,3]((0,1,1),(1,0,1),(1,1,0))
139 * \endcode
140 * This output is made for storing and retrieving matrices in a simple way but you can
141 * easily recognize the following:
142 * \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]
143 *
144 * \param os is a standard basic output stream
145 * \param m is a matrix expression
146 * \return a reference to the resulting output stream
147 */
148 template<class E, class T, class ME>
149 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
150 std::basic_ostream<E, T> &operator << (std::basic_ostream<E, T> &os,
151 const matrix_expression<ME> &m) {
152 typedef typename ME::size_type size_type;
153 size_type size1 = m ().size1 ();
154 size_type size2 = m ().size2 ();
155 std::basic_ostringstream<E, T, std::allocator<E> > s;
156 s.flags (os.flags ());
157 s.imbue (os.getloc ());
158 s.precision (os.precision ());
159 s << '[' << size1 << ',' << size2 << "](";
160 if (size1 > 0) {
161 s << '(' ;
162 if (size2 > 0)
163 s << m () (0, 0);
164 for (size_type j = 1; j < size2; ++ j)
165 s << ',' << m () (0, j);
166 s << ')';
167 }
168 for (size_type i = 1; i < size1; ++ i) {
169 s << ",(" ;
170 if (size2 > 0)
171 s << m () (i, 0);
172 for (size_type j = 1; j < size2; ++ j)
173 s << ',' << m () (i, j);
174 s << ')';
175 }
176 s << ')';
177 return os << s.str ().c_str ();
178 }
179
180 /** \brief input stream operator for matrices
181 *
182 * This is used to feed in matrices with data stored as an ASCII representation
183 * from a standard input stream.
184 *
185 * From a file or any valid standard stream, the format is:
186 * \c[<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>))
187 *
188 * You can use it like this
189 * \code
190 * my_input_stream >> my_matrix;
191 * \endcode
192 *
193 * You can only put data into a valid \c matrix<> not a \c matrix_expression
194 *
195 * \param is is a standard basic input stream
196 * \param m is a matrix
197 * \return a reference to the resulting input stream
198 */
199 template<class E, class T, class MT, class MF, class MA>
200 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
201 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
202 matrix<MT, MF, MA> &m) {
203 typedef typename matrix<MT, MF, MA>::size_type size_type;
204 E ch;
205 size_type size1, size2;
206 if (is >> ch && ch != '[') {
207 is.putback (ch);
208 is.setstate (std::ios_base::failbit);
209 } else if (is >> size1 >> ch && ch != ',') {
210 is.putback (ch);
211 is.setstate (std::ios_base::failbit);
212 } else if (is >> size2 >> ch && ch != ']') {
213 is.putback (ch);
214 is.setstate (std::ios_base::failbit);
215 } else if (! is.fail ()) {
216 matrix<MT, MF, MA> s (size1, size2);
217 if (is >> ch && ch != '(') {
218 is.putback (ch);
219 is.setstate (std::ios_base::failbit);
220 } else if (! is.fail ()) {
221 for (size_type i = 0; i < size1; i ++) {
222 if (is >> ch && ch != '(') {
223 is.putback (ch);
224 is.setstate (std::ios_base::failbit);
225 break;
226 }
227 for (size_type j = 0; j < size2; j ++) {
228 if (is >> s (i, j) >> ch && ch != ',') {
229 is.putback (ch);
230 if (j < size2 - 1) {
231 is.setstate (std::ios_base::failbit);
232 break;
233 }
234 }
235 }
236 if (is >> ch && ch != ')') {
237 is.putback (ch);
238 is.setstate (std::ios_base::failbit);
239 break;
240 }
241 if (is >> ch && ch != ',') {
242 is.putback (ch);
243 if (i < size1 - 1) {
244 is.setstate (std::ios_base::failbit);
245 break;
246 }
247 }
248 }
249 if (is >> ch && ch != ')') {
250 is.putback (ch);
251 is.setstate (std::ios_base::failbit);
252 }
253 }
254 if (! is.fail ())
255 m.swap (s);
256 }
257 return is;
258 }
259
260 /** \brief special input stream operator for symmetric matrices
261 *
262 * This is used to feed in symmetric matrices with data stored as an ASCII
263 * representation from a standard input stream.
264 *
265 * You can simply write your matrices in a file or any valid stream and read them again
266 * at a later time with this function. The format is the following:
267 * \code [<rows>,<columns>]((<m00>,<m01>,...,<m0N>),...,(<mM0>,<mM1>,...,<mMN>)) \endcode
268 *
269 * You can use it like this
270 * \code
271 * my_input_stream >> my_symmetric_matrix;
272 * \endcode
273 *
274 * You can only put data into a valid \c symmetric_matrix<>, not in a \c matrix_expression
275 * This function also checks that input data form a valid symmetric matrix
276 *
277 * \param is is a standard basic input stream
278 * \param m is a \c symmetric_matrix
279 * \return a reference to the resulting input stream
280 */
281 template<class E, class T, class MT, class MF1, class MF2, class MA>
282 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
283 std::basic_istream<E, T> &operator >> (std::basic_istream<E, T> &is,
284 symmetric_matrix<MT, MF1, MF2, MA> &m) {
285 typedef typename symmetric_matrix<MT, MF1, MF2, MA>::size_type size_type;
286 E ch;
287 size_type size1, size2;
288 MT value;
289 if (is >> ch && ch != '[') {
290 is.putback (ch);
291 is.setstate (std::ios_base::failbit);
292 } else if (is >> size1 >> ch && ch != ',') {
293 is.putback (ch);
294 is.setstate (std::ios_base::failbit);
295 } else if (is >> size2 >> ch && (size2 != size1 || ch != ']')) { // symmetric matrix must be square
296 is.putback (ch);
297 is.setstate (std::ios_base::failbit);
298 } else if (! is.fail ()) {
299 symmetric_matrix<MT, MF1, MF2, MA> s (size1, size2);
300 if (is >> ch && ch != '(') {
301 is.putback (ch);
302 is.setstate (std::ios_base::failbit);
303 } else if (! is.fail ()) {
304 for (size_type i = 0; i < size1; i ++) {
305 if (is >> ch && ch != '(') {
306 is.putback (ch);
307 is.setstate (std::ios_base::failbit);
308 break;
309 }
310 for (size_type j = 0; j < size2; j ++) {
311 if (is >> value >> ch && ch != ',') {
312 is.putback (ch);
313 if (j < size2 - 1) {
314 is.setstate (std::ios_base::failbit);
315 break;
316 }
317 }
318 if (i <= j) {
319 // this is the first time we read this element - set the value
320 s(i,j) = value;
321 }
322 else if ( s(i,j) != value ) {
323 // matrix is not symmetric
324 is.setstate (std::ios_base::failbit);
325 break;
326 }
327 }
328 if (is >> ch && ch != ')') {
329 is.putback (ch);
330 is.setstate (std::ios_base::failbit);
331 break;
332 }
333 if (is >> ch && ch != ',') {
334 is.putback (ch);
335 if (i < size1 - 1) {
336 is.setstate (std::ios_base::failbit);
337 break;
338 }
339 }
340 }
341 if (is >> ch && ch != ')') {
342 is.putback (ch);
343 is.setstate (std::ios_base::failbit);
344 }
345 }
346 if (! is.fail ())
347 m.swap (s);
348 }
349 return is;
350 }
351
352
353 }}}
354
355 #endif