Description

Class that implements Compressed Sparse matrix format in either Row (CSR) or Column (CSC) major order;.

The arrays are stored contiguously in memory (as needed by Intel MKL Pardiso) with array_alignment byte alignment.

The class is equipped with a sparsity lock feature.
When this feature is enabled, the matrix will hold the position of the elements - i.e. the sparsity pattern - even after calling a::Reset(). So, if an element already existed in a given position, the next call to SetElement() in that position will be much faster.

Warning
When the sparsity lock feature is turned on, also non-zero elements will be stored in the matrix in order to maximize the efficiency.

While building the matrix, the most demanding operation is the new elements insertion (specifically, those elements whose indexes are not stored in the matrix yet).
The performance is slow when: (most demanding first) 1. the arrays capacity is not enough to fit the matrix; 2. the arrays size is not enough to fit the matrix; 3. a new element must be inserted in a row that already contains elements with greater column index (swap 'column' and 'row' for CSC).

Some suggestions:

  • it is better to overestimate the number of non-zero, rather than underestimate;
  • it is better to store the elements in increasing column order, even at the cost of jumping from a row to another (swap 'column' and 'row' for CSC); - use sparsity lock feature whenever possible.

#include <ChCSMatrix.h>

Inheritance diagram for chrono::ChCSMatrix:
Collaboration diagram for chrono::ChCSMatrix:

Public Member Functions

 ChCSMatrix (int nrows=1, int ncols=1, bool row_major_format_on=true, int nonzeros=1)
 Create a CS matrix with the given dimensions. More...
 
 ~ChCSMatrix () override
 Destructor.
 
void SetElement (int row_sel, int col_sel, double insval, bool overwrite=true) override
 Set the value of the element with index (insrow, inscol) to insval. More...
 
double GetElement (int row_sel, int col_sel) const override
 Returns the value of the element with index (row, col). More...
 
