31#if defined(_MSC_VER) && (_MSC_VER < 1800)
33#define copysign _copysign
46 MFEM_ASSERT(s >= 0,
"invalid DenseMatrix size: " << s);
56 MFEM_ASSERT(m >= 0 && n >= 0,
57 "invalid DenseMatrix size: " << m <<
" x " << n);
58 const int capacity = m*n;
67 :
Matrix(mat.width, mat.height)
69 MFEM_CONTRACT_VAR(ch);
75 for (
int i = 0; i <
height; i++)
77 for (
int j = 0; j <
width; j++)
79 (*this)(i,j) = mat(j,i);
87 MFEM_ASSERT(h >= 0 && w >= 0,
88 "invalid DenseMatrix size: " << h <<
" x " << w);
115 MFEM_ASSERT(
height == y.
Size(),
"incompatible dimensions");
122 MFEM_ASSERT(
width == x.
Size(),
"incompatible dimensions");
130 "incompatible dimensions");
138 "incompatible dimensions");
146 "incompatible dimensions");
150 for (
int i = 0; i < hw; i++)
152 a += data[i] * m.data[i];
165 MFEM_ASSERT(
width == y.
Size(),
"incompatible dimensions");
172 MFEM_ASSERT(
height == x.
Size(),
"incompatible dimensions");
180 "incompatible dimensions");
188 "incompatible dimensions");
202 "incompatible dimensions");
206 for (
int col = 0; col <
width; col++)
209 for (
int row = 0; row <
height; row++)
211 yp[row] += x_col*d_col[row];
226 "incompatible dimensions");
228 const real_t *d_col = data;
229 for (
int col = 0; col <
width; col++)
232 for (
int row = 0; row <
height; row++)
234 y_col += x[row]*d_col[row];
244 "incompatible dimensions");
251 for (
int col = 0; col <
width; col++)
253 const real_t x_col =
a*xp[col];
254 for (
int row = 0; row <
height; row++)
256 yp[row] += x_col*d_col[row];
266 "incompatible dimensions");
268 const real_t *d_col = data;
269 for (
int col = 0; col <
width; col++)
272 for (
int row = 0; row <
height; row++)
274 y_col += x[row]*d_col[row];
285 for (
int i = 0; i <
height; i++)
288 for (
int j = 0; j <
width; j++)
290 Axi += (*this)(i,j) * x[j];
302 for (
int j = 0; j <
width; ++j)
304 for (
int i = 0; i <
height; ++i)
306 *(it_data++) *= s(i);
315 for (
int j = 0; j <
width; ++j)
317 for (
int i = 0; i <
height; ++i)
319 *(it_data++) /= s(i);
329 for (
int j = 0; j <
width; ++j)
332 for (
int i = 0; i <
height; ++i)
343 for (
int j = 0; j <
width; ++j)
345 const real_t sj = 1./s(j);
346 for (
int i = 0; i <
height; ++i)
358 mfem_error(
"DenseMatrix::SymmetricScaling: dimension mismatch");
364 for (
real_t * end_s = it_s +
width; it_s != end_s; ++it_s)
366 *(it_ss++) = sqrt(*it_s);
370 for (
int j = 0; j <
width; ++j)
372 for (
int i = 0; i <
height; ++i)
374 *(it_data++) *= ss[i]*ss[j];
386 mfem_error(
"DenseMatrix::InvSymmetricScaling: dimension mismatch");
392 for (
real_t * end_s = it_s +
width; it_s != end_s; ++it_s)
394 *(it_ss++) = 1./sqrt(*it_s);
398 for (
int j = 0; j <
width; ++j)
400 for (
int i = 0; i <
height; ++i)
402 *(it_data++) *= ss[i]*ss[j];
414 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
420 for (
int i = 0; i <
width; i++)
436 "The matrix must be square and "
437 <<
"of size less than or equal to 2."
438 <<
" Height() = " <<
Height()
439 <<
", Width() = " <<
Width());
445 data[0] = std::exp(data[0]);
456 const real_t e = (
a - d)*(
a - d) + 4*
b*c;
457 const real_t f = std::exp((
a + d)/2.0);
458 const real_t g = std::sqrt(std::abs(e)) / 2.0;
462 data[0] = 1.0 + (
a - d)/2.0;
463 data[3] = 1.0 - (
a - d)/2.0;
467 data[0] = std::cosh(g) + (
a - d)/2 * std::sinh(g) / g;
468 data[1] =
b * std::sinh(g) / g;
469 data[2] = c * std::sinh(g) / g;
470 data[3] = std::cosh(g) - (
a - d)/2 * std::sinh(g) / g;
474 data[0] = std::cos(g) + (
a - d)/2 * std::sin(g) / g;
475 data[1] =
b * std::sin(g) / g;
476 data[2] = c * std::sin(g) / g;
477 data[3] = std::cos(g) - (
a - d)/2 * std::sin(g) / g;
479 for (
int i = 0; i < 4; i++)
487 MFEM_ABORT(
"3x3 matrices are not currently supported");
491 MFEM_ABORT(
"Only 1x1 and 2x2 matrices are currently supported");
499 "The matrix must be square and "
500 <<
"sized larger than zero to compute the determinant."
501 <<
" Height() = " <<
Height()
502 <<
", Width() = " <<
Width());
510 return data[0] * data[3] - data[1] * data[2];
516 d[0] * (d[4] * d[8] - d[5] * d[7]) +
517 d[3] * (d[2] * d[7] - d[1] * d[8]) +
518 d[6] * (d[1] * d[5] - d[2] * d[4]);
524 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
525 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
526 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
528 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
529 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
530 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
532 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
533 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
534 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
536 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
537 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
538 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
547 return lu_factors.
Det();
562 return sqrt(data[0] * data[0] + data[1] * data[1]);
566 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
571 real_t E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
572 real_t G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
573 real_t F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
574 return sqrt(E * G - F * F);
576 mfem_error(
"DenseMatrix::Weight(): mismatched or unsupported dimensions");
583 for (
int i = 0; i < s; i++)
585 data[i] =
alpha*A[i];
591 for (
int j = 0; j <
Width(); j++)
593 for (
int i = 0; i <
Height(); i++)
595 (*this)(i,j) += c * A(i,j);
603 for (
int i = 0; i < s; i++)
612 for (
int i = 0; i < s; i++)
622 for (
int i = 0; i < s; i++)
638 "incompatible matrix sizes.");
644 for (
int j = 0; j <
width; j++)
646 for (
int i = 0; i <
height; i++)
648 (*this)(i, j) -= m(i, j);
658 for (
int i = 0; i < s; i++)
668 for (
int i = 0; i < hw; i++)
679 mfem_error(
"DenseMatrix::Invert(): dimension mismatch");
683#ifdef MFEM_USE_LAPACK
684 int *ipiv =
new int[
width];
693 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
696 MFEM_LAPACK_PREFIX(getri_)(&
width, data, &
width, ipiv, &qwork, &lwork, &info);
701 MFEM_LAPACK_PREFIX(getri_)(&
width, data, &
width, ipiv, work, &lwork, &info);
705 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
711 int c, i, j, n =
Width();
715 for (c = 0; c < n; c++)
717 a = fabs((*
this)(c, c));
719 for (j = c + 1; j < n; j++)
721 b = fabs((*
this)(j, c));
730 mfem_error(
"DenseMatrix::Invert() : singular matrix");
733 for (j = 0; j < n; j++)
738 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
739 for (j = 0; j < c; j++)
743 for (j++; j < n; j++)
747 for (i = 0; i < c; i++)
749 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
750 for (j = 0; j < c; j++)
752 (*this)(i, j) +=
b * (*
this)(c, j);
754 for (j++; j < n; j++)
756 (*this)(i, j) +=
b * (*
this)(c, j);
759 for (i++; i < n; i++)
761 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
762 for (j = 0; j < c; j++)
764 (*this)(i, j) +=
b * (*
this)(c, j);
766 for (j++; j < n; j++)
768 (*this)(i, j) +=
b * (*
this)(c, j);
773 for (c = n - 1; c >= 0; c--)
776 for (i = 0; i < n; i++)
790 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
800 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
802 for (
int j = 0; j < 10; j++)
804 for (
int i = 0; i < 10; i++)
819 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
820 if (tmp2.FNorm() < 1e-10) {
break; }
823 if (tmp2.FNorm() > 1e-10)
825 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
831 for (
int j = 0; j <
Width(); j++)
834 for (
int i = 0; i <
Height(); i++)
836 v[j] += (*this)(i,j)*(*
this)(i,j);
848 for (
int i = 0; i < hw; i++)
850 abs_entry = fabs(d[i]);
851 if (
norm < abs_entry)
863 real_t max_norm = 0.0, entry, fnorm2;
865 for (i = 0; i < hw; i++)
867 entry = fabs(data[i]);
868 if (entry > max_norm)
876 scale_factor = scaled_fnorm2 = 0.0;
881 for (i = 0; i < hw; i++)
883 entry = data[i] / max_norm;
884 fnorm2 += entry * entry;
887 scale_factor = max_norm;
888 scaled_fnorm2 = fnorm2;
893#ifdef MFEM_USE_LAPACK
911 int *ISUPPZ =
new int[2*N];
929 int hw =
a.Height() *
a.Width();
932 for (
int i = 0; i < hw; i++)
937 MFEM_LAPACK_PREFIX(syevr_)(&JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL,
938 &IU, &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK,
939 &LWORK, &QIWORK, &LIWORK, &INFO);
945 IWORK =
new int[LIWORK];
947 MFEM_LAPACK_PREFIX(syevr_)(&JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL,
948 &IU, &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK,
949 &LWORK, IWORK, &LIWORK, &INFO);
953 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: "
961 mfem::err <<
"dsyevr_Eigensystem(...):\n"
962 <<
" DSYEVR did not find all eigenvalues "
963 << M <<
"/" << N << endl;
968 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
972 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
975 for (IL = 0; IL < N; IL++)
976 for (IU = 0; IU <= IL; IU++)
979 for (M = 0; M < N; M++)
981 VL += Z[M+IL*N] * Z[M+IU*N];
998 <<
" Z^t Z - I deviation = " << VU
999 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1000 << W[0] <<
", N = " << N << endl;
1007 <<
" Z^t Z - I deviation = " << VU
1008 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1009 << W[0] <<
", N = " << N << endl;
1013 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1016 for (IL = 0; IL < N; IL++)
1017 for (IU = 0; IU < N; IU++)
1020 for (M = 0; M < N; M++)
1022 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
1024 VL = fabs(VL-data[IL+N*IU]);
1033 <<
" max matrix deviation = " << VU
1034 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1035 << W[0] <<
", N = " << N << endl;
1039 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1048 MFEM_CONTRACT_VAR(
a);
1049 MFEM_CONTRACT_VAR(ev);
1050 MFEM_CONTRACT_VAR(evect);
1056#ifdef MFEM_USE_LAPACK
1082 int hw =
a.Height() *
a.Width();
1084 for (
int i = 0; i < hw; i++)
1089 MFEM_LAPACK_PREFIX(syev_)(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1091 LWORK = (int) QWORK;
1092 WORK =
new real_t[LWORK];
1094 MFEM_LAPACK_PREFIX(syev_)(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1098 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1103 if (evect == NULL) {
delete [] A; }
1105 MFEM_CONTRACT_VAR(
a);
1106 MFEM_CONTRACT_VAR(ev);
1107 MFEM_CONTRACT_VAR(evect);
1111void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1113#ifdef MFEM_USE_LAPACK
1121 MFEM_CONTRACT_VAR(ev);
1122 MFEM_CONTRACT_VAR(evect);
1123 mfem_error(
"DenseMatrix::Eigensystem: Compiled without LAPACK");
1131#ifdef MFEM_USE_LAPACK
1160 int hw =
a.Height() *
a.Width();
1163 for (
int i = 0; i < hw; i++)
1169 MFEM_LAPACK_PREFIX(sygv_)(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W,
1170 &QWORK, &LWORK, &INFO);
1172 LWORK = (int) QWORK;
1173 WORK =
new real_t[LWORK];
1175 MFEM_LAPACK_PREFIX(sygv_)(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK,
1180 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1186 if (evect == NULL) {
delete [] A; }
1188 MFEM_CONTRACT_VAR(
a);
1189 MFEM_CONTRACT_VAR(
b);
1190 MFEM_CONTRACT_VAR(ev);
1191 MFEM_CONTRACT_VAR(evect);
1195void DenseMatrix::Eigensystem(DenseMatrix &
b, Vector &ev,
1198#ifdef MFEM_USE_LAPACK
1203 MFEM_CONTRACT_VAR(
b);
1204 MFEM_CONTRACT_VAR(ev);
1205 MFEM_CONTRACT_VAR(evect);
1206 mfem_error(
"DenseMatrix::Eigensystem(generalized): Compiled without LAPACK");
1212#ifdef MFEM_USE_LAPACK
1218 real_t *
a = copy_of_this.data;
1228 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n,
a, &m, s,
u, &m, vt, &n,
1229 &qwork, &lwork, &info);
1231 lwork = (int) qwork;
1232 work =
new real_t[lwork];
1234 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n,
a, &m, s,
u, &m, vt, &n,
1235 work, &lwork, &info);
1240 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1244 MFEM_CONTRACT_VAR(sv);
1246 mfem_error(
"DenseMatrix::SingularValues: Compiled without LAPACK");
1256 for (
int i=0; i < sv.
Size(); ++i)
1268 "The matrix must be square and sized 1, 2, or 3 to compute the"
1270 <<
" Height() = " <<
Height()
1271 <<
", Width() = " <<
Width());
1318 const real_t* rp = data + r;
1321 for (
int i = 0; i < n; i++)
1336 for (
int i = 0; i < m; i++)
1350 for (
int i = 0; i <
height; ++i)
1352 d(i) = (*this)(i,i);
1366 for (
int j = 0; j <
width; ++j)
1367 for (
int i = 0; i <
height; ++i)
1369 l(i) += fabs((*
this)(i,j));
1378 for (
int j = 0; j <
width; ++j)
1379 for (
int i = 0; i <
height; ++i)
1381 l(i) += fabs((*
this)(i,j));
1390 for (
int j = 0; j <
width; ++j)
1391 for (
int i = 0; i <
height; ++i)
1396 for (
int i = 0; i <
height; ++i)
1405 for (
int i = 0; i <
height; i++)
1408 for (
int j = 0; j <
width; j++)
1421 for (
int i = 0; i < N; i++)
1425 for (
int i = 0; i < n; i++)
1436 for (i = 0; i < N; i++)
1440 for (i = 0; i < n; i++)
1442 data[i*(n+1)] = diag[i];
1453 for (i = 0; i <
Height(); i++)
1454 for (j = i+1; j <
Width(); j++)
1457 (*this)(i,j) = (*
this)(j,i);
1472 for (
int i = 0; i <
Height(); i++)
1473 for (
int j = 0; j <
Width(); j++)
1475 (*this)(i,j) = A(j,i);
1484 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1492 for (
int i = 0; i <
Height(); i++)
1495 for (
int j = 0; j <
Width(); j++)
1498 (*this)(i, j) = 0.0;
1512 mfem_error(
"DenseMatrix::GradToCurl(...): dimension mismatch");
1518 for (
int i = 0; i < n; i++)
1535 for (
int i = 0; i < n; i++)
1565 MFEM_VERIFY(
Width() == 2,
1566 "DenseMatrix::GradToVectorCurl2D(...): dimension must be 2")
1570 for (
int i = 0; i < n; i++)
1572 curl(i,0) = (*this)(i,1);
1573 curl(i,1) = -(*this)(i,0);
1579 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1586 for (
int i = 0; i < n; i++)
1596 for (
int j = 0; j <
Width(); j++)
1598 for (
int i = row1; i <= row2; i++)
1600 (*this)(i-row1,j) = A(i,j);
1609 for (
int j = col1; j <= col2; j++)
1611 for (
int i = 0; i <
Height(); i++)
1613 (*this)(i,j-col1) = A(i,j);
1622 for (
int j = 0; j < n; j++)
1624 for (
int i = 0; i < m; i++)
1626 (*this)(i,j) = A(Aro+i,Aco+j);
1635 for (
int j = 0; j < A.
Width(); j++)
1637 for (
int i = 0; i < A.
Height(); i++)
1639 (*this)(row_offset+i,col_offset+j) = *(v++);
1648 for (
int i = 0; i < A.
Width(); i++)
1650 for (
int j = 0; j < A.
Height(); j++)
1652 (*this)(row_offset+i,col_offset+j) = *(v++);
1658 int row_offset,
int col_offset)
1660 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1661 "this DenseMatrix is too small to accommodate the submatrix. "
1662 <<
"row_offset = " << row_offset
1664 <<
", this->Height() = " << this->
Height()
1665 <<
", col_offset = " << col_offset
1667 <<
", this->Width() = " << this->
Width()
1669 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1670 "The A DenseMatrix is too small to accommodate the submatrix. "
1673 <<
", A.Height() = " << A.
Height()
1674 <<
", Aco = " << Aco
1676 <<
", A.Width() = " << A.
Width()
1679 for (
int j = 0; j < n; j++)
1681 for (
int i = 0; i < m; i++)
1683 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1690 for (
int i = 0; i < n; i++)
1692 for (
int j = i+1; j < n; j++)
1694 (*this)(row_offset+i,col_offset+j) =
1695 (*
this)(row_offset+j,col_offset+i) = 0.0;
1699 for (
int i = 0; i < n; i++)
1701 (*this)(row_offset+i,col_offset+i) = c;
1708 for (
int i = 0; i < n; i++)
1710 for (
int j = i+1; j < n; j++)
1712 (*this)(row_offset+i,col_offset+j) =
1713 (*
this)(row_offset+j,col_offset+i) = 0.0;
1717 for (
int i = 0; i < n; i++)
1719 (*this)(row_offset+i,col_offset+i) = diag[i];
1727 int i, j, i_off = 0, j_off = 0;
1729 for (j = 0; j < A.
Width(); j++)
1736 for (i = 0; i < A.
Height(); i++)
1743 (*this)(i-i_off,j-j_off) = A(i,j);
1759 if (co+aw >
Width() || ro+ah > h)
1761 mfem_error(
"DenseMatrix::AddMatrix(...) 1 : dimension mismatch");
1765 p = data + ro + co * h;
1768 for (
int c = 0; c < aw; c++)
1770 for (
int r = 0; r < ah; r++)
1789 if (co+aw >
Width() || ro+ah > h)
1791 mfem_error(
"DenseMatrix::AddMatrix(...) 2 : dimension mismatch");
1795 p = data + ro + co * h;
1798 for (
int c = 0; c < aw; c++)
1800 for (
int r = 0; r < ah; r++)
1812 int idx_max = idx.
Max();
1813 MFEM_VERIFY(idx.
Min() >=0 && idx_max < this->
height && idx_max < this->
width,
1814 "DenseMatrix::GetSubMatrix: Index out of bounds");
1819 for (
int i = 0; i<k; i++)
1822 for (
int j = 0; j<k; j++)
1825 adata[i+j*k] = this->data[ii+jj*
height];
1833 int k = idx_i.
Size();
1834 int l = idx_j.
Size();
1836 MFEM_VERIFY(idx_i.
Min() >=0 && idx_i.
Max() < this->height,
1837 "DenseMatrix::GetSubMatrix: Row index out of bounds");
1838 MFEM_VERIFY(idx_j.
Min() >=0 && idx_j.
Max() < this->width,
1839 "DenseMatrix::GetSubMatrix: Col index out of bounds");
1845 for (
int i = 0; i<k; i++)
1848 for (
int j = 0; j<l; j++)
1851 adata[i+j*k] = this->data[ii+jj*
height];
1858 MFEM_VERIFY(iend >= ibeg,
"DenseMatrix::GetSubMatrix: Inconsistent range");
1859 MFEM_VERIFY(ibeg >=0,
1860 "DenseMatrix::GetSubMatrix: Negative index");
1861 MFEM_VERIFY(iend <= this->
height && iend <= this->
width,
1862 "DenseMatrix::GetSubMatrix: Index bigger than upper bound");
1864 int k = iend - ibeg;
1869 for (
int i = 0; i<k; i++)
1872 for (
int j = 0; j<k; j++)
1875 adata[i+j*k] = this->data[ii+jj*
height];
1883 MFEM_VERIFY(iend >= ibeg,
1884 "DenseMatrix::GetSubMatrix: Inconsistent row range");
1885 MFEM_VERIFY(jend >= jbeg,
1886 "DenseMatrix::GetSubMatrix: Inconsistent col range");
1887 MFEM_VERIFY(ibeg >=0,
1888 "DenseMatrix::GetSubMatrix: Negative row index");
1889 MFEM_VERIFY(jbeg >=0,
1890 "DenseMatrix::GetSubMatrix: Negative row index");
1891 MFEM_VERIFY(iend <= this->
height,
1892 "DenseMatrix::GetSubMatrix: Index bigger than row upper bound");
1893 MFEM_VERIFY(jend <= this->
width,
1894 "DenseMatrix::GetSubMatrix: Index bigger than col upper bound");
1896 int k = iend - ibeg;
1897 int l = jend - jbeg;
1902 for (
int i = 0; i<k; i++)
1905 for (
int j = 0; j<l; j++)
1908 adata[i+j*k] = this->data[ii+jj*
height];
1917 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1919 int idx_max = idx.
Max();
1921 MFEM_VERIFY(idx.
Min() >=0,
1922 "DenseMatrix::SetSubMatrix: Negative index");
1923 MFEM_VERIFY(idx_max < this->
height,
1924 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1925 MFEM_VERIFY(idx_max < this->
width,
1926 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1931 for (
int i = 0; i<k; i++)
1934 for (
int j = 0; j<k; j++)
1937 this->data[ii+jj*
height] = adata[i+j*k];
1945 int k = idx_i.
Size();
1946 int l = idx_j.
Size();
1948 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1949 MFEM_VERIFY(idx_i.
Min() >=0,
1950 "DenseMatrix::SetSubMatrix: Negative row index");
1951 MFEM_VERIFY(idx_j.
Min() >=0,
1952 "DenseMatrix::SetSubMatrix: Negative col index");
1953 MFEM_VERIFY(idx_i.
Max() < this->height,
1954 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1955 MFEM_VERIFY(idx_j.
Max() < this->width,
1956 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1961 for (
int i = 0; i<k; i++)
1964 for (
int j = 0; j<l; j++)
1967 this->data[ii+jj*
height] = adata[i+j*k];
1976 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::SetSubmatrix: A is not square");
1977 MFEM_VERIFY(ibeg >=0,
1978 "DenseMatrix::SetSubmatrix: Negative index");
1979 MFEM_VERIFY(ibeg + k <= this->
height,
1980 "DenseMatrix::SetSubmatrix: index bigger than row upper bound");
1981 MFEM_VERIFY(ibeg + k <= this->
width,
1982 "DenseMatrix::SetSubmatrix: index bigger than col upper bound");
1987 for (
int i = 0; i<k; i++)
1990 for (
int j = 0; j<k; j++)
1993 this->data[ii+jj*
height] = adata[i+j*k];
2003 MFEM_VERIFY(ibeg>=0,
2004 "DenseMatrix::SetSubmatrix: Negative row index");
2005 MFEM_VERIFY(jbeg>=0,
2006 "DenseMatrix::SetSubmatrix: Negative col index");
2007 MFEM_VERIFY(ibeg + k <= this->
height,
2008 "DenseMatrix::SetSubmatrix: Index bigger than row upper bound");
2009 MFEM_VERIFY(jbeg + l <= this->
width,
2010 "DenseMatrix::SetSubmatrix: Index bigger than col upper bound");
2015 for (
int i = 0; i<k; i++)
2018 for (
int j = 0; j<l; j++)
2021 this->data[ii+jj*
height] = adata[i+j*k];
2030 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2032 int idx_max = idx.
Max();
2034 MFEM_VERIFY(idx.
Min() >=0,
"DenseMatrix::AddSubMatrix: Negative index");
2035 MFEM_VERIFY(idx_max < this->
height,
2036 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2037 MFEM_VERIFY(idx_max < this->
width,
2038 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2043 for (
int i = 0; i<k; i++)
2046 for (
int j = 0; j<k; j++)
2049 this->data[ii+jj*
height] += adata[i+j*k];
2057 int k = idx_i.
Size();
2058 int l = idx_j.
Size();
2060 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2062 MFEM_VERIFY(idx_i.
Min() >=0,
2063 "DenseMatrix::AddSubMatrix: Negative row index");
2064 MFEM_VERIFY(idx_j.
Min() >=0,
2065 "DenseMatrix::AddSubMatrix: Negative col index");
2066 MFEM_VERIFY(idx_i.
Max() < this->height,
2067 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2068 MFEM_VERIFY(idx_j.
Max() < this->width,
2069 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2074 for (
int i = 0; i<k; i++)
2077 for (
int j = 0; j<l; j++)
2080 this->data[ii+jj*
height] += adata[i+j*k];
2088 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::AddSubmatrix: A is not square");
2090 MFEM_VERIFY(ibeg>=0,
2091 "DenseMatrix::AddSubmatrix: Negative index");
2092 MFEM_VERIFY(ibeg + k <= this->
Height(),
2093 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2094 MFEM_VERIFY(ibeg + k <= this->
Width(),
2095 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2100 for (
int i = 0; i<k; i++)
2103 for (
int j = 0; j<k; j++)
2106 this->data[ii+jj*
height] += adata[i+j*k];
2116 MFEM_VERIFY(ibeg>=0,
2117 "DenseMatrix::AddSubmatrix: Negative row index");
2118 MFEM_VERIFY(jbeg>=0,
2119 "DenseMatrix::AddSubmatrix: Negative col index");
2120 MFEM_VERIFY(ibeg + k <= this->
height,
2121 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2122 MFEM_VERIFY(jbeg + l <= this->
width,
2123 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2128 for (
int i = 0; i<k; i++)
2131 for (
int j = 0; j<l; j++)
2134 this->data[ii+jj*
height] += adata[i+j*k];
2144 for (
int i = 0; i < n; i++)
2146 vdata[i] += data[i];
2155 for (
int i = 0; i < n; i++)
2168 mfem_error(
"DenseMatrix::AdjustDofDirection(...): dimension mismatch");
2172 const int *dof = dofs;
2173 for (
int i = 0; i < n-1; i++)
2175 const int s = (dof[i] < 0) ? (-1) : (1);
2176 for (
int j = i+1; j < n; j++)
2178 const int t = (dof[j] < 0) ? (-s) : (s);
2181 (*this)(i,j) = -(*
this)(i,j);
2182 (*this)(j,i) = -(*
this)(j,i);
2191 const int nr = row_dofs.
Size();
2192 const int nc = col_dofs.
Size();
2195 "DenseMatrix::AdjustDofDirection: size mismatch.");
2198 Vector rsign(nr), csign(nc);
2200 for (
int i = 0; i < nr; i++)
2202 const int d = row_dofs[i];
2203 if (d >= 0) { rsign(i) = 1.0; }
2204 else { rsign(i) = -1.0; row_dofs[i] = -d - 1;
continue; }
2208 for (
int j = 0; j < nc; j++)
2210 const int d = col_dofs[j];
2211 if (d >= 0) { csign(j) = 1.0; }
2212 else { csign(j) = -1.0; col_dofs[j] = -d - 1;
continue; }
2217 for (
int i = 0; i < nr; i++)
2219 const real_t rs = rsign(i);
2220 for (
int j = 0; j < nc; j++)
2222 (*this)(i,j) *= rs * csign(j);
2229 for (
int j = 0; j <
Width(); j++)
2231 (*this)(row, j) = value;
2237 for (
int i = 0; i <
Height(); i++)
2239 (*this)(i, col) = value;
2245 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
2246 for (
int j = 0; j <
Width(); j++)
2248 (*this)(r, j) = row[j];
2260 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
2261 for (
int i = 0; i <
Height(); i++)
2263 (*this)(i, c) = col[i];
2275 for (
int col = 0; col <
Width(); col++)
2277 for (
int row = 0; row <
Height(); row++)
2279 if (std::abs(
operator()(row,col)) <= eps)
2290 ios::fmtflags old_flags = os.flags();
2292 os << setiosflags(ios::scientific | ios::showpos);
2293 for (
int i = 0; i <
height; i++)
2295 os <<
"[row " << i <<
"]\n";
2296 for (
int j = 0; j <
width; j++)
2299 if (j+1 ==
width || (j+1) % width_ == 0)
2310 os.flags(old_flags);
2316 ios::fmtflags old_flags = os.flags();
2318 os << setiosflags(ios::scientific | ios::showpos);
2319 for (
int i = 0; i <
height; i++)
2321 for (
int j = 0; j <
width; j++)
2329 os.flags(old_flags);
2334 ios::fmtflags old_fmt = os.flags();
2335 os.setf(ios::scientific);
2336 std::streamsize old_prec = os.precision(14);
2338 os <<
"(* Read file into Mathematica using: "
2339 <<
"myMat = Get[\"this_file_name\"] *)\n";
2342 for (
int i = 0; i <
height; i++)
2345 for (
int j = 0; j <
width; j++)
2347 os <<
"Internal`StringToMReal[\"" << (*this)(i,j) <<
"\"]";
2348 if (j <
width - 1) { os <<
','; }
2352 if (i <
height - 1) { os <<
','; }
2357 os.precision(old_prec);
2364 ios::fmtflags old_flags = os.flags();
2366 os << setiosflags(ios::scientific | ios::showpos);
2367 for (
int j = 0; j <
width; j++)
2369 os <<
"[col " << j <<
"]\n";
2370 for (
int i = 0; i <
height; i++)
2373 if (i+1 ==
height || (i+1) % width_ == 0)
2384 os.flags(old_flags);
2393 for (
int i = 0; i <
width; i++)
2398 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2431 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
2432 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
2433 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
2442 if (std::abs(det) <= TOL) {
return false; }
2450 if (std::abs(det) <= TOL) {
return false; }
2452 real_t invdet = 1. / det;
2457 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
2458 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
2467 if (!lu.
Factor(N,TOL)) {
return false; }
2479 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2480 b.Width() == c.
Height(),
"incompatible dimensions");
2482#ifdef MFEM_USE_LAPACK
2483 static char transa =
'N', transb =
'N';
2485 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2487 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2488 c.
Data(), &k, &beta,
a.Data(), &m);
2490 const int ah =
a.Height();
2491 const int aw =
a.Width();
2492 const int bw =
b.Width();
2503 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2504 b.Width() == c.
Height(),
"incompatible dimensions");
2506#ifdef MFEM_USE_LAPACK
2507 static char transa =
'N', transb =
'N';
2508 static real_t beta = 1.0;
2509 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2511 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2512 c.
Data(), &k, &beta,
a.Data(), &m);
2514 const int ah =
a.Height();
2515 const int aw =
a.Width();
2516 const int bw =
b.Width();
2520 for (
int j = 0; j < aw; j++)
2522 for (
int k = 0; k < bw; k++)
2524 for (
int i = 0; i < ah; i++)
2526 ad[i+j*ah] +=
alpha * bd[i+k*ah] * cd[k+j*bw];
2535 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2536 b.Width() == c.
Height(),
"incompatible dimensions");
2538#ifdef MFEM_USE_LAPACK
2539 static char transa =
'N', transb =
'N';
2541 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2543 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2544 c.
Data(), &k, &beta,
a.Data(), &m);
2546 const int ah =
a.Height();
2547 const int aw =
a.Width();
2548 const int bw =
b.Width();
2552 for (
int j = 0; j < aw; j++)
2554 for (
int k = 0; k < bw; k++)
2556 for (
int i = 0; i < ah; i++)
2558 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2568 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
2570 mfem_error(
"CalcAdjugate(...): unsupported dimensions");
2572 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
2574 mfem_error(
"CalcAdjugate(...): dimension mismatch");
2578 if (
a.Width() <
a.Height())
2587 if (
a.Height() == 3)
2596 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2597 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2598 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2600 ad[0] = d[0]*g - d[3]*
f;
2601 ad[1] = d[3]*e - d[0]*
f;
2602 ad[2] = d[1]*g - d[4]*
f;
2603 ad[3] = d[4]*e - d[1]*
f;
2604 ad[4] = d[2]*g - d[5]*
f;
2605 ad[5] = d[5]*e - d[2]*
f;
2614 else if (
a.Width() == 2)
2617 adja(0,1) = -
a(0,1);
2618 adja(1,0) = -
a(1,0);
2623 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2624 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2625 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2627 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2628 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2629 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2631 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2632 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2633 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2640 if (
a.Height() !=
a.Width() || adjat.
Height() != adjat.
Width() ||
2641 a.Width() != adjat.
Width() ||
a.Width() < 1 ||
a.Width() > 3)
2643 mfem_error(
"CalcAdjugateTranspose(...): dimension mismatch");
2650 else if (
a.Width() == 2)
2652 adjat(0,0) =
a(1,1);
2653 adjat(1,0) = -
a(0,1);
2654 adjat(0,1) = -
a(1,0);
2655 adjat(1,1) =
a(0,0);
2659 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2660 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2661 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2663 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2664 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2665 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2667 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2668 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2669 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2675 MFEM_ASSERT(
a.Width() <=
a.Height() &&
a.Width() >= 1 &&
a.Height() <= 3,
"");
2676 MFEM_ASSERT(inva.
Height() ==
a.Width(),
"incorrect dimensions");
2677 MFEM_ASSERT(inva.
Width() ==
a.Height(),
"incorrect dimensions");
2679 if (
a.Width() <
a.Height())
2683 if (
a.Height() == 2)
2703 MFEM_ASSERT(std::abs(t) > 1.0e-14 * pow(
a.FNorm()/
a.Width(),
a.Width()),
2704 "singular matrix!");
2710 inva(0,0) = 1.0 /
a.
Det();
2724 if ( (
a.Width() !=
a.Height()) || ( (
a.Height()!= 1) && (
a.Height()!= 2)
2725 && (
a.Height()!= 3) ) )
2727 mfem_error(
"CalcInverseTranspose(...): dimension mismatch");
2736 inva(0,0) = 1.0 /
a(0,0);
2739 inva(0,0) =
a(1,1) * t ;
2740 inva(1,0) = -
a(0,1) * t ;
2741 inva(0,1) = -
a(1,0) * t ;
2742 inva(1,1) =
a(0,0) * t ;
2745 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*t;
2746 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*t;
2747 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*t;
2749 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*t;
2750 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*t;
2751 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*t;
2753 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*t;
2754 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*t;
2755 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*t;
2765 "Matrix must be 3x2 or 2x1, "
2766 <<
"and the Vector must be sized with the rows. "
2767 <<
" J.Height() = " << J.
Height()
2768 <<
", J.Width() = " << J.
Width()
2769 <<
", n.Size() = " << n.
Size()
2780 n(0) = d[1]*d[5] - d[2]*d[4];
2781 n(1) = d[2]*d[3] - d[0]*d[5];
2782 n(2) = d[0]*d[4] - d[1]*d[3];
2788 const int height =
a.Height();
2789 const int width =
a.Width();
2790 for (
int i = 0; i < height; i++)
2792 for (
int j = 0; j <= i; j++)
2795 for (
int k = 0; k < width; k++)
2797 temp +=
a(i,k) *
a(j,k);
2799 aat(j,i) = aat(i,j) = temp;
2806 for (
int i = 0; i < A.
Height(); i++)
2808 for (
int j = 0; j < i; j++)
2811 for (
int k = 0; k < A.
Width(); k++)
2813 t += D(k) * A(i, k) * A(j, k);
2821 for (
int i = 0; i < A.
Height(); i++)
2824 for (
int k = 0; k < A.
Width(); k++)
2826 t += D(k) * A(i, k) * A(i, k);
2834 for (
int i = 0; i < A.
Height(); i++)
2836 for (
int j = 0; j <= i; j++)
2839 for (
int k = 0; k < A.
Width(); k++)
2841 t += D(k) * A(i, k) * A(j, k);
2843 ADAt(j, i) = ADAt(i, j) = t;
2854 mfem_error(
"MultABt(...): dimension mismatch");
2858#ifdef MFEM_USE_LAPACK
2859 static char transa =
'N', transb =
'T';
2863 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
2864 B.
Data(), &n, &beta, ABt.
Data(), &m);
2866 const int ah = A.
Height();
2867 const int bh = B.
Height();
2868 const int aw = A.
Width();
2875 const int ah = A.
Height();
2876 const int bh = B.
Height();
2877 const int aw = A.
Width();
2882 for (
int j = 0; j < bh; j++)
2883 for (
int i = 0; i < ah; i++)
2886 const real_t *ap = ad + i;
2887 const real_t *bp = bd + j;
2888 for (
int k = 0; k < aw; k++)
2900 for (i = 0; i < A.
Height(); i++)
2901 for (j = 0; j < B.
Height(); j++)
2904 for (k = 0; k < A.
Width(); k++)
2906 d += A(i, k) * B(j, k);
2920 mfem_error(
"MultADBt(...): dimension mismatch");
2924 const int ah = A.
Height();
2925 const int bh = B.
Height();
2926 const int aw = A.
Width();
2932 for (
int i = 0, s = ah*bh; i < s; i++)
2936 for (
int k = 0; k < aw; k++)
2939 for (
int j = 0; j < bh; j++)
2941 const real_t dk_bjk = dd[k] * bd[j];
2942 for (
int i = 0; i < ah; i++)
2944 cp[i] += ad[i] * dk_bjk;
2959 mfem_error(
"AddMultABt(...): dimension mismatch");
2963#ifdef MFEM_USE_LAPACK
2964 static char transa =
'N', transb =
'T';
2968 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
2969 B.
Data(), &n, &beta, ABt.
Data(), &m);
2971 const int ah = A.
Height();
2972 const int bh = B.
Height();
2973 const int aw = A.
Width();
2978 for (
int k = 0; k < aw; k++)
2981 for (
int j = 0; j < bh; j++)
2983 const real_t bjk = bd[j];
2984 for (
int i = 0; i < ah; i++)
2986 cp[i] += ad[i] * bjk;
2997 for (i = 0; i < A.
Height(); i++)
2998 for (j = 0; j < B.
Height(); j++)
3001 for (k = 0; k < A.
Width(); k++)
3003 d += A(i, k) * B(j, k);
3017 mfem_error(
"AddMultADBt(...): dimension mismatch");
3021 const int ah = A.
Height();
3022 const int bh = B.
Height();
3023 const int aw = A.
Width();
3029 for (
int k = 0; k < aw; k++)
3032 for (
int j = 0; j < bh; j++)
3034 const real_t dk_bjk = dd[k] * bd[j];
3035 for (
int i = 0; i < ah; i++)
3037 cp[i] += ad[i] * dk_bjk;
3053 mfem_error(
"AddMult_a_ABt(...): dimension mismatch");
3057#ifdef MFEM_USE_LAPACK
3058 static char transa =
'N', transb =
'T';
3060 static real_t beta = 1.0;
3063 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
3064 B.
Data(), &n, &beta, ABt.
Data(), &m);
3066 const int ah = A.
Height();
3067 const int bh = B.
Height();
3068 const int aw = A.
Width();
3073 for (
int k = 0; k < aw; k++)
3076 for (
int j = 0; j < bh; j++)
3079 for (
int i = 0; i < ah; i++)
3081 cp[i] += ad[i] * bjk;
3092 for (i = 0; i < A.
Height(); i++)
3093 for (j = 0; j < B.
Height(); j++)
3096 for (k = 0; k < A.
Width(); k++)
3098 d += A(i, k) * B(j, k);
3111 mfem_error(
"MultAtB(...): dimension mismatch");
3115#ifdef MFEM_USE_LAPACK
3116 static char transa =
'T', transb =
'N';
3120 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3121 B.
Data(), &k, &beta, AtB.
Data(), &m);
3123 const int ah = A.
Height();
3124 const int aw = A.
Width();
3125 const int bw = B.
Width();
3130 for (
int j = 0; j < bw; j++)
3133 for (
int i = 0; i < aw; i++)
3136 for (
int k = 0; k < ah; k++)
3149 for (i = 0; i < A.
Width(); i++)
3150 for (j = 0; j < B.
Width(); j++)
3153 for (k = 0; k < A.
Height(); k++)
3155 d += A(k, i) * B(k, j);
3168#ifdef MFEM_USE_LAPACK
3169 static char transa =
'T', transb =
'N';
3173 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3174 B.
Data(), &k, &beta, AtB.
Data(), &m);
3176 const int ah = A.
Height();
3177 const int aw = A.
Width();
3178 const int bw = B.
Width();
3183 for (
int j = 0; j < bw; j++)
3186 for (
int i = 0; i < aw; i++)
3189 for (
int k = 0; k < ah; k++)
3207#ifdef MFEM_USE_LAPACK
3208 static char transa =
'T', transb =
'N';
3210 static real_t beta = 1.0;
3213 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3214 B.
Data(), &k, &beta, AtB.
Data(), &m);
3216 const int ah = A.
Height();
3217 const int aw = A.
Width();
3218 const int bw = B.
Width();
3223 for (
int j = 0; j < bw; j++)
3226 for (
int i = 0; i < aw; i++)
3229 for (
int k = 0; k < ah; k++)
3245 for (
int i = 0; i < A.
Height(); i++)
3247 for (
int j = 0; j < i; j++)
3250 for (
int k = 0; k < A.
Width(); k++)
3252 d += A(i,k) * A(j,k);
3254 AAt(i, j) += (d *=
a);
3258 for (
int k = 0; k < A.
Width(); k++)
3260 d += A(i,k) * A(i,k);
3268 for (
int i = 0; i < A.
Height(); i++)
3270 for (
int j = 0; j <= i; j++)
3273 for (
int k = 0; k < A.
Width(); k++)
3275 d += A(i,k) * A(j,k);
3277 AAt(i, j) = AAt(j, i) =
a * d;
3284 for (
int i = 0; i < v.
Size(); i++)
3286 for (
int j = 0; j <= i; j++)
3288 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3298 mfem_error(
"MultVWt(...): dimension mismatch");
3302 for (
int i = 0; i < v.
Size(); i++)
3305 for (
int j = 0; j < w.
Size(); j++)
3307 VWt(i, j) = vi * w(j);
3314 const int m = v.
Size(), n = w.
Size();
3319 mfem_error(
"AddMultVWt(...): dimension mismatch");
3323 for (
int i = 0; i < m; i++)
3326 for (
int j = 0; j < n; j++)
3328 VWt(i, j) += vi * w(j);
3335 const int n = v.
Size();
3340 mfem_error(
"AddMultVVt(...): dimension mismatch");
3344 for (
int i = 0; i < n; i++)
3347 for (
int j = 0; j < i; j++)
3349 const real_t vivj = vi * v(j);
3353 VVt(i, i) += vi * vi;
3360 const int m = v.
Size(), n = w.
Size();
3365 mfem_error(
"AddMult_a_VWt(...): dimension mismatch");
3369 for (
int j = 0; j < n; j++)
3372 for (
int i = 0; i < m; i++)
3374 VWt(i, j) += v(i) * awj;
3382 "incompatible dimensions!");
3384 const int n = v.
Size();
3385 for (
int i = 0; i < n; i++)
3388 for (
int j = 0; j < i; j++)
3390 const real_t avivj = avi * v(j);
3394 VVt(i, i) += avi * v(i);
3417#ifdef MFEM_USE_LAPACK
3419 if (m) { MFEM_LAPACK_PREFIX(getrf_)(&m, &m,
data, &m,
ipiv, &info); }
3424 for (
int i = 0; i < m; i++)
3429 real_t a = std::abs(data_ptr[piv+i*m]);
3430 for (
int j = i+1; j < m; j++)
3432 const real_t b = std::abs(data_ptr[j+i*m]);
3443 for (
int j = 0; j < m; j++)
3450 if (
abs(data_ptr[i + i*m]) <= TOL)
3455 const real_t a_ii_inv = 1.0 / data_ptr[i+i*m];
3456 for (
int j = i+1; j < m; j++)
3458 data_ptr[j+i*m] *= a_ii_inv;
3460 for (
int k = i+1; k < m; k++)
3462 const real_t a_ik = data_ptr[i+k*m];
3463 for (
int j = i+1; j < m; j++)
3465 data_ptr[j+k*m] -= a_ik * data_ptr[j+i*m];
3477 for (
int i=0; i<m; i++)
3481 det *= -
data[m * i + i];
3485 det *=
data[m * i + i];
3494 for (
int k = 0; k < n; k++)
3497 for (
int i = 0; i < m; i++)
3500 for (
int j = i+1; j < m; j++)
3502 x_i += x[j] *
data[i+j*m];
3507 for (
int i = m-1; i >= 0; i--)
3510 for (
int j = 0; j < i; j++)
3512 x_i += x[j] *
data[i+j*m];
3517 for (
int i = m-1; i >= 0; i--)
3528 for (
int k = 0; k < n; k++)
3538 for (
int k = 0; k < n; k++)
3547#ifdef MFEM_USE_LAPACK
3552 MFEM_LAPACK_PREFIX(getrs_)(&
trans, &m, &n,
data, &m,
ipiv, X, &m, &info);
3554 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3565#ifdef MFEM_USE_LAPACK
3566 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3570 MFEM_LAPACK_PREFIX(trsm_)(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3571 MFEM_LAPACK_PREFIX(trsm_)(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3577 for (
int k = 0; k < n; k++)
3579 for (
int j = 0; j < m; j++)
3582 for (
int i = j+1; i < m; i++)
3584 x[i*n] -=
data[j + i*m] * x_j;
3592 for (
int k = 0; k < n; k++)
3594 for (
int j = m-1; j >= 0; j--)
3596 const real_t x_j = x[j*n];
3597 for (
int i = 0; i < j; i++)
3599 x[i*n] -=
data[j + i*m] * x_j;
3607 for (
int k = 0; k < n; k++)
3609 for (
int i = m-1; i >= 0; --i)
3622 for (
int k = 0; k < m; k++)
3624 const real_t minus_x_k = -( x[k] = 1.0/
data[k+k*m] );
3625 for (
int i = 0; i < k; i++)
3627 x[i] =
data[i+k*m] * minus_x_k;
3629 for (
int j = k-1; j >= 0; j--)
3632 for (
int i = 0; i < j; i++)
3634 x[i] -=
data[i+j*m] * x_j;
3642 for (
int j = 0; j < k; j++)
3645 for (
int i = 0; i <= j; i++)
3647 X[i+j*m] += X[i+k*m] * minus_L_kj;
3649 for (
int i = j+1; i < m; i++)
3651 X[i+j*m] = X[i+k*m] * minus_L_kj;
3655 for (
int k = m-2; k >= 0; k--)
3657 for (
int j = 0; j < k; j++)
3660 for (
int i = 0; i < m; i++)
3662 X[i+j*m] -= X[i+k*m] * L_kj;
3667 for (
int k = m-1; k >= 0; k--)
3672 for (
int i = 0; i < m; i++)
3698 SubMult(m, n, r, L21, B1, B2);
3705 SubMult(n, m, r, U12, X2, Y1);
3713#ifdef MFEM_USE_LAPACK
3716 MFEM_VERIFY(
data,
"Matrix data not set");
3717 if (m) { MFEM_LAPACK_PREFIX(potrf_)(&uplo, &m,
data, &m, &info); }
3721 for (
int j = 0; j<m; j++)
3724 for (
int k = 0; k<j; k++)
3729 MFEM_VERIFY(
data[j+j*m] -
a > 0.,
3730 "CholeskyFactors::Factor: The matrix is not SPD");
3732 data[j+j*m] = std::sqrt(
data[j+j*m] -
a);
3734 if (
data[j + j*m] <= TOL)
3739 for (
int i = j+1; i<m; i++)
3742 for (
int k = 0; k<j; k++)
3756 for (
int i=0; i<m; i++)
3758 det *=
data[i + i*m];
3767 for (
int k = 0; k < n; k++)
3769 for (
int j = m-1; j >= 0; j--)
3772 for (
int i = 0; i < j; i++)
3774 x_j += x[i] *
data[j+i*m];
3785 for (
int k = 0; k < n; k++)
3787 for (
int i = 0; i < m; i++)
3790 for (
int j = i+1; j < m; j++)
3792 x_i += x[j] *
data[j+i*m];
3803#ifdef MFEM_USE_LAPACK
3809 MFEM_LAPACK_PREFIX(trtrs_)(&uplo, &
trans, &diag, &m, &n,
data, &m, X, &m,
3811 MFEM_VERIFY(!info,
"CholeskyFactors:LSolve:: info");
3815 for (
int k = 0; k < n; k++)
3818 for (
int j = 0; j < m; j++)
3821 for (
int i = j+1; i < m; i++)
3823 x[i] -=
data[i+j*m] * x_j;
3833#ifdef MFEM_USE_LAPACK
3840 MFEM_LAPACK_PREFIX(trtrs_)(&uplo, &
trans, &diag, &m, &n,
data, &m, X, &m,
3842 MFEM_VERIFY(!info,
"CholeskyFactors:USolve:: info");
3847 for (
int k = 0; k < n; k++)
3849 for (
int j = m-1; j >= 0; j--)
3852 for (
int i = 0; i < j; i++)
3854 x[i] -=
data[j+i*m] * x_j;
3864#ifdef MFEM_USE_LAPACK
3867 MFEM_LAPACK_PREFIX(potrs_)(&uplo, &m, &n,
data, &m, X, &m, &info);
3868 MFEM_VERIFY(!info,
"CholeskyFactors:Solve:: info");
3878#ifdef MFEM_USE_LAPACK
3888 MFEM_LAPACK_PREFIX(trsm_)(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3889 MFEM_LAPACK_PREFIX(trsm_)(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3894 for (
int k = 0; k < n; k++)
3896 for (
int j = 0; j < m; j++)
3899 for (
int i = j+1; i < m; i++)
3901 x[i*n] -=
data[i + j*m] * x_j;
3908 for (
int k = 0; k < n; k++)
3910 for (
int j = m-1; j >= 0; j--)
3913 for (
int i = 0; i < j; i++)
3915 x[i*n] -=
data[j + i*m] * x_j;
3926#ifdef MFEM_USE_LAPACK
3928 for (
int i = 0; i<m; i++)
3930 for (
int j = i; j<m; j++)
3932 X[j+i*m] =
data[j+i*m];
3937 MFEM_LAPACK_PREFIX(potri_)(&uplo, &m, X, &m, &info);
3938 MFEM_VERIFY(!info,
"CholeskyFactors:GetInverseMatrix:: info");
3940 for (
int i = 0; i<m; i++)
3942 for (
int j = i+1; j<m; j++)
3944 X[i+j*m] = X[j+i*m];
3949 for (
int k = 0; k<m; k++)
3951 X[k+k*m] = 1./
data[k+k*m];
3952 for (
int i = k+1; i < m; i++)
3955 for (
int j=k; j<i; j++)
3957 s -=
data[i+j*m] * X[j+k*m]/
data[i+i*m];
3962 for (
int i = 0; i < m; i++)
3964 for (
int j = i; j < m; j++)
3967 for (
int k=j; k<m; k++)
3969 s += X[k+i*m] * X[k+j*m];
3971 X[i+j*m] = X[j+i*m] = s;
3978void DenseMatrixInverse::Init(
int m)
3986 factors =
new LUFactors();
3993 dynamic_cast<LUFactors *
>(factors)->ipiv =
new int[m];
4002 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4011 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4018 MFEM_ASSERT(a,
"DenseMatrix is not given");
4019 const real_t *adata = a->data;
4021 for (
int i = 0; i < s; i++)
4023 factors->
data[i] = adata[i];
4036 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
4040 if (own_data) {
delete [] factors->
data; }
4046 if (own_data) {
delete [] lu->
ipiv; }
4058 MFEM_VERIFY(
p != NULL,
"Operator is not a DenseMatrix!");
4064 for (
int row = 0; row <
height; row++)
4087 for (
int i = 0; i <
width; i++)
4098 delete [] factors->
data;
4101 delete []
dynamic_cast<LUFactors *
>(factors)->ipiv;
4107#ifdef MFEM_USE_LAPACK
4121 MFEM_LAPACK_PREFIX(syev_)(&jobz, &uplo, &n, EVect.
Data(), &n, EVal.
GetData(),
4122 &qwork, &lwork, &info);
4124 lwork = (int) qwork;
4125 work =
new real_t[lwork];
4130 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4135 lwork = other.lwork;
4137 work =
new real_t[lwork];
4143 if (mat.
Width() != n)
4145 mfem_error(
"DenseMatrixEigensystem::Eval(): dimension mismatch");
4150 MFEM_LAPACK_PREFIX(syev_)(&jobz, &uplo, &n, EVect.
Data(), &n, EVal.
GetData(),
4151 work, &lwork, &info);
4155 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
4169 bool left_eigen_vectors,
4170 bool right_eigen_vectors)
4173 MFEM_VERIFY(A.
Height() == A.
Width(),
"A has to be a square matrix");
4174 MFEM_VERIFY(B.
Height() == B.
Width(),
"B has to be a square matrix");
4176 MFEM_VERIFY(B.
Height() == n,
"A and B dimension mismatch");
4182 if (left_eigen_vectors)
4187 if (right_eigen_vectors)
4200 int nl = max(1,Vl.
Height());
4201 int nr = max(1,Vr.
Height());
4203 MFEM_LAPACK_PREFIX(ggev_)(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,
4204 alphar, alphai, beta, Vl.
Data(), &nl, Vr.
Data(),
4205 &nr, &qwork, &lwork, &info);
4207 lwork = (int) qwork;
4208 work =
new real_t[lwork];
4213 int nl = max(1,Vl.
Height());
4214 int nr = max(1,Vr.
Height());
4218 MFEM_LAPACK_PREFIX(ggev_)(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,
4219 alphar, alphai, beta, Vl.
Data(), &nl, Vr.
Data(),
4220 &nr, work, &lwork, &info);
4223 mfem::err <<
"DenseMatrixGeneralizedEigensystem::Eval(): DGGEV error code: "
4229 for (
int i = 0; i<n; i++)
4233 evalues_r(i) = alphar[i]/beta[i];
4234 evalues_i(i) = alphai[i]/beta[i];
4253 bool left_singular_vectors,
4254 bool right_singular_vectors)
4258 jobu = (left_singular_vectors)?
'S' :
'N';
4259 jobvt = (right_singular_vectors)?
'S' :
'N';
4264 bool left_singular_vectors,
4265 bool right_singular_vectors)
4269 jobu = (left_singular_vectors)?
'S' :
'N';
4270 jobvt = (right_singular_vectors)?
'S' :
'N';
4275 char left_singular_vectors,
4276 char right_singular_vectors)
4280 jobu = left_singular_vectors;
4281 jobvt = right_singular_vectors;
4286 char left_singular_vectors,
4287 char right_singular_vectors)
4291 jobu = left_singular_vectors;
4292 jobvt = right_singular_vectors;
4296void DenseMatrixSVD::Init()
4301 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n, NULL, &m, sv.
GetData(),
4302 NULL, &m, NULL, &n, &qwork, &lwork, &info);
4303 lwork = (int) qwork;
4304 work =
new real_t[lwork];
4315 real_t * datau =
nullptr;
4316 real_t * datavt =
nullptr;
4322 else if (jobu ==
'S')
4332 else if (jobvt ==
'S')
4338 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n, Mc.
Data(), &m, sv.
GetData(),
4339 datau, &m, datavt, &n, work, &lwork, &info);
4343 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4360 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4368 for (
int i = 0; i < ne; i++)
4371 for (
int col = 0; col < n; col++)
4373 x_col = xp[dofs[col]];
4374 for (
int row = 0; row < n; row++)
4376 yp[dofs[row]] += x_col*d_col[row];
4385 for (
int i = 0; i < ne; i++)
4388 x_col = xp[dofs[0]];
4389 for (
int row = 0; row < n; row++)
4391 ye(row) = x_col*d_col[row];
4394 for (
int col = 1; col < n; col++)
4396 x_col = xp[dofs[col]];
4397 for (
int row = 0; row < n; row++)
4399 ye(row) += x_col*d_col[row];
4403 for (
int row = 0; row < n; row++)
4405 yp[dofs[row]] += ye(row);
4414 for (
int i=0; i<s; i++)
4431#ifdef MFEM_USE_LAPACK
4435 int LDAB = (2*KL) + KU + 1;
4440 MFEM_LAPACK_PREFIX(gbsv_)(&N, &KL, &KU, &NRHS, AB.
GetData(), &LDAB,
4442 MFEM_ASSERT(info == 0,
"BandedSolve failed in LAPACK");
4448 int LDAB = (2*KL) + KU + 1;
4451 char trans = transpose ?
'T' :
'N';
4453 MFEM_LAPACK_PREFIX(gbtrs_)(&
trans, &N, &KL, &KU, &NRHS, AB.
GetData(), &LDAB,
4455 MFEM_ASSERT(info == 0,
"BandedFactorizedSolve failed in LAPACK");
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
int Size() const
Return the logical size of the array.
T * GetData()
Returns the data.
static void LUFactor(DenseTensor &A, Array< int > &P)
Replaces the block diagonal matrix with its LU factors. The pivots are stored in P.
static void LUSolve(const DenseTensor &A, const Array< int > &P, Vector &x)
Replaces with , given the LU factors A and pivots P of the block-diagonal matrix .
void UMult(int m, int n, real_t *X) const
void Solve(int m, int n, real_t *X) const override
void RightSolve(int m, int n, real_t *X) const
void USolve(int m, int n, real_t *X) const
void LSolve(int m, int n, real_t *X) const
bool Factor(int m, real_t TOL=0.0) override
Compute the Cholesky factorization of the current matrix.
void GetInverseMatrix(int m, real_t *X) const override
Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
void LMult(int m, int n, real_t *X) const
real_t Det(int m) const override
~DenseMatrixEigensystem()
DenseMatrixEigensystem(DenseMatrix &m)
~DenseMatrixGeneralizedEigensystem()
DenseMatrixGeneralizedEigensystem(DenseMatrix &a, DenseMatrix &b, bool left_eigen_vectors=false, bool right_eigen_vectors=false)
void TestInversion()
Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
DenseMatrixInverse(bool spd_=false)
Default constructor.
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
void Factor()
Factor the current DenseMatrix, *a.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
real_t Det() const
Compute the determinant of the original DenseMatrix using the LU factors.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
MFEM_DEPRECATED DenseMatrixSVD(DenseMatrix &M, bool left_singular_vectors=false, bool right_singular_vectors=false)
Constructor for the DenseMatrixSVD.
void Eval(DenseMatrix &M)
Evaluate the SVD.
Data type dense matrix using column-major storage.
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
void CopyMNDiag(real_t c, int n, int row_offset, int col_offset)
Copy c on the diagonal of size n to *this at row_offset, col_offset.
void AddMult_a(real_t a, const Vector &x, Vector &y) const
y += a * A.x
void GetRowl1(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
void AddMultTranspose_a(real_t a, const Vector &x, Vector &y) const
y += a * A^t x
void Set(real_t alpha, const real_t *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
void TestInversion()
Invert and print the numerical conditioning of the inversion.
void CopyExceptMN(const DenseMatrix &A, int m, int n)
Copy All rows and columns except m and n from A.
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
void Transpose()
(*this) = (*this)^t
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
void Threshold(real_t eps)
Replace small entries, abs(a_ij) <= eps, with zero.
const real_t * HostRead() const
Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
void CalcEigenvalues(real_t *lambda, real_t *vec) const
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
void SetRow(int r, const real_t *row)
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
MFEM_DEPRECATED void Getl1Diag(Vector &l) const
real_t & operator()(int i, int j)
Returns reference to a_{ij}.
real_t InnerProduct(const real_t *x, const real_t *y) const
Compute y^t A x.
real_t * Data() const
Returns the matrix data array. Warning: this method casts away constness.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const override
y += a * A.x
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
friend class DenseMatrixInverse
void AdjustDofDirection(const Array< int > &dofs)
void SetCol(int c, const real_t *col)
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
void Invert()
Replaces the current matrix with its inverse.
void AbsMult(const Vector &x, Vector &y) const override
Absolute-value matrix vector multiplication.
void GetRowl2(Vector &l) const
Returns the l2norm of the rows of the DenseMatrix.
DenseMatrix & operator+=(const real_t *m)
void Neg()
(*this) = -(*this)
real_t operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
void CopyMNt(const DenseMatrix &A, int row_offset, int col_offset)
Copy matrix A^t to the location in *this at row_offset, col_offset.
void AddMultTranspose(const Vector &x, Vector &y, const real_t a=1.0) const override
y += a * A^t x
void AbsMultTranspose(const Vector &x, Vector &y) const override
Multiply a vector with the absolute-value transpose matrix.
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
void SingularValues(Vector &sv) const
real_t FNorm() const
Compute the Frobenius norm of the matrix.
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
void SetSubMatrix(const Array< int > &idx, const DenseMatrix &A)
Set (*this)(idx[i],idx[j]) = A(i,j)
virtual void PrintT(std::ostream &out=mfem::out, int width_=4) const
Prints the transpose matrix to stream out.
void AddSubMatrix(const Array< int > &idx, const DenseMatrix &A)
(*this)(idx[i],idx[j]) += A(i,j)
real_t Trace() const
Trace of a square matrix.
void Diag(real_t c, int n)
Creates n x n diagonal matrix with diagonal elements c.
void SquareRootInverse()
Replaces the current matrix with its square root inverse.
virtual void PrintMathematica(std::ostream &out=mfem::out) const
DenseMatrix & operator*=(real_t c)
void Swap(DenseMatrix &other)
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i.
void GetRowSums(Vector &l) const
Returns the row sums of the DenseMatrix.
real_t & Elem(int i, int j) override
Returns reference to a_{ij}.
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
int Rank(real_t tol) const
void Add(const real_t c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
void PrintMatlab(std::ostream &out=mfem::out) const override
Prints operator in Matlab format.
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
DenseMatrix & operator-=(const DenseMatrix &m)
real_t CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
void GradToCurl(DenseMatrix &curl)
DenseMatrix & operator=(const DenseMatrix &)=default
Copy assignment (deep copy).
void Print(std::ostream &out=mfem::out, int width_=4) const override
Prints matrix to stream out.
void GetColumn(int c, Vector &col) const
void GradToVectorCurl2D(DenseMatrix &curl)
MatrixInverse * Inverse() const override
Returns a pointer to the inverse matrix.
real_t MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
void Norm2(real_t *v) const
Take the 2-norm of the columns of A and store in v.
void GetFromVector(int offset, const Vector &v)
Get the matrix 'data' from the Vector 'v' at the given 'offset'.
void GetRow(int r, Vector &row) const
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
void GradToDiv(Vector &div)
Rank 3 tensor (array of matrices)
DenseTensor & operator=(const DenseTensor &other)
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
virtual void GetInverseMatrix(int m, real_t *X) const
virtual void Solve(int m, int n, real_t *X) const
virtual bool Factor(int m, real_t TOL=0.0)
A class to initialize the size of a Tensor.
void LSolve(int m, int n, real_t *X) const
static void SubMult(int m, int n, int r, const real_t *A21, const real_t *X1, real_t *X2)
bool Factor(int m, real_t TOL=0.0) override
Compute the LU factorization of the current matrix.
void Mult(int m, int n, real_t *X) const
void USolve(int m, int n, real_t *X) const
void BlockFactor(int m, int n, real_t *A12, real_t *A21, real_t *A22) const
real_t Det(int m) const override
void BlockForwSolve(int m, int n, int r, const real_t *L21, real_t *B1, real_t *B2) const
void Solve(int m, int n, real_t *X) const override
void RightSolve(int m, int n, real_t *X) const
void BlockBackSolve(int m, int n, int r, const real_t *U12, const real_t *X2, real_t *Y1) const
void GetInverseMatrix(int m, real_t *X) const override
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
static constexpr int ipiv_base
Abstract data type for matrix inverse.
Abstract data type matrix.
bool IsSquare() const
Returns whether the matrix is a square matrix.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
int Size() const
Returns the size of the vector.
void SetSize(int s)
Resize the vector to size s.
virtual real_t * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void trans(const Vector &u, Vector &x)
MFEM_HOST_DEVICE void CalcInverse(const T *data, T *inv_data)
Return the inverse of a matrix with given size and data into the matrix with data inv_data.
MFEM_HOST_DEVICE real_t CalcSingularvalue< 2 >(const real_t *data, const int i)
Return the i'th singular value of the matrix of size 2 with given data.
MFEM_HOST_DEVICE void CalcEigenvalues< 2 >(const real_t *data, real_t *lambda, real_t *vec)
MFEM_HOST_DEVICE void Add(const int height, const int width, const TALPHA alpha, const TA *Adata, const TB *Bdata, TC *Cdata)
Compute C = A + alpha*B, where the matrices A, B and C are of size height x width with data Adata,...
MFEM_HOST_DEVICE void AbsMult(const int height, const int width, const TA *data, const TX *x, TY *y)
Absolute-value matrix vector multiplication: y = |A| x, where the matrix A is of size height x width ...
MFEM_HOST_DEVICE void Mult(const int height, const int width, const TA *data, const TX *x, TY *y)
Matrix vector multiplication: y = A x, where the matrix A is of size height x width with given data,...
MFEM_HOST_DEVICE void CalcLeftInverse< 2, 1 >(const real_t *d, real_t *left_inv)
MFEM_HOST_DEVICE void LSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- L^{-1} P X, for a vector X of length...
MFEM_HOST_DEVICE void MultABt(const int Aheight, const int Awidth, const int Bheight, const TA *Adata, const TB *Bdata, TC *ABtdata)
Multiply a matrix of size Aheight x Awidth and data Adata with the transpose of a matrix of size Bhei...
MFEM_HOST_DEVICE void MultTranspose(const int height, const int width, const TA *data, const TX *x, TY *y)
Matrix transpose vector multiplication: y = At x, where the matrix A is of size height x width with g...
MFEM_HOST_DEVICE void USolve(const real_t *data, const int m, real_t *x)
Assuming L.U = P.A factored matrix of size (m x m), compute X <- U^{-1} X, for a vector X of length m...
MFEM_HOST_DEVICE void AbsMultTranspose(const int height, const int width, const TA *data, const TX *x, TY *y)
Absolute-value matrix transpose vector multiplication: y = |At| x, where the matrix A is of size heig...
MFEM_HOST_DEVICE void Symmetrize(const int size, T *data)
Symmetrize a square matrix with given size and data: A -> (A+A^T)/2.
MFEM_HOST_DEVICE void CalcLeftInverse< 3, 2 >(const real_t *d, real_t *left_inv)
MFEM_HOST_DEVICE void BlockFactor(const real_t *data, int m, const int *ipiv, int n, real_t *A12, real_t *A21, real_t *A22)
MFEM_HOST_DEVICE void CalcLeftInverse< 3, 1 >(const real_t *d, real_t *left_inv)
MFEM_HOST_DEVICE real_t CalcSingularvalue< 3 >(const real_t *data, const int i)
Return the i'th singular value of the matrix of size 3 with given data.
MFEM_HOST_DEVICE void CalcEigenvalues< 3 >(const real_t *data, real_t *lambda, real_t *vec)
MFEM_HOST_DEVICE void SubMult(const int m, const int n, const int r, const real_t *A21, const real_t *X1, real_t *X2)
Given an (n x m) matrix A21, compute X2 <- X2 - A21 X1, for matrices X1, and X2 of size (m x r) and (...
void CalcOrtho(const DenseMatrix &J, Vector &n)
void AddMult_a_ABt(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
real_t u(const Vector &xvec)
void mfem_error(const char *msg)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void BatchLUSolve(const DenseTensor &Mlu, const Array< int > &P, Vector &X)
Solve batch linear systems. Calls BatchedLinAlg::LUSolve.
void AddMult_a(real_t alpha, const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += alpha * B * C.
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
void MultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
void AddMultVVt(const Vector &v, DenseMatrix &VVt)
VVt += v v^t.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void dsygv_Eigensystem(DenseMatrix &a, DenseMatrix &b, Vector &ev, DenseMatrix *evect)
void dsyevr_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void AddMult_a_VWt(const real_t a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void AddMult_a_VVt(const real_t a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void BatchLUFactor(DenseTensor &Mlu, Array< int > &P, const real_t TOL)
Compute the LU factorization of a batch of matrices. Calls BatchedLinAlg::LUFactor.
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
int CheckFinite(const real_t *v, const int n)
void AddMult_a_AtB(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
AtB += a * A^t * B.
void dsyev_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
bool LinearSolve(DenseMatrix &A, real_t *X, real_t TOL)
Solves the dense linear system, A * X = B for X
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
void AddMult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
void AddMultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void AddMultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
AtB += A^t * B.
std::function< real_t(const Vector &)> f(real_t mass_coeff)
void BandedFactorizedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B, bool transpose, Array< int > &ipiv)
void Mult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
constexpr real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt += A D A^t, where D is diagonal.
void BandedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B, Array< int > &ipiv)
real_t p(const Vector &x, real_t t)
MFEM_HOST_DEVICE real_t norm(const Complex &z)
MFEM_HOST_DEVICE real_t abs(const Complex &z)