GemaCoreLib
The GeMA Core library
gmArmadilloSolverMatrix.h
Go to the documentation of this file.
1 /************************************************************************
2 **
3 ** Copyright (C) 2014 by Carlos Augusto Teixera Mendes
4 ** All rights reserved.
5 **
6 ** This file is part of the "GeMA" software. It's use should respect
7 ** the terms in the license agreement that can be found together
8 ** with this source code.
9 ** It is provided AS IS, with NO WARRANTY OF ANY KIND,
10 ** INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11 ** A PARTICULAR PURPOSE.
12 **
13 ************************************************************************/
14 
25 #ifndef _GEMA_ARMADILLO_SOLVER_MATRIX_H_
26 #define _GEMA_ARMADILLO_SOLVER_MATRIX_H_
27 
28 #include "gmSolverMatrix.h"
29 #include "gmThreadManager.h"
30 #include "gmSparseMatrix.h"
31 
32 #include <assert.h>
33 
34 #include <armadillo>
35 
36 template <class T> class GmAppendBuffer;
37 
39 template <class T> class GmArmadilloSolverMatrixBase : public GmSolverMatrix
40 {
41 public:
44  : _mat(nlin, ncol)
45  {
46  Q_UNUSED(options);
48 
49  _mat.zeros();
50  _sym = false;
51  }
52 
55 
56  // See comments on the base class
57  virtual bool supportsBatchInsert() const { return false; }
58 
59  // See comments on the base class
60  virtual bool supportsSparseLayouts() const { return false; }
61 
62  // See comments on the base class
63  virtual bool supportsRandomSet() const { return true; }
64 
65  // See comments on the base class
66  virtual ParallelAddMode supportedParallelAddMode() const { return REENTRANT_SUPPORT; }
67 
68  // See comments on the base class
69  virtual bool beginBatchInsert(size_t expectedEntries = 0) { Q_UNUSED(expectedEntries); assert(GmThreadManager::inMainThread()); return true; }
70 
71  // See comments on the base class
72  virtual bool endBatchInsert(bool discardData = false) { Q_UNUSED(discardData); assert(GmThreadManager::inMainThread()); return true; }
73 
74  // See comments on the base class
75  virtual GmSparseMatrixLayoutBuilder* layoutBuilder() const { assert(GmThreadManager::inMainThread()); return NULL; }
76 
77  // See comments on the base class
78  virtual bool emptyLayout() const { assert(GmThreadManager::inMainThread()); return false; }
79 
80  // See comments on the base class
81  virtual bool symmetric() const { return _sym.loadAcquire(); }
82 
83  // See comments on the base class
84  virtual void setSymmetric(bool sym) { _sym.storeRelease(sym); }
85 
86  // See comments on the base class
87  virtual int nlin() const { return _mat.n_rows; }
88 
89  // See comments on the base class
90  virtual int ncol() const { return _mat.n_cols; }
91 
92  // See comments on the base class
93  virtual int layoutSize() const { assert(GmThreadManager::inMainThread()); return _mat.n_elem; }
94 
95  // See comments on the base class
96  virtual double at(int lin, int col) const { assert(GmThreadManager::inMainThread()); return _mat(lin, col); }
97 
98  // See comments on the base class
99  virtual bool inLayout(int lin, int col) const { assert(GmThreadManager::inMainThread()); return _mat(lin, col) != 0.0; }
100 
101  // See comments on the base class
102  virtual void set(int lin, int col, double val) { assert(GmThreadManager::inMainThread()); _mat(lin, col) = val; }
103 
104  // See comments on the base class
105  virtual void add(int lin, int col, double val) { _mat(lin, col) += val; }
106 
107  // See comments on the base class
108  virtual void set(GmSolverMatrix* A, GmSolverMatrix* B, double c, bool sameStructure)
109  {
110  Q_UNUSED(sameStructure);
112  assert(A->nlin() == _mat.n_rows && A->ncol() == _mat.n_cols);
113  assert(B->nlin() == _mat.n_rows && B->ncol() == _mat.n_cols);
114 
117  if(newA && newB)
118  _mat = newA->_mat + c * newB->_mat;
119  else
120  {
121  for(unsigned int j = 0; j<_mat.n_cols; j++) // In Armadillo, values are stored in column order
122  for(unsigned int i = 0; i<_mat.n_rows; i++)
123  _mat(i, j) = A->at(i, j) + c * B->at(i, j);
124  }
125 
126  if(symmetric() && (!A->symmetric() || !B->symmetric()))
127  setSymmetric(false);
128  }
129 
130  // See comments on the base class
131  virtual void clear(bool keepSparseLayout)
132  {
133  Q_UNUSED(keepSparseLayout);
135  _mat.zeros();
136  setSymmetric(false);
137  }
138 
139  // See comments on the base class
140  virtual void clearLineAndColumnSet(const QList<int>& indexList, bool setDiagonal, bool keepSparseLayout)
141  {
142  Q_UNUSED(keepSparseLayout);
144  foreach(int i, indexList)
145  {
146  _mat.row(i).zeros();
147  _mat.col(i).zeros();
148  if(setDiagonal)
149  _mat(i, i) = 1.0;
150  }
151  }
152 
153  // See comments on the base class
154  virtual void ensureDiagonal()
155  {
157  for(int i = 0; i < _mat.n_rows; i++)
158  {
159  if(_mat(i, i) == 0.0)
160  _mat(i, i) = 1.0;
161  }
162  }
163 
164  // See comments on the base class
165  virtual void matAdd(const GmVector& a, const GmVector& b, double zeroTol = 0.0)
166  {
168  assert(a.n_rows == _mat.n_rows);
169  assert(b.n_rows == _mat.n_cols);
170  for(int j = 0; j < _mat.n_cols; j++) // In Armadillo, values are stored in column order
171  {
172  double bv = b[j];
173  for(int i = 0; i < _mat.n_rows; i++)
174  {
175  double v = _mat(i, j) + a[i] * bv;
176  if(fabs(v) > zeroTol)
177  _mat(i, j) = v;
178  }
179  }
180  }
181 
182  // See comments on the base class
183  virtual void mul(const GmVector& a, GmVector& b) const
184  {
186  assert(a.n_elem == _mat.n_cols);
187  b = _mat * a;
188  }
189 
190  // See comments on the base class
191  virtual void mulAdd(const GmVector& a, GmVector& b) const
192  {
194  assert(a.n_elem == _mat.n_cols);
195  b += _mat * a;
196  }
197 
198  // See comments on the base class
199  virtual void mulSub(const GmVector& a, GmVector& b) const
200  {
202  assert(a.n_elem == _mat.n_cols);
203  b -= _mat * a;
204  }
205 
206  // See comments on the base class
207  virtual void columnMulAdd(int col, GmVector& f, double v, const bool* skipRows = NULL) const
208  {
210  assert(f.n_elem == _mat.n_rows);
211  for(int i = 0; i < _mat.n_rows; i++)
212  {
213  if(skipRows && skipRows[i])
214  continue;
215  f[i] += _mat(i, col) * v;
216  }
217  }
218 
220  T& armadilloMatrix() { return _mat; }
221 
222  // See comments on the base class
223  virtual size_t usedMemory() const { return _mat.n_rows * _mat.n_cols * sizeof(double); }
224 
225 private:
226  Q_DISABLE_COPY(GmArmadilloSolverMatrixBase);
227 
228 protected:
229  T _mat;
231 };
232 
235 
238 {
239 public:
241  GmArmadilloSparseSolverMatrix(int nlin, int ncol, GmSparseMatrixOptions options);
242 
244 
245  // See comments on the base class
246  virtual bool supportsBatchInsert() const { return true; }
247 
248  // See comments on the base class
249  virtual ParallelAddMode supportedParallelAddMode() const { return THREAD_SAFE_SUPPORT; }
250 
251  virtual bool beginBatchInsert(size_t expectedEntries = 0);
252  virtual bool endBatchInsert(bool discardData = false);
253 
254  // See comments on the base class
255  virtual bool supportsRandomSet() const { return true; }
256 
257  // See comments on the base class
258  virtual int layoutSize() const { assert(GmThreadManager::inMainThread()); return _mat.n_nonzero; }
259 
260  virtual void add(int lin, int col, double val);
261 
262  virtual void clearLineAndColumnSet(const QList<int>& indexList, bool setDiagonal, bool keepSparseLayout);
263 
264  virtual void matAdd(const GmVector& a, const GmVector& b, double zeroTol = 0.0);
265 
266  /* This is the same implementation as in the base class.
267  Repeated here to add an assert and to circumvent some weird compiler errors where a call to
268  set(int, int, double) would try to call set(GmSolverMatrix*, GmSolverMatrix*, double)
269  */
270  virtual void set(int lin, int col, double val) { assert(GmThreadManager::inMainThread()); assert(!_batch); _mat(lin, col) = val; }
271 
272  virtual void set(GmSolverMatrix* A, GmSolverMatrix* B, double c, bool sameStructure);
273 
274  virtual void columnMulAdd(int col, GmVector& f, double v, const bool* skipRows = NULL) const;
275 
276  virtual size_t usedMemory() const;
277 
278 private:
279  bool doEnd(bool ordered);
280 
281  virtual void addFromThread(int tid, int lin, int col, double val);
282 
283 protected:
285  bool _batch;
286 
289 };
290 
291 #endif
292 
virtual void ensureDiagonal()
Updates any zero diagonal value to 1.0. If diagonal values do not belong to the layout,...
Definition: gmArmadilloSolverMatrix.h:154
virtual double at(int lin, int col) const
Returns the value in the position Mat[lin][col].
Definition: gmArmadilloSolverMatrix.h:96
virtual ParallelAddMode supportedParallelAddMode() const
Returns the supported mode for calling add.
Definition: gmArmadilloSolverMatrix.h:249
T & armadilloMatrix()
Returns the internal Armadillo matrix.
Definition: gmArmadilloSolverMatrix.h:220
virtual int nlin() const =0
Returns the number of lines in the matrix. IMPORTANT: This function implementation MUST be thread saf...
Base interface class for Solver Matrix objects.
Definition: gmSolverMatrix.h:97
virtual void columnMulAdd(int col, GmVector &f, double v, const bool *skipRows=NULL) const
Updates the given vector adding to it a matrix column multiplied by a scalar value.
Definition: gmArmadilloSolverMatrix.h:207
virtual int ncol() const =0
Returns the number of columns in the matrix. IMPORTANT: This function implementation MUST be thread s...
An interface for building the layout structure of a sparse matrix.
Definition: gmSparseMatrixLayoutBuilder.h:39
QAtomicInt _sym
Flag marking the matrix as symmetric or not.
Definition: gmArmadilloSolverMatrix.h:230
virtual bool emptyLayout() const
If the matrix supports sparse layouts and the layout is currently empty, returns true....
Definition: gmArmadilloSolverMatrix.h:78
virtual bool supportsBatchInsert() const
Does this matrix supports batch inserts? See comments on the class documentation.
Definition: gmArmadilloSolverMatrix.h:246
virtual int nlin() const
Returns the number of lines in the matrix. IMPORTANT: This function implementation MUST be thread saf...
Definition: gmArmadilloSolverMatrix.h:87
virtual void set(GmSolverMatrix *A, GmSolverMatrix *B, double c, bool sameStructure)
Sets the values of the whole matrix to the result of the expresion A + c * B, where A and B are matri...
Definition: gmArmadilloSolverMatrix.h:108
virtual ParallelAddMode supportedParallelAddMode() const
Returns the supported mode for calling add.
Definition: gmArmadilloSolverMatrix.h:66
bool _batch
Are we in batch mode?
Definition: gmArmadilloSolverMatrix.h:285
Set of configuration options for Sparse matrices.
Definition: gmSparseMatrixOptions.h:54
GmArmadilloSolverMatrixBase(int nlin, int ncol, GmSparseMatrixOptions options=GmSparseMatrixOptions(GM_ARMADILLO_TRIPLET_LIST))
Constructor. Receives as parameters the matrix size.
Definition: gmArmadilloSolverMatrix.h:43
A virtual class representing a buffer of T objects that can be appended in a thread-safe way,...
Definition: gmArmadilloSolverMatrix.h:36
virtual void set(int lin, int col, double val)
Sets the value in the position Mat[lin][col] to the specified value.
Definition: gmArmadilloSolverMatrix.h:270
Declaration of the GmThreadManager class.
virtual void setSymmetric(bool sym)
Marks the matrix as symmetric or not.
Definition: gmArmadilloSolverMatrix.h:84
ParallelAddMode
Supported modes for calling add from multiple threads in parallel.
Definition: gmSolverMatrix.h:107
An implementation of the GmSolverMatrix interface using as base the Armadillo library.
Definition: gmArmadilloSolverMatrix.h:39
virtual int layoutSize() const
Returns the size of the sparse matrix layout.
Definition: gmArmadilloSolverMatrix.h:93
GmArmadilloSolverMatrixBase< arma::mat > GmArmadilloSolverMatrix
The standard 'Full' matrix based on Armadillo.
Definition: gmArmadilloSolverMatrix.h:234
GmSparseMatrixOptions _opt
The set of sparse matrix options, reused from GmSparseMatrix.
Definition: gmArmadilloSolverMatrix.h:284
virtual void mulSub(const GmVector &a, GmVector &b) const
Multiplies the matrix ('X') by a vector 'a' subtracting the result from 'b' (b = b - X * a).
Definition: gmArmadilloSolverMatrix.h:199
virtual void clearLineAndColumnSet(const QList< int > &indexList, bool setDiagonal, bool keepSparseLayout)
Clears a set of lines and columns from the matrix, filling them with zeroes, optionally puting a 1....
Definition: gmArmadilloSolverMatrix.h:140
virtual double at(int lin, int col) const =0
Returns the value in the position Mat[lin][col].
The standard 'Sparse' matrix based on Armadillo.
Definition: gmArmadilloSolverMatrix.h:237
virtual bool supportsSparseLayouts() const
Does this matrix supports sparse layouts? See comments on the class documentation.
Definition: gmArmadilloSolverMatrix.h:60
virtual GmSparseMatrixLayoutBuilder * layoutBuilder() const
If the matrix supports sparse layouts, returns a builder object that can be used to initialize the ma...
Definition: gmArmadilloSolverMatrix.h:75
virtual ~GmArmadilloSolverMatrixBase()
Destructor.
Definition: gmArmadilloSolverMatrix.h:54
T loadAcquire() const const
T _mat
The Armadillo matrix.
Definition: gmArmadilloSolverMatrix.h:229
virtual bool symmetric() const =0
Returns true if the matrix was marked as symmetric by setSymmetric() (it does not check for matrix sy...
virtual bool supportsRandomSet() const
Does this matrix supports setting a value on a random position outside the matrix initialization proc...
Definition: gmArmadilloSolverMatrix.h:63
void storeRelease(T newValue)
virtual bool endBatchInsert(bool discardData=false)
Ends a batch insert process. Important: see comments on the class documentation.
Definition: gmArmadilloSolverMatrix.h:72
virtual void clear(bool keepSparseLayout)
Clears the matrix, filling it with zeros. The keepSparseLayout flag is a hint that the matrix layout ...
Definition: gmArmadilloSolverMatrix.h:131
virtual size_t usedMemory() const
Returns an estimative of the memory used by the matrix in bytes.
Definition: gmArmadilloSolverMatrix.h:223
#define GMC_API_EXPORT
Macro for controling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_LI...
Definition: gmCoreConfig.h:35
virtual void mul(const GmVector &a, GmVector &b) const
Multiplies the matrix ('X') by a vector 'a' storing the result in 'b' (b = X * a).
Definition: gmArmadilloSolverMatrix.h:183
virtual int ncol() const
Returns the number of columns in the matrix. IMPORTANT: This function implementation MUST be thread s...
Definition: gmArmadilloSolverMatrix.h:90
Declaration of the GmSolverMatrix interface classes.
virtual void matAdd(const GmVector &a, const GmVector &b, double zeroTol=0.0)
Adds to the current matrix ('X') the (dense) matrix resulting from multiplying the column vector 'a' ...
Definition: gmArmadilloSolverMatrix.h:165
static bool inMainThread()
Is the current thread the main thread? Equivalent to comparing the currentId() with 0.
Definition: gmThreadManager.h:169
Declaration of the GmSparseMatrix template class.
virtual void set(int lin, int col, double val)
Sets the value in the position Mat[lin][col] to the specified value.
Definition: gmArmadilloSolverMatrix.h:102
virtual bool supportsBatchInsert() const
Does this matrix supports batch inserts? See comments on the class documentation.
Definition: gmArmadilloSolverMatrix.h:57
GmAppendBuffer< arma::uword > * _positions
The positions array ordered as (row, column) pairs while batch inserting values.
Definition: gmArmadilloSolverMatrix.h:287
virtual void mulAdd(const GmVector &a, GmVector &b) const
Multiplies the matrix ('X') by a vector 'a' adding the result to 'b' (b = b + X * a).
Definition: gmArmadilloSolverMatrix.h:191
virtual bool beginBatchInsert(size_t expectedEntries=0)
Begins a batch insert process. Important: see comments on the class documentation.
Definition: gmArmadilloSolverMatrix.h:69
virtual int layoutSize() const
Returns the size of the sparse matrix layout.
Definition: gmArmadilloSolverMatrix.h:258
arma::vec GmVector
The basic type for a GeMA vector object. Currently based on an Armadillo vector.
Definition: gmVector.h:34
virtual void add(int lin, int col, double val)
Adds the given value to the value in the position Mat[lin][col].
Definition: gmArmadilloSolverMatrix.h:105
GmAppendBuffer< double > * _values
The values array while batch inserting values (size = _positions size / 2)
Definition: gmArmadilloSolverMatrix.h:288
virtual bool inLayout(int lin, int col) const
Returns true if the given position belongs to the matrix sparse layout.
Definition: gmArmadilloSolverMatrix.h:99
Definition: gmSparseMatrixOptions.h:48
virtual bool supportsRandomSet() const
Does this matrix supports setting a value on a random position outside the matrix initialization proc...
Definition: gmArmadilloSolverMatrix.h:255
virtual bool symmetric() const
Returns true if the matrix was marked as symmetric by setSymmetric() (it does not check for matrix sy...
Definition: gmArmadilloSolverMatrix.h:81