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)
53 mutable int current_row;
55 mutable RowNode ** ColPtrNode;
57 #ifdef MFEM_USE_MEMALLOC
85 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n);
89 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n,
bool ownij,
90 bool owna,
bool issorted);
111 void Clear() { Destroy(); SetEmpty(); }
114 bool Empty() {
return (A == NULL) && (Rows == NULL); }
117 inline int *
GetI()
const {
return I; }
119 inline int *
GetJ()
const {
return J; }
123 int RowSize(
const int i)
const;
151 virtual double &
Elem(
int i,
int j);
154 virtual const double &
Elem(
int i,
int j)
const;
176 const double a = 1.0)
const;
180 const double a=1.0)
const;
249 double sc = 1.0)
const;
253 double sc = 1.0)
const;
259 virtual void Finalize(
int skip_zeros = 1);
272 inline void SetColPtr(
const int row)
const;
275 inline void _Add_(
const int col,
const double a)
277 inline void _Set_(
const int col,
const double a)
279 inline double _Get_(
const int col)
const;
281 inline double &
SearchRow(
const int row,
const int col);
282 inline void _Add_(
const int row,
const int col,
const double a)
284 inline void _Set_(
const int row,
const int col,
const double a)
287 void Set(
const int i,
const int j,
const double a);
288 void Add(
const int i,
const int j,
const double a);
314 void ScaleRow(
const int row,
const double scale);
333 void Print(std::ostream &out = std::cout,
int width_ = 4)
const;
336 void PrintMatlab(std::ostream &out = std::cout)
const;
339 void PrintMM(std::ostream &out = std::cout)
const;
342 void PrintCSR(std::ostream &out)
const;
348 int Walk(
int &i,
int &j,
double &a);
386 SparseMatrix *
Transpose(
const SparseMatrix &A);
397 SparseMatrix *
Mult(
const SparseMatrix &A,
const SparseMatrix &B,
398 SparseMatrix *OAB = NULL);
402 const AbstractSparseMatrix &B);
405 DenseMatrix *
Mult(
const SparseMatrix &A, DenseMatrix &B);
408 DenseMatrix *
RAP(
const SparseMatrix &A, DenseMatrix &P);
412 SparseMatrix *
RAP(
const SparseMatrix &A,
const SparseMatrix &R,
413 SparseMatrix *ORAP = NULL);
416 SparseMatrix *
RAP(
const SparseMatrix &Rt,
const SparseMatrix &A,
417 const SparseMatrix &P);
420 SparseMatrix *
Mult_AtDA(
const SparseMatrix &A,
const Vector &D,
421 SparseMatrix *OAtDA = NULL);
425 SparseMatrix *
Add(
const SparseMatrix & A,
const SparseMatrix & B);
427 SparseMatrix *
Add(
double a,
const SparseMatrix & A,
double b,
428 const SparseMatrix & B);
430 SparseMatrix *
Add(Array<SparseMatrix *> & Ai);
439 if (ColPtrNode == NULL)
441 ColPtrNode =
new RowNode *[
width];
442 for (
int i = 0; i <
width; i++)
444 ColPtrNode[i] = NULL;
447 for (RowNode *node_p = Rows[row]; node_p != NULL; node_p = node_p->Prev)
449 ColPtrNode[node_p->Column] = node_p;
456 ColPtrJ =
new int[
width];
457 for (
int i = 0; i <
width; i++)
462 for (
int j = I[row], end = I[row+1]; j < end; j++)
473 for (RowNode *node_p = Rows[current_row]; node_p != NULL;
474 node_p = node_p->Prev)
476 ColPtrNode[node_p->Column] = NULL;
479 for (
int j = I[current_row], end = I[current_row+1]; j < end; j++)
489 RowNode *node_p = ColPtrNode[col];
492 #ifdef MFEM_USE_MEMALLOC
493 node_p = NodesMem->
Alloc();
495 node_p =
new RowNode;
497 node_p->Prev = Rows[current_row];
498 node_p->Column = col;
500 Rows[current_row] = ColPtrNode[col] = node_p;
502 return node_p->Value;
506 const int j = ColPtrJ[col];
507 MFEM_VERIFY(j != -1,
"Entry for column " << col <<
" is not allocated.");
516 RowNode *node_p = ColPtrNode[col];
517 return (node_p == NULL) ? 0.0 : node_p->Value;
521 const int j = ColPtrJ[col];
522 return (j == -1) ? 0.0 : A[j];
532 for (node_p = Rows[row]; 1; node_p = node_p->Prev)
536 #ifdef MFEM_USE_MEMALLOC
537 node_p = NodesMem->
Alloc();
539 node_p =
new RowNode;
541 node_p->Prev = Rows[row];
542 node_p->Column = col;
547 else if (node_p->Column == col)
552 return node_p->Value;
556 int *Ip = I+row, *Jp = J;
557 for (
int k = Ip[0], end = Ip[1]; k < end; k++)
564 MFEM_ABORT(
"Could not find entry for row = " << row <<
", col = " << col);
void _Add_(const int row, const int col, const double a)
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 _Add_(const int col, const double a)
void Clear()
Clear the contents of the SparseMatrix.
void _Set_(const int row, const int col, 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 MakeRef(const SparseMatrix &master)
double & SearchRow(const int col)
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 BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, but treat all elements as booleans (zero=false, nonzero=true).
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Abstract data type for sparse matrices.
SparseMatrix & operator+=(const SparseMatrix &B)
void EliminateRowCol(int rc, const double sol, Vector &rhs, int d=0)
Data type dense matrix using column-major storage.
void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
virtual ~SparseMatrix()
Destroys sparse matrix.
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()
Lose the ownership of the graph (I, J) and data (A) arrays.
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 _Set_(const int col, const double a)
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, but treat all elements as booleans (zero=false, nonzero=true).
SparseMatrix * Mult_AtDA(const SparseMatrix &A, const Vector &D, SparseMatrix *OAtDA)
Matrix multiplication A^t D A. All matrices must be finalized.
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 SetGraphOwner(bool ownij)
Set the graph ownership flag (I and J arrays).
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
bool OwnsData() const
Get the data ownership flag (A array).
void EliminateCol(int col)
void ScaleColumns(const Vector &sr)
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
SparseMatrix()
Create an empty SparseMatrix.
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.
bool OwnsGraph() const
Get the graph ownership flag (I and J arrays).
void SetWidth(int width_=-1)
Change the width of a SparseMatrix.
bool areColumnsSorted() const
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)
void Swap< SparseMatrix >(SparseMatrix &a, SparseMatrix &b)
Specialization of the template function Swap<> for class SparseMatrix.
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.
void EliminateRowColDiag(int rc, double value)
Perform elimination and set the diagonal entry to the given value.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void SetColPtr(const int row) const
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.
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.
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 SetDataOwner(bool owna)
Set the data ownership flag (A array).
bool Empty()
Check if the SparseMatrix is empty.
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.
double _Get_(const int col) const
void Swap(SparseMatrix &other)
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 .