LOOS  v2.3.2
MatrixWrite.hpp
1 /*
2  MatrixWrite.hpp
3 
4  Class for handling writing 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 #if !defined(LOOS_MATRIXWRITE_HPP)
31 #define LOOS_MATRIXWRITE_HPP
32 
33 #include <iostream>
34 #include <fstream>
35 #include <sstream>
36 #include <string>
37 #include <string.h> // ?
38 #include <stdexcept>
39 #include <cassert>
40 #include <iterator>
41 
42 #include <algorithm>
43 
44 #include <utility>
45 #include <boost/format.hpp>
46 
47 #include <loos_defs.hpp>
48 
49 #include <Matrix.hpp>
50 
51 
52 namespace loos {
53 
54 
55  // Forward declaration for matrix writing implementation
56  template<class T, class P, template<typename> class S, class F>
58 
59  namespace internal {
60 
61  // This is the default formatter for matrix elements
62  template<typename T>
64  std::string operator()(const T& t) {
65  std::stringstream ss;
66  ss << t;
67  return(ss.str());
68  }
69  };
70  }
71 
72 
74 
83  template<typename T>
85  public:
86  PreciseMatrixFormatter(const int width, const int precision) : wi(width), pr(precision) { }
87  PreciseMatrixFormatter() : wi(16), pr(8) { }
88 
89  std::string operator()(const T& t) {
90  std::ostringstream oss;
91  oss << std::setw(wi) << std::setprecision(pr) << t;
92  return(oss.str());
93  }
94 
95  private:
96  int wi, pr;
97 
98  };
99 
100 
102  template<typename T>
104  public:
105  ScientificMatrixFormatter(const int width, const int precision) : wi (width), pr(precision) { }
106  ScientificMatrixFormatter() : wi(16), pr(8) { }
107 
108  std::string operator()(const T& t) {
109  std::ostringstream oss;
110  oss << std::scientific << std::setw(wi) << std::setprecision(pr) << t;
111  return(oss.str());
112  }
113 
114  private:
115  int wi, pr;
116 
117  };
118 
119 
120  // The following are the templated global functions. Do not
121  // overload/specialize them. Instead, specialize the
122  // MatrixWriteImpl class...
123 
125 
139  template<class T, class P, template<typename> class S, class F>
140  std::ostream& writeAsciiMatrix(std::ostream& os, const Math::Matrix<T,P,S>& M,
141  const std::string& meta, const Math::Range& start,
142  const Math::Range& end, const bool trans = false, F fmt = F()) {
143  return(MatrixWriteImpl<T,P,S,F>::write(os, M, meta, start, end, trans, fmt));
144  }
145 
146 
148  template<class T, class P, template<typename> class S>
149  std::ostream& writeAsciiMatrix(std::ostream& os, const Math::Matrix<T,P,S>& M,
150  const std::string& meta, const Math::Range& start,
151  const Math::Range& end, const bool trans = false) {
152  return(MatrixWriteImpl<T,P,S,internal::BasicMatrixFormatter<T> >::write(os, M, meta, start, end, trans));
153  }
154 
156  template<class T, class P, template<typename> class S, class F>
157  std::ostream& writeAsciiMatrix(std::ostream& os, const Math::Matrix<T,P,S>& M,
158  const std::string& meta, const bool trans = false, F fmt = F()) {
159  Math::Range start(0,0);
160  Math::Range end(M.rows(), M.cols());
161  return(MatrixWriteImpl<T,P,S,F>::write(os, M, meta, start, end, trans, fmt));
162  }
163 
165 
175  template<class T, class P, template<typename> class S>
176  std::ostream& writeAsciiMatrix(std::ostream& os, const Math::Matrix<T,P,S>& M,
177  const std::string& meta, const bool trans = false) {
178  Math::Range start(0,0);
179  Math::Range end(M.rows(), M.cols());
180  return(MatrixWriteImpl<T,P,S,internal::BasicMatrixFormatter<T> >::write(os, M, meta, start, end, trans));
181  }
182 
184  template<class T, class P, template<typename> class S, class F>
185  void writeAsciiMatrix(const std::string& fname, const Math::Matrix<T,P,S>& M,
186  const std::string& meta, const Math::Range& start,
187  const Math::Range& end, const bool trans = false, F fmt = F()) {
188  std::ofstream ofs(fname.c_str());
189  if (!ofs.is_open())
190  throw(std::runtime_error("Cannot open " + fname + " for writing."));
191  MatrixWriteImpl<T,P,S,F>::write(ofs, M, meta, start, end, trans, fmt);
192  }
193 
195  template<class T, class P, template<typename> class S>
196  void writeAsciiMatrix(const std::string& fname, const Math::Matrix<T,P,S>& M,
197  const std::string& meta, const Math::Range& start,
198  const Math::Range& end, const bool trans = false) {
199  std::ofstream ofs(fname.c_str());
200  if (!ofs.is_open())
201  throw(std::runtime_error("Cannot open " + fname + " for writing."));
202  MatrixWriteImpl<T,P,S,internal::BasicMatrixFormatter<T> >::write(ofs, M, meta, start, end, trans);
203  }
204 
205 
207  template<class T, class P, template<typename> class S, class F>
208  void writeAsciiMatrix(const std::string& fname, const Math::Matrix<T,P,S>& M,
209  const std::string& meta, const bool trans = false, F fmt = F()) {
210  Math::Range start(0,0);
211  Math::Range end(M.rows(), M.cols());
212 
213  std::ofstream ofs(fname.c_str());
214  if (!ofs.is_open())
215  throw(std::runtime_error("Cannot open " + fname + " for writing."));
216  MatrixWriteImpl<T,P,S,F>::write(ofs, M, meta, start, end, trans, fmt);
217  }
218 
219 
221 
227  template<class T, class P, template<typename> class S>
228  void writeAsciiMatrix(const std::string& fname, const Math::Matrix<T,P,S>& M,
229  const std::string& meta, const bool trans = false) {
230  Math::Range start(0,0);
231  Math::Range end(M.rows(), M.cols());
232 
233  std::ofstream ofs(fname.c_str());
234  if (!ofs.is_open())
235  throw(std::runtime_error("Cannot open " + fname + " for writing."));
236  MatrixWriteImpl<T,P,S,internal::BasicMatrixFormatter<T> >::write(ofs, M, meta, start, end, trans);
237  }
238 
239 
240  // Writing implementation and specializations...
241 
242  template<class T, class P, template<typename> class S, class F>
243  struct MatrixWriteImpl {
244  static std::ostream& write(std::ostream& os,
245  const Math::Matrix<T,P,S>& M,
246  const std::string& meta,
247  const Math::Range& start, const Math::Range& end,
248  const bool trans, F fmt = F()) {
249  os << "# " << meta << std::endl;
250 
251  uint m = end.first - start.first;
252  uint n = end.second - start.second;
253  uint ja = start.first;
254  uint jb = end.first;
255  uint ia = start.second;
256  uint ib = end.second;
257 
258  if (trans) {
259  std::swap(m,n);
260  std::swap(ja, ia);
261  std::swap(jb, ib);
262  }
263 
264  os << boost::format("# %d %d (%d)\n") % m % n % 0;
265  for (uint j=ja; j<jb; j++) {
266  for (uint i=ia; i<ib; i++)
267  if (trans)
268  os << fmt(M(i, j)) << " ";
269  else
270  os << fmt(M(j, i)) << " ";
271  os << std::endl;
272  }
273  return(os);
274  }
275  };
276 
278 
279  template<class T, class P, class F>
280  struct MatrixWriteImpl<T, P, Math::SparseArray, F> {
281  static std::ostream& write(std::ostream& os,
283  const std::string& meta,
284  const Math::Range& start, const Math::Range& end,
285  const bool trans, F fmt = F()) {
286  os << "# " << meta << std::endl;
287  os << boost::format("# %d %d %d SPARSE\n") % M.actualSize() % M.rows() % M.cols();
289 
290  for (ci = M.begin(); ci != M.end(); ++ci)
291  os << (*ci).first << "\t" << fmt((*ci).second) << std::endl;
292 
293  return(os);
294  }
295  };
296 
297 
299 
300  template<class T, template<typename> class S, class F>
301  struct MatrixWriteImpl<T, Math::Triangular, S, F> {
302  static std::ostream& write(std::ostream& os,
304  const std::string& meta,
305  const Math::Range& start, const Math::Range& end,
306  const bool trans, F fmt = F()) {
307  os << "# " << meta << std::endl;
308  os << boost::format("# %d TRIANGULAR\n") % M.rows();
309  long s = M.size();
310  for (long i=0; i<s; i++)
311  os << fmt(M[i]) << std::endl;
312 
313  return(os);
314  }
315  };
316 
317 }
318 
319 
320 #endif
Simple matrix template class using policy classes to determine behavior.
Definition: MatrixImpl.hpp:53
Generic matrix element formatter using scientific notation...
std::ostream & writeAsciiMatrix(std::ostream &os, const Math::Matrix< T, P, S > &M, const std::string &meta, const Math::Range &start, const Math::Range &end, const bool trans=false, F fmt=F())
Write a submatrix to a stream.
Generic matrix element formatter allowing setting of width and precision.
Definition: MatrixWrite.hpp:84
std::pair< uint, uint > Range
Specify a range for columns/rows [first,second)
Definition: MatrixImpl.hpp:49
Namespace for most things not already encapsulated within a class.