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));
1376 for (
int i = 0; i <
height; i++)
1379 for (
int j = 0; j <
width; j++)
1392 for (
int i = 0; i < N; i++)
1396 for (
int i = 0; i < n; i++)
1407 for (i = 0; i < N; i++)
1411 for (i = 0; i < n; i++)
1413 data[i*(n+1)] = diag[i];
1424 for (i = 0; i <
Height(); i++)
1425 for (j = i+1; j <
Width(); j++)
1428 (*this)(i,j) = (*
this)(j,i);
1443 for (
int i = 0; i <
Height(); i++)
1444 for (
int j = 0; j <
Width(); j++)
1446 (*this)(i,j) = A(j,i);
1455 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1463 for (
int i = 0; i <
Height(); i++)
1466 for (
int j = 0; j <
Width(); j++)
1469 (*this)(i, j) = 0.0;
1483 mfem_error(
"DenseMatrix::GradToCurl(...): dimension mismatch");
1489 for (
int i = 0; i < n; i++)
1506 for (
int i = 0; i < n; i++)
1536 MFEM_VERIFY(
Width() == 2,
1537 "DenseMatrix::GradToVectorCurl2D(...): dimension must be 2")
1541 for (
int i = 0; i < n; i++)
1543 curl(i,0) = (*this)(i,1);
1544 curl(i,1) = -(*this)(i,0);
1550 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1557 for (
int i = 0; i < n; i++)
1567 for (
int j = 0; j <
Width(); j++)
1569 for (
int i = row1; i <= row2; i++)
1571 (*this)(i-row1,j) = A(i,j);
1580 for (
int j = col1; j <= col2; j++)
1582 for (
int i = 0; i <
Height(); i++)
1584 (*this)(i,j-col1) = A(i,j);
1593 for (
int j = 0; j < n; j++)
1595 for (
int i = 0; i < m; i++)
1597 (*this)(i,j) = A(Aro+i,Aco+j);
1606 for (
int j = 0; j < A.
Width(); j++)
1608 for (
int i = 0; i < A.
Height(); i++)
1610 (*this)(row_offset+i,col_offset+j) = *(v++);
1619 for (
int i = 0; i < A.
Width(); i++)
1621 for (
int j = 0; j < A.
Height(); j++)
1623 (*this)(row_offset+i,col_offset+j) = *(v++);
1629 int row_offset,
int col_offset)
1631 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1632 "this DenseMatrix is too small to accommodate the submatrix. "
1633 <<
"row_offset = " << row_offset
1635 <<
", this->Height() = " << this->
Height()
1636 <<
", col_offset = " << col_offset
1638 <<
", this->Width() = " << this->
Width()
1640 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1641 "The A DenseMatrix is too small to accommodate the submatrix. "
1644 <<
", A.Height() = " << A.
Height()
1645 <<
", Aco = " << Aco
1647 <<
", A.Width() = " << A.
Width()
1650 for (
int j = 0; j < n; j++)
1652 for (
int i = 0; i < m; i++)
1654 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1661 for (
int i = 0; i < n; i++)
1663 for (
int j = i+1; j < n; j++)
1665 (*this)(row_offset+i,col_offset+j) =
1666 (*
this)(row_offset+j,col_offset+i) = 0.0;
1670 for (
int i = 0; i < n; i++)
1672 (*this)(row_offset+i,col_offset+i) = c;
1679 for (
int i = 0; i < n; i++)
1681 for (
int j = i+1; j < n; j++)
1683 (*this)(row_offset+i,col_offset+j) =
1684 (*
this)(row_offset+j,col_offset+i) = 0.0;
1688 for (
int i = 0; i < n; i++)
1690 (*this)(row_offset+i,col_offset+i) = diag[i];
1698 int i, j, i_off = 0, j_off = 0;
1700 for (j = 0; j < A.
Width(); j++)
1707 for (i = 0; i < A.
Height(); i++)
1714 (*this)(i-i_off,j-j_off) = A(i,j);
1730 if (co+aw >
Width() || ro+ah > h)
1732 mfem_error(
"DenseMatrix::AddMatrix(...) 1 : dimension mismatch");
1736 p = data + ro + co * h;
1739 for (
int c = 0; c < aw; c++)
1741 for (
int r = 0; r < ah; r++)
1760 if (co+aw >
Width() || ro+ah > h)
1762 mfem_error(
"DenseMatrix::AddMatrix(...) 2 : dimension mismatch");
1766 p = data + ro + co * h;
1769 for (
int c = 0; c < aw; c++)
1771 for (
int r = 0; r < ah; r++)
1783 int idx_max = idx.
Max();
1784 MFEM_VERIFY(idx.
Min() >=0 && idx_max < this->
height && idx_max < this->
width,
1785 "DenseMatrix::GetSubMatrix: Index out of bounds");
1790 for (
int i = 0; i<k; i++)
1793 for (
int j = 0; j<k; j++)
1796 adata[i+j*k] = this->data[ii+jj*
height];
1804 int k = idx_i.
Size();
1805 int l = idx_j.
Size();
1807 MFEM_VERIFY(idx_i.
Min() >=0 && idx_i.
Max() < this->height,
1808 "DenseMatrix::GetSubMatrix: Row index out of bounds");
1809 MFEM_VERIFY(idx_j.
Min() >=0 && idx_j.
Max() < this->width,
1810 "DenseMatrix::GetSubMatrix: Col index out of bounds");
1816 for (
int i = 0; i<k; i++)
1819 for (
int j = 0; j<l; j++)
1822 adata[i+j*k] = this->data[ii+jj*
height];
1829 MFEM_VERIFY(iend >= ibeg,
"DenseMatrix::GetSubMatrix: Inconsistent range");
1830 MFEM_VERIFY(ibeg >=0,
1831 "DenseMatrix::GetSubMatrix: Negative index");
1832 MFEM_VERIFY(iend <= this->
height && iend <= this->
width,
1833 "DenseMatrix::GetSubMatrix: Index bigger than upper bound");
1835 int k = iend - ibeg;
1840 for (
int i = 0; i<k; i++)
1843 for (
int j = 0; j<k; j++)
1846 adata[i+j*k] = this->data[ii+jj*
height];
1854 MFEM_VERIFY(iend >= ibeg,
1855 "DenseMatrix::GetSubMatrix: Inconsistent row range");
1856 MFEM_VERIFY(jend >= jbeg,
1857 "DenseMatrix::GetSubMatrix: Inconsistent col range");
1858 MFEM_VERIFY(ibeg >=0,
1859 "DenseMatrix::GetSubMatrix: Negative row index");
1860 MFEM_VERIFY(jbeg >=0,
1861 "DenseMatrix::GetSubMatrix: Negative row index");
1862 MFEM_VERIFY(iend <= this->
height,
1863 "DenseMatrix::GetSubMatrix: Index bigger than row upper bound");
1864 MFEM_VERIFY(jend <= this->
width,
1865 "DenseMatrix::GetSubMatrix: Index bigger than col upper bound");
1867 int k = iend - ibeg;
1868 int l = jend - jbeg;
1873 for (
int i = 0; i<k; i++)
1876 for (
int j = 0; j<l; j++)
1879 adata[i+j*k] = this->data[ii+jj*
height];
1888 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1890 int idx_max = idx.
Max();
1892 MFEM_VERIFY(idx.
Min() >=0,
1893 "DenseMatrix::SetSubMatrix: Negative index");
1894 MFEM_VERIFY(idx_max < this->
height,
1895 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1896 MFEM_VERIFY(idx_max < this->
width,
1897 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1902 for (
int i = 0; i<k; i++)
1905 for (
int j = 0; j<k; j++)
1908 this->data[ii+jj*
height] = adata[i+j*k];
1916 int k = idx_i.
Size();
1917 int l = idx_j.
Size();
1919 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1920 MFEM_VERIFY(idx_i.
Min() >=0,
1921 "DenseMatrix::SetSubMatrix: Negative row index");
1922 MFEM_VERIFY(idx_j.
Min() >=0,
1923 "DenseMatrix::SetSubMatrix: Negative col index");
1924 MFEM_VERIFY(idx_i.
Max() < this->height,
1925 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1926 MFEM_VERIFY(idx_j.
Max() < this->width,
1927 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1932 for (
int i = 0; i<k; i++)
1935 for (
int j = 0; j<l; j++)
1938 this->data[ii+jj*
height] = adata[i+j*k];
1947 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::SetSubmatrix: A is not square");
1948 MFEM_VERIFY(ibeg >=0,
1949 "DenseMatrix::SetSubmatrix: Negative index");
1950 MFEM_VERIFY(ibeg + k <= this->
height,
1951 "DenseMatrix::SetSubmatrix: index bigger than row upper bound");
1952 MFEM_VERIFY(ibeg + k <= this->
width,
1953 "DenseMatrix::SetSubmatrix: index bigger than col upper bound");
1958 for (
int i = 0; i<k; i++)
1961 for (
int j = 0; j<k; j++)
1964 this->data[ii+jj*
height] = adata[i+j*k];
1974 MFEM_VERIFY(ibeg>=0,
1975 "DenseMatrix::SetSubmatrix: Negative row index");
1976 MFEM_VERIFY(jbeg>=0,
1977 "DenseMatrix::SetSubmatrix: Negative col index");
1978 MFEM_VERIFY(ibeg + k <= this->
height,
1979 "DenseMatrix::SetSubmatrix: Index bigger than row upper bound");
1980 MFEM_VERIFY(jbeg + l <= this->
width,
1981 "DenseMatrix::SetSubmatrix: Index bigger than col upper bound");
1986 for (
int i = 0; i<k; i++)
1989 for (
int j = 0; j<l; j++)
1992 this->data[ii+jj*
height] = adata[i+j*k];
2001 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2003 int idx_max = idx.
Max();
2005 MFEM_VERIFY(idx.
Min() >=0,
"DenseMatrix::AddSubMatrix: Negative index");
2006 MFEM_VERIFY(idx_max < this->
height,
2007 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2008 MFEM_VERIFY(idx_max < this->
width,
2009 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2014 for (
int i = 0; i<k; i++)
2017 for (
int j = 0; j<k; j++)
2020 this->data[ii+jj*
height] += adata[i+j*k];
2028 int k = idx_i.
Size();
2029 int l = idx_j.
Size();
2031 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2033 MFEM_VERIFY(idx_i.
Min() >=0,
2034 "DenseMatrix::AddSubMatrix: Negative row index");
2035 MFEM_VERIFY(idx_j.
Min() >=0,
2036 "DenseMatrix::AddSubMatrix: Negative col index");
2037 MFEM_VERIFY(idx_i.
Max() < this->height,
2038 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2039 MFEM_VERIFY(idx_j.
Max() < this->width,
2040 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2045 for (
int i = 0; i<k; i++)
2048 for (
int j = 0; j<l; j++)
2051 this->data[ii+jj*
height] += adata[i+j*k];
2059 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::AddSubmatrix: A is not square");
2061 MFEM_VERIFY(ibeg>=0,
2062 "DenseMatrix::AddSubmatrix: Negative index");
2063 MFEM_VERIFY(ibeg + k <= this->
Height(),
2064 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2065 MFEM_VERIFY(ibeg + k <= this->
Width(),
2066 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2071 for (
int i = 0; i<k; i++)
2074 for (
int j = 0; j<k; j++)
2077 this->data[ii+jj*
height] += adata[i+j*k];
2087 MFEM_VERIFY(ibeg>=0,
2088 "DenseMatrix::AddSubmatrix: Negative row index");
2089 MFEM_VERIFY(jbeg>=0,
2090 "DenseMatrix::AddSubmatrix: Negative col index");
2091 MFEM_VERIFY(ibeg + k <= this->
height,
2092 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2093 MFEM_VERIFY(jbeg + l <= this->
width,
2094 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2099 for (
int i = 0; i<k; i++)
2102 for (
int j = 0; j<l; j++)
2105 this->data[ii+jj*
height] += adata[i+j*k];
2115 for (
int i = 0; i < n; i++)
2117 vdata[i] += data[i];
2126 for (
int i = 0; i < n; i++)
2139 mfem_error(
"DenseMatrix::AdjustDofDirection(...): dimension mismatch");
2144 for (
int i = 0; i < n-1; i++)
2146 const int s = (dof[i] < 0) ? (-1) : (1);
2147 for (
int j = i+1; j < n; j++)
2149 const int t = (dof[j] < 0) ? (-s) : (s);
2152 (*this)(i,j) = -(*
this)(i,j);
2153 (*this)(j,i) = -(*
this)(j,i);
2161 for (
int j = 0; j <
Width(); j++)
2163 (*this)(row, j) = value;
2169 for (
int i = 0; i <
Height(); i++)
2171 (*this)(i, col) = value;
2177 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
2178 for (
int j = 0; j <
Width(); j++)
2180 (*this)(r, j) = row[j];
2192 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
2193 for (
int i = 0; i <
Height(); i++)
2195 (*this)(i, c) = col[i];
2207 for (
int col = 0; col <
Width(); col++)
2209 for (
int row = 0; row <
Height(); row++)
2211 if (std::abs(
operator()(row,col)) <= eps)
2222 ios::fmtflags old_flags = os.flags();
2224 os << setiosflags(ios::scientific | ios::showpos);
2225 for (
int i = 0; i <
height; i++)
2227 os <<
"[row " << i <<
"]\n";
2228 for (
int j = 0; j <
width; j++)
2231 if (j+1 ==
width || (j+1) % width_ == 0)
2242 os.flags(old_flags);
2248 ios::fmtflags old_flags = os.flags();
2250 os << setiosflags(ios::scientific | ios::showpos);
2251 for (
int i = 0; i <
height; i++)
2253 for (
int j = 0; j <
width; j++)
2261 os.flags(old_flags);
2266 ios::fmtflags old_fmt = os.flags();
2267 os.setf(ios::scientific);
2268 std::streamsize old_prec = os.precision(14);
2270 os <<
"(* Read file into Mathematica using: "
2271 <<
"myMat = Get[\"this_file_name\"] *)\n";
2274 for (
int i = 0; i <
height; i++)
2277 for (
int j = 0; j <
width; j++)
2279 os <<
"Internal`StringToMReal[\"" << (*this)(i,j) <<
"\"]";
2280 if (j <
width - 1) { os <<
','; }
2284 if (i <
height - 1) { os <<
','; }
2289 os.precision(old_prec);
2296 ios::fmtflags old_flags = os.flags();
2298 os << setiosflags(ios::scientific | ios::showpos);
2299 for (
int j = 0; j <
width; j++)
2301 os <<
"[col " << j <<
"]\n";
2302 for (
int i = 0; i <
height; i++)
2305 if (i+1 ==
height || (i+1) % width_ == 0)
2316 os.flags(old_flags);
2325 for (
int i = 0; i <
width; i++)
2330 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2363 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
2364 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
2365 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
2374 if (std::abs(det) <= TOL) {
return false; }
2382 if (std::abs(det) <= TOL) {
return false; }
2384 real_t invdet = 1. / det;
2389 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
2390 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
2399 if (!lu.
Factor(N,TOL)) {
return false; }
2411 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2412 b.Width() == c.
Height(),
"incompatible dimensions");
2414#ifdef MFEM_USE_LAPACK
2415 static char transa =
'N', transb =
'N';
2417 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2419 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2420 c.
Data(), &k, &beta,
a.Data(), &m);
2422 const int ah =
a.Height();
2423 const int aw =
a.Width();
2424 const int bw =
b.Width();
2435 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2436 b.Width() == c.
Height(),
"incompatible dimensions");
2438#ifdef MFEM_USE_LAPACK
2439 static char transa =
'N', transb =
'N';
2440 static real_t beta = 1.0;
2441 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2443 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2444 c.
Data(), &k, &beta,
a.Data(), &m);
2446 const int ah =
a.Height();
2447 const int aw =
a.Width();
2448 const int bw =
b.Width();
2452 for (
int j = 0; j < aw; j++)
2454 for (
int k = 0; k < bw; k++)
2456 for (
int i = 0; i < ah; i++)
2458 ad[i+j*ah] +=
alpha * bd[i+k*ah] * cd[k+j*bw];
2467 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2468 b.Width() == c.
Height(),
"incompatible dimensions");
2470#ifdef MFEM_USE_LAPACK
2471 static char transa =
'N', transb =
'N';
2473 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2475 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2476 c.
Data(), &k, &beta,
a.Data(), &m);
2478 const int ah =
a.Height();
2479 const int aw =
a.Width();
2480 const int bw =
b.Width();
2484 for (
int j = 0; j < aw; j++)
2486 for (
int k = 0; k < bw; k++)
2488 for (
int i = 0; i < ah; i++)
2490 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2500 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
2502 mfem_error(
"CalcAdjugate(...): unsupported dimensions");
2504 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
2506 mfem_error(
"CalcAdjugate(...): dimension mismatch");
2510 if (
a.Width() <
a.Height())
2519 if (
a.Height() == 3)
2528 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2529 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2530 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2532 ad[0] = d[0]*g - d[3]*
f;
2533 ad[1] = d[3]*e - d[0]*
f;
2534 ad[2] = d[1]*g - d[4]*
f;
2535 ad[3] = d[4]*e - d[1]*
f;
2536 ad[4] = d[2]*g - d[5]*
f;
2537 ad[5] = d[5]*e - d[2]*
f;
2546 else if (
a.Width() == 2)
2549 adja(0,1) = -
a(0,1);
2550 adja(1,0) = -
a(1,0);
2555 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2556 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2557 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2559 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2560 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2561 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2563 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2564 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2565 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2572 if (
a.Height() !=
a.Width() || adjat.
Height() != adjat.
Width() ||
2573 a.Width() != adjat.
Width() ||
a.Width() < 1 ||
a.Width() > 3)
2575 mfem_error(
"CalcAdjugateTranspose(...): dimension mismatch");
2582 else if (
a.Width() == 2)
2584 adjat(0,0) =
a(1,1);
2585 adjat(1,0) = -
a(0,1);
2586 adjat(0,1) = -
a(1,0);
2587 adjat(1,1) =
a(0,0);
2591 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2592 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2593 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2595 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2596 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2597 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2599 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2600 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2601 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2607 MFEM_ASSERT(
a.Width() <=
a.Height() &&
a.Width() >= 1 &&
a.Height() <= 3,
"");
2608 MFEM_ASSERT(inva.
Height() ==
a.Width(),
"incorrect dimensions");
2609 MFEM_ASSERT(inva.
Width() ==
a.Height(),
"incorrect dimensions");
2611 if (
a.Width() <
a.Height())
2615 if (
a.Height() == 2)
2635 MFEM_ASSERT(std::abs(t) > 1.0e-14 * pow(
a.FNorm()/
a.Width(),
a.Width()),
2636 "singular matrix!");
2642 inva(0,0) = 1.0 /
a.
Det();
2656 if ( (
a.Width() !=
a.Height()) || ( (
a.Height()!= 1) && (
a.Height()!= 2)
2657 && (
a.Height()!= 3) ) )
2659 mfem_error(
"CalcInverseTranspose(...): dimension mismatch");
2668 inva(0,0) = 1.0 /
a(0,0);
2671 inva(0,0) =
a(1,1) * t ;
2672 inva(1,0) = -
a(0,1) * t ;
2673 inva(0,1) = -
a(1,0) * t ;
2674 inva(1,1) =
a(0,0) * t ;
2677 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*t;
2678 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*t;
2679 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*t;
2681 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*t;
2682 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*t;
2683 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*t;
2685 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*t;
2686 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*t;
2687 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*t;
2697 "Matrix must be 3x2 or 2x1, "
2698 <<
"and the Vector must be sized with the rows. "
2699 <<
" J.Height() = " << J.
Height()
2700 <<
", J.Width() = " << J.
Width()
2701 <<
", n.Size() = " << n.
Size()
2712 n(0) = d[1]*d[5] - d[2]*d[4];
2713 n(1) = d[2]*d[3] - d[0]*d[5];
2714 n(2) = d[0]*d[4] - d[1]*d[3];
2720 const int height =
a.Height();
2721 const int width =
a.Width();
2722 for (
int i = 0; i < height; i++)
2724 for (
int j = 0; j <= i; j++)
2727 for (
int k = 0; k < width; k++)
2729 temp +=
a(i,k) *
a(j,k);
2731 aat(j,i) = aat(i,j) = temp;
2738 for (
int i = 0; i < A.
Height(); i++)
2740 for (
int j = 0; j < i; j++)
2743 for (
int k = 0; k < A.
Width(); k++)
2745 t += D(k) * A(i, k) * A(j, k);
2753 for (
int i = 0; i < A.
Height(); i++)
2756 for (
int k = 0; k < A.
Width(); k++)
2758 t += D(k) * A(i, k) * A(i, k);
2766 for (
int i = 0; i < A.
Height(); i++)
2768 for (
int j = 0; j <= i; j++)
2771 for (
int k = 0; k < A.
Width(); k++)
2773 t += D(k) * A(i, k) * A(j, k);
2775 ADAt(j, i) = ADAt(i, j) = t;
2786 mfem_error(
"MultABt(...): dimension mismatch");
2790#ifdef MFEM_USE_LAPACK
2791 static char transa =
'N', transb =
'T';
2795 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
2796 B.
Data(), &n, &beta, ABt.
Data(), &m);
2798 const int ah = A.
Height();
2799 const int bh = B.
Height();
2800 const int aw = A.
Width();
2807 const int ah = A.
Height();
2808 const int bh = B.
Height();
2809 const int aw = A.
Width();
2814 for (
int j = 0; j < bh; j++)
2815 for (
int i = 0; i < ah; i++)
2818 const real_t *ap = ad + i;
2819 const real_t *bp = bd + j;
2820 for (
int k = 0; k < aw; k++)
2832 for (i = 0; i < A.
Height(); i++)
2833 for (j = 0; j < B.
Height(); j++)
2836 for (k = 0; k < A.
Width(); k++)
2838 d += A(i, k) * B(j, k);
2852 mfem_error(
"MultADBt(...): dimension mismatch");
2856 const int ah = A.
Height();
2857 const int bh = B.
Height();
2858 const int aw = A.
Width();
2864 for (
int i = 0, s = ah*bh; i < s; i++)
2868 for (
int k = 0; k < aw; k++)
2871 for (
int j = 0; j < bh; j++)
2873 const real_t dk_bjk = dd[k] * bd[j];
2874 for (
int i = 0; i < ah; i++)
2876 cp[i] += ad[i] * dk_bjk;
2891 mfem_error(
"AddMultABt(...): dimension mismatch");
2895#ifdef MFEM_USE_LAPACK
2896 static char transa =
'N', transb =
'T';
2900 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
2901 B.
Data(), &n, &beta, ABt.
Data(), &m);
2903 const int ah = A.
Height();
2904 const int bh = B.
Height();
2905 const int aw = A.
Width();
2910 for (
int k = 0; k < aw; k++)
2913 for (
int j = 0; j < bh; j++)
2915 const real_t bjk = bd[j];
2916 for (
int i = 0; i < ah; i++)
2918 cp[i] += ad[i] * bjk;
2929 for (i = 0; i < A.
Height(); i++)
2930 for (j = 0; j < B.
Height(); j++)
2933 for (k = 0; k < A.
Width(); k++)
2935 d += A(i, k) * B(j, k);
2949 mfem_error(
"AddMultADBt(...): dimension mismatch");
2953 const int ah = A.
Height();
2954 const int bh = B.
Height();
2955 const int aw = A.
Width();
2961 for (
int k = 0; k < aw; k++)
2964 for (
int j = 0; j < bh; j++)
2966 const real_t dk_bjk = dd[k] * bd[j];
2967 for (
int i = 0; i < ah; i++)
2969 cp[i] += ad[i] * dk_bjk;
2985 mfem_error(
"AddMult_a_ABt(...): dimension mismatch");
2989#ifdef MFEM_USE_LAPACK
2990 static char transa =
'N', transb =
'T';
2992 static real_t beta = 1.0;
2995 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &m,
2996 B.
Data(), &n, &beta, ABt.
Data(), &m);
2998 const int ah = A.
Height();
2999 const int bh = B.
Height();
3000 const int aw = A.
Width();
3005 for (
int k = 0; k < aw; k++)
3008 for (
int j = 0; j < bh; j++)
3011 for (
int i = 0; i < ah; i++)
3013 cp[i] += ad[i] * bjk;
3024 for (i = 0; i < A.
Height(); i++)
3025 for (j = 0; j < B.
Height(); j++)
3028 for (k = 0; k < A.
Width(); k++)
3030 d += A(i, k) * B(j, k);
3043 mfem_error(
"MultAtB(...): dimension mismatch");
3047#ifdef MFEM_USE_LAPACK
3048 static char transa =
'T', transb =
'N';
3052 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3053 B.
Data(), &k, &beta, AtB.
Data(), &m);
3055 const int ah = A.
Height();
3056 const int aw = A.
Width();
3057 const int bw = B.
Width();
3062 for (
int j = 0; j < bw; j++)
3065 for (
int i = 0; i < aw; i++)
3068 for (
int k = 0; k < ah; k++)
3081 for (i = 0; i < A.
Width(); i++)
3082 for (j = 0; j < B.
Width(); j++)
3085 for (k = 0; k < A.
Height(); k++)
3087 d += A(k, i) * B(k, j);
3100#ifdef MFEM_USE_LAPACK
3101 static char transa =
'T', transb =
'N';
3105 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3106 B.
Data(), &k, &beta, AtB.
Data(), &m);
3108 const int ah = A.
Height();
3109 const int aw = A.
Width();
3110 const int bw = B.
Width();
3115 for (
int j = 0; j < bw; j++)
3118 for (
int i = 0; i < aw; i++)
3121 for (
int k = 0; k < ah; k++)
3139#ifdef MFEM_USE_LAPACK
3140 static char transa =
'T', transb =
'N';
3142 static real_t beta = 1.0;
3145 MFEM_LAPACK_PREFIX(gemm_)(&transa, &transb, &m, &n, &k, &
alpha, A.
Data(), &k,
3146 B.
Data(), &k, &beta, AtB.
Data(), &m);
3148 const int ah = A.
Height();
3149 const int aw = A.
Width();
3150 const int bw = B.
Width();
3155 for (
int j = 0; j < bw; j++)
3158 for (
int i = 0; i < aw; i++)
3161 for (
int k = 0; k < ah; k++)
3177 for (
int i = 0; i < A.
Height(); i++)
3179 for (
int j = 0; j < i; j++)
3182 for (
int k = 0; k < A.
Width(); k++)
3184 d += A(i,k) * A(j,k);
3186 AAt(i, j) += (d *=
a);
3190 for (
int k = 0; k < A.
Width(); k++)
3192 d += A(i,k) * A(i,k);
3200 for (
int i = 0; i < A.
Height(); i++)
3202 for (
int j = 0; j <= i; j++)
3205 for (
int k = 0; k < A.
Width(); k++)
3207 d += A(i,k) * A(j,k);
3209 AAt(i, j) = AAt(j, i) =
a * d;
3216 for (
int i = 0; i < v.
Size(); i++)
3218 for (
int j = 0; j <= i; j++)
3220 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3230 mfem_error(
"MultVWt(...): dimension mismatch");
3234 for (
int i = 0; i < v.
Size(); i++)
3237 for (
int j = 0; j < w.
Size(); j++)
3239 VWt(i, j) = vi * w(j);
3246 const int m = v.
Size(), n = w.
Size();
3251 mfem_error(
"AddMultVWt(...): dimension mismatch");
3255 for (
int i = 0; i < m; i++)
3258 for (
int j = 0; j < n; j++)
3260 VWt(i, j) += vi * w(j);
3267 const int n = v.
Size();
3272 mfem_error(
"AddMultVVt(...): dimension mismatch");
3276 for (
int i = 0; i < n; i++)
3279 for (
int j = 0; j < i; j++)
3281 const real_t vivj = vi * v(j);
3285 VVt(i, i) += vi * vi;
3292 const int m = v.
Size(), n = w.
Size();
3297 mfem_error(
"AddMult_a_VWt(...): dimension mismatch");
3301 for (
int j = 0; j < n; j++)
3304 for (
int i = 0; i < m; i++)
3306 VWt(i, j) += v(i) * awj;
3314 "incompatible dimensions!");
3316 const int n = v.
Size();
3317 for (
int i = 0; i < n; i++)
3320 for (
int j = 0; j < i; j++)
3322 const real_t avivj = avi * v(j);
3326 VVt(i, i) += avi * v(i);
3349#ifdef MFEM_USE_LAPACK
3351 if (m) { MFEM_LAPACK_PREFIX(getrf_)(&m, &m,
data, &m,
ipiv, &info); }
3356 for (
int i = 0; i < m; i++)
3361 real_t a = std::abs(data_ptr[piv+i*m]);
3362 for (
int j = i+1; j < m; j++)
3364 const real_t b = std::abs(data_ptr[j+i*m]);
3375 for (
int j = 0; j < m; j++)
3382 if (
abs(data_ptr[i + i*m]) <= TOL)
3387 const real_t a_ii_inv = 1.0 / data_ptr[i+i*m];
3388 for (
int j = i+1; j < m; j++)
3390 data_ptr[j+i*m] *= a_ii_inv;
3392 for (
int k = i+1; k < m; k++)
3394 const real_t a_ik = data_ptr[i+k*m];
3395 for (
int j = i+1; j < m; j++)
3397 data_ptr[j+k*m] -= a_ik * data_ptr[j+i*m];
3409 for (
int i=0; i<m; i++)
3413 det *= -
data[m * i + i];
3417 det *=
data[m * i + i];
3426 for (
int k = 0; k < n; k++)
3429 for (
int i = 0; i < m; i++)
3432 for (
int j = i+1; j < m; j++)
3434 x_i += x[j] *
data[i+j*m];
3439 for (
int i = m-1; i >= 0; i--)
3442 for (
int j = 0; j < i; j++)
3444 x_i += x[j] *
data[i+j*m];
3449 for (
int i = m-1; i >= 0; i--)
3460 for (
int k = 0; k < n; k++)
3470 for (
int k = 0; k < n; k++)
3479#ifdef MFEM_USE_LAPACK
3484 MFEM_LAPACK_PREFIX(getrs_)(&
trans, &m, &n,
data, &m,
ipiv, X, &m, &info);
3486 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3497#ifdef MFEM_USE_LAPACK
3498 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3502 MFEM_LAPACK_PREFIX(trsm_)(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3503 MFEM_LAPACK_PREFIX(trsm_)(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3509 for (
int k = 0; k < n; k++)
3511 for (
int j = 0; j < m; j++)
3514 for (
int i = j+1; i < m; i++)
3516 x[i*n] -=
data[j + i*m] * x_j;
3524 for (
int k = 0; k < n; k++)
3526 for (
int j = m-1; j >= 0; j--)
3528 const real_t x_j = x[j*n];
3529 for (
int i = 0; i < j; i++)
3531 x[i*n] -=
data[j + i*m] * x_j;
3539 for (
int k = 0; k < n; k++)
3541 for (
int i = m-1; i >= 0; --i)
3554 for (
int k = 0; k < m; k++)
3556 const real_t minus_x_k = -( x[k] = 1.0/
data[k+k*m] );
3557 for (
int i = 0; i < k; i++)
3559 x[i] =
data[i+k*m] * minus_x_k;
3561 for (
int j = k-1; j >= 0; j--)
3564 for (
int i = 0; i < j; i++)
3566 x[i] -=
data[i+j*m] * x_j;
3574 for (
int j = 0; j < k; j++)
3577 for (
int i = 0; i <= j; i++)
3579 X[i+j*m] += X[i+k*m] * minus_L_kj;
3581 for (
int i = j+1; i < m; i++)
3583 X[i+j*m] = X[i+k*m] * minus_L_kj;
3587 for (
int k = m-2; k >= 0; k--)
3589 for (
int j = 0; j < k; j++)
3592 for (
int i = 0; i < m; i++)
3594 X[i+j*m] -= X[i+k*m] * L_kj;
3599 for (
int k = m-1; k >= 0; k--)
3604 for (
int i = 0; i < m; i++)
3630 SubMult(m, n, r, L21, B1, B2);
3637 SubMult(n, m, r, U12, X2, Y1);
3645#ifdef MFEM_USE_LAPACK
3648 MFEM_VERIFY(
data,
"Matrix data not set");
3649 if (m) { MFEM_LAPACK_PREFIX(potrf_)(&uplo, &m,
data, &m, &info); }
3653 for (
int j = 0; j<m; j++)
3656 for (
int k = 0; k<j; k++)
3661 MFEM_VERIFY(
data[j+j*m] -
a > 0.,
3662 "CholeskyFactors::Factor: The matrix is not SPD");
3664 data[j+j*m] = std::sqrt(
data[j+j*m] -
a);
3666 if (
data[j + j*m] <= TOL)
3671 for (
int i = j+1; i<m; i++)
3674 for (
int k = 0; k<j; k++)
3688 for (
int i=0; i<m; i++)
3690 det *=
data[i + i*m];
3699 for (
int k = 0; k < n; k++)
3701 for (
int j = m-1; j >= 0; j--)
3704 for (
int i = 0; i < j; i++)
3706 x_j += x[i] *
data[j+i*m];
3717 for (
int k = 0; k < n; k++)
3719 for (
int i = 0; i < m; i++)
3722 for (
int j = i+1; j < m; j++)
3724 x_i += x[j] *
data[j+i*m];
3735#ifdef MFEM_USE_LAPACK
3741 MFEM_LAPACK_PREFIX(trtrs_)(&uplo, &
trans, &diag, &m, &n,
data, &m, X, &m,
3743 MFEM_VERIFY(!info,
"CholeskyFactors:LSolve:: info");
3747 for (
int k = 0; k < n; k++)
3750 for (
int j = 0; j < m; j++)
3753 for (
int i = j+1; i < m; i++)
3755 x[i] -=
data[i+j*m] * x_j;
3765#ifdef MFEM_USE_LAPACK
3772 MFEM_LAPACK_PREFIX(trtrs_)(&uplo, &
trans, &diag, &m, &n,
data, &m, X, &m,
3774 MFEM_VERIFY(!info,
"CholeskyFactors:USolve:: info");
3779 for (
int k = 0; k < n; k++)
3781 for (
int j = m-1; j >= 0; j--)
3784 for (
int i = 0; i < j; i++)
3786 x[i] -=
data[j+i*m] * x_j;
3796#ifdef MFEM_USE_LAPACK
3799 MFEM_LAPACK_PREFIX(potrs_)(&uplo, &m, &n,
data, &m, X, &m, &info);
3800 MFEM_VERIFY(!info,
"CholeskyFactors:Solve:: info");
3810#ifdef MFEM_USE_LAPACK
3820 MFEM_LAPACK_PREFIX(trsm_)(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3821 MFEM_LAPACK_PREFIX(trsm_)(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3826 for (
int k = 0; k < n; k++)
3828 for (
int j = 0; j < m; j++)
3831 for (
int i = j+1; i < m; i++)
3833 x[i*n] -=
data[i + j*m] * x_j;
3840 for (
int k = 0; k < n; k++)
3842 for (
int j = m-1; j >= 0; j--)
3845 for (
int i = 0; i < j; i++)
3847 x[i*n] -=
data[j + i*m] * x_j;
3858#ifdef MFEM_USE_LAPACK
3860 for (
int i = 0; i<m; i++)
3862 for (
int j = i; j<m; j++)
3864 X[j+i*m] =
data[j+i*m];
3869 MFEM_LAPACK_PREFIX(potri_)(&uplo, &m, X, &m, &info);
3870 MFEM_VERIFY(!info,
"CholeskyFactors:GetInverseMatrix:: info");
3872 for (
int i = 0; i<m; i++)
3874 for (
int j = i+1; j<m; j++)
3876 X[i+j*m] = X[j+i*m];
3881 for (
int k = 0; k<m; k++)
3883 X[k+k*m] = 1./
data[k+k*m];
3884 for (
int i = k+1; i < m; i++)
3887 for (
int j=k; j<i; j++)
3889 s -=
data[i+j*m] * X[j+k*m]/
data[i+i*m];
3894 for (
int i = 0; i < m; i++)
3896 for (
int j = i; j < m; j++)
3899 for (
int k=j; k<m; k++)
3901 s += X[k+i*m] * X[k+j*m];
3903 X[i+j*m] = X[j+i*m] = s;
3910void DenseMatrixInverse::Init(
int m)
3918 factors =
new LUFactors();
3925 dynamic_cast<LUFactors *
>(factors)->ipiv =
new int[m];
3934 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3943 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3950 MFEM_ASSERT(a,
"DenseMatrix is not given");
3951 const real_t *adata = a->data;
3953 for (
int i = 0; i < s; i++)
3955 factors->
data[i] = adata[i];
3968 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
3972 if (own_data) {
delete [] factors->
data; }
3978 if (own_data) {
delete [] lu->
ipiv; }
3990 MFEM_VERIFY(
p != NULL,
"Operator is not a DenseMatrix!");
3996 for (
int row = 0; row <
height; row++)
4019 for (
int i = 0; i <
width; i++)
4030 delete [] factors->
data;
4033 delete []
dynamic_cast<LUFactors *
>(factors)->ipiv;
4039#ifdef MFEM_USE_LAPACK
4053 MFEM_LAPACK_PREFIX(syev_)(&jobz, &uplo, &n, EVect.
Data(), &n, EVal.
GetData(),
4054 &qwork, &lwork, &info);
4056 lwork = (int) qwork;
4057 work =
new real_t[lwork];
4062 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4067 lwork = other.lwork;
4069 work =
new real_t[lwork];
4075 if (mat.
Width() != n)
4077 mfem_error(
"DenseMatrixEigensystem::Eval(): dimension mismatch");
4082 MFEM_LAPACK_PREFIX(syev_)(&jobz, &uplo, &n, EVect.
Data(), &n, EVal.
GetData(),
4083 work, &lwork, &info);
4087 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
4101 bool left_eigen_vectors,
4102 bool right_eigen_vectors)
4105 MFEM_VERIFY(A.
Height() == A.
Width(),
"A has to be a square matrix");
4106 MFEM_VERIFY(B.
Height() == B.
Width(),
"B has to be a square matrix");
4108 MFEM_VERIFY(B.
Height() == n,
"A and B dimension mismatch");
4114 if (left_eigen_vectors)
4119 if (right_eigen_vectors)
4132 int nl = max(1,Vl.
Height());
4133 int nr = max(1,Vr.
Height());
4135 MFEM_LAPACK_PREFIX(ggev_)(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,
4136 alphar, alphai, beta, Vl.
Data(), &nl, Vr.
Data(),
4137 &nr, &qwork, &lwork, &info);
4139 lwork = (int) qwork;
4140 work =
new real_t[lwork];
4145 int nl = max(1,Vl.
Height());
4146 int nr = max(1,Vr.
Height());
4150 MFEM_LAPACK_PREFIX(ggev_)(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,
4151 alphar, alphai, beta, Vl.
Data(), &nl, Vr.
Data(),
4152 &nr, work, &lwork, &info);
4155 mfem::err <<
"DenseMatrixGeneralizedEigensystem::Eval(): DGGEV error code: "
4161 for (
int i = 0; i<n; i++)
4165 evalues_r(i) = alphar[i]/beta[i];
4166 evalues_i(i) = alphai[i]/beta[i];
4185 bool left_singular_vectors,
4186 bool right_singular_vectors)
4190 jobu = (left_singular_vectors)?
'S' :
'N';
4191 jobvt = (right_singular_vectors)?
'S' :
'N';
4196 bool left_singular_vectors,
4197 bool right_singular_vectors)
4201 jobu = (left_singular_vectors)?
'S' :
'N';
4202 jobvt = (right_singular_vectors)?
'S' :
'N';
4207 char left_singular_vectors,
4208 char right_singular_vectors)
4212 jobu = left_singular_vectors;
4213 jobvt = right_singular_vectors;
4218 char left_singular_vectors,
4219 char right_singular_vectors)
4223 jobu = left_singular_vectors;
4224 jobvt = right_singular_vectors;
4228void DenseMatrixSVD::Init()
4233 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n, NULL, &m, sv.
GetData(),
4234 NULL, &m, NULL, &n, &qwork, &lwork, &info);
4235 lwork = (int) qwork;
4236 work =
new real_t[lwork];
4247 real_t * datau =
nullptr;
4248 real_t * datavt =
nullptr;
4254 else if (jobu ==
'S')
4264 else if (jobvt ==
'S')
4270 MFEM_LAPACK_PREFIX(gesvd_)(&jobu, &jobvt, &m, &n, Mc.
Data(), &m, sv.
GetData(),
4271 datau, &m, datavt, &n, work, &lwork, &info);
4275 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4292 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4300 for (
int i = 0; i < ne; i++)
4303 for (
int col = 0; col < n; col++)
4305 x_col = xp[dofs[col]];
4306 for (
int row = 0; row < n; row++)
4308 yp[dofs[row]] += x_col*d_col[row];
4317 for (
int i = 0; i < ne; i++)
4320 x_col = xp[dofs[0]];
4321 for (
int row = 0; row < n; row++)
4323 ye(row) = x_col*d_col[row];
4326 for (
int col = 1; col < n; col++)
4328 x_col = xp[dofs[col]];
4329 for (
int row = 0; row < n; row++)
4331 ye(row) += x_col*d_col[row];
4335 for (
int row = 0; row < n; row++)
4337 yp[dofs[row]] += ye(row);
4346 for (
int i=0; i<s; i++)
4363#ifdef MFEM_USE_LAPACK
4367 int LDAB = (2*KL) + KU + 1;
4372 MFEM_LAPACK_PREFIX(gbsv_)(&N, &KL, &KU, &NRHS, AB.
GetData(), &LDAB,
4374 MFEM_ASSERT(info == 0,
"BandedSolve failed in LAPACK");
4380 int LDAB = (2*KL) + KU + 1;
4383 char trans = transpose ?
'T' :
'N';
4385 MFEM_LAPACK_PREFIX(gbtrs_)(&
trans, &N, &KL, &KU, &NRHS, AB.
GetData(), &LDAB,
4387 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 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))
void Getl1Diag(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
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 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.
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 AdjustDofDirection(Array< int > &dofs)
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
Compute 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)
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
DenseTensor & operator=(real_t c)
Sets the tensor elements equal to constant c.
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)
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
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.
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)