double & Element (int row_sel, int col_sel)
 Create the element with index (row_sel, col_sel) (if it doesn't exist) and return its reference.
 
double & operator() (int row_sel, int col_sel)
 Create the element with index (row_sel, col_sel)(if it doesn't exist) and return its reference.
 
double & operator() (int index)
 Create the element with index index (if it doesn't exist) and return its reference.
 
void Reset (int nrows, int ncols, int nonzeros_hint=0) override
 Resize the matrix in order to have nrows rows and ncols columns. More...
 
bool Resize (int nrows, int ncols, int nonzeros_hint=0) override
 Equivalent to Reset().
 
int GetNNZ () const override
 Get the number of non-zero elements stored in this matrix.
 
int * GetCS_LeadingIndexArray () const override
 Return the row|column index array in the CSR|CSC representation of this matrix.
 
int * GetCS_TrailingIndexArray () const override
 Return the column|row index array in the CSR|CSC representation of this matrix.
 
double * GetCS_ValueArray () const override
 Return the array of matrix values in the CSR|CSC representation of this matrix.
 
bool Compress () override
 Compress the internal arrays and purge all uninitialized elements.
 
int Inflate (int storage_augm, int lead_sel=0, int trail_sel=-1)
 Add not-initialized element to the matrix. More...
 
void Trim ()
 Trims the internal arrays to have exactly the dimension needed, nothing more.
 
void Prune (double pruning_threshold=0)
 The same as Compress(), but also removes elements whose absolute value is less or equal to pruning_threshold. More...
 
int GetTrailingIndexLength () const
 Get the length of the trailing-index array (e.g. column index if row major, row index if column major)
 
int GetTrailingIndexCapacity () const
 Get the capacity of the trailing-index array (e.g. column index if row major, row index if column major)
 
void SetMaxShifts (int max_shifts_new=std::numeric_limits< int >::max())
 Advanced use. More...
 
bool IsCompressed () const
 Check if the matrix is compressed i.e. if the matrix elements are stored contiguously in the arrays.
 
bool IsRowMajor () const
 Check if the matrix is stored in row major format.
 
void LoadSparsityPattern (ChSparsityPatternLearner &sparsity_learner) override
 Load the sparsity pattern from sparsity_learner matrix; the internal arrays will be reshaped in order to accommodate the sparsity pattern.
 
int VerifyMatrix () const
 Verify if the matrix respects the Compressed Sparse Row|Column standard. More...
 
void ImportFromDatFile (std::string filepath="", bool row_major_format_on=true)
 Import data from separated file (a.dat, ia.dat, ja.dat) given the format.
 
void ExportToDatFile (std::string filepath="", int precision=6) const
 Export data to separated file (a.dat, ia.dat, ja.dat) with the given precision precision.
 
ChCSMatrixoperator= (const ChCSMatrix &mat_source)
 Copy operator: make a copy of mat_source.
 
ChCSMatrixoperator+= (const ChCSMatrix &mat_source)
 Add mat_source to this, as [this]+=[mat_source].
 
ChCSMatrixoperator-= (const ChCSMatrix &mat_source)
 Subtract mat_source to this, as [this]-=[mat_source].
 
ChCSMatrixoperator*= (const double coeff)
 Multiply this for coeff, as [this]*=coeff;.
 
bool operator== (const ChCSMatrix &mat_source) const
 Check if this is equal to mat_source componentwise. More...
 
void MatrMultiply (const ChMatrix< double > &matB, ChMatrix< double > &mat_out, bool transposeA=false) const
 Multiply this (or this transposed, if transposeA is true) to matB and put the result in mat_out.
 
void MatrMultiplyClipped (const ChMatrix< double > &matB, ChMatrix< double > &mat_out, int start_row_this, int end_row_this, int start_col_this, int end_col_this, int start_row_matB, int start_row_mat_out, bool transposeA=false, int start_col_matB=0, int end_col_matB=0, int start_col_mat_out=0) const
 Multiply part of this (or part of this transposed, if transposeA is true) to matB and put the result in mat_out. More...
 
void ForEachExistentValue (std::function< void(double *)> func)
 Apply the given function func to any existent and initialized element in the matrix. More...
 
void ForEachExistentValueInRange (std::function< void(double *)> func, int start_row, int end_row, int start_col, int end_col)
 Apply the given function func to any existent and initialized element in the matrix in the range [start_row, end_row] and [start_col, end_col]. More...
 
void ForEachExistentValueInRange (std::function< void(int, int, double)> func, int start_row, int end_row, int start_col, int end_col) const
 Apply the given function func to any existent and initialized element in the matrix in the range [start_row, end_row] and [start_col, end_col]. More...
 
void ForEachExistentValueThatMeetsRequirement (std::function< void(int, int, double)> func, std::function< bool(int, int, double)> requirement) const
 Apply the given function func to any existent and initialized element in the matrix that meets the requirement. More...
 
- Public Member Functions inherited from chrono::ChSparseMatrix
 ChSparseMatrix (int nrows=0, int ncols=0, int nnz=0)
 Construct a sparse matrix with nrows and ncols and with nnz non-zero elements. More...
 
 ChSparseMatrix (const ChSparseMatrix &other)
 
int GetNumRows () const
 Get the number of rows of this matrix.
 
int GetNumColumns () const
 Get the number of columns of this matrix.
 
void SetType (SymmetryType type)
 Set the symmetry type for this sparse matrix (default: GENERAL). More...
 
SymmetryType GetType () const
 Return the symmetry type of this matrix.
 
void SetSparsityPatternLock (bool val)
 Enable/disable a lock on the matrix sparsity pattern (default: false).
 
virtual void PasteMatrix (const ChMatrix<> &matra, int insrow, int inscol, bool overwrite=true, bool transp=false)
 Paste a given matrix into this sparse matrix at position (insrow, inscol). More...
 
virtual void PasteClippedMatrix (const ChMatrix<> &matra, int cliprow, int clipcol, int nrows, int ncolumns, int insrow, int inscol, bool overwrite=true)
 Paste a clipped portion of the given matrix into this sparse matrix at position (insrow, inscol). More...
 
virtual void PasteTranspMatrix (const ChMatrix<> &matra, int insrow, int inscol)
 Same as PasteMatrix(), but with overwrite set to true and transp set to true. More...
 
virtual void PasteSumMatrix (const ChMatrix<> &matra, int insrow, int inscol)
 Same as PasteMatrix(), but with overwrite set to false and transp set to false. More...
 
virtual void PasteSumTranspMatrix (const ChMatrix<> &matra, int insrow, int inscol)
 Same as PasteMatrix(), but with overwrite set to false and transp set to true. More...
 
virtual void PasteSumClippedMatrix (const ChMatrix<> &matra, int cliprow, int clipcol, int nrows, int ncolumns, int insrow, int inscol)
 Same as PasteClippedMatrix(), but with overwrite set to false. More...
 

Protected Member Functions

void reset_arrays (int lead_dim, int trail_dim, int nonzeros)
 (internal) Really reset the internal arrays to the given dimensions. More...
 
ChCSMatrixapply_operator (const ChCSMatrix &mat_source, std::function< void(double &, const double &)> f)
 
void insert (int &trail_i, const int &lead_sel)
 (internal) Insert a non existing element in the position trai_i, given the row(CSR) or column(CSC) lead_sel
 
void copy_and_distribute (const index_vector_t &trailIndex_src, const values_vector_t &values_src, const std::vector< bool > &initialized_element_src, index_vector_t &trailIndex_dest, values_vector_t &values_dest, std::vector< bool > &initialized_element_dest, int &trail_ins, int lead_ins, int storage_augm)
 (internal) Copy arrays from source vectors to destination vectors (source and destination vectors can coincide). More...
 

Static Protected Member Functions

static void distribute_integer_range_on_vector (index_vector_t &vector, int initial_number, int final_number)
 (internal) The vector elements will contain equally spaced indexes, going from initial_number to final_number. More...
 

Additional Inherited Members

- Public Types inherited from chrono::ChSparseMatrix
enum  SymmetryType { GENERAL, SYMMETRIC_POSDEF, SYMMETRIC_INDEF, STRUCTURAL_SYMMETRIC }
 Symmetry type of the matrix. More...
 
- Protected Attributes inherited from chrono::ChSparseMatrix
int m_num_rows
 number of rows
 
int m_num_cols
 number of columns
 
int m_nnz
 number of non-zero elements
 
SymmetryType m_type = GENERAL
 matrix type
 
bool m_lock = false
 indicate whether or not the matrix sparsity pattern should be locked
 
bool m_update_sparsity_pattern = false
 let the matrix acquire the sparsity pattern
 

Constructor & Destructor Documentation

chrono::ChCSMatrix::ChCSMatrix ( int  nrows = 1,
int  ncols = 1,
bool  row_major_format_on = true,
int  nonzeros = 1 
)

Create a CS matrix with the given dimensions.

Parameters
nrowsnumber of rows
ncolsnumber of columns
row_major_format_oncreate a Row Major matrix?
nonzerosnumber of non-zeros

Member Function Documentation

void chrono::ChCSMatrix::copy_and_distribute ( const index_vector_t &  trailIndex_src,
const values_vector_t &  values_src,
const std::vector< bool > &  initialized_element_src,
index_vector_t &  trailIndex_dest,
values_vector_t &  values_dest,
std::vector< bool > &  initialized_element_dest,
int &  trail_ins,
int  lead_ins,
int  storage_augm 
)
protected

(internal) Copy arrays from source vectors to destination vectors (source and destination vectors can coincide).

In the meantime it puts a given number of not-initialized spaces (storage_augm) in the matrix, equally distributed between the rows.

Parameters
trailIndex_srctrailing dimension index (source)
values_srcvalues array (source)
initialized_element_srcarray with initialization flags (source)
trailIndex_desttrailing dimension index (destination)
values_destvalues array (destination)
initialized_element_destarray with initialization flags (destination)
trail_insthe position in the trailIndex where a new element must be inserted (the element that caused the insertion)
lead_insthe position, referred to the leading dimension, where a new element must be inserted (the element that caused the insertion)
storage_augmnumber of not-initialized spaces to add
void chrono::ChCSMatrix::distribute_integer_range_on_vector ( index_vector_t &  vector,
int  initial_number,
int  final_number 
)
staticprotected

(internal) The vector elements will contain equally spaced indexes, going from initial_number to final_number.

void chrono::ChCSMatrix::ForEachExistentValue ( std::function< void(double *)>  func)

Apply the given function func to any existent and initialized element in the matrix.

To the function func will be passed the pointer to the existing element.

void chrono::ChCSMatrix::ForEachExistentValueInRange ( std::function< void(double *)>  func,
int  start_row,
int  end_row,
int  start_col,
int  end_col 
)

Apply the given function func to any existent and initialized element in the matrix in the range [start_row, end_row] and [start_col, end_col].

To the function func will be passed the pointer to the existing element.

void chrono::ChCSMatrix::ForEachExistentValueInRange ( std::function< void(int, int, double)>  func,
int  start_row,
int  end_row,
int  start_col,
int  end_col 
) const

Apply the given function func to any existent and initialized element in the matrix in the range [start_row, end_row] and [start_col, end_col].

To the function func will be passed by value the triplet: row index, column index, value. The most useful way to call this function is with

func = std::bind(foo(), other_arguments, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);

where, in particular, foo() can even be a class method and other_arguments can also be this

void chrono::ChCSMatrix::ForEachExistentValueThatMeetsRequirement ( std::function< void(int, int, double)>  func,
std::function< bool(int, int, double)>  requirement 
) const

Apply the given function func to any existent and initialized element in the matrix that meets the requirement.

To the function requirement will be passed by value the triplet: row index, column index, value; only if the returned boolean is true, then the function func will be called as well, with the same arguments. The most useful way to call this function is with

func = std::bind(foo(), other_arguments, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);

where, in particular, foo() can even be a class method and other_arguments can also be this

double chrono::ChCSMatrix::GetElement ( int  row,
int  col 
) const
overridevirtual

Returns the value of the element with index (row, col).

Returns zero if an element is not stored.

Implements chrono::ChSparseMatrix.

int chrono::ChCSMatrix::Inflate ( int  storage_augm,
int  lead_sel = 0,
int  trail_sel = -1 
)

Add not-initialized element to the matrix.

If many new element should be inserted it can improve the speed.

void chrono::ChCSMatrix::MatrMultiplyClipped ( const ChMatrix< double > &  matB,
ChMatrix< double > &  mat_out,
int  start_row_this,
int  end_row_this,
int  start_col_this,
int  end_col_this,
int  start_row_matB,
int  start_row_mat_out,
bool  transposeA = false,
int  start_col_matB = 0,
int  end_col_matB = 0,
int  start_col_mat_out = 0 
) const

Multiply part of this (or part of this transposed, if transposeA is true) to matB and put the result in mat_out.

Parameters
start_row_thisfirst row of this that has to be taken into account for the multiplication
transposeAmultiply for this transposed instead of this
bool chrono::ChCSMatrix::operator== ( const ChCSMatrix mat_source) const

Check if this is equal to mat_source componentwise.

It allows non compressed matrices.

void chrono::ChCSMatrix::Prune ( double  pruning_threshold = 0)

The same as Compress(), but also removes elements whose absolute value is less or equal to pruning_threshold.

void chrono::ChCSMatrix::Reset ( int  nrows,
int  ncols,
int  nonzeros_hint = 0 
)
overridevirtual

Resize the matrix in order to have nrows rows and ncols columns.

The nonzeros_hint value is just a hint.
The matrix can befully reset, or partially reset (i.e. maintaining the sparsity pattern).
For partial reset the following must apply:

Implements chrono::ChSparseMatrix.

void chrono::ChCSMatrix::reset_arrays ( int  lead_dim,
int  trail_dim,
int  nonzeros 
)
protected

(internal) Really reset the internal arrays to the given dimensions.

It checks if the dimensions are consistent, but no smart choice are made here.

void chrono::ChCSMatrix::SetElement ( int  insrow,
int  inscol,
double  insval,
bool  overwrite = true 
)
overridevirtual

Set the value of the element with index (insrow, inscol) to insval.

Parameters
[in]insrowrow index of the element;
[in]inscolcolumn index of the element;
[in]insvalvalue of the element;
[in]overwritetells if the new element should overwrite an existing element or be summed to it.

Implements chrono::ChSparseMatrix.

void chrono::ChCSMatrix::SetMaxShifts ( int  max_shifts_new = std::numeric_limits<int>::max())

Advanced use.

While inserting new elements in the matrix SetMaxShifts() tells how far in the array the internal algorithm should look for a not-initialized space.

int chrono::ChCSMatrix::VerifyMatrix ( ) const

Verify if the matrix respects the Compressed Sparse Row|Column standard.


3 - warning message: the row (CSR) | column (CSC) is empty
1 - warning message: the matrix is not compressed
0 - all good!
-1 - error message: leadIndex is not strictly ascending
-2 - error message: there are not-initialized element NOT at the end of the row (CSR) | column (CSC)
-4 - error message: trailIndex has not ascending indexes within the rows (CSR) | columns (CSC)