MarketIO.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_SPARSE_MARKET_IO_H
12 #define EIGEN_SPARSE_MARKET_IO_H
13 
14 #include <iostream>
15 #include <vector>
16 
17 // IWYU pragma: private
18 #include "./InternalHeaderCheck.h"
19 
20 namespace Eigen {
21 
22 namespace internal {
23 template <typename Scalar, typename StorageIndex>
24 inline void GetMarketLine(const char* line, StorageIndex& i, StorageIndex& j, Scalar& value) {
25  std::stringstream sline(line);
26  sline >> i >> j >> value;
27 }
28 
29 template <>
30 inline void GetMarketLine(const char* line, int& i, int& j, float& value) {
31  std::sscanf(line, "%d %d %g", &i, &j, &value);
32 }
33 
34 template <>
35 inline void GetMarketLine(const char* line, int& i, int& j, double& value) {
36  std::sscanf(line, "%d %d %lg", &i, &j, &value);
37 }
38 
39 template <>
40 inline void GetMarketLine(const char* line, int& i, int& j, std::complex<float>& value) {
41  std::sscanf(line, "%d %d %g %g", &i, &j, &numext::real_ref(value), &numext::imag_ref(value));
42 }
43 
44 template <>
45 inline void GetMarketLine(const char* line, int& i, int& j, std::complex<double>& value) {
46  std::sscanf(line, "%d %d %lg %lg", &i, &j, &numext::real_ref(value), &numext::imag_ref(value));
47 }
48 
49 template <typename Scalar, typename StorageIndex>
50 inline void GetMarketLine(const char* line, StorageIndex& i, StorageIndex& j, std::complex<Scalar>& value) {
51  std::stringstream sline(line);
52  Scalar valR, valI;
53  sline >> i >> j >> valR >> valI;
54  value = std::complex<Scalar>(valR, valI);
55 }
56 
57 template <typename RealScalar>
58 inline void GetDenseElt(const std::string& line, RealScalar& val) {
59  std::istringstream newline(line);
60  newline >> val;
61 }
62 
63 template <typename RealScalar>
64 inline void GetDenseElt(const std::string& line, std::complex<RealScalar>& val) {
65  RealScalar valR, valI;
66  std::istringstream newline(line);
67  newline >> valR >> valI;
68  val = std::complex<RealScalar>(valR, valI);
69 }
70 
71 template <typename Scalar>
72 inline void putMarketHeader(std::string& header, int sym) {
73  header = "%%MatrixMarket matrix coordinate ";
74  if (internal::is_same<Scalar, std::complex<float> >::value ||
75  internal::is_same<Scalar, std::complex<double> >::value) {
76  header += " complex";
77  if (sym == Symmetric)
78  header += " symmetric";
79  else if (sym == SelfAdjoint)
80  header += " Hermitian";
81  else
82  header += " general";
83  } else {
84  header += " real";
85  if (sym == Symmetric)
86  header += " symmetric";
87  else
88  header += " general";
89  }
90 }
91 
92 template <typename Scalar, typename StorageIndex>
93 inline void PutMatrixElt(Scalar value, StorageIndex row, StorageIndex col, std::ofstream& out) {
94  out << row << " " << col << " " << value << "\n";
95 }
96 template <typename Scalar, typename StorageIndex>
97 inline void PutMatrixElt(std::complex<Scalar> value, StorageIndex row, StorageIndex col, std::ofstream& out) {
98  out << row << " " << col << " " << value.real() << " " << value.imag() << "\n";
99 }
100 
101 template <typename Scalar>
102 inline void putDenseElt(Scalar value, std::ofstream& out) {
103  out << value << "\n";
104 }
105 template <typename Scalar>
106 inline void putDenseElt(std::complex<Scalar> value, std::ofstream& out) {
107  out << value.real() << " " << value.imag() << "\n";
108 }
109 
110 } // end namespace internal
111 
122 inline bool getMarketHeader(const std::string& filename, int& sym, bool& iscomplex, bool& isdense) {
123  sym = 0;
124  iscomplex = false;
125  isdense = false;
126  std::ifstream in(filename.c_str(), std::ios::in);
127  if (!in) return false;
128 
130  // The matrix header is always the first line in the file
131  std::getline(in, line);
132  eigen_assert(in.good());
133 
134  std::stringstream fmtline(line);
135  std::string substr[5];
136  fmtline >> substr[0] >> substr[1] >> substr[2] >> substr[3] >> substr[4];
137  if (substr[2].compare("array") == 0) isdense = true;
138  if (substr[3].compare("complex") == 0) iscomplex = true;
139  if (substr[4].compare("symmetric") == 0)
140  sym = Symmetric;
141  else if (substr[4].compare("Hermitian") == 0)
142  sym = SelfAdjoint;
143 
144  return true;
145 }
155 template <typename SparseMatrixType>
156 bool loadMarket(SparseMatrixType& mat, const std::string& filename) {
157  typedef typename SparseMatrixType::Scalar Scalar;
158  typedef typename SparseMatrixType::StorageIndex StorageIndex;
159  std::ifstream input(filename.c_str(), std::ios::in);
160  if (!input) return false;
161 
162  char rdbuffer[4096];
163  input.rdbuf()->pubsetbuf(rdbuffer, 4096);
164 
165  const int maxBuffersize = 2048;
166  char buffer[maxBuffersize];
167 
168  bool readsizes = false;
169 
171  std::vector<T> elements;
172 
173  Index M(-1), N(-1), NNZ(-1);
174  Index count = 0;
175  while (input.getline(buffer, maxBuffersize)) {
176  // skip comments
177  // NOTE An appropriate test should be done on the header to get the symmetry
178  if (buffer[0] == '%') continue;
179 
180  if (!readsizes) {
181  std::stringstream line(buffer);
182  line >> M >> N >> NNZ;
183  if (M > 0 && N > 0) {
184  readsizes = true;
185  mat.resize(M, N);
186  mat.reserve(NNZ);
187  elements.reserve(NNZ);
188  }
189  } else {
190  StorageIndex i(-1), j(-1);
191  Scalar value;
192  internal::GetMarketLine(buffer, i, j, value);
193 
194  i--;
195  j--;
196  if (i >= 0 && j >= 0 && i < M && j < N) {
197  ++count;
198  elements.push_back(T(i, j, value));
199  } else {
200  std::cerr << "Invalid read: " << i << "," << j << "\n";
201  return false;
202  }
203  }
204  }
205 
206  mat.setFromTriplets(elements.begin(), elements.end());
207  if (count != NNZ) {
208  std::cerr << count << "!=" << NNZ << "\n";
209  return false;
210  }
211  input.close();
212  return true;
213 }
214 
225 template <typename DenseType>
226 bool loadMarketDense(DenseType& mat, const std::string& filename) {
227  typedef typename DenseType::Scalar Scalar;
228  std::ifstream in(filename.c_str(), std::ios::in);
229  if (!in) return false;
230 
232  Index rows(0), cols(0);
233  do { // Skip comments
234  std::getline(in, line);
235  eigen_assert(in.good());
236  } while (line[0] == '%');
237  std::istringstream newline(line);
238  newline >> rows >> cols;
239 
240  bool sizes_not_positive = (rows < 1 || cols < 1);
241  bool wrong_input_rows = (DenseType::MaxRowsAtCompileTime != Dynamic && rows > DenseType::MaxRowsAtCompileTime) ||
242  (DenseType::RowsAtCompileTime != Dynamic && rows != DenseType::RowsAtCompileTime);
243  bool wrong_input_cols = (DenseType::MaxColsAtCompileTime != Dynamic && cols > DenseType::MaxColsAtCompileTime) ||
244  (DenseType::ColsAtCompileTime != Dynamic && cols != DenseType::ColsAtCompileTime);
245 
246  if (sizes_not_positive || wrong_input_rows || wrong_input_cols) {
247  if (sizes_not_positive) {
248  std::cerr << "non-positive row or column size in file" << filename << "\n";
249  } else {
250  std::cerr << "Input matrix can not be resized to" << rows << " x " << cols << "as given in " << filename << "\n";
251  }
252  in.close();
253  return false;
254  }
255 
256  mat.resize(rows, cols);
257  Index row = 0;
258  Index col = 0;
259  Index n = 0;
260  Scalar value;
261  while (std::getline(in, line) && (row < rows) && (col < cols)) {
263  // matrixmarket format is column major
264  mat(row, col) = value;
265  row++;
266  if (row == rows) {
267  row = 0;
268  col++;
269  }
270  n++;
271  }
272  in.close();
273  if (n != mat.size()) {
274  std::cerr << "Unable to read all elements from file " << filename << "\n";
275  return false;
276  }
277  return true;
278 }
283 template <typename VectorType>
285  return loadMarketDense(vec, filename);
286 }
287 
298 template <typename SparseMatrixType>
299 bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sym = 0) {
300  typedef typename SparseMatrixType::Scalar Scalar;
301  typedef typename SparseMatrixType::RealScalar RealScalar;
302  std::ofstream out(filename.c_str(), std::ios::out);
303  if (!out) return false;
304 
305  out.flags(std::ios_base::scientific);
306  out.precision(std::numeric_limits<RealScalar>::digits10 + 2);
307  std::string header;
308  internal::putMarketHeader<Scalar>(header, sym);
309  out << header << std::endl;
310  out << mat.rows() << " " << mat.cols() << " " << mat.nonZeros() << "\n";
311  int count = 0;
312  EIGEN_UNUSED_VARIABLE(count);
313  for (int j = 0; j < mat.outerSize(); ++j)
314  for (typename SparseMatrixType::InnerIterator it(mat, j); it; ++it) {
315  ++count;
316  internal::PutMatrixElt(it.value(), it.row() + 1, it.col() + 1, out);
317  }
318  out.close();
319  return true;
320 }
321 
332 template <typename DenseType>
333 bool saveMarketDense(const DenseType& mat, const std::string& filename) {
334  typedef typename DenseType::Scalar Scalar;
335  typedef typename DenseType::RealScalar RealScalar;
336  std::ofstream out(filename.c_str(), std::ios::out);
337  if (!out) return false;
338 
339  out.flags(std::ios_base::scientific);
340  out.precision(std::numeric_limits<RealScalar>::digits10 + 2);
341  if (internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value)
342  out << "%%MatrixMarket matrix array complex general\n";
343  else
344  out << "%%MatrixMarket matrix array real general\n";
345  out << mat.rows() << " " << mat.cols() << "\n";
346  for (Index i = 0; i < mat.cols(); i++) {
347  for (Index j = 0; j < mat.rows(); j++) {
349  }
350  }
351  out.close();
352  return true;
353 }
354 
359 template <typename VectorType>
361  return saveMarketDense(vec, filename);
362 }
363 
364 } // end namespace Eigen
365 
366 #endif // EIGEN_SPARSE_MARKET_IO_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
Eigen::Triplet< double > T
Definition: EigenUnitTest.cpp:11
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:966
#define eigen_assert(x)
Definition: Macros.h:910
m col(1)
m row(1)
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
SCALAR Scalar
Definition: bench_gemm.cpp:45
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:50
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
void compare(const Packet &a, const Packet &b)
Definition: blasutil.cpp:24
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
Index size() const
Definition: SparseMatrixBase.h:187
Index nonZeros() const
Definition: SparseCompressedBase.h:64
Index cols() const
Definition: SparseMatrix.h:161
Index outerSize() const
Definition: SparseMatrix.h:166
void resize(Index rows, Index cols)
Definition: SparseMatrix.h:734
Index rows() const
Definition: SparseMatrix.h:159
void setFromTriplets(const InputIterators &begin, const InputIterators &end)
Definition: SparseMatrix.h:1328
void reserve(Index reserveSize)
Definition: SparseMatrix.h:315
A small structure to hold a non zero as a triplet (i,j,value).
Definition: SparseUtil.h:187
@ N
Definition: constructor.cpp:22
@ SelfAdjoint
Definition: Constants.h:227
@ Symmetric
Definition: Constants.h:229
void putMarketHeader(std::string &header, int sym)
Definition: MarketIO.h:72
void PutMatrixElt(Scalar value, StorageIndex row, StorageIndex col, std::ofstream &out)
Definition: MarketIO.h:93
void GetDenseElt(const std::string &line, RealScalar &val)
Definition: MarketIO.h:58
void GetMarketLine(const char *line, StorageIndex &i, StorageIndex &j, Scalar &value)
Definition: MarketIO.h:24
void putDenseElt(Scalar value, std::ofstream &out)
Definition: MarketIO.h:102
EIGEN_DEVICE_FUNC internal::add_const_on_value_type_t< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar)> imag_ref(const Scalar &x)
Definition: MathFunctions.h:1072
EIGEN_DEVICE_FUNC internal::add_const_on_value_type_t< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar)> real_ref(const Scalar &x)
Definition: MathFunctions.h:1051
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
bool loadMarketVector(VectorType &vec, const std::string &filename)
Same functionality as loadMarketDense, deprecated.
Definition: MarketIO.h:284
squared absolute value
Definition: GlobalFunctions.h:87
bool saveMarket(const SparseMatrixType &mat, const std::string &filename, int sym=0)
writes a sparse Matrix to a marketmarket format file
Definition: MarketIO.h:299
bool loadMarket(SparseMatrixType &mat, const std::string &filename)
Loads a sparse matrix from a matrixmarket format file.
Definition: MarketIO.h:156
bool saveMarketVector(const VectorType &vec, const std::string &filename)
Same functionality as saveMarketDense, deprecated.
Definition: MarketIO.h:360
bool getMarketHeader(const std::string &filename, int &sym, bool &iscomplex, bool &isdense)
Reads the header of a matrixmarket file and determines the properties of a matrix.
Definition: MarketIO.h:122
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
bool loadMarketDense(DenseType &mat, const std::string &filename)
Loads a dense Matrix or Vector from a matrixmarket file. If a statically sized matrix has to be parse...
Definition: MarketIO.h:226
bool saveMarketDense(const DenseType &mat, const std::string &filename)
writes a dense Matrix or vector to a marketmarket format file
Definition: MarketIO.h:333
const int Dynamic
Definition: Constants.h:25
string filename
Definition: MergeRestartFiles.py:39
val
Definition: calibrate.py:119
line
Definition: calibrate.py:103
Definition: Eigen_Colamd.h:49
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
Definition: Meta.h:205
Definition: fft_test_shared.h:66
std::ofstream out("Result.txt")
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2