Feellgood
sparseMat.h
Go to the documentation of this file.
1 #ifndef SPARSEMAT_H
2 #define SPARSEMAT_H
3 
23 #include <set>
24 #include <map>
25 #include <vector>
26 #include <iostream>
27 #include <cassert>
28 #include <algorithm>
29 #include <execution>
30 #include <mutex>
31 
32 #include "config.h"
33 #include "algebraCore.h"
34 
35 namespace algebra
36 {
37 
42 using MatrixShape = std::vector<std::set<int>>;
43 
52 {
53  friend class r_sparseMat;
54 
58  using SparseVector = std::map<int, double>;
59 
60 public:
62  w_sparseMat(int N) : rows(N) {}
63 
70  void insert(const int i, const int j, const double val)
71  {
72  assert(i >= 0 && i < rows.size());
73  assert(j >= 0 && j < rows.size());
74  rows[i][j] += val;
75  }
76 
77 private:
79  std::vector<SparseVector> rows;
80 };
81 
82 
89 {
103  {
104  std::mutex mutex;
105  std::vector<int> indices;
106  std::vector<double> values;
111  double& operator[](int j)
112  {
113  auto it = std::lower_bound(indices.begin(), indices.end(), j);
114  assert(it != indices.end() && *it == j);
115  int k = it - indices.begin();
116  return values[k];
117  }
118  };
119 
120 public:
122  r_sparseMat(const w_sparseMat &source) : rows(source.rows.size())
123  {
124  for (size_t i = 0; i < source.rows.size(); ++i)
125  {
126  const w_sparseMat::SparseVector& source_row = source.rows[i];
127  SparseVector& row = rows[i];
128  row.indices.reserve(source_row.size());
129  row.values.reserve(source_row.size());
130  for (auto it = source_row.begin(); it != source_row.end(); ++it)
131  {
132  row.indices.push_back(it->first);
133  row.values.push_back(it->second);
134  }
135  }
136  }
137 
139  r_sparseMat(const MatrixShape &shape) : rows(shape.size())
140  {
141  for (size_t i = 0; i < shape.size(); ++i)
142  {
143  const std::set<int>& row_shape = shape[i];
144  SparseVector& row = rows[i];
145  row.indices.reserve(row_shape.size());
146  for (auto it = row_shape.begin(); it != row_shape.end(); ++it)
147  row.indices.push_back(*it);
148  row.values.resize(row_shape.size());
149  }
150  }
151 
153  void clear()
154  {
155  for (SparseVector& row: rows)
156  for (double& value: row.values)
157  value = 0;
158  }
159 
163  void set(int i, int j, double val)
164  {
165  assert(i >= 0 && i < rows.size());
166  assert(j >= 0 && j < rows.size());
167  rows[i][j] = val;
168  }
169 
174  void add(int i, int j, double val)
175  {
176  assert(i >= 0 && i < rows.size());
177  assert(j >= 0 && j < rows.size());
178  SparseVector& row = rows[i];
179  std::mutex& mutex = row.mutex;
180  double& value = row[j];
181  mutex.lock();
182  value += val;
183  mutex.unlock();
184  }
185 
187  void print(std::ostream & flux = std::cout) const
188  {
189  flux << "[\n";
190  for (const SparseVector& row: rows)
191  {
192  flux << " {";
193  for (size_t k = 0; k < row.indices.size(); ++k)
194  {
195  flux << row.indices[k] << ": " << row.values[k];
196  flux << (k < row.indices.size()-1 ? ", " : "\n");
197  }
198  flux << "}\n";
199  }
200  flux << ']';
201  }
202 
204  double operator() (const int i, const int j) const
205  {
206  assert(i >= 0 && i < rows.size());
207  assert(j >= 0 && j < rows.size());
208  const SparseVector& row = rows[i];
209  auto it = std::lower_bound(row.indices.begin(), row.indices.end(), j);
210  if (it == row.indices.end() || *it != j)
211  return 0;
212  int k = it - row.indices.begin();
213  return row.values[k];
214  }
215 
217  template <typename T>
218  void mult(std::vector<T> const& X, std::vector<T> &Y)
219  {
220  assert(X.size() == rows.size());
221  assert(Y.size() == rows.size());
222  std::transform(EXEC_POL, rows.begin(), rows.end(), Y.begin(),
223  [&X](const SparseVector &row)
224  {
225  double val = 0;
226  for (size_t k = 0; k < row.indices.size(); ++k)
227  val += row.values[k] * X[row.indices[k]];
228  return val;
229  });
230  }
231 
233  template <typename T>
234  void build_diag_precond(std::vector<T> &D) const
235  {
236  assert(D.size() == rows.size());
237  for (size_t i = 0; i < rows.size(); ++i)
238  {
239  const double c = (*this)(i,i);
240  assert(c != 0);
241  D[i] = 1.0 / c;
242  }
243  }
244 
245 private:
250  std::vector<SparseVector> rows;
251 }; // end class r_sparseMat
252 
253 } // end namespace algebra
254 
255 #endif
Read-mode square sparse matrix.
Definition: sparseMat.h:89
r_sparseMat(const MatrixShape &shape)
Definition: sparseMat.h:139
void mult(std::vector< T > const &X, std::vector< T > &Y)
Definition: sparseMat.h:218
std::vector< SparseVector > rows
Definition: sparseMat.h:250
void build_diag_precond(std::vector< T > &D) const
Definition: sparseMat.h:234
void clear()
Definition: sparseMat.h:153
r_sparseMat(const w_sparseMat &source)
Definition: sparseMat.h:122
void print(std::ostream &flux=std::cout) const
Definition: sparseMat.h:187
double operator()(const int i, const int j) const
Definition: sparseMat.h:204
void add(int i, int j, double val)
Definition: sparseMat.h:174
void set(int i, int j, double val)
Definition: sparseMat.h:163
Write-mode sparse matrix.
Definition: sparseMat.h:52
w_sparseMat(int N)
Definition: sparseMat.h:62
void insert(const int i, const int j, const double val)
Definition: sparseMat.h:70
std::map< int, double > SparseVector
Definition: sparseMat.h:58
std::vector< SparseVector > rows
Definition: sparseMat.h:79
const int N
Definition: facette.h:17
constexpr double D
Definition: tetra.h:32
std::vector< std::set< int > > MatrixShape
Definition: sparseMat.h:42
Definition: sparseMat.h:103
std::vector< double > values
Definition: sparseMat.h:106
double & operator[](int j)
Definition: sparseMat.h:111
std::vector< int > indices
Definition: sparseMat.h:105
std::mutex mutex
Definition: sparseMat.h:104