Feellgood
sparseMat.h
Go to the documentation of this file.
1 #ifndef SPARSEMAT_H
2 #define SPARSEMAT_H
3 
19 #include <set>
20 #include <map>
21 #include <vector>
22 #include <iostream>
23 #include <cassert>
24 #include <algorithm>
25 #include <execution>
26 #include <mutex>
27 
28 #include "config.h"
29 #include "algebraCore.h"
30 
31 namespace algebra
32 {
33 
38 using MatrixShape = std::vector<std::set<int>>;
39 
46 {
59  struct SparseVector
60  {
61  std::mutex mutex;
62  std::vector<int> indices;
63  std::vector<double> values;
68  double& operator[](int j)
69  {
70  auto it = std::lower_bound(indices.begin(), indices.end(), j);
71  assert(it != indices.end() && *it == j);
72  int k = it - indices.begin();
73  return values[k];
74  }
75  };
76 
77 public:
79  SparseMatrix(const MatrixShape &shape) : rows(shape.size())
80  {
81  for (size_t i = 0; i < shape.size(); ++i)
82  {
83  const std::set<int>& row_shape = shape[i];
84  SparseVector& row = rows[i];
85  row.indices.reserve(row_shape.size());
86  for (auto it = row_shape.begin(); it != row_shape.end(); ++it)
87  row.indices.push_back(*it);
88  row.values.resize(row_shape.size());
89  }
90  }
91 
93  void clear()
94  {
95  for (SparseVector& row: rows)
96  for (double& value: row.values)
97  value = 0;
98  }
99 
103  void set(int i, int j, double val)
104  {
105  assert(i >= 0 && i < rows.size());
106  assert(j >= 0 && j < rows.size());
107  rows[i][j] = val;
108  }
109 
114  void add(int i, int j, double val)
115  {
116  assert(i >= 0 && i < rows.size());
117  assert(j >= 0 && j < rows.size());
118  SparseVector& row = rows[i];
119  std::mutex& mutex = row.mutex;
120  double& value = row[j];
121  mutex.lock();
122  value += val;
123  mutex.unlock();
124  }
125 
127  void print(std::ostream & flux = std::cout) const
128  {
129  flux << "[\n";
130  for (const SparseVector& row: rows)
131  {
132  flux << " {";
133  for (size_t k = 0; k < row.indices.size(); ++k)
134  {
135  flux << row.indices[k] << ": " << row.values[k];
136  flux << (k < row.indices.size()-1 ? ", " : "\n");
137  }
138  flux << "}\n";
139  }
140  flux << ']';
141  }
142 
144  double operator() (const int i, const int j) const
145  {
146  assert(i >= 0 && i < rows.size());
147  assert(j >= 0 && j < rows.size());
148  const SparseVector& row = rows[i];
149  auto it = std::lower_bound(row.indices.begin(), row.indices.end(), j);
150  if (it == row.indices.end() || *it != j)
151  return 0;
152  int k = it - row.indices.begin();
153  return row.values[k];
154  }
155 
157  template <typename T>
158  void mult(std::vector<T> const& X, std::vector<T> &Y)
159  {
160  assert(X.size() == rows.size());
161  assert(Y.size() == rows.size());
162  std::transform(EXEC_POL, rows.begin(), rows.end(), Y.begin(),
163  [&X](const SparseVector &row)
164  {
165  double val = 0;
166  for (size_t k = 0; k < row.indices.size(); ++k)
167  val += row.values[k] * X[row.indices[k]];
168  return val;
169  });
170  }
171 
173  template <typename T>
174  void build_diag_precond(std::vector<T> &D) const
175  {
176  assert(D.size() == rows.size());
177  for (size_t i = 0; i < rows.size(); ++i)
178  {
179  const double c = (*this)(i,i);
180  assert(c != 0);
181  D[i] = 1.0 / c;
182  }
183  }
184 
185 private:
190  std::vector<SparseVector> rows;
191 }; // end class SparseMatrix
192 
193 } // end namespace algebra
194 
195 #endif
Square sparse matrix.
Definition: sparseMat.h:46
void build_diag_precond(std::vector< T > &D) const
Definition: sparseMat.h:174
void clear()
Definition: sparseMat.h:93
void set(int i, int j, double val)
Definition: sparseMat.h:103
void mult(std::vector< T > const &X, std::vector< T > &Y)
Definition: sparseMat.h:158
std::vector< SparseVector > rows
Definition: sparseMat.h:190
void add(int i, int j, double val)
Definition: sparseMat.h:114
void print(std::ostream &flux=std::cout) const
Definition: sparseMat.h:127
SparseMatrix(const MatrixShape &shape)
Definition: sparseMat.h:79
double operator()(const int i, const int j) const
Definition: sparseMat.h:144
constexpr double D
Definition: tetra.h:54
std::vector< std::set< int > > MatrixShape
Definition: sparseMat.h:38
Definition: sparseMat.h:60
double & operator[](int j)
Definition: sparseMat.h:68
std::vector< int > indices
Definition: sparseMat.h:62
std::mutex mutex
Definition: sparseMat.h:61
std::vector< double > values
Definition: sparseMat.h:63