LOOS  v2.3.2
MatrixRead.hpp
1 /*
2  MatrixRead.hpp
3 
4  Reading of Matrix objects...
5 */
6 
7 
8 /*
9  This file is part of LOOS.
10 
11  LOOS (Lightweight Object-Oriented Structure library)
12  Copyright (c) 2008, Tod D. Romo, Alan Grossfield
13  Department of Biochemistry and Biophysics
14  School of Medicine & Dentistry, University of Rochester
15 
16  This package (LOOS) is free software: you can redistribute it and/or modify
17  it under the terms of the GNU General Public License as published by
18  the Free Software Foundation under version 3 of the License.
19 
20  This package is distributed in the hope that it will be useful,
21  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  GNU General Public License for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with this program. If not, see <http://www.gnu.org/licenses/>.
27 */
28 
29 
30 
31 #if !defined(LOOS_MATRIXREAD_HPP)
32 #define LOOS_MATRIXREAD_HPP
33 
34 #include <iostream>
35 #include <fstream>
36 #include <sstream>
37 #include <string>
38 #include <string.h> // ?
39 #include <stdexcept>
40 #include <cassert>
41 #include <iterator>
42 
43 #include <utility>
44 
45 #include <boost/format.hpp>
46 
47 #include <loos_defs.hpp>
48 #include <Matrix.hpp>
49 
50 
51 namespace loos {
52 
54  class MatrixReadError : public std::runtime_error {
55  public:
56  explicit MatrixReadError(const std::string& msg) : runtime_error(msg) { }
57  };
58 
59  // Forward declaration for reading implementations...
60  template<class T, class P, template<typename> class S>
62 
63 
64 
65  // The following are the templated global functions. Do not
66  // overload/specialize them. Instead, specialize the
67  // MatrixReadImpl class...
68 
69 
71  template<class T, class P, template<typename> class S>
73  return(MatrixReadImpl<T,P,S>::read(is));
74  }
75 
77  template<class T, class P, template<typename> class S>
78  void readAsciiMatrix(std::istream& is, Math::Matrix<T,P,S>& M) {
80  }
81 
83  template<class T, class P, template<typename> class S>
84  Math::Matrix<T,P,S> readAsciiMatrix(const std::string& fname) {
85  std::ifstream ifs(fname.c_str());
86  if (!ifs)
87  throw(MatrixReadError("Cannot open " + fname + " for reading."));
88  return(MatrixReadImpl<T,P,S>::read(ifs));
89  }
90 
92  template<class T, class P, template<typename> class S>
93  void readAsciiMatrix(const std::string& fname, Math::Matrix<T,P,S>& M) {
94  std::ifstream ifs(fname.c_str());
95  if (!ifs)
96  throw(MatrixReadError("Cannot open " + fname + " for reading."));
98  }
99 
100  // Implementations and specializations...
101 
102  template<class T, class P, template<typename> class S>
103  struct MatrixReadImpl {
104  static Math::Matrix<T,P,S> read(std::istream& is) {
105  std::string inbuf;
106  int m = 0, n = 0;
107 
108  // First, search for the marker...
109  int k = 0;
110  while (getline(is, inbuf).good()) {
111  ++k;
112  int i = sscanf(inbuf.c_str(), "# %d %d", &m, &n);
113  if (i == 2)
114  break;
115  }
116  if (m == 0 && n == 0)
117  throw(MatrixReadError("Could not find magic marker in matrix file"));
118  if (m == 0 || n == 0)
119  throw(MatrixReadError("Error while reading magic marker"));
120 
121 
122  T datum;
123  Math::Matrix<T,P,S> R(m, n);
124  for (int j=0;j < m; ++j) {
125  for (int i=0; i<n; ++i) {
126  if (!(is >> inbuf)) {
127  std::stringstream s;
128  s << "Read error at (" << j << "," << i << ") with input '" << inbuf << "'";
129  throw(MatrixReadError(s.str()));
130  }
131  std::istringstream iss(inbuf);
132  if (!(iss >> datum)) {
133  std::stringstream s;
134  s << "Invalid conversion on matrix read at (" << j << "," << i << ") of '" << inbuf << "'";
135  throw(MatrixReadError(s.str()));
136  }
137  R(j, i) = datum;
138  }
139  }
140 
141  return(R);
142  }
143  };
144 
146  template<class T, class P>
147  struct MatrixReadImpl<T,P,Math::SparseArray> {
148  static Math::Matrix<T,P, Math::SparseArray> read(std::istream& is) {
149  std::string inbuf;
150  uint m = 0, n = 0;
151  ulong l = 0;
152 
153  // First, search for the marker...
154  while (getline(is, inbuf).good()) {
155  char buf[20];
156  int i = sscanf(inbuf.c_str(), "# %lu %u %u %10s", &l, &m, &n, buf);
157  if (i != 4)
158  continue;
159  if (strncmp(buf, "SPARSE", 6) == 0)
160  break;
161  throw(MatrixReadError("Magic matrix line found, but the matrix appears not to be sparse."));
162  }
163 
164  if (m == 0)
165  throw(MatrixReadError("Could not find magic matrix line"));
166 
168  for (ulong i = 0; i<l; ++i) {
169  ulong j;
170  T datum;
171 
172  // Get the index
173  if (!(is >> j)) {
174  std::stringstream s;
175  s << "Invalid conversion on matrix read at [" << i << "]";
176  throw(MatrixReadError(s.str()));
177  }
178 
179  // Get the value
180  if (!(is >> datum)) {
181  std::stringstream s;
182  s << "Invalid conversion on matrix read at [" << i << "]";
183  throw(MatrixReadError(s.str()));
184  }
185  M[j] = datum;
186  }
187 
188  return(M);
189  }
190  };
191 
192 
194  template<class T, template<typename> class S>
195  struct MatrixReadImpl<T,Math::Triangular,S> {
196  static Math::Matrix<T, Math::Triangular, S> read(std::istream& is) {
197  std::string inbuf;
198  int m = 0;
199 
200  // First, search for the marker...
201  while (getline(is, inbuf).good()) {
202  char buf[20];
203  int i = sscanf(inbuf.c_str(), "# %d %10s", &m, buf);
204  if (i != 2)
205  continue;
206  if (strncmp(buf, "TRIANGULAR", 10) == 0)
207  break;
208  throw(MatrixReadError("Magic matrix line found, but the matrix appears not to be triangular."));
209  }
210 
211  if (m == 0)
212  throw(MatrixReadError("Could not find magic matrix line"));
213  int n = m;
214 
216  long s = R.size();
217  T datum;
218 
219  for (long i=0; i<s; i++) {
220  if (!(is >> datum)) {
221  std::stringstream s;
222  s << "Invalid conversion on matrix read at [" << i << "]";
223  throw(MatrixReadError(s.str()));
224  }
225  R[i] = datum;
226  }
227 
228  return(R);
229  }
230 
231 
232  };
233 
234 
235 }
236 
237 #endif
Simple matrix template class using policy classes to determine behavior.
Definition: MatrixImpl.hpp:53
Generic reading error class.
Definition: MatrixRead.hpp:54
Math::Matrix< T, P, S > readAsciiMatrix(std::istream &is)
Read in a matrix from a stream returning a newly created matrix.
Definition: MatrixRead.hpp:72
Namespace for most things not already encapsulated within a class.