19 #ifndef SURGSIM_MATH_SPARSEMATRIX_H 20 #define SURGSIM_MATH_SPARSEMATRIX_H 22 #include <Eigen/Sparse> 38 template <
class DerivedSub,
class SparseType,
40 ((SparseType::Flags & Eigen::RowMajorBit) == Eigen::RowMajorBit) ? Eigen::RowMajor : Eigen::ColMajor >
44 typedef typename SparseType::Scalar T;
45 typedef typename SparseType::StorageIndex StorageIndex;
53 void assign(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
54 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId) {}
59 void assign(T* ptr,
const T& value) {}
67 void add(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
68 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId) {}
73 void add(T* ptr,
const T& value) {}
77 template <
class DerivedSub,
class SparseType>
81 typedef typename SparseType::Scalar T;
82 typedef typename SparseType::StorageIndex StorageIndex;
84 void assign(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
85 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId)
87 typedef Eigen::Matrix < T, Eigen::Dynamic, 1, Eigen::DontAlign | Eigen::ColMajor > ColVector;
91 Eigen::Map<ColVector>(&ptr[start], n).
operator = (subMatrix.col(colRowId).segment(0, n));
94 void assign(T* ptr,
const T& value)
99 void add(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
100 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId)
102 typedef Eigen::Matrix < T, Eigen::Dynamic, 1, Eigen::DontAlign | Eigen::ColMajor > ColVector;
106 Eigen::Map<ColVector>(&ptr[start], n).
operator += (subMatrix.col(colRowId).segment(0, n));
109 void add(T* ptr,
const T& value)
116 template <
class DerivedSub,
class SparseType>
120 typedef typename SparseType::Scalar T;
121 typedef typename SparseType::StorageIndex StorageIndex;
123 void assign(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
124 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId)
126 typedef Eigen::Matrix < T, 1, Eigen::Dynamic, Eigen::DontAlign | Eigen::RowMajor > RowVector;
130 Eigen::Map<RowVector>(&ptr[start], m).
operator = (subMatrix.row(colRowId).segment(0, m));
133 void assign(T* ptr,
const T& value)
138 void add(T* ptr, StorageIndex start, Eigen::Index n, Eigen::Index m,
139 const Eigen::Ref<const DerivedSub>& subMatrix, Eigen::Index colRowId)
141 typedef Eigen::Matrix < T, 1, Eigen::Dynamic, Eigen::DontAlign | Eigen::RowMajor > RowVector;
145 Eigen::Map<RowVector>(&ptr[start], m).
operator += (subMatrix.row(colRowId).segment(0, m));
148 void add(T* ptr,
const T& value)
178 template <
int Opt,
typename StorageIndex>
180 Eigen::Index rowStart, Eigen::Index columnStart, Eigen::Index n, Eigen::Index m,
181 Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix,
182 void (
Operation<
Matrix, Eigen::SparseMatrix<double, Opt, StorageIndex>>::*op)
183 (
double*, StorageIndex, Eigen::Index, Eigen::Index,
const Eigen::Ref<const Matrix>&, Eigen::Index))
186 SURGSIM_ASSERT(
nullptr != matrix) <<
"Invalid recipient matrix, nullptr found";
188 SURGSIM_ASSERT(subMatrix.rows() >= n) <<
"subMatrix doesn't have enough rows";
189 SURGSIM_ASSERT(subMatrix.cols() >= m) <<
"subMatrix doesn't have enough columns";
191 SURGSIM_ASSERT(matrix->rows() >= rowStart + n) <<
"The block is out of range in matrix";
192 SURGSIM_ASSERT(matrix->cols() >= columnStart + m) <<
"The block is out of range in matrix";
193 SURGSIM_ASSERT(matrix->valuePtr() !=
nullptr) <<
"The matrix is not initialized correctly, null pointer to values";
195 double* ptr = matrix->valuePtr();
196 const StorageIndex* innerIndices = matrix->innerIndexPtr();
197 const StorageIndex* outerIndices = matrix->outerIndexPtr();
200 const Index outerStart = (Opt == Eigen::ColMajor ? columnStart : rowStart);
201 const Index innerStart = (Opt == Eigen::ColMajor ? rowStart : columnStart);
202 const Index outerSize = (Opt == Eigen::ColMajor ? m : n);
203 const Index innerSize = (Opt == Eigen::ColMajor ? n : m);
205 for (Index outerLoop = 0; outerLoop < outerSize; ++outerLoop)
209 const StorageIndex innerStartIdInCurrentOuter = outerIndices[outerStart + outerLoop];
210 const StorageIndex innerStartIdInNextOuter = outerIndices[outerStart + outerLoop + 1];
213 StorageIndex innerFirstElement;
214 if (static_cast<Index>(innerIndices[innerStartIdInCurrentOuter]) == innerStart)
216 innerFirstElement = innerStartIdInCurrentOuter;
220 innerFirstElement =
static_cast<StorageIndex
>(matrix->data().searchLowerIndex(
221 static_cast<Index>(innerStartIdInCurrentOuter), static_cast<Index>(innerStartIdInNextOuter) - 1,
226 SURGSIM_ASSERT(static_cast<Index>(innerIndices[innerFirstElement]) == innerStart) <<
227 "matrix is missing an element of the block (1st element on a row/column)";
231 SURGSIM_ASSERT(innerSize <= static_cast<Index>(innerStartIdInNextOuter - innerFirstElement)) <<
232 "matrix is missing elements of the block (but not the 1st element on a row/column)";
236 static_cast<Index>(innerIndices[static_cast<Index>(innerFirstElement) + innerSize - 1])) <<
237 "The last element of the block does not have the expected index. " <<
238 "The matrix is missing elements of the block (but not the 1st element on a row/column)";
240 (operation.*op)(ptr, innerFirstElement, n, m, subMatrix, outerLoop);
266 template <
int Opt,
typename StorageIndex>
267 void blockOperation(
const Eigen::Ref<const Matrix>& subMatrix, Eigen::Index rowStart, Eigen::Index columnStart,
268 Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix,
269 void (
Operation<
Matrix, Eigen::SparseMatrix<double, Opt, StorageIndex>>::*op)(
double*,
const double&))
272 SURGSIM_ASSERT(
nullptr != matrix) <<
"Invalid recipient matrix, nullptr found";
275 Index n = subMatrix.rows();
276 Index m = subMatrix.cols();
277 SURGSIM_ASSERT(matrix->rows() >= rowStart + n) <<
"The block is out of range in matrix";
278 SURGSIM_ASSERT(matrix->cols() >= columnStart + m) <<
"The block is out of range in matrix";
280 for (Index row = 0; row < n; ++row)
282 for (Index column = 0; column < m; ++column)
284 (operation.*op)(&matrix->coeffRef(rowStart + row, columnStart + column), subMatrix(row, column));
296 template <
int Opt,
typename StorageIndex>
297 void addSubMatrix(
const Eigen::Ref<const Matrix>& subMatrix, Eigen::Index blockIdRow,
298 Eigen::Index blockIdCol, Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix)
300 blockOperation(subMatrix, subMatrix.rows() * blockIdRow, subMatrix.cols() * blockIdCol, matrix,
311 template <
int Opt,
typename StorageIndex>
313 Eigen::Index blockIdCol, Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix)
315 blockWithSearch(subMatrix, subMatrix.rows() * blockIdRow, subMatrix.cols() * blockIdCol,
316 subMatrix.rows(), subMatrix.cols(), matrix,
326 template <
int Opt,
typename StorageIndex>
327 void assignSubMatrix(
const Eigen::Ref<const Matrix>& subMatrix, Eigen::Index blockIdRow, Eigen::Index blockIdCol,
328 Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix)
330 blockOperation(subMatrix, subMatrix.rows() * blockIdRow, subMatrix.cols() * blockIdCol, matrix,
340 template <
int Opt,
typename StorageIndex>
342 Eigen::Index blockIdRow, Eigen::Index blockIdCol, Eigen::SparseMatrix<double, Opt, StorageIndex>* matrix)
344 blockWithSearch(subMatrix, subMatrix.rows() * blockIdRow, subMatrix.cols() * blockIdCol,
345 subMatrix.rows(), subMatrix.cols(), matrix,
352 template <
typename T,
int Opt,
typename StorageIndex>
353 void zeroRow(Eigen::Index row, Eigen::SparseMatrix<T, Opt, StorageIndex>* matrix)
355 for (Eigen::Index column = 0; column < matrix->cols(); ++column)
357 if (matrix->coeff(row, column))
359 matrix->coeffRef(row, column) = 0;
367 template <
typename T,
int Opt,
typename StorageIndex>
368 inline void zeroColumn(Eigen::Index column, Eigen::SparseMatrix<T, Opt, StorageIndex>* matrix)
370 for (Eigen::Index row = 0; row < matrix->rows(); ++row)
372 if (matrix->coeff(row, column))
374 matrix->coeffRef(row, column) = 0;
383 template <
typename T,
int Opt,
typename StorageIndex>
384 inline void clearMatrix(Eigen::SparseMatrix<T, Opt, StorageIndex>* matrix)
386 SURGSIM_ASSERT(matrix->isCompressed()) <<
"Invalid matrix. Matrix must be in compressed form.";
387 T* ptr = matrix->valuePtr();
388 for (Eigen::Index value = 0; value < matrix->nonZeros(); ++value)
398 #endif // SURGSIM_MATH_SPARSEMATRIX_H Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
Helper class to run operation a column/row of a matrix to a chunk of memory where the size is dynamic...
Definition: SparseMatrix.h:41
void zeroColumn(size_t column, Eigen::DenseBase< Derived > *matrix)
Helper method to zero a column of a matrix.
Definition: Matrix.h:235
void add(T *ptr, StorageIndex start, Eigen::Index n, Eigen::Index m, const Eigen::Ref< const DerivedSub > &subMatrix, Eigen::Index colRowId)
Do the addition of a row/column of a matrix to a chunk of memory.
Definition: SparseMatrix.h:67
Eigen::SparseMatrix< double > SparseMatrix
A sparse matrix.
Definition: SparseMatrix.h:32
void assignSubMatrix(const Eigen::Ref< const Matrix > &subMatrix, Eigen::Index blockIdRow, Eigen::Index blockIdCol, Eigen::SparseMatrix< double, Opt, StorageIndex > *matrix)
Assign a dense sub-matrix into a matrix that may need the memory locations to be initialized.
Definition: SparseMatrix.h:327
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
void add(T *ptr, const T &value)
Do the addition of a single matrix element (operator +=)
Definition: SparseMatrix.h:73
void assignSubMatrixNoInitialize(const Eigen::Ref< const Matrix > &subMatrix, Eigen::Index blockIdRow, Eigen::Index blockIdCol, Eigen::SparseMatrix< double, Opt, StorageIndex > *matrix)
Assign a dense sub-matrix into a sparse matrix that does not need the memory locations to be initiali...
Definition: SparseMatrix.h:341
void blockWithSearch(const Eigen::Ref< const Matrix > &subMatrix, Eigen::Index rowStart, Eigen::Index columnStart, Eigen::Index n, Eigen::Index m, Eigen::SparseMatrix< double, Opt, StorageIndex > *matrix, void(Operation< Matrix, Eigen::SparseMatrix< double, Opt, StorageIndex >>::*op)(double *, StorageIndex, Eigen::Index, Eigen::Index, const Eigen::Ref< const Matrix > &, Eigen::Index))
Runs a given operation on a SparseMatrix block(i, j, n, m) from a (n x m) 'subMatrix' with searching ...
Definition: SparseMatrix.h:179
void addSubMatrix(const SubMatrix &subMatrix, size_t blockIdRow, size_t blockIdCol, size_t blockSizeRow, size_t blockSizeCol, Matrix *matrix)
Helper method to add a sub-matrix into a matrix, for the sake of clarity.
Definition: Matrix.h:157
void zeroRow(size_t row, Eigen::DenseBase< Derived > *matrix)
Helper method to zero a row of a matrix.
Definition: Matrix.h:225
void assign(T *ptr, StorageIndex start, Eigen::Index n, Eigen::Index m, const Eigen::Ref< const DerivedSub > &subMatrix, Eigen::Index colRowId)
Do the assignment of a row/column of a matrix to a chunk of memory.
Definition: SparseMatrix.h:53
Definitions of small fixed-size square matrix types.
void blockOperation(const Eigen::Ref< const Matrix > &subMatrix, Eigen::Index rowStart, Eigen::Index columnStart, Eigen::SparseMatrix< double, Opt, StorageIndex > *matrix, void(Operation< Matrix, Eigen::SparseMatrix< double, Opt, StorageIndex >>::*op)(double *, const double &))
Runs a given operation on a SparseMatrix block(i, j, n, m) from a (n x m) 'subMatrix' with searching ...
Definition: SparseMatrix.h:267
The header that provides the assertion API.
void addSubMatrixNoInitialize(const Eigen::Ref< const Matrix > &subMatrix, Eigen::Index blockIdRow, Eigen::Index blockIdCol, Eigen::SparseMatrix< double, Opt, StorageIndex > *matrix)
Add a dense sub-matrix into a sparse matrix that does not need the memory locations to be initialized...
Definition: SparseMatrix.h:312
void assign(T *ptr, const T &value)
Do the assignment of a single matrix element (operator =)
Definition: SparseMatrix.h:59
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dynamic size matrix.
Definition: Matrix.h:65
void clearMatrix(Eigen::SparseMatrix< T, Opt, StorageIndex > *matrix)
Helper method to zero all entries of a matrix specialized for Sparse Matrices.
Definition: SparseMatrix.h:384