15 #include "../general/table.hpp"
16 #include "../general/sort_pairs.hpp"
35 Rows(new RowNode *[nrows]),
43 for (
int i = 0; i < nrows; i++)
48 #ifdef MFEM_USE_MEMALLOC
65 #ifdef MFEM_USE_MEMALLOC
71 bool ownij,
bool owna,
bool issorted)
83 #ifdef MFEM_USE_MEMALLOC
91 A =
new double[ nnz ];
92 for (
int i=0; i<nnz; ++i)
108 #ifdef MFEM_USE_MEMALLOC
111 I =
new int[nrows + 1];
112 J =
new int[nrows * rowsize];
113 A =
new double[nrows * rowsize];
115 for (
int i = 0; i <= nrows; i++)
131 memcpy(
I, mat.
I,
sizeof(
int)*(
height+1));
132 memcpy(
J, mat.
J,
sizeof(
int)*nnz);
142 memcpy(
A, mat.
A,
sizeof(
double)*nnz);
146 #ifdef MFEM_USE_MEMALLOC
152 #ifdef MFEM_USE_MEMALLOC
156 for (
int i = 0; i <
height; i++)
158 RowNode **node_pp = &
Rows[i];
159 for (RowNode *node_p = mat.
Rows[i]; node_p; node_p = node_p->Prev)
161 #ifdef MFEM_USE_MEMALLOC
164 RowNode *new_node_p =
new RowNode;
166 new_node_p->Value = node_p->Value;
167 new_node_p->Column = node_p->Column;
168 *node_pp = new_node_p;
169 node_pp = &new_node_p->Prev;
189 MFEM_ASSERT(master.
Finalized(),
"'master' must be finalized");
207 #ifdef MFEM_USE_MEMALLOC
223 return I[gi+1]-
I[gi];
227 RowNode *row =
Rows[gi];
228 for ( ; row != NULL; row = row->Prev)
229 if (row->Value != 0.0)
242 for (
int i=0; i <
height; ++i)
244 rowSize =
I[i+1]-
I[i];
245 out = (out > rowSize) ? out : rowSize;
250 for (
int i=0; i <
height; ++i)
253 out = (out > rowSize) ? out : rowSize;
262 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
269 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
276 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
283 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
290 if (newWidth ==
width)
295 else if ( newWidth == -1)
301 else if (newWidth >
width)
312 ColPtrJ =
static_cast<int *
>(NULL);
320 "The new width needs to be bigger or equal to the actual width");
328 MFEM_VERIFY(
Finalized(),
"Matrix is not Finalized!");
336 for (
int j = 0, i = 0; i <
height; i++)
340 for (
int k = 0; k < row.
Size(); k++)
346 for (
int k = 0; k < row.
Size(); k++, j++)
357 MFEM_VERIFY(
Finalized(),
"Matrix is not Finalized!");
359 for (
int row = 0, end = 0; row <
height; row++)
363 for (j = start;
true; j++)
365 MFEM_VERIFY(j < end,
"diagonal entry not found in row = " << row);
366 if (
J[j] == row) {
break; }
368 const double diag =
A[j];
369 for ( ; j > start; j--)
391 MFEM_ASSERT(i < height && i >= 0 && j < width && j >= 0,
392 "Trying to access element outside of the matrix. "
393 <<
"height = " <<
height <<
", "
394 <<
"width = " <<
width <<
", "
395 <<
"i = " << i <<
", "
398 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
400 for (
int k =
I[i], end =
I[i+1]; k < end; k++)
408 MFEM_ABORT(
"Did not find i = " << i <<
", j = " << j <<
" in matrix.");
414 static const double zero = 0.0;
416 MFEM_ASSERT(i < height && i >= 0 && j < width && j >= 0,
417 "Trying to access element outside of the matrix. "
418 <<
"height = " <<
height <<
", "
419 <<
"width = " <<
width <<
", "
420 <<
"i = " << i <<
", "
425 for (
int k =
I[i], end =
I[i+1]; k < end; k++)
435 for (RowNode *node_p =
Rows[i]; node_p != NULL; node_p = node_p->Prev)
437 if (node_p->Column == j)
439 return node_p->Value;
450 "Matrix must be square, not height = " <<
height <<
", width = " <<
width);
451 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
456 for (
int i = 0; i <
height; i++)
460 for (j =
I[i]; j < end; j++)
484 "Input vector size (" << x.
Size() <<
") must match matrix width (" <<
width
487 "Output vector size (" << y.
Size() <<
") must match matrix height (" <<
height
492 const double *xp = x.
GetData();
497 for (i = 0; i <
height; i++)
499 RowNode *row =
Rows[i];
501 for ( ; row != NULL; row = row->Prev)
503 b += row->Value * xp[row->Column];
511 int *Jp =
J, *Ip =
I;
515 #ifndef MFEM_USE_OPENMP
516 for (i = j = 0; i <
height; i++)
519 for (end = Ip[i+1]; j < end; j++)
521 d += Ap[j] * xp[Jp[j]];
526 #pragma omp parallel for private(j,end)
527 for (i = 0; i <
height; i++)
530 for (j = Ip[i], end = Ip[i+1]; j < end; j++)
532 d += Ap[j] * xp[Jp[j]];
540 for (i = j = 0; i <
height; i++)
543 for (end = Ip[i+1]; j < end; j++)
545 d += Ap[j] * xp[Jp[j]];
559 const double a)
const
562 "Input vector size (" << x.
Size() <<
") must match matrix height (" <<
height
565 "Output vector size (" << y.
Size() <<
") must match matrix width (" <<
width
574 for (i = 0; i <
height; i++)
576 RowNode *row =
Rows[i];
578 for ( ; row != NULL; row = row->Prev)
580 yp[row->Column] += row->Value * b;
586 for (i = 0; i <
height; i++)
588 double xi = a * x(i);
590 for (j =
I[i]; j < end; j++)
600 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
602 for (
int i = 0; i < rows.
Size(); i++)
607 for (
int j =
I[r]; j < end; j++)
618 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
620 for (
int i = 0; i < rows.
Size(); i++)
625 for (
int j =
I[r]; j < end; j++)
627 val +=
A[j] * x(
J[j]);
635 MFEM_ASSERT(
Finalized(),
"Matrix must be finalized.");
636 MFEM_ASSERT(x.
Size() ==
Width(),
"Input vector size (" << x.
Size()
637 <<
") must match matrix width (" <<
Width() <<
")");
642 for (
int i = 0; i <
Height(); i++)
645 for (
int j =
I[i]; j < end; j++)
659 MFEM_ASSERT(
Finalized(),
"Matrix must be finalized.");
660 MFEM_ASSERT(x.
Size() ==
Height(),
"Input vector size (" << x.
Size()
661 <<
") must match matrix height (" <<
Height() <<
")");
666 for (
int i = 0; i <
Height(); i++)
671 for (
int j =
I[i]; j < end; j++)
682 <<
" must be equal to Width() = " <<
Width());
684 <<
" must be equal to Height() = " <<
Height());
686 for (
int i = 0; i <
height; i++)
690 for (
int j =
I[i], end =
I[i+1]; j < end; j++)
695 for (RowNode *np =
Rows[i]; np != NULL; np = np->Prev)
697 a += np->Value * x(np->Column);
707 for (
int i = 0; i <
height; i++)
711 for (
int j =
I[i], end =
I[i+1]; j < end; j++)
716 for (RowNode *np =
Rows[i]; np != NULL; np = np->Prev)
726 MFEM_VERIFY(irow <
height,
727 "row " << irow <<
" not in matrix with height " <<
height);
731 for (
int j =
I[irow], end =
I[irow+1]; j < end; j++)
736 for (RowNode *np =
Rows[irow]; np != NULL; np = np->Prev)
738 a += fabs(np->Value);
759 for (i = 1; i <=
height; i++)
762 for (aux =
Rows[i-1]; aux != NULL; aux = aux->Prev)
763 if (!skip_zeros || aux->Value != 0.0)
767 if (fix_empty_rows && !nr) { nr = 1; }
776 for (j = i = 0; i <
height; i++)
780 for (aux =
Rows[i]; aux != NULL; aux = aux->Prev)
782 if (!skip_zeros || aux->Value != 0.0)
787 if ( lastCol >
J[j] )
797 if (fix_empty_rows && !nr)
805 #ifdef MFEM_USE_MEMALLOC
809 for (i = 0; i <
height; i++)
811 RowNode *node_p =
Rows[i];
812 while (node_p != NULL)
815 node_p = node_p->Prev;
828 int nr = (
height + br - 1)/br, nc = (
width + bc - 1)/bc;
830 for (
int j = 0; j < bc; j++)
832 for (
int i = 0; i < br; i++)
834 int *bI =
new int[nr + 1];
835 for (
int k = 0; k <= nr; k++)
843 for (
int gr = 0; gr <
height; gr++)
845 int bi = gr/nr, i = gr%nr + 1;
848 for (
int j =
I[gr]; j <
I[gr+1]; j++)
852 blocks(bi,
J[j]/nc)->I[i]++;
858 for (RowNode *n_p =
Rows[gr]; n_p != NULL; n_p = n_p->Prev)
860 if (n_p->Value != 0.0)
862 blocks(bi, n_p->Column/nc)->I[i]++;
868 for (
int j = 0; j < bc; j++)
870 for (
int i = 0; i < br; i++)
874 for (
int k = 1; k <= nr; k++)
876 rs = b.
I[k], b.
I[k] = nnz, nnz += rs;
879 b.
A =
new double[nnz];
883 for (
int gr = 0; gr <
height; gr++)
885 int bi = gr/nr, i = gr%nr + 1;
888 for (
int j =
I[gr]; j <
I[gr+1]; j++)
893 b.
J[b.
I[i]] =
J[j] % nc;
901 for (RowNode *n_p =
Rows[gr]; n_p != NULL; n_p = n_p->Prev)
903 if (n_p->Value != 0.0)
906 b.
J[b.
I[i]] = n_p->Column % nc;
907 b.
A[b.
I[i]] = n_p->Value;
919 return std::numeric_limits<double>::infinity();
929 for (
int i = 1; i <
height; i++)
931 for (
int j =
I[i]; j <
I[i+1]; j++)
935 symm = std::max(symm, std::abs(
A[j]-(*
this)(
J[j],i)));
942 for (
int i = 0; i <
height; i++)
944 for (RowNode *node_p =
Rows[i]; node_p != NULL; node_p = node_p->Prev)
946 int col = node_p->Column;
949 symm = std::max(symm, std::abs(node_p->Value-(*
this)(col,i)));
959 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
962 for (i = 1; i <
height; i++)
963 for (j =
I[i]; j <
I[i+1]; j++)
966 A[j] += (*this)(
J[j],i);
968 (*this)(J[j],i) = A[j];
982 for (
int i = 0; i <
height; i++)
984 for (RowNode *node_p =
Rows[i]; node_p != NULL; node_p = node_p->Prev)
1001 for (
int j = 0; j < nnz; j++)
1003 m = std::max(m, std::abs(
A[j]));
1008 for (
int i = 0; i <
height; i++)
1009 for (RowNode *n_p =
Rows[i]; n_p != NULL; n_p = n_p->Prev)
1011 m = std::max(m, std::abs(n_p->Value));
1024 const double *Ap =
A;
1026 for (
int i = 0; i < nz; i++)
1028 counter += (std::abs(Ap[i]) <= tol);
1033 for (
int i = 0; i <
height; i++)
1035 for (RowNode *aux =
Rows[i]; aux != NULL; aux = aux->Prev)
1037 counter += (std::abs(aux->Value) <= tol);
1058 for (
int i = 0; i <
height; i++)
1060 for (RowNode *aux =
Rows[i]; aux != NULL; aux = aux->Prev)
1078 MFEM_ASSERT(row < height && row >= 0,
1079 "Row " << row <<
" not in matrix of height " <<
height);
1081 MFEM_VERIFY(!
Finalized(),
"Matrix must NOT be finalized.");
1083 for (aux =
Rows[row]; aux != NULL; aux = aux->Prev)
1085 rhs(aux->Column) -= sol * aux->Value;
1094 MFEM_ASSERT(row < height && row >= 0,
1095 "Row " << row <<
" not in matrix of height " <<
height);
1097 "if setOneDiagonal, must be rectangular matrix, not height = "
1101 for (
int i=
I[row]; i <
I[row+1]; ++i)
1106 for (aux =
Rows[row]; aux != NULL; aux = aux->Prev)
1121 MFEM_VERIFY(!
Finalized(),
"Matrix must NOT be finalized.");
1123 for (
int i = 0; i <
height; i++)
1124 for (aux =
Rows[i]; aux != NULL; aux = aux->Prev)
1125 if (aux -> Column == col)
1135 for (
int i = 0; i <
height; i++)
1136 for (
int jpos =
I[i]; jpos !=
I[i+1]; ++jpos)
1137 if (cols[
J[jpos]] )
1141 (*b)(i) -=
A[jpos] * (*x)(
J[jpos] );
1149 for (
int i = 0; i <
height; i++)
1150 for (aux =
Rows[i]; aux != NULL; aux = aux->Prev)
1151 if (cols[aux -> Column])
1155 (*b)(i) -= aux -> Value * (*x)(aux -> Column);
1167 MFEM_ASSERT(rc < height && rc >= 0,
1168 "Row " << rc <<
" not in matrix of height " <<
height);
1172 for (
int j =
I[rc]; j <
I[rc+1]; j++)
1174 if ((col =
J[j]) == rc)
1178 rhs(rc) =
A[j] * sol;
1189 for (
int k = I[col]; 1; k++)
1193 mfem_error(
"SparseMatrix::EliminateRowCol () #2");
1195 else if (
J[k] == rc)
1197 rhs(col) -= sol *
A[k];
1207 for (RowNode *aux =
Rows[rc]; aux != NULL; aux = aux->Prev)
1209 if ((col = aux->Column) == rc)
1213 rhs(rc) = aux->Value * sol;
1224 for (RowNode *node =
Rows[col]; 1; node = node->Prev)
1228 mfem_error(
"SparseMatrix::EliminateRowCol () #3");
1230 else if (node->Column == rc)
1232 rhs(col) -= sol * node->Value;
1246 int num_rhs = rhs.
Width();
1248 MFEM_ASSERT(rc < height && rc >= 0,
1249 "Row " << rc <<
" not in matrix of height " <<
height);
1250 MFEM_ASSERT(sol.
Size() == num_rhs,
"solution size (" << sol.
Size()
1251 <<
") must match rhs width (" << num_rhs <<
")");
1254 for (
int j =
I[rc]; j <
I[rc+1]; j++)
1255 if ((col =
J[j]) == rc)
1258 for (
int r = 0; r < num_rhs; r++)
1260 rhs(rc,r) =
A[j] * sol(r);
1266 for (
int r = 0; r < num_rhs; r++)
1274 for (
int k = I[col]; 1; k++)
1277 mfem_error(
"SparseMatrix::EliminateRowColMultipleRHS() #3");
1279 else if (
J[k] == rc)
1281 for (
int r = 0; r < num_rhs; r++)
1283 rhs(col,r) -= sol(r) *
A[k];
1290 for (RowNode *aux =
Rows[rc]; aux != NULL; aux = aux->Prev)
1291 if ((col = aux->Column) == rc)
1294 for (
int r = 0; r < num_rhs; r++)
1296 rhs(rc,r) = aux->Value * sol(r);
1302 for (
int r = 0; r < num_rhs; r++)
1310 for (RowNode *node =
Rows[col]; 1; node = node->Prev)
1313 mfem_error(
"SparseMatrix::EliminateRowColMultipleRHS() #4");
1315 else if (node->Column == rc)
1317 for (
int r = 0; r < num_rhs; r++)
1319 rhs(col,r) -= sol(r) * node->Value;
1331 MFEM_ASSERT(rc < height && rc >= 0,
1332 "Row " << rc <<
" not in matrix of height " <<
height);
1336 for (
int j =
I[rc]; j <
I[rc+1]; j++)
1337 if ((col =
J[j]) == rc)
1347 for (
int k = I[col]; 1; k++)
1350 mfem_error(
"SparseMatrix::EliminateRowCol() #2");
1352 else if (
J[k] == rc)
1361 RowNode *aux, *node;
1363 for (aux =
Rows[rc]; aux != NULL; aux = aux->Prev)
1365 if ((col = aux->Column) == rc)
1375 for (node =
Rows[col]; 1; node = node->Prev)
1378 mfem_error(
"SparseMatrix::EliminateRowCol() #3");
1380 else if (node->Column == rc)
1396 MFEM_ASSERT(rc < height && rc >= 0,
1397 "Row " << rc <<
" not in matrix of height " <<
height);
1401 for (
int j =
I[rc]; j <
I[rc+1]; j++)
1402 if ((col =
J[j]) == rc)
1409 for (
int k = I[col]; 1; k++)
1412 mfem_error(
"SparseMatrix::EliminateRowCol() #2");
1414 else if (
J[k] == rc)
1423 RowNode *aux, *node;
1425 for (aux =
Rows[rc]; aux != NULL; aux = aux->Prev)
1427 if ((col = aux->Column) == rc)
1434 for (node =
Rows[col]; 1; node = node->Prev)
1437 mfem_error(
"SparseMatrix::EliminateRowCol() #3");
1439 else if (node->Column == rc)
1456 for (nd =
Rows[rc]; nd != NULL; nd = nd->Prev)
1458 if ((col = nd->Column) == rc)
1462 Ae.
Add(rc, rc, nd->Value - 1.0);
1468 Ae.
Add(rc, col, nd->Value);
1470 for (nd2 =
Rows[col]; 1; nd2 = nd2->Prev)
1476 else if (nd2->Column == rc)
1478 Ae.
Add(col, rc, nd2->Value);
1488 for (
int j =
I[rc]; j <
I[rc+1]; j++)
1490 if ((col =
J[j]) == rc)
1494 Ae.
Add(rc, rc,
A[j] - 1.0);
1500 Ae.
Add(rc, col,
A[j]);
1502 for (
int k = I[col];
true; k++)
1508 else if (
J[k] == rc)
1510 Ae.
Add(col, rc,
A[k]);
1522 for (
int i = 0; i <
height; i++)
1523 if (
I[i+1] ==
I[i]+1 && fabs(
A[
I[i]]) < 1e-16)
1534 for (i = 0; i <
height; i++)
1537 for (j =
I[i]; j <
I[i+1]; j++)
1543 for (j = I[i]; j < I[i+1]; j++)
1559 double sum, *yp = y.
GetData();
1560 const double *xp = x.
GetData();
1564 RowNode *diag_p, *n_p, **R =
Rows;
1566 for (i = 0; i < s; i++)
1570 for (n_p = R[i]; n_p != NULL; n_p = n_p->Prev)
1571 if ((c = n_p->Column) == i)
1577 sum += n_p->Value * yp[c];
1580 if (diag_p != NULL && diag_p->Value != 0.0)
1582 yp[i] = (xp[i] - sum) / diag_p->Value;
1584 else if (xp[i] == sum)
1590 mfem_error(
"SparseMatrix::Gauss_Seidel_forw()");
1596 int j, end, d, *Ip =
I, *Jp =
J;
1600 for (i = 0; i < s; i++)
1605 for ( ; j < end; j++)
1606 if ((c = Jp[j]) == i)
1612 sum += Ap[j] * yp[c];
1615 if (d >= 0 && Ap[d] != 0.0)
1617 yp[i] = (xp[i] - sum) / Ap[d];
1619 else if (xp[i] == sum)
1625 mfem_error(
"SparseMatrix::Gauss_Seidel_forw(...) #2");
1634 double sum, *yp = y.
GetData();
1635 const double *xp = x.
GetData();
1639 RowNode *diag_p, *n_p, **R =
Rows;
1641 for (i =
height-1; i >= 0; i--)
1645 for (n_p = R[i]; n_p != NULL; n_p = n_p->Prev)
1646 if ((c = n_p->Column) == i)
1652 sum += n_p->Value * yp[c];
1655 if (diag_p != NULL && diag_p->Value != 0.0)
1657 yp[i] = (xp[i] - sum) / diag_p->Value;
1659 else if (xp[i] == sum)
1665 mfem_error(
"SparseMatrix::Gauss_Seidel_back()");
1671 int j, beg, d, *Ip =
I, *Jp =
J;
1675 for (i =
height-1; i >= 0; i--)
1680 for ( ; j >= beg; j--)
1681 if ((c = Jp[j]) == i)
1687 sum += Ap[j] * yp[c];
1690 if (d >= 0 && Ap[d] != 0.0)
1692 yp[i] = (xp[i] - sum) / Ap[d];
1694 else if (xp[i] == sum)
1700 mfem_error(
"SparseMatrix::Gauss_Seidel_back(...) #2");
1708 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
1711 for (
int i = 0; i <
height; i++)
1715 for (
int j =
I[i]; j <
I[i+1]; j++)
1723 if (d >= 0 &&
A[d] != 0.0)
1725 double a = 1.8 * fabs(
A[d]) / norm;
1733 mfem_error(
"SparseMatrix::GetJacobiScaling() #2");
1742 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
1744 for (
int i = 0; i <
height; i++)
1748 for (
int j =
I[i]; j <
I[i+1]; j++)
1756 sum -=
A[j] * x0(
J[j]);
1759 if (d >= 0 &&
A[d] != 0.0)
1761 x1(i) = sc * (sum /
A[d]) + (1.0 - sc) * x0(i);
1772 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
1774 bool scale = (sc != 1.0);
1775 for (
int i = 0, j = 0; i <
height; i++)
1780 MFEM_VERIFY(j != end,
"Couldn't find diagonal in row. i = " << i
1782 <<
", I[i+1] = " << end );
1785 MFEM_VERIFY(std::abs(
A[j]) > 0.0,
"Diagonal " << j <<
" must be nonzero");
1788 x(i) = sc * b(i) /
A[j];
1805 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
1807 for (
int i = 0; i <
height; i++)
1809 double resi = b(i), norm = 0.0;
1810 for (
int j =
I[i]; j <
I[i+1]; j++)
1812 resi -=
A[j] * x0(
J[j]);
1817 x1(i) = x0(i) + sc * resi / norm;
1821 MFEM_ABORT(
"L1 norm of row " << i <<
" is zero.");
1829 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
1831 for (
int i = 0; i <
height; i++)
1833 double resi = b(i), sum = 0.0;
1834 for (
int j =
I[i]; j <
I[i+1]; j++)
1836 resi -=
A[j] * x0(
J[j]);
1841 x1(i) = x0(i) + sc * resi / sum;
1845 MFEM_ABORT(
"sum of row " << i <<
" is zero.");
1853 int i, j, gi, gj, s, t;
1856 for (i = 0; i < rows.
Size(); i++)
1858 if ((gi=rows[i]) < 0) { gi = -1-gi, s = -1; }
1861 "Trying to insert a row " << gi <<
" outside the matrix height "
1864 for (j = 0; j < cols.
Size(); j++)
1866 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
1868 MFEM_ASSERT(gj <
width,
1869 "Trying to insert a column " << gj <<
" outside the matrix width "
1872 if (skip_zeros && a == 0.0)
1876 if (&rows != &cols || subm(j, i) == 0.0)
1881 if (t < 0) { a = -a; }
1893 if ((gi=i) < 0) { gi = -1-gi, s = -1; }
1896 "Trying to insert a row " << gi <<
" outside the matrix height "
1898 if ((gj=j) < 0) { gj = -1-gj, t = -s; }
1900 MFEM_ASSERT(gj <
width,
1901 "Trying to insert a column " << gj <<
" outside the matrix width "
1903 if (t < 0) { a = -a; }
1912 if ((gi=i) < 0) { gi = -1-gi, s = -1; }
1915 "Trying to insert a row " << gi <<
" outside the matrix height "
1917 if ((gj=j) < 0) { gj = -1-gj, t = -s; }
1919 MFEM_ASSERT(gj <
width,
1920 "Trying to insert a column " << gj <<
" outside the matrix width "
1922 if (t < 0) { a = -a; }
1929 int i, j, gi, gj, s, t;
1932 for (i = 0; i < rows.
Size(); i++)
1934 if ((gi=rows[i]) < 0) { gi = -1-gi, s = -1; }
1937 "Trying to insert a row " << gi <<
" outside the matrix height "
1940 for (j = 0; j < cols.
Size(); j++)
1943 if (skip_zeros && a == 0.0)
1947 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
1949 MFEM_ASSERT(gj <
width,
1950 "Trying to insert a column " << gj <<
" outside the matrix width "
1952 if (t < 0) { a = -a; }
1964 int i, j, gi, gj, s, t;
1967 for (i = 0; i < rows.
Size(); i++)
1969 if ((gi=rows[i]) < 0) { gi = -1-gi, s = -1; }
1972 "Trying to insert a row " << gi <<
" outside the matrix height "
1975 for (j = 0; j < cols.
Size(); j++)
1978 if (skip_zeros && a == 0.0)
1982 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
1984 MFEM_ASSERT(gj <
width,
1985 "Trying to insert a column " << gj <<
" outside the matrix width "
1987 if (t < 0) { a = -a; }
1997 int i, j, gi, gj, s, t;
2000 for (i = 0; i < rows.
Size(); i++)
2002 if ((gi=rows[i]) < 0) { gi = -1-gi, s = -1; }
2005 "Trying to insert a row " << gi <<
" outside the matrix height "
2008 for (j = 0; j < cols.
Size(); j++)
2010 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
2012 MFEM_ASSERT(gj <
width,
2013 "Trying to insert a column " << gj <<
" outside the matrix width "
2016 subm(i, j) = (t < 0) ? (-a) : (a);
2031 "Trying to insert a row " << gi <<
" outside the matrix height "
2035 return (
Rows[gi] == NULL);
2039 return (
I[gi] ==
I[gi+1]);
2048 if ((gi=row) < 0) { gi = -1-gi; }
2050 "Trying to insert a row " << gi <<
" outside the matrix height "
2054 for (n =
Rows[gi], j = 0; n; n = n->Prev)
2060 for (n =
Rows[gi], j = 0; n; n = n->Prev, j++)
2062 cols[j] = n->Column;
2077 MFEM_ASSERT(row >= 0,
"Row not valid: " << row );
2088 if ((gi=row) < 0) { gi = -1-gi, s = -1; }
2091 "Trying to insert a row " << gi <<
" outside the matrix height "
2097 for (
int j = 0; j < cols.
Size(); j++)
2099 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
2101 MFEM_ASSERT(gj <
width,
2102 "Trying to insert a column " << gj <<
" outside the matrix"
2103 " width " <<
width);
2105 if (t < 0) { a = -a; }
2113 MFEM_ASSERT(cols.
Size() == srow.
Size(),
"");
2115 for (
int i =
I[gi], j = 0; j < cols.
Size(); j++, i++)
2117 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
2119 MFEM_ASSERT(gj <
width,
2120 "Trying to insert a column " << gj <<
" outside the matrix"
2121 " width " <<
width);
2133 int j, gi, gj, s, t;
2136 MFEM_VERIFY(!
Finalized(),
"Matrix must NOT be finalized.");
2138 if ((gi=row) < 0) { gi = -1-gi, s = -1; }
2141 "Trying to insert a row " << gi <<
" outside the matrix height "
2144 for (j = 0; j < cols.
Size(); j++)
2146 if ((gj=cols[j]) < 0) { gj = -1-gj, t = -s; }
2148 MFEM_ASSERT(gj <
width,
2149 "Trying to insert a column " << gj <<
" outside the matrix width "
2156 if (t < 0) { a = -a; }
2174 for (aux =
Rows[i]; aux != NULL; aux = aux -> Prev)
2176 aux -> Value *= scale;
2181 int j, end =
I[i+1];
2183 for (j =
I[i]; j < end; j++)
2196 for (
int i=0; i <
height; ++i)
2199 for (aux =
Rows[i]; aux != NULL; aux = aux -> Prev)
2201 aux -> Value *= scale;
2209 for (
int i=0; i <
height; ++i)
2213 for (j =
I[i]; j < end; j++)
2226 for (
int i=0; i <
height; ++i)
2228 for (aux =
Rows[i]; aux != NULL; aux = aux -> Prev)
2230 aux -> Value *= sr(aux->Column);
2238 for (
int i=0; i <
height; ++i)
2241 for (j =
I[i]; j < end; j++)
2252 "Mismatch of this matrix size and rhs. This height = "
2253 <<
height <<
", width = " <<
width <<
", B.height = "
2256 for (
int i = 0; i <
height; i++)
2261 for (RowNode *aux = B.
Rows[i]; aux != NULL; aux = aux->Prev)
2263 _Add_(aux->Column, aux->Value);
2268 for (
int j = B.
I[i]; j < B.
I[i+1]; j++)
2281 for (
int i = 0; i <
height; i++)
2286 for (RowNode *np =
Rows[i]; np != NULL; np = np->Prev)
2288 np->Value += a * B.
_Get_(np->Column);
2293 for (
int j =
I[i]; j <
I[i+1]; j++)
2305 for (
int i = 0, nnz =
I[
height]; i < nnz; i++)
2310 for (
int i = 0; i <
height; i++)
2311 for (RowNode *node_p =
Rows[i]; node_p != NULL;
2312 node_p = node_p -> Prev)
2314 node_p -> Value = a;
2323 for (
int i = 0, nnz =
I[
height]; i < nnz; i++)
2328 for (
int i = 0; i <
height; i++)
2329 for (RowNode *node_p =
Rows[i]; node_p != NULL;
2330 node_p = node_p -> Prev)
2332 node_p -> Value *= a;
2345 for (i = 0; i <
height; i++)
2347 out <<
"[row " << i <<
"]\n";
2348 for (nd =
Rows[i], j = 0; nd != NULL; nd = nd->Prev, j++)
2350 out <<
" (" << nd->Column <<
"," << nd->Value <<
")";
2351 if ( !((j+1) % _width) )
2364 for (i = 0; i <
height; i++)
2366 out <<
"[row " << i <<
"]\n";
2367 for (j =
I[i]; j <
I[i+1]; j++)
2369 out <<
" (" <<
J[j] <<
"," <<
A[j] <<
")";
2370 if ( !((j+1-I[i]) % _width) )
2375 if ((j-I[i]) % _width)
2384 out <<
"% size " <<
height <<
" " <<
width <<
"\n";
2387 ios::fmtflags old_fmt = out.flags();
2388 out.setf(ios::scientific);
2389 std::streamsize old_prec = out.precision(14);
2391 for (i = 0; i <
height; i++)
2392 for (j =
I[i]; j <
I[i+1]; j++)
2394 out << i+1 <<
" " <<
J[j]+1 <<
" " <<
A[j] <<
'\n';
2396 out.precision(old_prec);
2403 ios::fmtflags old_fmt = out.flags();
2404 out.setf(ios::scientific);
2405 std::streamsize old_prec = out.precision(14);
2407 out <<
"%%MatrixMarket matrix coordinate real general" <<
'\n'
2408 <<
"% Generated by MFEM" <<
'\n';
2411 for (i = 0; i <
height; i++)
2412 for (j =
I[i]; j <
I[i+1]; j++)
2414 out << i+1 <<
" " <<
J[j]+1 <<
" " <<
A[j] <<
'\n';
2416 out.precision(old_prec);
2422 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
2428 for (i = 0; i <=
height; i++)
2430 out <<
I[i]+1 <<
'\n';
2433 for (i = 0; i <
I[
height]; i++)
2435 out <<
J[i]+1 <<
'\n';
2438 for (i = 0; i < I[
height]; i++)
2440 out <<
A[i] <<
'\n';
2446 MFEM_VERIFY(
Finalized(),
"Matrix must be finalized.");
2451 out <<
width <<
'\n';
2453 for (i = 0; i <=
height; i++)
2455 out <<
I[i] <<
'\n';
2458 for (i = 0; i <
I[
height]; i++)
2460 out <<
J[i] <<
'\n';
2463 for (i = 0; i < I[
height]; i++)
2465 out <<
A[i] <<
'\n';
2471 const double MiB = 1024.*1024;
2473 double pz = 100./nnz;
2483 "SparseMatrix statistics:\n"
2486 " Dimensions : " <<
height <<
" x " <<
width <<
"\n"
2487 " Number of entries (total) : " << nnz <<
"\n"
2488 " Number of entries (per row) : " << 1.*nnz/
Height() <<
"\n"
2489 " Number of stored zeros : " << nz*pz <<
"% (" << nz <<
")\n"
2490 " Number of Inf/Nan entries : " << nnf*pz <<
"% ("<< nnf <<
")\n"
2491 " Norm, max |a_ij| : " << max_norm <<
"\n"
2492 " Symmetry, max |a_ij-a_ji| : " << symm <<
"\n"
2493 " Number of small entries:\n"
2494 " |a_ij| <= 1e-12*Norm : " << ns12*pz <<
"% (" << ns12 <<
")\n"
2495 " |a_ij| <= 1e-15*Norm : " << ns15*pz <<
"% (" << ns15 <<
")\n"
2496 " |a_ij| <= 1e-18*Norm : " << ns18*pz <<
"% (" << ns18 <<
")\n";
2499 out <<
" Memory used by CSR : " <<
2500 (
sizeof(int)*(
height+1+nnz)+
sizeof(double)*nnz)/MiB <<
" MiB\n";
2504 size_t used_mem =
sizeof(RowNode*)*
height;
2505 #ifdef MFEM_USE_MEMALLOC
2508 for (
int i = 0; i <
height; i++)
2510 for (RowNode *aux =
Rows[i]; aux != NULL; aux = aux->Prev)
2512 used_mem +=
sizeof(RowNode);
2516 out <<
" Memory used by LIL : " << used_mem/MiB <<
" MiB\n";
2537 #if !defined(MFEM_USE_MEMALLOC)
2538 for (
int i = 0; i <
height; i++)
2540 RowNode *aux, *node_p =
Rows[i];
2541 while (node_p != NULL)
2544 node_p = node_p->Prev;
2560 #ifdef MFEM_USE_MEMALLOC
2575 for (
int *jptr = start_j; jptr != end_j; ++jptr)
2577 awidth = std::max(awidth, *jptr + 1);
2583 for (
int i = 0; i <
height; i++)
2585 for (aux =
Rows[i]; aux != NULL; aux = aux->Prev)
2587 awidth = std::max(awidth, aux->Column + 1);
2599 for (
int i = 0; i < n; i++)
2609 "Finalize must be called before Transpose. Use TransposeRowMatrix instead");
2612 int m, n, nnz, *A_i, *A_j, *At_i, *At_j;
2613 double *A_data, *At_data;
2622 At_i =
new int[n+1];
2623 At_j =
new int[nnz];
2624 At_data =
new double[nnz];
2626 for (i = 0; i <= n; i++)
2630 for (i = 0; i < nnz; i++)
2634 for (i = 1; i < n; i++)
2636 At_i[i+1] += At_i[i];
2639 for (i = j = 0; i < m; i++)
2642 for ( ; j < end; j++)
2644 At_j[At_i[A_j[j]]] = i;
2645 At_data[At_i[A_j[j]]] = A_data[j];
2650 for (i = n; i > 0; i--)
2652 At_i[i] = At_i[i-1];
2663 int m, n, nnz, *At_i, *At_j;
2673 for (i = 0; i < m; i++)
2675 A.
GetRow(i, Acols, Avals);
2693 At_i =
new int[n+1];
2694 At_j =
new int[nnz];
2695 At_data =
new double[nnz];
2697 for (i = 0; i <= n; i++)
2702 for (i = 0; i < m; i++)
2704 A.
GetRow(i, Acols, Avals);
2705 for (j = 0; j<Acols.
Size(); ++j)
2710 for (i = 1; i < n; i++)
2712 At_i[i+1] += At_i[i];
2715 for (i = 0; i < m; i++)
2717 A.
GetRow(i, Acols, Avals);
2718 for (j = 0; j<Acols.
Size(); ++j)
2720 At_j[At_i[Acols[j]]] = i;
2721 At_data[At_i[Acols[j]]] = Avals[j];
2726 for (i = n; i > 0; i--)
2728 At_i[i] = At_i[i-1];
2739 int nrowsA, ncolsA, nrowsB, ncolsB;
2740 int *A_i, *A_j, *B_i, *B_j, *C_i, *C_j, *B_marker;
2741 double *A_data, *B_data, *C_data;
2742 int ia, ib, ic, ja, jb, num_nonzeros;
2743 int row_start, counter;
2744 double a_entry, b_entry;
2752 MFEM_VERIFY(ncolsA == nrowsB,
2753 "number of columns of A (" << ncolsA
2754 <<
") must equal number of rows of B (" << nrowsB <<
")");
2763 B_marker =
new int[ncolsB];
2765 for (ib = 0; ib < ncolsB; ib++)
2772 C_i =
new int[nrowsA+1];
2774 C_i[0] = num_nonzeros = 0;
2775 for (ic = 0; ic < nrowsA; ic++)
2777 for (ia = A_i[ic]; ia < A_i[ic+1]; ia++)
2780 for (ib = B_i[ja]; ib < B_i[ja+1]; ib++)
2783 if (B_marker[jb] != ic)
2790 C_i[ic+1] = num_nonzeros;
2793 C_j =
new int[num_nonzeros];
2794 C_data =
new double[num_nonzeros];
2796 C =
new SparseMatrix (C_i, C_j, C_data, nrowsA, ncolsB);
2798 for (ib = 0; ib < ncolsB; ib++)
2807 MFEM_VERIFY(nrowsA == C -> Height() && ncolsB == C -> Width(),
2808 "Input matrix sizes do not match output sizes"
2809 <<
" nrowsA = " << nrowsA
2810 <<
", C->Height() = " << C->
Height()
2811 <<
" ncolsB = " << ncolsB
2812 <<
", C->Width() = " << C->
Width());
2816 C_data = C -> GetData();
2820 for (ic = 0; ic < nrowsA; ic++)
2823 row_start = counter;
2824 for (ia = A_i[ic]; ia < A_i[ic+1]; ia++)
2827 a_entry = A_data[ia];
2828 for (ib = B_i[ja]; ib < B_i[ja+1]; ib++)
2831 b_entry = B_data[ib];
2832 if (B_marker[jb] < row_start)
2834 B_marker[jb] = counter;
2839 C_data[counter] = a_entry*b_entry;
2844 C_data[B_marker[jb]] += a_entry*b_entry;
2852 "With pre-allocated output matrix, number of non-zeros ("
2854 <<
") did not match number of entries changed from matrix-matrix multiply, "
2865 int nrowsA, ncolsA, nrowsB, ncolsB;
2866 int *C_i, *C_j, *B_marker;
2868 int ia, ib, ic, ja, jb, num_nonzeros;
2869 int row_start, counter;
2870 double a_entry, b_entry;
2878 MFEM_VERIFY(ncolsA == nrowsB,
2879 "number of columns of A (" << ncolsA
2880 <<
") must equal number of rows of B (" << nrowsB <<
")");
2882 B_marker =
new int[ncolsB];
2884 for (ib = 0; ib < ncolsB; ib++)
2889 C_i =
new int[nrowsA+1];
2891 C_i[0] = num_nonzeros = 0;
2895 for (ic = 0; ic < nrowsA; ic++)
2897 A.
GetRow(ic, colsA, dataA);
2898 for (ia = 0; ia < colsA.
Size(); ia++)
2901 B.
GetRow(ja, colsB, dataB);
2902 for (ib = 0; ib < colsB.
Size(); ib++)
2905 if (B_marker[jb] != ic)
2912 C_i[ic+1] = num_nonzeros;
2915 C_j =
new int[num_nonzeros];
2916 C_data =
new double[num_nonzeros];
2918 C =
new SparseMatrix(C_i, C_j, C_data, nrowsA, ncolsB);
2920 for (ib = 0; ib < ncolsB; ib++)
2926 for (ic = 0; ic < nrowsA; ic++)
2928 row_start = counter;
2929 A.
GetRow(ic, colsA, dataA);
2930 for (ia = 0; ia < colsA.
Size(); ia++)
2933 a_entry = dataA[ia];
2934 B.
GetRow(ja, colsB, dataB);
2935 for (ib = 0; ib < colsB.
Size(); ib++)
2938 b_entry = dataB[ib];
2939 if (B_marker[jb] < row_start)
2941 B_marker[jb] = counter;
2943 C_data[counter] = a_entry*b_entry;
2948 C_data[B_marker[jb]] += a_entry*b_entry;
2963 for (
int j = 0; j < B.
Width(); ++j)
2967 A.
Mult(columnB, columnC);
2977 Mult (R, *AP, *_RAP);
3007 int i, At_nnz, *At_j;
3011 At_nnz = At -> NumNonZeroElems();
3012 At_j = At -> GetJ();
3013 At_data = At -> GetData();
3014 for (i = 0; i < At_nnz; i++)
3016 At_data[i] *= D(At_j[i]);
3027 int ncols = A.
Width();
3029 int * C_i =
new int[nrows+1];
3033 int * A_i = A.
GetI();
3034 int * A_j = A.
GetJ();
3035 double * A_data = A.
GetData();
3037 int * B_i = B.
GetI();
3038 int * B_j = B.
GetJ();
3039 double * B_data = B.
GetData();
3041 int * marker =
new int[ncols];
3042 std::fill(marker, marker+ncols, -1);
3044 int num_nonzeros = 0, jcol;
3046 for (
int ic = 0; ic < nrows; ic++)
3048 for (
int ia = A_i[ic]; ia < A_i[ic+1]; ia++)
3054 for (
int ib = B_i[ic]; ib < B_i[ic+1]; ib++)
3057 if (marker[jcol] != ic)
3063 C_i[ic+1] = num_nonzeros;
3066 C_j =
new int[num_nonzeros];
3067 C_data =
new double[num_nonzeros];
3069 for (
int ia = 0; ia < ncols; ia++)
3075 for (
int ic = 0; ic < nrows; ic++)
3077 for (
int ia = A_i[ic]; ia < A_i[ic+1]; ia++)
3081 C_data[pos] = a*A_data[ia];
3085 for (
int ib = B_i[ic]; ib < B_i[ic+1]; ib++)
3088 if (marker[jcol] < C_i[ic])
3091 C_data[pos] = b*B_data[ib];
3097 C_data[marker[jcol]] += b*B_data[ib];
3103 return new SparseMatrix(C_i, C_j, C_data, nrows, ncols);
3108 return Add(1.,A,1.,B);
3113 MFEM_ASSERT(Ai.
Size() > 0,
"invalid size Ai.Size() = " << Ai.
Size());
3118 for (
int i=1; i < Ai.
Size(); ++i)
3120 result =
Add(*accumulate, *Ai[i]);
3126 accumulate = result;
3144 #ifdef MFEM_USE_MEMALLOC
double GetJacobiScaling() const
Determine appropriate scaling for Jacobi iteration.
int CheckFinite() const
Count the number of entries that are NOT finite, i.e. Inf or Nan.
int Size() const
Logical size of the array.
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.
int CheckFinite(const double *v, const int n)
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 NewDataAndSize(double *d, int s)
Set the Vector data and size, deleting the old data, if owned.
void Clear()
Clear the contents of the SparseMatrix.
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
size_t MemoryUsage() const
void DiagScale(const Vector &b, Vector &x, double sc=1.0) const
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
void MakeRef(const SparseMatrix &master)
Clear the contents of the SparseMatrix and make it a reference to master.
void SetSize(int s)
Resize the vector to size s.
double & SearchRow(const int col)
bool Empty() const
Check if the SparseMatrix is empty.
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
int * I
Array with size (height+1) containing the row offsets.
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)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
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
int Size() const
Returns the size of the vector.
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.
virtual int NumNonZeroElems() const =0
Returns the number of non-zeros in a matrix.
void EliminateRowColMultipleRHS(int rc, const Vector &sol, DenseMatrix &rhs, int d=0)
void PrintInfo(std::ostream &out) const
Print various sparse matrix staticstics.
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
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 PrintMM(std::ostream &out=mfem::out) const
Prints matrix in Matrix Market sparse format.
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)
bool IsFinite(const double &val)
void MoveDiagonalFirst()
Move the diagonal entry to the first position in each row, preserving the order of the rest of the co...
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)
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
Extract all column indices and values from a given row.
bool isSorted
Are the columns sorted already.
SparseMatrix()
Create an empty SparseMatrix.
bool ownData
Say whether we own the pointers for A (should we free them?).
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.
double IsSymmetric() const
Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
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 Sort()
Sorts the array. This requires operator< to be defined for T.
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const =0
void PrintMatlab(std::ostream &out=mfem::out) const
Prints matrix in matlab format.
void EliminateZeroRows()
If a row contains only zeros, set its diagonal to 1.
double * GetData() const
Return element data, i.e. array A.
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 Swap(Array< T > &, Array< T > &)
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 mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Set(const int i, const int j, const double a)
void GetColumnReference(int c, Vector &col)
int * J
Array with size I[height], containing the column indices for all matrix entries, as indexed by the I ...
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.
RowNode ** Rows
Array of linked lists, one for every row. This array represents the linked list (LIL) storage format...
int height
Dimension of the output / number of rows in the matrix.
void EliminateRow(int row, const double sol, Vector &rhs)
Eliminates a column from the transpose matrix.
double * A
Array with size I[height], containing the actual entries of the sparse matrix, as indexed by the I ar...
void GetDiag(Vector &d) const
Returns the Diagonal of A.
MemAlloc< RowNode, 1024 > RowNodeAlloc
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.
bool ownGraph
Say whether we own the pointers for I and J (should we free them?).
SparseMatrix & operator*=(double a)
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
void MakeRef(T *, int)
Make this Array a reference to a pointer.
void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
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
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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 width
Dimension of the input / number of columns in the matrix.
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 .
void Neg()
(*this) = -(*this)