GemaCoreLib
The GeMA Core library
Loading...
Searching...
No Matches
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
36template <class T> class GmAppendBuffer;
37
39template <class T> class GmArmadilloSolverMatrixBase : public GmSolverMatrix
40{
41public:
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 QVector<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 // See comments on the base class
226 virtual bool hasNanInf() const { return _mat.has_inf() || _mat.has_nan(); }
227
228 // This function is currently not implemented for Full matrices. If we really need
229 // this, we have to remove it from here and add it to GmArmadilloSolverMatrix (that
230 // will have to be transformed from a typedef into a real class). Optionally, we could
231 // use C++ 20 concepts to have an implementation of this function for T == arma::mat
232 // only
233 virtual bool saveMatrixCoordinatesToFile(FILE* f) const { Q_UNUSED(f); return false; }
234
235private:
236 Q_DISABLE_COPY(GmArmadilloSolverMatrixBase);
237
238protected:
241};
242
245
248{
249public:
251 GmArmadilloSparseSolverMatrix(int nlin, int ncol, GmSparseMatrixOptions options);
252
254
255 // See comments on the base class
256 virtual bool supportsBatchInsert() const { return true; }
257
258 // See comments on the base class
259 virtual ParallelAddMode supportedParallelAddMode() const { return THREAD_SAFE_SUPPORT; }
260
261 virtual bool beginBatchInsert(size_t expectedEntries = 0);
262 virtual bool endBatchInsert(bool discardData = false);
263
264 // See comments on the base class
265 virtual bool supportsRandomSet() const { return true; }
266
267 // See comments on the base class
268 virtual int layoutSize() const { assert(GmThreadManager::inMainThread()); return _mat.n_nonzero; }
269
270 virtual void add(int lin, int col, double val);
271
272 virtual void clearLineAndColumnSet(const QVector<int>& indexList, bool setDiagonal, bool keepSparseLayout);
273
274 virtual void matAdd(const GmVector& a, const GmVector& b, double zeroTol = 0.0);
275
276 /* This is the same implementation as in the base class.
277 Repeated here to add an assert and to circumvent some weird compiler errors where a call to
278 set(int, int, double) would try to call set(GmSolverMatrix*, GmSolverMatrix*, double)
279 */
280 virtual void set(int lin, int col, double val) { assert(GmThreadManager::inMainThread()); assert(!_batch); _mat(lin, col) = val; }
281
282 virtual void set(GmSolverMatrix* A, GmSolverMatrix* B, double c, bool sameStructure);
283
284 virtual void columnMulAdd(int col, GmVector& f, double v, const bool* skipRows = NULL) const;
285
286 virtual size_t usedMemory() const;
287
288 virtual bool saveMatrixCoordinatesToFile(FILE* f) const;
289
290private:
291 bool doEnd(bool ordered);
292
293 virtual void addFromThread(int tid, int lin, int col, double val);
294
295protected:
297 bool _batch;
298
301};
302
303#endif
304
A virtual class representing a buffer of T objects that can be appended in a thread-safe way,...
Definition gmAppendBuffer.h:66
An implementation of the GmSolverMatrix interface using as base the Armadillo library.
Definition gmArmadilloSolverMatrix.h:40
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 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 void setSymmetric(bool sym)
Marks the matrix as symmetric or not.
Definition gmArmadilloSolverMatrix.h:84
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
T _mat
The Armadillo matrix.
Definition gmArmadilloSolverMatrix.h:239
QAtomicInt _sym
Flag marking the matrix as symmetric or not.
Definition gmArmadilloSolverMatrix.h:240
virtual bool emptyLayout() const
If the matrix supports sparse layouts and the layout is currently empty, returns true....
Definition gmArmadilloSolverMatrix.h:78
virtual double at(int lin, int col) const
Returns the value in the position Mat[lin][col].
Definition gmArmadilloSolverMatrix.h:96
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 void ensureDiagonal()
Updates any zero diagonal value to 1.0. If diagonal values do not belong to the layout,...
Definition gmArmadilloSolverMatrix.h:154
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 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
virtual bool inLayout(int lin, int col) const
Returns true if the given position belongs to the matrix sparse layout.
Definition gmArmadilloSolverMatrix.h:99
GmArmadilloSolverMatrixBase(int nlin, int ncol, GmSparseMatrixOptions options=GmSparseMatrixOptions(GM_ARMADILLO_TRIPLET_LIST))
Constructor. Receives as parameters the matrix size.
Definition gmArmadilloSolverMatrix.h:43
virtual bool supportsSparseLayouts() const
Does this matrix supports sparse layouts? See comments on the class documentation.
Definition gmArmadilloSolverMatrix.h:60
virtual void set(GmSolverMatrix *A, GmSolverMatrix *B, double c, bool sameStructure)
Sets the values of the whole matrix to the result of the expression A + c * B, where A and B are matr...
Definition gmArmadilloSolverMatrix.h:108
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 bool saveMatrixCoordinatesToFile(FILE *f) const
Helper function to GmNumSolver saving capabilities, responsible for saving the matrix contents to the...
Definition gmArmadilloSolverMatrix.h:233
T & armadilloMatrix()
Returns the internal Armadillo matrix.
Definition gmArmadilloSolverMatrix.h:220
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 bool hasNanInf() const
Returns true if the matrix contains nan or inf values.
Definition gmArmadilloSolverMatrix.h:226
virtual int layoutSize() const
Returns the size of the sparse matrix layout.
Definition gmArmadilloSolverMatrix.h:93
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
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 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 endBatchInsert(bool discardData=false)
Ends a batch insert process. Important: see comments on the class documentation.
Definition gmArmadilloSolverMatrix.h:72
virtual int ncol() const
Returns the number of columns in the matrix. IMPORTANT: This function implementation MUST be thread s...
Definition gmArmadilloSolverMatrix.h:90
virtual bool supportsBatchInsert() const
Does this matrix supports batch inserts? See comments on the class documentation.
Definition gmArmadilloSolverMatrix.h:57
virtual size_t usedMemory() const
Returns an estimative of the memory used by the matrix in bytes.
Definition gmArmadilloSolverMatrix.h:223
virtual bool supportsRandomSet() const
Does this matrix supports setting a value on a random position outside the matrix initialization proc...
Definition gmArmadilloSolverMatrix.h:63
virtual ~GmArmadilloSolverMatrixBase()
Destructor.
Definition gmArmadilloSolverMatrix.h:54
virtual ParallelAddMode supportedParallelAddMode() const
Returns the supported mode for calling add.
Definition gmArmadilloSolverMatrix.h:66
virtual void clearLineAndColumnSet(const QVector< int > &indexList, bool setDiagonal, bool keepSparseLayout)
Clears a set of lines and columns from the matrix, filling them with zeroes, optionally putting a 1....
Definition gmArmadilloSolverMatrix.h:140
The standard 'Sparse' matrix based on Armadillo.
Definition gmArmadilloSolverMatrix.h:248
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:280
GmAppendBuffer< double > * _values
The values array while batch inserting values (size = _positions size / 2)
Definition gmArmadilloSolverMatrix.h:300
virtual bool supportsRandomSet() const
Does this matrix supports setting a value on a random position outside the matrix initialization proc...
Definition gmArmadilloSolverMatrix.h:265
virtual ParallelAddMode supportedParallelAddMode() const
Returns the supported mode for calling add.
Definition gmArmadilloSolverMatrix.h:259
virtual bool supportsBatchInsert() const
Does this matrix supports batch inserts? See comments on the class documentation.
Definition gmArmadilloSolverMatrix.h:256
GmSparseMatrixOptions _opt
The set of sparse matrix options, reused from GmSparseMatrix.
Definition gmArmadilloSolverMatrix.h:296
bool _batch
Are we in batch mode?
Definition gmArmadilloSolverMatrix.h:297
GmAppendBuffer< arma::uword > * _positions
The positions array ordered as (row, column) pairs while batch inserting values.
Definition gmArmadilloSolverMatrix.h:299
virtual int layoutSize() const
Returns the size of the sparse matrix layout.
Definition gmArmadilloSolverMatrix.h:268
Base interface class for Solver Matrix objects.
Definition gmSolverMatrix.h:100
virtual int nlin() const =0
Returns the number of lines in the matrix. IMPORTANT: This function implementation MUST be thread saf...
virtual bool symmetric() const =0
Returns true if the matrix was marked as symmetric by setSymmetric() (it does not check for matrix sy...
virtual int ncol() const =0
Returns the number of columns in the matrix. IMPORTANT: This function implementation MUST be thread s...
virtual double at(int lin, int col) const =0
Returns the value in the position Mat[lin][col].
ParallelAddMode
Supported modes for calling add from multiple threads in parallel.
Definition gmSolverMatrix.h:110
An interface for building the layout structure of a sparse matrix.
Definition gmSparseMatrixLayoutBuilder.h:40
Set of configuration options for Sparse matrices.
Definition gmSparseMatrixOptions.h:55
static bool inMainThread()
Is the current thread the main thread? Equivalent to comparing the currentId() with 0.
Definition gmThreadManager.h:174
GmArmadilloSolverMatrixBase< arma::mat > GmArmadilloSolverMatrix
The standard 'Full' matrix based on Armadillo.
Definition gmArmadilloSolverMatrix.h:244
#define GMC_API_EXPORT
Macro for controlling if the class is being exported (GEMA_CORE_LIB defined) or imported (GEMA_CORE_L...
Definition gmCoreConfig.h:35
Declaration of the GmSolverMatrix interface classes.
Declaration of the GmSparseMatrix template class.
@ GM_ARMADILLO_TRIPLET_LIST
Definition gmSparseMatrixOptions.h:48
Declaration of the GmThreadManager class.
arma::vec GmVector
The basic type for a GeMA vector object. Currently based on an Armadillo vector.
Definition gmVector.h:34
T loadAcquire() const const
void storeRelease(T newValue)