12 #ifndef MFEM_SPARSEMAT
13 #define MFEM_SPARSEMAT
17 #include "../general/mem_alloc.hpp"
18 #include "../general/table.hpp"
26 #if defined(__alignas_is_defined)
52 mutable int current_row;
54 mutable RowNode ** ColPtrNode;
56 #ifdef MFEM_USE_MEMALLOC
69 inline void SetColPtr(
const int row)
const;
70 inline void ClearColPtr()
const;
71 inline double &SearchRow(
const int col);
72 inline void _Add_(
const int col,
const double a)
73 { SearchRow(col) += a; }
74 inline void _Set_(
const int col,
const double a)
75 { SearchRow(col) = a; }
76 inline double _Get_(
const int col)
const;
78 inline double &SearchRow(
const int row,
const int col);
79 inline void _Add_(
const int row,
const int col,
const double a)
80 { SearchRow(row, col) += a; }
81 inline void _Set_(
const int row,
const int col,
const double a)
82 { SearchRow(row, col) = a; }
88 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n);
90 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n,
bool ownij,
bool owna,
97 inline int *
GetI()
const {
return I; }
99 inline int *
GetJ()
const {
return J; }
103 int RowSize(
const int i)
const;
131 virtual double &
Elem(
int i,
int j);
134 virtual const double &
Elem(
int i,
int j)
const;
156 const double a = 1.0)
const;
160 const double a=1.0)
const;
222 double sc = 1.0)
const;
226 double sc = 1.0)
const;
232 virtual void Finalize(
int skip_zeros = 1);
245 void Set(
const int i,
const int j,
const double a);
246 void Add(
const int i,
const int j,
const double a);
271 void ScaleRow(
const int row,
const double scale);
290 void Print(std::ostream &out = std::cout,
int width_ = 4)
const;
293 void PrintMatlab(std::ostream &out = std::cout)
const;
296 void PrintMM(std::ostream &out = std::cout)
const;
299 void PrintCSR(std::ostream &out)
const;
305 int Walk(
int &i,
int &j,
double &a);
335 SparseMatrix *
Transpose(
const SparseMatrix &A);
346 SparseMatrix *
Mult(
const SparseMatrix &A,
const SparseMatrix &B,
347 SparseMatrix *OAB = NULL);
351 const AbstractSparseMatrix &B);
356 SparseMatrix *
RAP(
const SparseMatrix &A,
const SparseMatrix &R,
357 SparseMatrix *ORAP = NULL);
360 SparseMatrix *
RAP(
const SparseMatrix &Rt,
const SparseMatrix &A,
361 const SparseMatrix &P);
365 SparseMatrix *
Mult_AtDA(
const SparseMatrix &A,
const Vector &D,
366 SparseMatrix *OAtDA = NULL);
370 SparseMatrix *
Add(
const SparseMatrix & A,
const SparseMatrix & B);
372 SparseMatrix *
Add(
double a,
const SparseMatrix & A,
double b,
373 const SparseMatrix & B);
375 SparseMatrix *
Add(Array<SparseMatrix *> & Ai);
380 inline void SparseMatrix::SetColPtr(
const int row)
const
384 if (ColPtrNode == NULL)
386 ColPtrNode =
new RowNode *[
width];
387 for (
int i = 0; i <
width; i++)
389 ColPtrNode[i] = NULL;
392 for (RowNode *node_p = Rows[row]; node_p != NULL; node_p = node_p->Prev)
394 ColPtrNode[node_p->Column] = node_p;
401 ColPtrJ =
new int[
width];
402 for (
int i = 0; i <
width; i++)
407 for (
int j = I[row], end = I[row+1]; j < end; j++)
415 inline void SparseMatrix::ClearColPtr()
const
418 for (RowNode *node_p = Rows[current_row]; node_p != NULL;
419 node_p = node_p->Prev)
421 ColPtrNode[node_p->Column] = NULL;
424 for (
int j = I[current_row], end = I[current_row+1]; j < end; j++)
430 inline double &SparseMatrix::SearchRow(
const int col)
434 RowNode *node_p = ColPtrNode[col];
437 #ifdef MFEM_USE_MEMALLOC
438 node_p = NodesMem->
Alloc();
440 node_p =
new RowNode;
442 node_p->Prev = Rows[current_row];
443 node_p->Column = col;
445 Rows[current_row] = ColPtrNode[col] = node_p;
447 return node_p->Value;
451 const int j = ColPtrJ[col];
452 MFEM_VERIFY(j != -1,
"Entry for column " << col <<
" is not allocated.");
457 inline double SparseMatrix::_Get_(
const int col)
const
461 RowNode *node_p = ColPtrNode[col];
462 return (node_p == NULL) ? 0.0 : node_p->Value;
466 const int j = ColPtrJ[col];
467 return (j == -1) ? 0.0 : A[j];
471 inline double &SparseMatrix::SearchRow(
const int row,
const int col)
477 for (node_p = Rows[row]; 1; node_p = node_p->Prev)
481 #ifdef MFEM_USE_MEMALLOC
482 node_p = NodesMem->
Alloc();
484 node_p =
new RowNode;
486 node_p->Prev = Rows[row];
487 node_p->Column = col;
492 else if (node_p->Column == col)
497 return node_p->Value;
501 int *Ip = I+row, *Jp = J;
502 for (
int k = Ip[0], end = Ip[1]; k < end; k++)
509 MFEM_ABORT(
"Could not find entry for row = " << row <<
", col = " << col);
double GetJacobiScaling() const
Determine appropriate scaling for Jacobi iteration.
SparseMatrix * TransposeAbstractSparseMatrix(const AbstractSparseMatrix &A, int useActualWidth)
Transpose of a sparse matrix. A does not need to be a CSR matrix.
int RowSize(const int i) const
Returns the number of elements in row i.
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
void Add(const int i, const int j, const double a)
void Print(std::ostream &out=std::cout, int width_=4) const
Prints matrix to stream out.
void DiagScale(const Vector &b, Vector &x, double sc=1.0) const
void PrintMM(std::ostream &out=std::cout) const
Prints matrix in Matrix Market sparse format.
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Abstract data type for sparse matrices.
void EliminateRowCol(int rc, const double sol, Vector &rhs, int d=0)
void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += At * x (default) or y += a * At * x
Abstract data type for matrix inverse.
void EliminateRowColMultipleRHS(int rc, const Vector &sol, DenseMatrix &rhs, int d=0)
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void LoseData()
Call this if data has been stolen.
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
void SortColumnIndices()
Sort the column indices corresponding to each row.
void PartAddMult(const Array< int > &rows, const Vector &x, Vector &y, const double a=1.0) const
bool RowIsEmpty(const int row) const
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
void ScaleRow(const int row, const double scale)
int ActualWidth()
Returns the actual Width of the matrix.
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
void EliminateCol(int col)
void ScaleColumns(const Vector &sr)
virtual ~SparseMatrix()
Destroys sparse matrix.
void PrintCSR2(std::ostream &out) const
Prints a sparse matrix to stream out in CSR format.
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
void EliminateCols(Array< int > &cols, Vector *x=NULL, Vector *b=NULL)
Eliminate all columns 'i' for which cols[i] != 0.
void SetWidth(int width_=-1)
Change the width of a SparseMatrix.
bool areColumnsSorted() const
friend void Swap(SparseMatrix &A, SparseMatrix &B)
HypreParMatrix * RAP(HypreParMatrix *A, HypreParMatrix *P)
Returns the matrix P^t * A * P.
double IsSymmetric() const
Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix.
void SetDiagIdentity()
If a row contains only one diag entry of zero, set it to 1.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
void ScaleRows(const Vector &sl)
virtual void Finalize(int skip_zeros=1)
void EliminateZeroRows()
If a row contains only zeros, set its diagonal to 1.
double * GetData() const
Return element data.
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
int * GetI() const
Return the array I.
void Jacobi(const Vector &b, const Vector &x0, Vector &x1, double sc) const
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void SparseMatrixFunction(SparseMatrix &S, double(*f)(double))
Applies f() to each element of the matrix (after it is finalized).
virtual MatrixInverse * Inverse() const
Returns a pointer to approximation of the matrix inverse.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
SparseMatrix & operator=(double a)
void SetSubMatrixTranspose(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Set(const int i, const int j, const double a)
void PrintMatlab(std::ostream &out=std::cout) const
Prints matrix in matlab format.
int Size() const
For backward compatibility define Size to be synonym of Height()
void Gauss_Seidel_back(const Vector &x, Vector &y) const
void Gauss_Seidel_forw(const Vector &x, Vector &y) const
Gauss-Seidel forward and backward iterations over a vector x.
SparseMatrix(int nrows, int ncols=0)
Creates sparse matrix.
void EliminateRow(int row, const double sol, Vector &rhs)
Eliminates a column from the transpose matrix.
void GetDiag(Vector &d) const
Returns the Diagonal of A.
SparseMatrix * Mult_AtDA(const SparseMatrix &A, const Vector &D, SparseMatrix *OAtDA)
double GetRowNorml1(int irow) const
For i = irow compute .
double & operator()(int i, int j)
Returns reference to A[i][j].
void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
SparseMatrix & operator*=(double a)
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
int Walk(int &i, int &j, double &a)
Walks the sparse matrix.
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm)
void Jacobi2(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) const
int MaxRowSize() const
Returns the maximum number of elements among all rows.
void Jacobi3(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) const
SparseMatrix * MultAbstractSparseMatrix(const AbstractSparseMatrix &A, const AbstractSparseMatrix &B)
Matrix product of sparse matrices. A and B do not need to be CSR matrices.
SparseMatrix & operator+=(SparseMatrix &B)
int * GetJ() const
Return the array J.
void PrintCSR(std::ostream &out) const
Prints matrix to stream out in hypre_CSRMatrix format.
double InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
int CountSmallElems(double tol) const
Count the number of entries with |a_ij| < tol.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
void GetRowSums(Vector &x) const
For all i compute .