io.hpp 13 KB

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