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 "algebraCore.h"
33 
34 namespace algebra
35 {
36 
41 using MatrixShape = std::vector<std::set<int>>;
42 
51 {
52  friend class r_sparseMat;
53 
57  using SparseVector = std::map<int, double>;
58 
59 public:
61  w_sparseMat(int N) : rows(N) {}
62 
69  void insert(const int i, const int j, const double val)
70  {
71  assert(i >= 0 && i < rows.size());
72  assert(j >= 0 && j < rows.size());
73  rows[i][j] += val;
74  }
75 
76 private:
77  std::vector<SparseVector> rows;
78 };
79 
80 
87 {
101  {
102  std::mutex mutex;
103  std::vector<int> indices;
104  std::vector<double> values;
105  };
106 
107 public:
109  r_sparseMat(const w_sparseMat &source) : rows(source.rows.size())
110  {
111  for (size_t i = 0; i < source.rows.size(); ++i)
112  {
113  const w_sparseMat::SparseVector& source_row = source.rows[i];
114  SparseVector& row = rows[i];
115  row.indices.reserve(source_row.size());
116  row.values.reserve(source_row.size());
117  for (auto it = source_row.begin(); it != source_row.end(); ++it)
118  {
119  row.indices.push_back(it->first);
120  row.values.push_back(it->second);
121  }
122  }
123  }
124 
126  r_sparseMat(const MatrixShape &shape) : rows(shape.size())
127  {
128  for (size_t i = 0; i < shape.size(); ++i)
129  {
130  const std::set<int>& row_shape = shape[i];
131  SparseVector& row = rows[i];
132  row.indices.reserve(row_shape.size());
133  for (auto it = row_shape.begin(); it != row_shape.end(); ++it)
134  row.indices.push_back(*it);
135  row.values.resize(row_shape.size());
136  }
137  }
138 
140  void clear()
141  {
142  for (SparseVector& row: rows)
143  for (double& value: row.values)
144  value = 0;
145  }
146 
151  void add(int i, int j, double val)
152  {
153  assert(i >= 0 && i < rows.size());
154  assert(j >= 0 && j < rows.size());
155  SparseVector& row = rows[i];
156  auto it = std::lower_bound(row.indices.begin(), row.indices.end(), j);
157  assert(it != row.indices.end() && *it == j);
158  int k = it - row.indices.begin();
159  std::mutex& mutex = row.mutex;
160  double& value = row.values[k];
161  mutex.lock();
162  value += val;
163  mutex.unlock();
164  }
165 
167  void print(std::ostream & flux = std::cout) const
168  {
169  flux << "[\n";
170  for (const SparseVector& row: rows)
171  {
172  flux << " {";
173  for (size_t k = 0; k < row.indices.size(); ++k)
174  {
175  flux << row.indices[k] << ": " << row.values[k];
176  flux << (k < row.indices.size()-1 ? ", " : "\n");
177  }
178  flux << "}\n";
179  }
180  flux << ']';
181  }
182 
184  double operator() (const int i, const int j) const
185  {
186  assert(i >= 0 && i < rows.size());
187  assert(j >= 0 && j < rows.size());
188  const SparseVector& row = rows[i];
189  auto it = std::lower_bound(row.indices.begin(), row.indices.end(), j);
190  if (it == row.indices.end() || *it != j)
191  return 0;
192  int k = it - row.indices.begin();
193  return row.values[k];
194  }
195 
197  template <typename T>
198  void mult(std::vector<T> const& X, std::vector<T> &Y)
199  {
200  assert(X.size() == rows.size());
201  assert(Y.size() == rows.size());
202  std::transform(std::execution::par, rows.begin(), rows.end(), Y.begin(),
203  [&X](const SparseVector &row)
204  {
205  double val = 0;
206  for (size_t k = 0; k < row.indices.size(); ++k)
207  val += row.values[k] * X[row.indices[k]];
208  return val;
209  });
210  }
211 
213  template <typename T>
214  void build_diag_precond(std::vector<T> &D) const
215  {
216  assert(D.size() == rows.size());
217  for (size_t i = 0; i < rows.size(); ++i)
218  {
219  const double c = (*this)(i,i);
220  assert(c != 0);
221  D[i] = 1.0 / c;
222  }
223  }
224 
225 private:
230  std::vector<SparseVector> rows;
231 }; // end class r_sparseMat
232 
233 } // end namespace algebra
234 
235 #endif
Read-mode square sparse matrix.
Definition: sparseMat.h:87
r_sparseMat(const MatrixShape &shape)
Definition: sparseMat.h:126
void mult(std::vector< T > const &X, std::vector< T > &Y)
Definition: sparseMat.h:198
std::vector< SparseVector > rows
Definition: sparseMat.h:230
void build_diag_precond(std::vector< T > &D) const
Definition: sparseMat.h:214
void clear()
Definition: sparseMat.h:140
r_sparseMat(const w_sparseMat &source)
Definition: sparseMat.h:109
void print(std::ostream &flux=std::cout) const
Definition: sparseMat.h:167
double operator()(const int i, const int j) const
Definition: sparseMat.h:184
void add(int i, int j, double val)
Definition: sparseMat.h:151
Write-mode sparse matrix.
Definition: sparseMat.h:51
w_sparseMat(int N)
Definition: sparseMat.h:61
void insert(const int i, const int j, const double val)
Definition: sparseMat.h:69
std::map< int, double > SparseVector
Definition: sparseMat.h:57
const int N
Definition: facette.h:17
constexpr double D
Definition: tetra.h:32
std::vector< std::set< int > > MatrixShape
Definition: sparseMat.h:41
Definition: sparseMat.h:101
std::vector< double > values
Definition: sparseMat.h:104
std::vector< int > indices
Definition: sparseMat.h:103
std::mutex mutex
Definition: sparseMat.h:102