Line data Source code
1 : /*
2 : * This file implement input/output operation on sparse matrix
3 : * It has been found on the internet. No Copyright.
4 : */
5 :
6 :
7 :
8 : #include <boost/numeric/ublas/vector.hpp>
9 : #include <boost/numeric/ublas/matrix_sparse.hpp>
10 : #include <boost/numeric/ublas/io.hpp>
11 : #include <boost/numeric/ublas/operation.hpp>
12 :
13 : #include <iostream>
14 :
15 :
16 : namespace boost { namespace numeric { namespace ublas {
17 :
18 : namespace io {
19 :
20 : template<class ME>
21 : class sparse_ioproxy {
22 : public:
23 : typedef ME matrix_expression_type;
24 : typedef sparse_ioproxy<ME> self_type;
25 1 : sparse_ioproxy(matrix_expression_type & me) : me(me) {}
26 :
27 4 : matrix_expression_type & operator() () const {
28 4 : return me;
29 : }
30 0 : matrix_expression_type & operator() () {
31 0 : return me;
32 : }
33 :
34 : private:
35 : sparse_ioproxy () {}
36 : matrix_expression_type &me;
37 : };
38 :
39 : template < class ME >
40 1 : sparse_ioproxy<ME> sparse(ME& me) {
41 1 : return sparse_ioproxy<ME>(me);
42 : }
43 :
44 : template<class E, class T, class ME>
45 : std::basic_ostream<E, T> &
46 1 : output (std::basic_ostream<E, T> &os,
47 : const sparse_ioproxy<ME> m,
48 : row_major_tag) {
49 :
50 : typedef typename ME::size_type size_type;
51 : typedef ME ex_type;
52 1 : size_type size1 = m () .size1 ();
53 1 : size_type size2 = m () .size2 ();
54 2 : std::basic_ostringstream<E, T, std::allocator<E> > s;
55 1 : s.flags (os.flags ());
56 1 : s.imbue (os.getloc ());
57 1 : s.precision (os.precision ());
58 1 : s << '[' << size1 << ',' << size2 << "]";
59 1 : s << "(";
60 2 : typename ex_type::const_iterator1 i = m().begin1();
61 2 : typename ex_type::const_iterator1 n = m().end1();
62 1 : bool one_back = (i != n);
63 583 : for (; i != n; ++i) {
64 582 : typename ex_type::const_iterator2 ri=i.begin();
65 582 : typename ex_type::const_iterator2 rn=i.end();
66 291 : bool nonempty = (ri != rn);
67 291 : if (nonempty) {
68 582 : s << "(" << ri.index1() << "," << ri.index2()
69 582 : << ":" << *ri << ")";
70 291 : ++ri;
71 : }
72 1799 : for (; ri != rn; ++ri) {
73 1508 : s << ",(" << ri.index1() << "," << ri.index2()
74 1508 : << ":" << *ri << ")";
75 : }
76 291 : if (nonempty) { s << ';'; }
77 : }
78 1 : if (one_back) s.seekp(-1, std::ios_base::cur);
79 1 : s << ')';
80 2 : return os << s.str ().c_str ();
81 : }
82 :
83 : template<class E, class T, class ME>
84 : std::basic_ostream<E, T> &
85 : output (std::basic_ostream<E, T> &os,
86 : const sparse_ioproxy<ME> m,
87 : column_major_tag) {
88 :
89 : typedef typename ME::size_type size_type;
90 : typedef ME ex_type;
91 : size_type size1 = m () .size1 ();
92 : size_type size2 = m () .size2 ();
93 : std::basic_ostringstream<E, T, std::allocator<E> > s;
94 : s.flags (os.flags ());
95 : s.imbue (os.getloc ());
96 : s.precision (os.precision ());
97 : s << '[' << size1 << ',' << size2 << "]";
98 : s << "(";
99 : typename ex_type::const_iterator2 i = m().begin2();
100 : typename ex_type::const_iterator2 n = m().end2();
101 : bool one_back = (i != n);
102 : for (; i != n; ++i) {
103 : typename ex_type::const_iterator1 ri=i.begin();
104 : typename ex_type::const_iterator1 rn=i.end();
105 : bool nonempty = (ri != rn);
106 : if (nonempty) {
107 : s << "(" << ri.index1() << "," << ri.index2()
108 : << ":" << *ri << ")";
109 : ++ri;
110 : }
111 : for (; ri != rn; ++ri) {
112 : s << ",(" << ri.index1() << "," << ri.index2()
113 : << ":" << *ri << ")";
114 : }
115 : if (nonempty) { s << ';'; }
116 : }
117 : if (one_back) s.seekp(-1, std::ios_base::cur);
118 : s << ')';
119 : return os << s.str ().c_str ();
120 : }
121 :
122 : template<class E, class T, class ME>
123 : std::basic_ostream<E, T> &
124 1 : operator << (std::basic_ostream<E, T> &os,
125 : const sparse_ioproxy<ME> m) {
126 1 : return output(os, m, typename ME::orientation_category());
127 : }
128 :
129 : // note: the orientation of the data must match the orientation
130 : // of the matrix (otherwise push_back() will fail)
131 : template<class E, class T, class ME>
132 : std::basic_istream<E, T> &
133 0 : operator >> (std::basic_istream<E, T> &is,
134 : sparse_ioproxy<ME> m) {
135 :
136 : typedef typename ME::size_type size_type;
137 : typedef typename ME::value_type value_type;
138 : //typedef ME ex_type;
139 : E ch;
140 : size_type size1, size2;
141 0 : if (is >> ch && ch != '[') {
142 0 : is.putback (ch);
143 0 : is.setstate (std::ios_base::failbit);
144 0 : } else if (is >> size1 >> ch && ch != ',') {
145 0 : is.putback (ch);
146 0 : is.setstate (std::ios_base::failbit);
147 0 : } else if (is >> size2 >> ch && ch != ']') {
148 0 : is.putback (ch);
149 0 : is.setstate (std::ios_base::failbit);
150 0 : } else if (! is.fail ()) {
151 0 : ME s(size1, size2);
152 0 : if (is >> ch && ch != '(') {
153 0 : is.putback (ch);
154 0 : is.setstate (std::ios_base::failbit);
155 : } else {
156 0 : while ( ! is.fail() ) {
157 0 : is >> ch;
158 0 : if (ch == ')') {
159 0 : break;
160 0 : } else if (ch != '(') {
161 0 : is.putback (ch);
162 0 : is.setstate (std::ios_base::failbit);
163 : } else {
164 : // read triplet
165 : size_type i,j;
166 : value_type a;
167 0 : is >> i >> ch;
168 0 : if (is.fail() || ch != ',') {
169 0 : is.putback (ch);
170 0 : is.setstate (std::ios_base::failbit);
171 : }
172 0 : is >> j >> ch;
173 0 : if (is.fail() || ch != ':') {
174 0 : is.putback (ch);
175 0 : is.setstate (std::ios_base::failbit);
176 : }
177 0 : is >> a >> ch;
178 0 : if (is.fail() || ch != ')') {
179 0 : is.putback (ch);
180 0 : is.setstate (std::ios_base::failbit);
181 : }
182 0 : s.push_back(i,j,a);
183 0 : is >> ch;
184 0 : if ( ch == ')' ) {
185 0 : break;
186 0 : } else if ( ch != ',' && ch != ';' ) {
187 0 : is.putback (ch);
188 0 : is.setstate (std::ios_base::failbit);
189 : }
190 : }
191 : }
192 : }
193 0 : if (! is.fail ())
194 0 : m().assign_temporary (s);
195 : }
196 0 : return is;
197 : }
198 : }
199 :
200 : }}}
|