29#if defined(_MSC_VER) && (_MSC_VER < 1800)
31#define copysign _copysign
38sgemm_(
char *,
char *,
int *,
int *,
int *,
float *,
float *,
39 int *,
float *,
int *,
float *,
float *,
int *);
41sgetrf_(
int *,
int *,
float *,
int *,
int *,
int *);
43sgetrs_(
char *,
int *,
int *,
float *,
int *,
int *,
float *,
int *,
int *);
45sgetri_(
int *N,
float *A,
int *LDA,
int *IPIV,
float *WORK,
46 int *LWORK,
int *INFO);
48ssyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
float *A,
int *LDA,
49 float *VL,
float *VU,
int *IL,
int *IU,
float *ABSTOL,
int *M,
50 float *W,
float *Z,
int *LDZ,
int *ISUPPZ,
float *WORK,
int *LWORK,
51 int *IWORK,
int *LIWORK,
int *INFO);
53ssyev_(
char *JOBZ,
char *UPLO,
int *N,
float *A,
int *LDA,
float *W,
54 float *WORK,
int *LWORK,
int *INFO);
56ssygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
float *A,
int *LDA,
57 float *B,
int *LDB,
float *W,
float *WORK,
int *LWORK,
int *INFO);
59sgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
float *A,
int *LDA,
60 float *S,
float *U,
int *LDU,
float *VT,
int *LDVT,
float *WORK,
61 int *LWORK,
int *INFO);
63strsm_(
char *side,
char *uplo,
char *transa,
char *diag,
int *m,
int *n,
64 float *
alpha,
float *
a,
int *lda,
float *
b,
int *ldb);
66sggev_(
char *jobvl,
char *jobvr,
int *n,
float *
a,
int *lda,
float *B,
67 int *ldb,
float *alphar,
float *alphai,
float *
beta,
float *vl,
68 int * ldvl,
float * vr,
int * ldvr,
float * work,
int * lwork,
int* info);
72spotrf_(
char *,
int *,
float *,
int *,
int *);
75spotrs_(
char *,
int *,
int *,
float *,
int *,
float *,
int *,
int *);
78strtrs_(
char *,
char*,
char *,
int *,
int *,
float *,
int *,
float *,
int *,
81spotri_(
char *,
int *,
float *,
int*,
int *);
82#elif defined MFEM_USE_DOUBLE
84dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
85 int *,
double *,
int *,
double *,
double *,
int *);
87dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
89dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
91dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
92 int *LWORK,
int *INFO);
94dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
95 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
96 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
97 int *IWORK,
int *LIWORK,
int *INFO);
99dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
100 double *WORK,
int *LWORK,
int *INFO);
102dsygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
double *A,
int *LDA,
103 double *B,
int *LDB,
double *W,
double *WORK,
int *LWORK,
int *INFO);
105dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
106 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
107 int *LWORK,
int *INFO);
109dtrsm_(
char *side,
char *uplo,
char *transa,
char *diag,
int *m,
int *n,
110 double *
alpha,
double *
a,
int *lda,
double *
b,
int *ldb);
112dggev_(
char *jobvl,
char *jobvr,
int *n,
double *
a,
int *lda,
double *B,
113 int *ldb,
double *alphar,
double *alphai,
double *
beta,
double *vl,
114 int * ldvl,
double * vr,
int * ldvr,
double * work,
int * lwork,
int* info);
118dpotrf_(
char *,
int *,
double *,
int *,
int *);
121dpotrs_(
char *,
int *,
int *,
double *,
int *,
double *,
int *,
int *);
124dtrtrs_(
char *,
char*,
char *,
int *,
int *,
double *,
int *,
double *,
int *,
144 MFEM_ASSERT(m.data,
"invalid source matrix");
146 std::memcpy(data, m.data,
sizeof(
real_t)*hw);
152 MFEM_ASSERT(
s >= 0,
"invalid DenseMatrix size: " <<
s);
162 MFEM_ASSERT(m >= 0 && n >= 0,
163 "invalid DenseMatrix size: " << m <<
" x " << n);
164 const int capacity = m*n;
173 :
Matrix(mat.width, mat.height)
175 MFEM_CONTRACT_VAR(ch);
181 for (
int i = 0; i <
height; i++)
183 for (
int j = 0; j <
width; j++)
185 (*this)(i,j) = mat(j,i);
193 MFEM_ASSERT(h >= 0 && w >= 0,
194 "invalid DenseMatrix size: " << h <<
" x " << w);
227 MFEM_ASSERT(
height == y.
Size(),
"incompatible dimensions");
234 MFEM_ASSERT(
width == x.
Size(),
"incompatible dimensions");
242 "incompatible dimensions");
250 "incompatible dimensions");
254 for (
int i = 0; i < hw; i++)
256 a += data[i] * m.data[i];
265 for (
int col = 0; col <
width; col++)
268 for (
int row = 0; row <
height; row++)
270 y_col += x[row]*d_col[row];
279 MFEM_ASSERT(
width == y.
Size(),
"incompatible dimensions");
286 MFEM_ASSERT(
height == x.
Size(),
"incompatible dimensions");
294 "incompatible dimensions");
307 "incompatible dimensions");
311 for (
int col = 0; col <
width; col++)
314 for (
int row = 0; row <
height; row++)
316 yp[row] += x_col*d_col[row];
331 "incompatible dimensions");
333 const real_t *d_col = data;
334 for (
int col = 0; col <
width; col++)
337 for (
int row = 0; row <
height; row++)
339 y_col += x[row]*d_col[row];
349 "incompatible dimensions");
353 for (
int col = 0; col <
width; col++)
355 const real_t x_col =
a*xp[col];
356 for (
int row = 0; row <
height; row++)
358 yp[row] += x_col*d_col[row];
368 "incompatible dimensions");
370 const real_t *d_col = data;
371 for (
int col = 0; col <
width; col++)
374 for (
int row = 0; row <
height; row++)
376 y_col += x[row]*d_col[row];
387 for (
int i = 0; i <
height; i++)
390 for (
int j = 0; j <
width; j++)
392 Axi += (*this)(i,j) * x[j];
404 for (
int j = 0; j <
width; ++j)
406 for (
int i = 0; i <
height; ++i)
408 *(it_data++) *=
s(i);
417 for (
int j = 0; j <
width; ++j)
419 for (
int i = 0; i <
height; ++i)
421 *(it_data++) /=
s(i);
431 for (
int j = 0; j <
width; ++j)
434 for (
int i = 0; i <
height; ++i)
445 for (
int j = 0; j <
width; ++j)
448 for (
int i = 0; i <
height; ++i)
460 mfem_error(
"DenseMatrix::SymmetricScaling: dimension mismatch");
466 for (
real_t * end_s = it_s +
width; it_s != end_s; ++it_s)
468 *(it_ss++) = sqrt(*it_s);
472 for (
int j = 0; j <
width; ++j)
474 for (
int i = 0; i <
height; ++i)
476 *(it_data++) *= ss[i]*ss[j];
488 mfem_error(
"DenseMatrix::InvSymmetricScaling: dimension mismatch");
494 for (
real_t * end_s = it_s +
width; it_s != end_s; ++it_s)
496 *(it_ss++) = 1./sqrt(*it_s);
500 for (
int j = 0; j <
width; ++j)
502 for (
int i = 0; i <
height; ++i)
504 *(it_data++) *= ss[i]*ss[j];
516 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
522 for (
int i = 0; i <
width; i++)
538 "The matrix must be square and "
539 <<
"sized larger than zero to compute the determinant."
540 <<
" Height() = " <<
Height()
541 <<
", Width() = " <<
Width());
549 return data[0] * data[3] - data[1] * data[2];
555 d[0] * (d[4] * d[8] - d[5] * d[7]) +
556 d[3] * (d[2] * d[7] - d[1] * d[8]) +
557 d[6] * (d[1] * d[5] - d[2] * d[4]);
563 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
564 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
565 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
567 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
568 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
569 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
571 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
572 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
573 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
575 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
576 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
577 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
586 return lu_factors.
Det();
601 return sqrt(data[0] * data[0] + data[1] * data[1]);
605 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
610 real_t E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
611 real_t G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
612 real_t F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
613 return sqrt(E * G - F * F);
615 mfem_error(
"DenseMatrix::Weight(): mismatched or unsupported dimensions");
622 for (
int i = 0; i <
s; i++)
624 data[i] =
alpha*A[i];
630 for (
int j = 0; j <
Width(); j++)
632 for (
int i = 0; i <
Height(); i++)
634 (*this)(i,j) += c * A(i,j);
642 for (
int i = 0; i <
s; i++)
651 for (
int i = 0; i <
s; i++)
661 for (
int i = 0; i <
s; i++)
673 for (
int i = 0; i < hw; i++)
690 "incompatible matrix sizes.");
696 for (
int j = 0; j <
width; j++)
698 for (
int i = 0; i <
height; i++)
700 (*this)(i, j) -= m(i, j);
710 for (
int i = 0; i <
s; i++)
720 for (
int i = 0; i < hw; i++)
731 mfem_error(
"DenseMatrix::Invert(): dimension mismatch");
735#ifdef MFEM_USE_LAPACK
736 int *ipiv =
new int[
width];
741#ifdef MFEM_USE_SINGLE
743#elif defined MFEM_USE_DOUBLE
746 MFEM_ABORT(
"Floating point type undefined");
751 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
754#ifdef MFEM_USE_SINGLE
758 work =
new float[lwork];
761#elif defined MFEM_USE_DOUBLE
765 work =
new double[lwork];
769 MFEM_ABORT(
"Floating point type undefined");
774 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
780 int c, i, j, n =
Width();
784 for (c = 0; c < n; c++)
786 a = fabs((*
this)(c, c));
788 for (j = c + 1; j < n; j++)
790 b = fabs((*
this)(j, c));
799 mfem_error(
"DenseMatrix::Invert() : singular matrix");
802 for (j = 0; j < n; j++)
807 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
808 for (j = 0; j < c; j++)
812 for (j++; j < n; j++)
816 for (i = 0; i < c; i++)
818 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
819 for (j = 0; j < c; j++)
821 (*this)(i, j) +=
b * (*
this)(c, j);
823 for (j++; j < n; j++)
825 (*this)(i, j) +=
b * (*
this)(c, j);
828 for (i++; i < n; i++)
830 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
831 for (j = 0; j < c; j++)
833 (*this)(i, j) +=
b * (*
this)(c, j);
835 for (j++; j < n; j++)
837 (*this)(i, j) +=
b * (*
this)(c, j);
842 for (c = n - 1; c >= 0; c--)
845 for (i = 0; i < n; i++)
859 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
869 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
871 for (
int j = 0; j < 10; j++)
873 for (
int i = 0; i < 10; i++)
888 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
889 if (tmp2.FNorm() < 1e-10) {
break; }
892 if (tmp2.FNorm() > 1e-10)
894 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
900 for (
int j = 0; j <
Width(); j++)
903 for (
int i = 0; i <
Height(); i++)
905 v[j] += (*this)(i,j)*(*
this)(i,j);
915 real_t norm = 0.0, abs_entry;
917 for (
int i = 0; i < hw; i++)
919 abs_entry = fabs(d[i]);
920 if (norm < abs_entry)
932 real_t max_norm = 0.0, entry, fnorm2;
934 for (i = 0; i < hw; i++)
936 entry = fabs(data[i]);
937 if (entry > max_norm)
945 scale_factor = scaled_fnorm2 = 0.0;
950 for (i = 0; i < hw; i++)
952 entry = data[i] / max_norm;
953 fnorm2 += entry * entry;
956 scale_factor = max_norm;
957 scaled_fnorm2 = fnorm2;
962#ifdef MFEM_USE_LAPACK
980 int *ISUPPZ =
new int[2*N];
998 int hw =
a.Height() *
a.Width();
1001 for (
int i = 0; i < hw; i++)
1006#ifdef MFEM_USE_SINGLE
1007 ssyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
1008#elif defined MFEM_USE_DOUBLE
1009 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
1011 MFEM_ABORT(
"Floating point type undefined");
1013 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
1014 &QIWORK, &LIWORK, &INFO );
1016 LWORK = (int) QWORK;
1019 WORK =
new real_t[LWORK];
1020 IWORK =
new int[LIWORK];
1022#ifdef MFEM_USE_SINGLE
1023 ssyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
1024#elif defined MFEM_USE_DOUBLE
1025 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
1027 MFEM_ABORT(
"Floating point type undefined");
1029 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
1030 IWORK, &LIWORK, &INFO );
1034 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: "
1042 mfem::err <<
"dsyevr_Eigensystem(...):\n"
1043 <<
" DSYEVR did not find all eigenvalues "
1044 << M <<
"/" << N << endl;
1049 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
1053 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
1056 for (IL = 0; IL < N; IL++)
1057 for (IU = 0; IU <= IL; IU++)
1060 for (M = 0; M < N; M++)
1062 VL += Z[M+IL*N] * Z[M+IU*N];
1079 <<
" Z^t Z - I deviation = " << VU
1080 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1081 << W[0] <<
", N = " << N << endl;
1088 <<
" Z^t Z - I deviation = " << VU
1089 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1090 << W[0] <<
", N = " << N << endl;
1094 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1097 for (IL = 0; IL < N; IL++)
1098 for (IU = 0; IU < N; IU++)
1101 for (M = 0; M < N; M++)
1103 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
1105 VL = fabs(VL-data[IL+N*IU]);
1114 <<
" max matrix deviation = " << VU
1115 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1116 << W[0] <<
", N = " << N << endl;
1120 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1129 MFEM_CONTRACT_VAR(
a);
1130 MFEM_CONTRACT_VAR(ev);
1131 MFEM_CONTRACT_VAR(evect);
1137#ifdef MFEM_USE_LAPACK
1163 int hw =
a.Height() *
a.Width();
1165 for (
int i = 0; i < hw; i++)
1170#ifdef MFEM_USE_SINGLE
1171 ssyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1172#elif defined MFEM_USE_DOUBLE
1173 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1175 MFEM_ABORT(
"Floating point type undefined");
1178 LWORK = (int) QWORK;
1179 WORK =
new real_t[LWORK];
1181#ifdef MFEM_USE_SINGLE
1182 ssyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1183#elif defined MFEM_USE_DOUBLE
1184 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1186 MFEM_ABORT(
"Floating point type undefined");
1191 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1196 if (evect == NULL) {
delete [] A; }
1198 MFEM_CONTRACT_VAR(
a);
1199 MFEM_CONTRACT_VAR(ev);
1200 MFEM_CONTRACT_VAR(evect);
1204void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1206#ifdef MFEM_USE_LAPACK
1214 MFEM_CONTRACT_VAR(ev);
1215 MFEM_CONTRACT_VAR(evect);
1216 mfem_error(
"DenseMatrix::Eigensystem: Compiled without LAPACK");
1224#ifdef MFEM_USE_LAPACK
1253 int hw =
a.Height() *
a.Width();
1256 for (
int i = 0; i < hw; i++)
1262#ifdef MFEM_USE_SINGLE
1263 ssygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1264#elif defined MFEM_USE_DOUBLE
1265 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1267 MFEM_ABORT(
"Floating point type undefined");
1270 LWORK = (int) QWORK;
1271 WORK =
new real_t[LWORK];
1273#ifdef MFEM_USE_SINGLE
1274 ssygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1275#elif defined MFEM_USE_DOUBLE
1276 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1278 MFEM_ABORT(
"Floating point type undefined");
1283 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1289 if (evect == NULL) {
delete [] A; }
1291 MFEM_CONTRACT_VAR(
a);
1292 MFEM_CONTRACT_VAR(
b);
1293 MFEM_CONTRACT_VAR(ev);
1294 MFEM_CONTRACT_VAR(evect);
1298void DenseMatrix::Eigensystem(DenseMatrix &
b, Vector &ev,
1301#ifdef MFEM_USE_LAPACK
1306 MFEM_CONTRACT_VAR(
b);
1307 MFEM_CONTRACT_VAR(ev);
1308 MFEM_CONTRACT_VAR(evect);
1309 mfem_error(
"DenseMatrix::Eigensystem(generalized): Compiled without LAPACK");
1315#ifdef MFEM_USE_LAPACK
1321 real_t *
a = copy_of_this.data;
1331#ifdef MFEM_USE_SINGLE
1332 sgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1333#elif defined MFEM_USE_DOUBLE
1334 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1336 MFEM_ABORT(
"Floating point type undefined");
1338 s,
u, &m, vt, &n, &qwork, &lwork, &info);
1340 lwork = (int) qwork;
1341 work =
new real_t[lwork];
1343#ifdef MFEM_USE_SINGLE
1344 sgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1345#elif defined MFEM_USE_DOUBLE
1346 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1348 MFEM_ABORT(
"Floating point type undefined");
1350 s,
u, &m, vt, &n, work, &lwork, &info);
1355 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1359 MFEM_CONTRACT_VAR(sv);
1361 mfem_error(
"DenseMatrix::SingularValues: Compiled without LAPACK");
1371 for (
int i=0; i < sv.
Size(); ++i)
1383 "The matrix must be square and sized 1, 2, or 3 to compute the"
1385 <<
" Height() = " <<
Height()
1386 <<
", Width() = " <<
Width());
1433 const real_t* rp = data + r;
1436 for (
int i = 0; i < n; i++)
1451 for (
int i = 0; i < m; i++)
1465 for (
int i = 0; i <
height; ++i)
1467 d(i) = (*this)(i,i);
1481 for (
int j = 0; j <
width; ++j)
1482 for (
int i = 0; i <
height; ++i)
1484 l(i) += fabs((*
this)(i,j));
1491 for (
int i = 0; i <
height; i++)
1494 for (
int j = 0; j <
width; j++)
1507 for (
int i = 0; i < N; i++)
1511 for (
int i = 0; i < n; i++)
1522 for (i = 0; i < N; i++)
1526 for (i = 0; i < n; i++)
1528 data[i*(n+1)] = diag[i];
1539 for (i = 0; i <
Height(); i++)
1540 for (j = i+1; j <
Width(); j++)
1543 (*this)(i,j) = (*
this)(j,i);
1558 for (
int i = 0; i <
Height(); i++)
1559 for (
int j = 0; j <
Width(); j++)
1561 (*this)(i,j) = A(j,i);
1570 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1578 for (
int i = 0; i <
Height(); i++)
1581 for (
int j = 0; j <
Width(); j++)
1584 (*this)(i, j) = 0.0;
1598 mfem_error(
"DenseMatrix::GradToCurl(...): dimension mismatch");
1604 for (
int i = 0; i < n; i++)
1621 for (
int i = 0; i < n; i++)
1651 MFEM_VERIFY(
Width() == 2,
1652 "DenseMatrix::GradToVectorCurl2D(...): dimension must be 2")
1656 for (
int i = 0; i < n; i++)
1658 curl(i,0) = (*this)(i,1);
1659 curl(i,1) = -(*this)(i,0);
1665 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1672 for (
int i = 0; i < n; i++)
1682 for (
int j = 0; j <
Width(); j++)
1684 for (
int i = row1; i <= row2; i++)
1686 (*this)(i-row1,j) = A(i,j);
1695 for (
int j = col1; j <= col2; j++)
1697 for (
int i = 0; i <
Height(); i++)
1699 (*this)(i,j-col1) = A(i,j);
1708 for (
int j = 0; j < n; j++)
1710 for (
int i = 0; i < m; i++)
1712 (*this)(i,j) = A(Aro+i,Aco+j);
1721 for (
int j = 0; j < A.
Width(); j++)
1723 for (
int i = 0; i < A.
Height(); i++)
1725 (*this)(row_offset+i,col_offset+j) = *(v++);
1734 for (
int i = 0; i < A.
Width(); i++)
1736 for (
int j = 0; j < A.
Height(); j++)
1738 (*this)(row_offset+i,col_offset+j) = *(v++);
1744 int row_offset,
int col_offset)
1746 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1747 "this DenseMatrix is too small to accommodate the submatrix. "
1748 <<
"row_offset = " << row_offset
1750 <<
", this->Height() = " << this->
Height()
1751 <<
", col_offset = " << col_offset
1753 <<
", this->Width() = " << this->
Width()
1755 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1756 "The A DenseMatrix is too small to accommodate the submatrix. "
1759 <<
", A.Height() = " << A.
Height()
1760 <<
", Aco = " << Aco
1762 <<
", A.Width() = " << A.
Width()
1765 for (
int j = 0; j < n; j++)
1767 for (
int i = 0; i < m; i++)
1769 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1776 for (
int i = 0; i < n; i++)
1778 for (
int j = i+1; j < n; j++)
1780 (*this)(row_offset+i,col_offset+j) =
1781 (*
this)(row_offset+j,col_offset+i) = 0.0;
1785 for (
int i = 0; i < n; i++)
1787 (*this)(row_offset+i,col_offset+i) = c;
1794 for (
int i = 0; i < n; i++)
1796 for (
int j = i+1; j < n; j++)
1798 (*this)(row_offset+i,col_offset+j) =
1799 (*
this)(row_offset+j,col_offset+i) = 0.0;
1803 for (
int i = 0; i < n; i++)
1805 (*this)(row_offset+i,col_offset+i) = diag[i];
1813 int i, j, i_off = 0, j_off = 0;
1815 for (j = 0; j < A.
Width(); j++)
1822 for (i = 0; i < A.
Height(); i++)
1829 (*this)(i-i_off,j-j_off) = A(i,j);
1845 if (co+aw >
Width() || ro+ah > h)
1847 mfem_error(
"DenseMatrix::AddMatrix(...) 1 : dimension mismatch");
1851 p = data + ro + co * h;
1854 for (
int c = 0; c < aw; c++)
1856 for (
int r = 0; r < ah; r++)
1875 if (co+aw >
Width() || ro+ah > h)
1877 mfem_error(
"DenseMatrix::AddMatrix(...) 2 : dimension mismatch");
1881 p = data + ro + co * h;
1884 for (
int c = 0; c < aw; c++)
1886 for (
int r = 0; r < ah; r++)
1898 int idx_max = idx.
Max();
1899 MFEM_VERIFY(idx.
Min() >=0 && idx_max < this->
height && idx_max < this->
width,
1900 "DenseMatrix::GetSubMatrix: Index out of bounds");
1905 for (
int i = 0; i<k; i++)
1908 for (
int j = 0; j<k; j++)
1911 adata[i+j*k] = this->data[ii+jj*
height];
1919 int k = idx_i.
Size();
1920 int l = idx_j.
Size();
1922 MFEM_VERIFY(idx_i.
Min() >=0 && idx_i.
Max() < this->height,
1923 "DenseMatrix::GetSubMatrix: Row index out of bounds");
1924 MFEM_VERIFY(idx_j.
Min() >=0 && idx_j.
Max() < this->width,
1925 "DenseMatrix::GetSubMatrix: Col index out of bounds");
1931 for (
int i = 0; i<k; i++)
1934 for (
int j = 0; j<l; j++)
1937 adata[i+j*k] = this->data[ii+jj*
height];
1944 MFEM_VERIFY(iend >= ibeg,
"DenseMatrix::GetSubMatrix: Inconsistent range");
1945 MFEM_VERIFY(ibeg >=0,
1946 "DenseMatrix::GetSubMatrix: Negative index");
1947 MFEM_VERIFY(iend <= this->
height && iend <= this->
width,
1948 "DenseMatrix::GetSubMatrix: Index bigger than upper bound");
1950 int k = iend - ibeg;
1955 for (
int i = 0; i<k; i++)
1958 for (
int j = 0; j<k; j++)
1961 adata[i+j*k] = this->data[ii+jj*
height];
1969 MFEM_VERIFY(iend >= ibeg,
1970 "DenseMatrix::GetSubMatrix: Inconsistent row range");
1971 MFEM_VERIFY(jend >= jbeg,
1972 "DenseMatrix::GetSubMatrix: Inconsistent col range");
1973 MFEM_VERIFY(ibeg >=0,
1974 "DenseMatrix::GetSubMatrix: Negative row index");
1975 MFEM_VERIFY(jbeg >=0,
1976 "DenseMatrix::GetSubMatrix: Negative row index");
1977 MFEM_VERIFY(iend <= this->
height,
1978 "DenseMatrix::GetSubMatrix: Index bigger than row upper bound");
1979 MFEM_VERIFY(jend <= this->
width,
1980 "DenseMatrix::GetSubMatrix: Index bigger than col upper bound");
1982 int k = iend - ibeg;
1983 int l = jend - jbeg;
1988 for (
int i = 0; i<k; i++)
1991 for (
int j = 0; j<l; j++)
1994 adata[i+j*k] = this->data[ii+jj*
height];
2003 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
2005 int idx_max = idx.
Max();
2007 MFEM_VERIFY(idx.
Min() >=0,
2008 "DenseMatrix::SetSubMatrix: Negative index");
2009 MFEM_VERIFY(idx_max < this->
height,
2010 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
2011 MFEM_VERIFY(idx_max < this->
width,
2012 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
2017 for (
int i = 0; i<k; i++)
2020 for (
int j = 0; j<k; j++)
2023 this->data[ii+jj*
height] = adata[i+j*k];
2031 int k = idx_i.
Size();
2032 int l = idx_j.
Size();
2034 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
2035 MFEM_VERIFY(idx_i.
Min() >=0,
2036 "DenseMatrix::SetSubMatrix: Negative row index");
2037 MFEM_VERIFY(idx_j.
Min() >=0,
2038 "DenseMatrix::SetSubMatrix: Negative col index");
2039 MFEM_VERIFY(idx_i.
Max() < this->height,
2040 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
2041 MFEM_VERIFY(idx_j.
Max() < this->width,
2042 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
2047 for (
int i = 0; i<k; i++)
2050 for (
int j = 0; j<l; j++)
2053 this->data[ii+jj*
height] = adata[i+j*k];
2062 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::SetSubmatrix: A is not square");
2063 MFEM_VERIFY(ibeg >=0,
2064 "DenseMatrix::SetSubmatrix: Negative index");
2065 MFEM_VERIFY(ibeg + k <= this->
height,
2066 "DenseMatrix::SetSubmatrix: index bigger than row upper bound");
2067 MFEM_VERIFY(ibeg + k <= this->
width,
2068 "DenseMatrix::SetSubmatrix: index bigger than col upper bound");
2073 for (
int i = 0; i<k; i++)
2076 for (
int j = 0; j<k; j++)
2079 this->data[ii+jj*
height] = adata[i+j*k];
2089 MFEM_VERIFY(ibeg>=0,
2090 "DenseMatrix::SetSubmatrix: Negative row index");
2091 MFEM_VERIFY(jbeg>=0,
2092 "DenseMatrix::SetSubmatrix: Negative col index");
2093 MFEM_VERIFY(ibeg + k <= this->
height,
2094 "DenseMatrix::SetSubmatrix: Index bigger than row upper bound");
2095 MFEM_VERIFY(jbeg + l <= this->
width,
2096 "DenseMatrix::SetSubmatrix: Index bigger than col upper bound");
2101 for (
int i = 0; i<k; i++)
2104 for (
int j = 0; j<l; j++)
2107 this->data[ii+jj*
height] = adata[i+j*k];
2116 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2118 int idx_max = idx.
Max();
2120 MFEM_VERIFY(idx.
Min() >=0,
"DenseMatrix::AddSubMatrix: Negative index");
2121 MFEM_VERIFY(idx_max < this->
height,
2122 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2123 MFEM_VERIFY(idx_max < this->
width,
2124 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2129 for (
int i = 0; i<k; i++)
2132 for (
int j = 0; j<k; j++)
2135 this->data[ii+jj*
height] += adata[i+j*k];
2143 int k = idx_i.
Size();
2144 int l = idx_j.
Size();
2146 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2148 MFEM_VERIFY(idx_i.
Min() >=0,
2149 "DenseMatrix::AddSubMatrix: Negative row index");
2150 MFEM_VERIFY(idx_j.
Min() >=0,
2151 "DenseMatrix::AddSubMatrix: Negative col index");
2152 MFEM_VERIFY(idx_i.
Max() < this->height,
2153 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2154 MFEM_VERIFY(idx_j.
Max() < this->width,
2155 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2160 for (
int i = 0; i<k; i++)
2163 for (
int j = 0; j<l; j++)
2166 this->data[ii+jj*
height] += adata[i+j*k];
2174 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::AddSubmatrix: A is not square");
2176 MFEM_VERIFY(ibeg>=0,
2177 "DenseMatrix::AddSubmatrix: Negative index");
2178 MFEM_VERIFY(ibeg + k <= this->
Height(),
2179 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2180 MFEM_VERIFY(ibeg + k <= this->
Width(),
2181 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2186 for (
int i = 0; i<k; i++)
2189 for (
int j = 0; j<k; j++)
2192 this->data[ii+jj*
height] += adata[i+j*k];
2202 MFEM_VERIFY(ibeg>=0,
2203 "DenseMatrix::AddSubmatrix: Negative row index");
2204 MFEM_VERIFY(jbeg>=0,
2205 "DenseMatrix::AddSubmatrix: Negative col index");
2206 MFEM_VERIFY(ibeg + k <= this->
height,
2207 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2208 MFEM_VERIFY(jbeg + l <= this->
width,
2209 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2214 for (
int i = 0; i<k; i++)
2217 for (
int j = 0; j<l; j++)
2220 this->data[ii+jj*
height] += adata[i+j*k];
2230 for (
int i = 0; i < n; i++)
2232 vdata[i] += data[i];
2241 for (
int i = 0; i < n; i++)
2254 mfem_error(
"DenseMatrix::AdjustDofDirection(...): dimension mismatch");
2259 for (
int i = 0; i < n-1; i++)
2261 const int s = (dof[i] < 0) ? (-1) : (1);
2262 for (
int j = i+1; j < n; j++)
2264 const int t = (dof[j] < 0) ? (-
s) : (
s);
2267 (*this)(i,j) = -(*
this)(i,j);
2268 (*this)(j,i) = -(*
this)(j,i);
2276 for (
int j = 0; j <
Width(); j++)
2278 (*this)(row, j) = value;
2284 for (
int i = 0; i <
Height(); i++)
2286 (*this)(i, col) = value;
2292 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
2293 for (
int j = 0; j <
Width(); j++)
2295 (*this)(r, j) = row[j];
2307 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
2308 for (
int i = 0; i <
Height(); i++)
2310 (*this)(i, c) = col[i];
2322 for (
int col = 0; col <
Width(); col++)
2324 for (
int row = 0; row <
Height(); row++)
2326 if (std::abs(
operator()(row,col)) <= eps)
2337 ios::fmtflags old_flags = os.flags();
2339 os << setiosflags(ios::scientific | ios::showpos);
2340 for (
int i = 0; i <
height; i++)
2342 os <<
"[row " << i <<
"]\n";
2343 for (
int j = 0; j <
width; j++)
2346 if (j+1 ==
width || (j+1) % width_ == 0)
2357 os.flags(old_flags);
2363 ios::fmtflags old_flags = os.flags();
2365 os << setiosflags(ios::scientific | ios::showpos);
2366 for (
int i = 0; i <
height; i++)
2368 for (
int j = 0; j <
width; j++)
2376 os.flags(old_flags);
2382 ios::fmtflags old_flags = os.flags();
2384 os << setiosflags(ios::scientific | ios::showpos);
2385 for (
int j = 0; j <
width; j++)
2387 os <<
"[col " << j <<
"]\n";
2388 for (
int i = 0; i <
height; i++)
2391 if (i+1 ==
height || (i+1) % width_ == 0)
2402 os.flags(old_flags);
2411 for (
int i = 0; i <
width; i++)
2416 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2457 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
2458 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
2459 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
2468 if (std::abs(det) <= TOL) {
return false; }
2476 if (std::abs(det) <= TOL) {
return false; }
2478 real_t invdet = 1. / det;
2483 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
2484 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
2493 if (!lu.
Factor(N,TOL)) {
return false; }
2505 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2506 b.Width() == c.
Height(),
"incompatible dimensions");
2508#ifdef MFEM_USE_LAPACK
2509 static char transa =
'N', transb =
'N';
2511 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2513#ifdef MFEM_USE_SINGLE
2514 sgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2515#elif defined MFEM_USE_DOUBLE
2516 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2518 MFEM_ABORT(
"Floating point type undefined");
2522 const int ah =
a.Height();
2523 const int aw =
a.Width();
2524 const int bw =
b.Width();
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#ifdef MFEM_USE_SINGLE
2544 sgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2545#elif defined MFEM_USE_DOUBLE
2546 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2548 MFEM_ABORT(
"Floating point type undefined");
2552 const int ah =
a.Height();
2553 const int aw =
a.Width();
2554 const int bw =
b.Width();
2558 for (
int j = 0; j < aw; j++)
2560 for (
int k = 0; k < bw; k++)
2562 for (
int i = 0; i < ah; i++)
2564 ad[i+j*ah] +=
alpha * bd[i+k*ah] * cd[k+j*bw];
2573 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2574 b.Width() == c.
Height(),
"incompatible dimensions");
2576#ifdef MFEM_USE_LAPACK
2577 static char transa =
'N', transb =
'N';
2579 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2581#ifdef MFEM_USE_SINGLE
2582 sgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2583#elif defined MFEM_USE_DOUBLE
2584 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2588 const int ah =
a.Height();
2589 const int aw =
a.Width();
2590 const int bw =
b.Width();
2594 for (
int j = 0; j < aw; j++)
2596 for (
int k = 0; k < bw; k++)
2598 for (
int i = 0; i < ah; i++)
2600 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2610 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
2612 mfem_error(
"CalcAdjugate(...): unsupported dimensions");
2614 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
2616 mfem_error(
"CalcAdjugate(...): dimension mismatch");
2620 if (
a.Width() <
a.Height())
2629 if (
a.Height() == 3)
2638 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2639 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2640 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2642 ad[0] = d[0]*g - d[3]*
f;
2643 ad[1] = d[3]*e - d[0]*
f;
2644 ad[2] = d[1]*g - d[4]*
f;
2645 ad[3] = d[4]*e - d[1]*
f;
2646 ad[4] = d[2]*g - d[5]*
f;
2647 ad[5] = d[5]*e - d[2]*
f;
2656 else if (
a.Width() == 2)
2659 adja(0,1) = -
a(0,1);
2660 adja(1,0) = -
a(1,0);
2665 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2666 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2667 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2669 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2670 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2671 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2673 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2674 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2675 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2682 if (
a.Height() !=
a.Width() || adjat.
Height() != adjat.
Width() ||
2683 a.Width() != adjat.
Width() ||
a.Width() < 1 ||
a.Width() > 3)
2685 mfem_error(
"CalcAdjugateTranspose(...): dimension mismatch");
2692 else if (
a.Width() == 2)
2694 adjat(0,0) =
a(1,1);
2695 adjat(1,0) = -
a(0,1);
2696 adjat(0,1) = -
a(1,0);
2697 adjat(1,1) =
a(0,0);
2701 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2702 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2703 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2705 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2706 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2707 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2709 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2710 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2711 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2717 MFEM_ASSERT(
a.Width() <=
a.Height() &&
a.Width() >= 1 &&
a.Height() <= 3,
"");
2718 MFEM_ASSERT(inva.
Height() ==
a.Width(),
"incorrect dimensions");
2719 MFEM_ASSERT(inva.
Width() ==
a.Height(),
"incorrect dimensions");
2721 if (
a.Width() <
a.Height())
2725 if (
a.Height() == 2)
2745 MFEM_ASSERT(std::abs(
t) > 1.0e-14 * pow(
a.FNorm()/
a.Width(),
a.Width()),
2746 "singular matrix!");
2752 inva(0,0) = 1.0 /
a.
Det();
2766 if ( (
a.Width() !=
a.Height()) || ( (
a.Height()!= 1) && (
a.Height()!= 2)
2767 && (
a.Height()!= 3) ) )
2769 mfem_error(
"CalcInverseTranspose(...): dimension mismatch");
2778 inva(0,0) = 1.0 /
a(0,0);
2781 inva(0,0) =
a(1,1) *
t ;
2782 inva(1,0) = -
a(0,1) *
t ;
2783 inva(0,1) = -
a(1,0) *
t ;
2784 inva(1,1) =
a(0,0) *
t ;
2787 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*
t;
2788 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*
t;
2789 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*
t;
2791 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*
t;
2792 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*
t;
2793 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*
t;
2795 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*
t;
2796 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*
t;
2797 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*
t;
2807 "Matrix must be 3x2 or 2x1, "
2808 <<
"and the Vector must be sized with the rows. "
2809 <<
" J.Height() = " << J.
Height()
2810 <<
", J.Width() = " << J.
Width()
2811 <<
", n.Size() = " << n.
Size()
2822 n(0) = d[1]*d[5] - d[2]*d[4];
2823 n(1) = d[2]*d[3] - d[0]*d[5];
2824 n(2) = d[0]*d[4] - d[1]*d[3];
2830 const int height =
a.Height();
2831 const int width =
a.Width();
2832 for (
int i = 0; i < height; i++)
2834 for (
int j = 0; j <= i; j++)
2837 for (
int k = 0; k < width; k++)
2839 temp +=
a(i,k) *
a(j,k);
2841 aat(j,i) = aat(i,j) = temp;
2848 for (
int i = 0; i < A.
Height(); i++)
2850 for (
int j = 0; j < i; j++)
2853 for (
int k = 0; k < A.
Width(); k++)
2855 t += D(k) * A(i, k) * A(j, k);
2863 for (
int i = 0; i < A.
Height(); i++)
2866 for (
int k = 0; k < A.
Width(); k++)
2868 t += D(k) * A(i, k) * A(i, k);
2876 for (
int i = 0; i < A.
Height(); i++)
2878 for (
int j = 0; j <= i; j++)
2881 for (
int k = 0; k < A.
Width(); k++)
2883 t += D(k) * A(i, k) * A(j, k);
2885 ADAt(j, i) = ADAt(i, j) =
t;
2896 mfem_error(
"MultABt(...): dimension mismatch");
2900#ifdef MFEM_USE_LAPACK
2901 static char transa =
'N', transb =
'T';
2905#ifdef MFEM_USE_SINGLE
2907#elif defined MFEM_USE_DOUBLE
2912 const int ah = A.
Height();
2913 const int bh = B.
Height();
2914 const int aw = A.
Width();
2921 const int ah = A.
Height();
2922 const int bh = B.
Height();
2923 const int aw = A.
Width();
2928 for (
int j = 0; j < bh; j++)
2929 for (
int i = 0; i < ah; i++)
2932 const real_t *ap = ad + i;
2933 const real_t *bp = bd + j;
2934 for (
int k = 0; k < aw; k++)
2946 for (i = 0; i < A.
Height(); i++)
2947 for (j = 0; j < B.
Height(); j++)
2950 for (k = 0; k < A.
Width(); k++)
2952 d += A(i, k) * B(j, k);
2966 mfem_error(
"MultADBt(...): dimension mismatch");
2970 const int ah = A.
Height();
2971 const int bh = B.
Height();
2972 const int aw = A.
Width();
2978 for (
int i = 0,
s = ah*bh; i <
s; i++)
2982 for (
int k = 0; k < aw; k++)
2985 for (
int j = 0; j < bh; j++)
2987 const real_t dk_bjk = dd[k] * bd[j];
2988 for (
int i = 0; i < ah; i++)
2990 cp[i] += ad[i] * dk_bjk;
3005 mfem_error(
"AddMultABt(...): dimension mismatch");
3009#ifdef MFEM_USE_LAPACK
3010 static char transa =
'N', transb =
'T';
3014#ifdef MFEM_USE_SINGLE
3016#elif defined MFEM_USE_DOUBLE
3021 const int ah = A.
Height();
3022 const int bh = B.
Height();
3023 const int aw = A.
Width();
3028 for (
int k = 0; k < aw; k++)
3031 for (
int j = 0; j < bh; j++)
3033 const real_t bjk = bd[j];
3034 for (
int i = 0; i < ah; i++)
3036 cp[i] += ad[i] * bjk;
3047 for (i = 0; i < A.
Height(); i++)
3048 for (j = 0; j < B.
Height(); j++)
3051 for (k = 0; k < A.
Width(); k++)
3053 d += A(i, k) * B(j, k);
3067 mfem_error(
"AddMultADBt(...): dimension mismatch");
3071 const int ah = A.
Height();
3072 const int bh = B.
Height();
3073 const int aw = A.
Width();
3079 for (
int k = 0; k < aw; k++)
3082 for (
int j = 0; j < bh; j++)
3084 const real_t dk_bjk = dd[k] * bd[j];
3085 for (
int i = 0; i < ah; i++)
3087 cp[i] += ad[i] * dk_bjk;
3103 mfem_error(
"AddMult_a_ABt(...): dimension mismatch");
3107#ifdef MFEM_USE_LAPACK
3108 static char transa =
'N', transb =
'T';
3113#ifdef MFEM_USE_SINGLE
3115#elif defined MFEM_USE_DOUBLE
3120 const int ah = A.
Height();
3121 const int bh = B.
Height();
3122 const int aw = A.
Width();
3127 for (
int k = 0; k < aw; k++)
3130 for (
int j = 0; j < bh; j++)
3133 for (
int i = 0; i < ah; i++)
3135 cp[i] += ad[i] * bjk;
3146 for (i = 0; i < A.
Height(); i++)
3147 for (j = 0; j < B.
Height(); j++)
3150 for (k = 0; k < A.
Width(); k++)
3152 d += A(i, k) * B(j, k);
3165 mfem_error(
"MultAtB(...): dimension mismatch");
3169#ifdef MFEM_USE_LAPACK
3170 static char transa =
'T', transb =
'N';
3174#ifdef MFEM_USE_SINGLE
3176#elif defined MFEM_USE_DOUBLE
3181 const int ah = A.
Height();
3182 const int aw = A.
Width();
3183 const int bw = B.
Width();
3188 for (
int j = 0; j < bw; j++)
3191 for (
int i = 0; i < aw; i++)
3194 for (
int k = 0; k < ah; k++)
3207 for (i = 0; i < A.
Width(); i++)
3208 for (j = 0; j < B.
Width(); j++)
3211 for (k = 0; k < A.
Height(); k++)
3213 d += A(k, i) * B(k, j);
3226#ifdef MFEM_USE_LAPACK
3227 static char transa =
'T', transb =
'N';
3231#ifdef MFEM_USE_SINGLE
3233#elif defined MFEM_USE_DOUBLE
3238 const int ah = A.
Height();
3239 const int aw = A.
Width();
3240 const int bw = B.
Width();
3245 for (
int j = 0; j < bw; j++)
3248 for (
int i = 0; i < aw; i++)
3251 for (
int k = 0; k < ah; k++)
3269#ifdef MFEM_USE_LAPACK
3270 static char transa =
'T', transb =
'N';
3275#ifdef MFEM_USE_SINGLE
3277#elif defined MFEM_USE_DOUBLE
3282 const int ah = A.
Height();
3283 const int aw = A.
Width();
3284 const int bw = B.
Width();
3289 for (
int j = 0; j < bw; j++)
3292 for (
int i = 0; i < aw; i++)
3295 for (
int k = 0; k < ah; k++)
3311 for (
int i = 0; i < A.
Height(); i++)
3313 for (
int j = 0; j < i; j++)
3316 for (
int k = 0; k < A.
Width(); k++)
3318 d += A(i,k) * A(j,k);
3320 AAt(i, j) += (d *=
a);
3324 for (
int k = 0; k < A.
Width(); k++)
3326 d += A(i,k) * A(i,k);
3334 for (
int i = 0; i < A.
Height(); i++)
3336 for (
int j = 0; j <= i; j++)
3339 for (
int k = 0; k < A.
Width(); k++)
3341 d += A(i,k) * A(j,k);
3343 AAt(i, j) = AAt(j, i) =
a * d;
3350 for (
int i = 0; i < v.
Size(); i++)
3352 for (
int j = 0; j <= i; j++)
3354 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3364 mfem_error(
"MultVWt(...): dimension mismatch");
3368 for (
int i = 0; i < v.
Size(); i++)
3371 for (
int j = 0; j < w.
Size(); j++)
3373 VWt(i, j) = vi * w(j);
3380 const int m = v.
Size(), n = w.
Size();
3385 mfem_error(
"AddMultVWt(...): dimension mismatch");
3389 for (
int i = 0; i < m; i++)
3392 for (
int j = 0; j < n; j++)
3394 VWt(i, j) += vi * w(j);
3401 const int n = v.
Size();
3406 mfem_error(
"AddMultVVt(...): dimension mismatch");
3410 for (
int i = 0; i < n; i++)
3413 for (
int j = 0; j < i; j++)
3415 const real_t vivj = vi * v(j);
3419 VVt(i, i) += vi * vi;
3426 const int m = v.
Size(), n = w.
Size();
3431 mfem_error(
"AddMult_a_VWt(...): dimension mismatch");
3435 for (
int j = 0; j < n; j++)
3438 for (
int i = 0; i < m; i++)
3440 VWt(i, j) += v(i) * awj;
3448 "incompatible dimensions!");
3450 const int n = v.
Size();
3451 for (
int i = 0; i < n; i++)
3454 for (
int j = 0; j < i; j++)
3456 const real_t avivj = avi * v(j);
3460 VVt(i, i) += avi * v(i);
3483#ifdef MFEM_USE_LAPACK
3485#ifdef MFEM_USE_SINGLE
3487#elif defined MFEM_USE_DOUBLE
3490 MFEM_ABORT(
"Floating point type undefined");
3496 for (
int i = 0; i < m; i++)
3501 real_t a = std::abs(data_ptr[piv+i*m]);
3502 for (
int j = i+1; j < m; j++)
3504 const real_t b = std::abs(data_ptr[j+i*m]);
3515 for (
int j = 0; j < m; j++)
3522 if (abs(data_ptr[i + i*m]) <= TOL)
3527 const real_t a_ii_inv = 1.0 / data_ptr[i+i*m];
3528 for (
int j = i+1; j < m; j++)
3530 data_ptr[j+i*m] *= a_ii_inv;
3532 for (
int k = i+1; k < m; k++)
3534 const real_t a_ik = data_ptr[i+k*m];
3535 for (
int j = i+1; j < m; j++)
3537 data_ptr[j+k*m] -= a_ik * data_ptr[j+i*m];
3549 for (
int i=0; i<m; i++)
3553 det *= -
data[m * i + i];
3557 det *=
data[m * i + i];
3566 for (
int k = 0; k < n; k++)
3569 for (
int i = 0; i < m; i++)
3572 for (
int j = i+1; j < m; j++)
3574 x_i += x[j] *
data[i+j*m];
3579 for (
int i = m-1; i >= 0; i--)
3582 for (
int j = 0; j < i; j++)
3584 x_i += x[j] *
data[i+j*m];
3589 for (
int i = m-1; i >= 0; i--)
3600 for (
int k = 0; k < n; k++)
3603 for (
int i = 0; i < m; i++)
3608 for (
int j = 0; j < m; j++)
3611 for (
int i = j+1; i < m; i++)
3613 x[i] -=
data[i+j*m] * x_j;
3624 for (
int k = 0; k < n; k++)
3626 for (
int j = m-1; j >= 0; j--)
3629 for (
int i = 0; i < j; i++)
3631 x[i] -=
data[i+j*m] * x_j;
3640#ifdef MFEM_USE_LAPACK
3643#ifdef MFEM_USE_SINGLE
3645#elif defined MFEM_USE_DOUBLE
3648 MFEM_ABORT(
"Floating point type undefined");
3650 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3661#ifdef MFEM_USE_LAPACK
3662 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3666#ifdef MFEM_USE_SINGLE
3667 strsm_(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3668 strsm_(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3669#elif defined MFEM_USE_DOUBLE
3670 dtrsm_(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3671 dtrsm_(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3673 MFEM_ABORT(
"Floating point type undefined");
3680 for (
int k = 0; k < n; k++)
3682 for (
int j = 0; j < m; j++)
3685 for (
int i = j+1; i < m; i++)
3687 x[i*n] -=
data[j + i*m] * x_j;
3695 for (
int k = 0; k < n; k++)
3697 for (
int j = m-1; j >= 0; j--)
3699 const real_t x_j = x[j*n];
3700 for (
int i = 0; i < j; i++)
3702 x[i*n] -=
data[j + i*m] * x_j;
3710 for (
int k = 0; k < n; k++)
3712 for (
int i = m-1; i >= 0; --i)
3725 for (
int k = 0; k < m; k++)
3727 const real_t minus_x_k = -( x[k] = 1.0/
data[k+k*m] );
3728 for (
int i = 0; i < k; i++)
3730 x[i] =
data[i+k*m] * minus_x_k;
3732 for (
int j = k-1; j >= 0; j--)
3735 for (
int i = 0; i < j; i++)
3737 x[i] -=
data[i+j*m] * x_j;
3745 for (
int j = 0; j < k; j++)
3748 for (
int i = 0; i <= j; i++)
3750 X[i+j*m] += X[i+k*m] * minus_L_kj;
3752 for (
int i = j+1; i < m; i++)
3754 X[i+j*m] = X[i+k*m] * minus_L_kj;
3758 for (
int k = m-2; k >= 0; k--)
3760 for (
int j = 0; j < k; j++)
3763 for (
int i = 0; i < m; i++)
3765 X[i+j*m] -= X[i+k*m] * L_kj;
3770 for (
int k = m-1; k >= 0; k--)
3775 for (
int i = 0; i < m; i++)
3787 for (
int k = 0; k < r; k++)
3789 for (
int j = 0; j < m; j++)
3791 const real_t x1_jk = X1[j+k*m];
3792 for (
int i = 0; i < n; i++)
3794 X2[i+k*n] -= A21[i+j*n] * x1_jk;
3806 for (
int j = 0; j < m; j++)
3809 for (
int i = 0; i < n; i++)
3811 A21[i+j*n] *= u_jj_inv;
3813 for (
int k = j+1; k < m; k++)
3816 for (
int i = 0; i < n; i++)
3818 A21[i+k*n] -= A21[i+j*n] * u_jk;
3823 SubMult(m, n, n, A21, A12, A22);
3832 SubMult(m, n, r, L21, B1, B2);
3839 SubMult(n, m, r, U12, X2, Y1);
3847#ifdef MFEM_USE_LAPACK
3850 MFEM_VERIFY(
data,
"Matrix data not set");
3851#ifdef MFEM_USE_SINGLE
3853#elif defined MFEM_USE_DOUBLE
3856 MFEM_ABORT(
"Floating point type undefined");
3861 for (
int j = 0; j<m; j++)
3864 for (
int k = 0; k<j; k++)
3869 MFEM_VERIFY(
data[j+j*m] -
a > 0.,
3870 "CholeskyFactors::Factor: The matrix is not SPD");
3872 data[j+j*m] = std::sqrt(
data[j+j*m] -
a);
3874 if (
data[j + j*m] <= TOL)
3879 for (
int i = j+1; i<m; i++)
3882 for (
int k = 0; k<j; k++)
3896 for (
int i=0; i<m; i++)
3898 det *=
data[i + i*m];
3907 for (
int k = 0; k < n; k++)
3909 for (
int j = m-1; j >= 0; j--)
3912 for (
int i = 0; i < j; i++)
3914 x_j += x[i] *
data[j+i*m];
3925 for (
int k = 0; k < n; k++)
3927 for (
int i = 0; i < m; i++)
3930 for (
int j = i+1; j < m; j++)
3932 x_i += x[j] *
data[j+i*m];
3943#ifdef MFEM_USE_LAPACK
3949#ifdef MFEM_USE_SINGLE
3951#elif defined MFEM_USE_DOUBLE
3954 MFEM_ABORT(
"Floating point type undefined");
3956 MFEM_VERIFY(!info,
"CholeskyFactors:LSolve:: info");
3960 for (
int k = 0; k < n; k++)
3963 for (
int j = 0; j < m; j++)
3966 for (
int i = j+1; i < m; i++)
3968 x[i] -=
data[i+j*m] * x_j;
3978#ifdef MFEM_USE_LAPACK
3985#ifdef MFEM_USE_SINGLE
3987#elif defined MFEM_USE_DOUBLE
3990 MFEM_ABORT(
"Floating point type undefined");
3992 MFEM_VERIFY(!info,
"CholeskyFactors:USolve:: info");
3997 for (
int k = 0; k < n; k++)
3999 for (
int j = m-1; j >= 0; j--)
4002 for (
int i = 0; i < j; i++)
4004 x[i] -=
data[j+i*m] * x_j;
4014#ifdef MFEM_USE_LAPACK
4017#ifdef MFEM_USE_SINGLE
4019#elif defined MFEM_USE_DOUBLE
4022 MFEM_ABORT(
"Floating point type undefined");
4024 MFEM_VERIFY(!info,
"CholeskyFactors:Solve:: info");
4034#ifdef MFEM_USE_LAPACK
4044#ifdef MFEM_USE_SINGLE
4045 strsm_(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
4046 strsm_(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
4047#elif defined MFEM_USE_DOUBLE
4048 dtrsm_(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
4049 dtrsm_(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
4051 MFEM_ABORT(
"Floating point type undefined");
4057 for (
int k = 0; k < n; k++)
4059 for (
int j = 0; j < m; j++)
4062 for (
int i = j+1; i < m; i++)
4064 x[i*n] -=
data[i + j*m] * x_j;
4071 for (
int k = 0; k < n; k++)
4073 for (
int j = m-1; j >= 0; j--)
4076 for (
int i = 0; i < j; i++)
4078 x[i*n] -=
data[j + i*m] * x_j;
4089#ifdef MFEM_USE_LAPACK
4091 for (
int i = 0; i<m; i++)
4093 for (
int j = i; j<m; j++)
4095 X[j+i*m] =
data[j+i*m];
4100#ifdef MFEM_USE_SINGLE
4101 spotri_(&uplo, &m, X, &m, &info);
4102#elif defined MFEM_USE_DOUBLE
4103 dpotri_(&uplo, &m, X, &m, &info);
4105 MFEM_ABORT(
"Floating point type undefined");
4107 MFEM_VERIFY(!info,
"CholeskyFactors:GetInverseMatrix:: info");
4109 for (
int i = 0; i<m; i++)
4111 for (
int j = i+1; j<m; j++)
4113 X[i+j*m] = X[j+i*m];
4118 for (
int k = 0; k<m; k++)
4120 X[k+k*m] = 1./
data[k+k*m];
4121 for (
int i = k+1; i < m; i++)
4124 for (
int j=k; j<i; j++)
4126 s -=
data[i+j*m] * X[j+k*m]/
data[i+i*m];
4131 for (
int i = 0; i < m; i++)
4133 for (
int j = i; j < m; j++)
4136 for (
int k=j; k<m; k++)
4138 s += X[k+i*m] * X[k+j*m];
4140 X[i+j*m] = X[j+i*m] =
s;
4147void DenseMatrixInverse::Init(
int m)
4155 factors =
new LUFactors();
4162 dynamic_cast<LUFactors *
>(factors)->ipiv =
new int[m];
4171 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4180 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4187 MFEM_ASSERT(a,
"DenseMatrix is not given");
4188 const real_t *adata = a->data;
4190 for (
int i = 0; i <
s; i++)
4192 factors->
data[i] = adata[i];
4205 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
4209 if (own_data) {
delete [] factors->
data; }
4215 if (own_data) {
delete [] lu->
ipiv; }
4227 MFEM_VERIFY(
p != NULL,
"Operator is not a DenseMatrix!");
4233 for (
int row = 0; row <
height; row++)
4256 for (
int i = 0; i <
width; i++)
4267 delete [] factors->
data;
4270 delete []
dynamic_cast<LUFactors *
>(factors)->ipiv;
4276#ifdef MFEM_USE_LAPACK
4290#ifdef MFEM_USE_SINGLE
4292#elif defined MFEM_USE_DOUBLE
4295 MFEM_ABORT(
"Floating point type undefined");
4297 &qwork, &lwork, &info);
4299 lwork = (int) qwork;
4300 work =
new real_t[lwork];
4305 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4310 lwork = other.lwork;
4312 work =
new real_t[lwork];
4318 if (mat.
Width() != n)
4320 mfem_error(
"DenseMatrixEigensystem::Eval(): dimension mismatch");
4325#ifdef MFEM_USE_SINGLE
4327#elif defined MFEM_USE_DOUBLE
4330 MFEM_ABORT(
"Floating point type undefined");
4332 work, &lwork, &info);
4336 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
4350 bool left_eigen_vectors,
4351 bool right_eigen_vectors)
4354 MFEM_VERIFY(A.
Height() == A.
Width(),
"A has to be a square matrix");
4355 MFEM_VERIFY(B.
Height() == B.
Width(),
"B has to be a square matrix");
4357 MFEM_VERIFY(B.
Height() == n,
"A and B dimension mismatch");
4363 if (left_eigen_vectors)
4368 if (right_eigen_vectors)
4381 int nl = max(1,Vl.
Height());
4382 int nr = max(1,Vr.
Height());
4384#ifdef MFEM_USE_SINGLE
4385 sggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4386#elif defined MFEM_USE_DOUBLE
4387 dggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4389 MFEM_ABORT(
"Floating point type undefined");
4391 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4392 &qwork, &lwork, &info);
4394 lwork = (int) qwork;
4395 work =
new real_t[lwork];
4400 int nl = max(1,Vl.
Height());
4401 int nr = max(1,Vr.
Height());
4405#ifdef MFEM_USE_SINGLE
4406 sggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4407#elif defined MFEM_USE_DOUBLE
4408 dggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4410 MFEM_ABORT(
"Floating point type undefined");
4412 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4413 work, &lwork, &info);
4416 mfem::err <<
"DenseMatrixGeneralizedEigensystem::Eval(): DGGEV error code: "
4422 for (
int i = 0; i<n; i++)
4426 evalues_r(i) = alphar[i]/
beta[i];
4427 evalues_i(i) = alphai[i]/
beta[i];
4446 bool left_singular_vectors,
4447 bool right_singular_vectors)
4451 jobu = (left_singular_vectors)?
'S' :
'N';
4452 jobvt = (right_singular_vectors)?
'S' :
'N';
4457 bool left_singular_vectors,
4458 bool right_singular_vectors)
4462 jobu = (left_singular_vectors)?
'S' :
'N';
4463 jobvt = (right_singular_vectors)?
'S' :
'N';
4468 char left_singular_vectors,
4469 char right_singular_vectors)
4473 jobu = left_singular_vectors;
4474 jobvt = right_singular_vectors;
4479 char left_singular_vectors,
4480 char right_singular_vectors)
4484 jobu = left_singular_vectors;
4485 jobvt = right_singular_vectors;
4489void DenseMatrixSVD::Init()
4494#ifdef MFEM_USE_SINGLE
4496#elif defined MFEM_USE_DOUBLE
4499 MFEM_ABORT(
"Floating point type undefined");
4501 NULL, &n, &qwork, &lwork, &info);
4502 lwork = (int) qwork;
4503 work =
new real_t[lwork];
4514 real_t * datau =
nullptr;
4515 real_t * datavt =
nullptr;
4521 else if (jobu ==
'S')
4531 else if (jobvt ==
'S')
4537#ifdef MFEM_USE_SINGLE
4539#elif defined MFEM_USE_DOUBLE
4542 MFEM_ABORT(
"Floating point type undefined");
4544 datavt, &n, work, &lwork, &info);
4548 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4565 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4573 for (
int i = 0; i < ne; i++)
4576 for (
int col = 0; col < n; col++)
4578 x_col = xp[dofs[col]];
4579 for (
int row = 0; row < n; row++)
4581 yp[dofs[row]] += x_col*d_col[row];
4590 for (
int i = 0; i < ne; i++)
4593 x_col = xp[dofs[0]];
4594 for (
int row = 0; row < n; row++)
4596 ye(row) = x_col*d_col[row];
4599 for (
int col = 1; col < n; col++)
4601 x_col = xp[dofs[col]];
4602 for (
int row = 0; row < n; row++)
4604 ye(row) += x_col*d_col[row];
4608 for (
int row = 0; row < n; row++)
4610 yp[dofs[row]] += ye(row);
4619 for (
int i=0; i<
s; i++)
4635 const int m = Mlu.
SizeI();
4636 const int NE = Mlu.
SizeK();
4642 pivot_flag[0] =
true;
4643 bool *d_pivot_flag = pivot_flag.
ReadWrite();
4647 for (
int i = 0; i < m; i++)
4652 real_t a = fabs(data_all(piv,i,e));
4653 for (
int j = i+1; j < m; j++)
4655 const real_t b = fabs(data_all(j,i,e));
4662 ipiv_all(i,e) = piv;
4666 for (
int j = 0; j < m; j++)
4668 mfem::kernels::internal::Swap<real_t>(data_all(i,j,e), data_all(piv,j,e));
4673 if (abs(data_all(i,i,e)) <= TOL)
4675 d_pivot_flag[0] =
false;
4678 const real_t a_ii_inv = 1.0 / data_all(i,i,e);
4679 for (
int j = i+1; j < m; j++)
4681 data_all(j,i,e) *= a_ii_inv;
4684 for (
int k = i+1; k < m; k++)
4686 const real_t a_ik = data_all(i,k,e);
4687 for (
int j = i+1; j < m; j++)
4689 data_all(j,k,e) -= a_ik * data_all(j,i,e);
4697 MFEM_ASSERT(pivot_flag.
HostRead()[0],
"Batch LU factorization failed \n");
4703 const int m = Mlu.
SizeI();
4704 const int NE = Mlu.
SizeK();
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).
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
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 * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
void UMult(int m, int n, real_t *X) const
void RightSolve(int m, int n, real_t *X) const
virtual void GetInverseMatrix(int m, real_t *X) const
Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
void USolve(int m, int n, real_t *X) const
virtual real_t Det(int m) const
virtual void Solve(int m, int n, real_t *X) const
virtual bool Factor(int m, real_t TOL=0.0)
Compute the Cholesky factorization of the current matrix.
void LSolve(int m, int n, real_t *X) const
void LMult(int m, int n, real_t *X) const
~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.
virtual void SetOperator(const Operator &op)
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.
void CalcEigenvalues(real_t *lambda, real_t *vec) const
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
virtual void PrintMatlab(std::ostream &out=mfem::out) const
Prints operator in Matlab format.
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.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
real_t * GetData() const
Returns the matrix data array.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
virtual ~DenseMatrix()
Destroys dense matrix.
virtual void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const
y += a * A.x
friend class DenseMatrixInverse
virtual real_t & Elem(int i, int j)
Returns reference to a_{ij}.
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.
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 AdjustDofDirection(Array< int > &dofs)
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
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.
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
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 AddMultTranspose(const Vector &x, Vector &y, const real_t a=1.0) const
y += a * A^t x
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.
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 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)
void GetColumn(int c, Vector &col) const
void GradToVectorCurl2D(DenseMatrix &curl)
DenseMatrix & operator=(real_t c)
Sets the matrix elements equal to constant c.
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
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
DenseTensor & operator=(real_t c)
Sets the tensor elements equal to constant c.
void Swap(DenseTensor &t)
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)
virtual void GetInverseMatrix(int m, real_t *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
void Mult(int m, int n, real_t *X) const
void USolve(int m, int n, real_t *X) const
virtual bool Factor(int m, real_t TOL=0.0)
Compute the LU factorization of the current matrix.
void BlockFactor(int m, int n, real_t *A12, real_t *A21, real_t *A22) const
void BlockForwSolve(int m, int n, int r, const real_t *L21, real_t *B1, real_t *B2) const
void RightSolve(int m, int n, real_t *X) const
virtual real_t Det(int m) const
virtual void Solve(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
static const 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 Capacity() const
Return the size of the allocated memory.
void Delete()
Delete the owned pointers and reset the Memory object.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
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().
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
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.
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 spotri_(char *, int *, float *, int *, int *)
void sggev_(char *jobvl, char *jobvr, int *n, float *a, int *lda, float *B, int *ldb, float *alphar, float *alphai, float *beta, float *vl, int *ldvl, float *vr, int *ldvr, float *work, int *lwork, int *info)
void dsyev_(char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *W, double *WORK, int *LWORK, int *INFO)
void ssygv_(int *ITYPE, char *JOBZ, char *UPLO, int *N, float *A, int *LDA, float *B, int *LDB, float *W, float *WORK, int *LWORK, int *INFO)
void spotrs_(char *, int *, int *, float *, int *, float *, int *, int *)
void ssyevr_(char *JOBZ, char *RANGE, char *UPLO, int *N, float *A, int *LDA, float *VL, float *VU, int *IL, int *IU, float *ABSTOL, int *M, float *W, float *Z, int *LDZ, int *ISUPPZ, float *WORK, int *LWORK, int *IWORK, int *LIWORK, int *INFO)
void sgemm_(char *, char *, int *, int *, int *, float *, float *, int *, float *, int *, float *, float *, int *)
void dpotrs_(char *, int *, int *, double *, int *, double *, int *, int *)
void dtrtrs_(char *, char *, char *, int *, int *, double *, int *, double *, int *, int *)
void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, double *alpha, double *a, int *lda, double *b, int *ldb)
void dpotrf_(char *, int *, double *, int *, int *)
void dgesvd_(char *JOBU, char *JOBVT, int *M, int *N, double *A, int *LDA, double *S, double *U, int *LDU, double *VT, int *LDVT, double *WORK, int *LWORK, int *INFO)
void dsygv_(int *ITYPE, char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *B, int *LDB, double *W, double *WORK, int *LWORK, int *INFO)
void dgetri_(int *N, double *A, int *LDA, int *IPIV, double *WORK, int *LWORK, int *INFO)
void sgetrf_(int *, int *, float *, int *, int *, int *)
void dpotri_(char *, int *, double *, int *, int *)
void dsyevr_(char *JOBZ, char *RANGE, char *UPLO, int *N, double *A, int *LDA, double *VL, double *VU, int *IL, int *IU, double *ABSTOL, int *M, double *W, double *Z, int *LDZ, int *ISUPPZ, double *WORK, int *LWORK, int *IWORK, int *LIWORK, int *INFO)
void spotrf_(char *, int *, float *, int *, int *)
void sgetrs_(char *, int *, int *, float *, int *, int *, float *, int *, int *)
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *)
void dgetrf_(int *, int *, double *, int *, int *, int *)
void sgesvd_(char *JOBU, char *JOBVT, int *M, int *N, float *A, int *LDA, float *S, float *U, int *LDU, float *VT, int *LDVT, float *WORK, int *LWORK, int *INFO)
void dggev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *B, int *ldb, double *alphar, double *alphai, double *beta, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)
void strtrs_(char *, char *, char *, int *, int *, float *, int *, float *, int *, int *)
void strsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, float *alpha, float *a, int *lda, float *b, int *ldb)
void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *)
void ssyev_(char *JOBZ, char *UPLO, int *N, float *A, int *LDA, float *W, float *WORK, int *LWORK, int *INFO)
void sgetri_(int *N, float *A, int *LDA, int *IPIV, float *WORK, int *LWORK, int *INFO)
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 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 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 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 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 LUSolve(const real_t *data, const int m, const int *ipiv, real_t *x)
Assuming L.U = P.A for a factored matrix (m x m),.
void CalcOrtho(const DenseMatrix &J, Vector &n)
void Swap(Array< T > &, Array< T > &)
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 dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, double *alpha, double *a, int *lda, double *b, int *ldb)
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.
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)
const T * HostRead(const Memory< T > &mem, int size)
Shortcut to Read(const Memory<T> &mem, int size, false)
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.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
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.
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 strsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, float *alpha, float *a, int *lda, float *b, int *ldb)
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 Mult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
void forall(int N, lambda &&body)
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.
real_t p(const Vector &x, real_t t)