16 #include "kernels.hpp" 20 #include "kernels.hpp" 21 #include "../general/forall.hpp" 22 #include "../general/table.hpp" 23 #include "../general/globals.hpp" 30 #if defined(_MSC_VER) && (_MSC_VER < 1800) 32 #define copysign _copysign 36 #ifdef MFEM_USE_LAPACK 38 dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
39 int *,
double *,
int *,
double *,
double *,
int *);
41 dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
43 dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
45 dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
46 int *LWORK,
int *INFO);
48 dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
49 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
50 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
51 int *IWORK,
int *LIWORK,
int *INFO);
53 dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
54 double *WORK,
int *LWORK,
int *INFO);
56 dsygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
double *A,
int *LDA,
57 double *B,
int *LDB,
double *W,
double *WORK,
int *LWORK,
int *INFO);
59 dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
60 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
61 int *LWORK,
int *INFO);
63 dtrsm_(
char *side,
char *uplo,
char *transa,
char *diag,
int *m,
int *n,
64 double *
alpha,
double *
a,
int *lda,
double *
b,
int *ldb);
66 dggev_(
char *jobvl,
char *jobvr,
int *n,
double *
a,
int *lda,
double *B,
67 int *ldb,
double *alphar,
double *alphai,
double *beta,
double *vl,
68 int * ldvl,
double * vr,
int * ldvr,
double * work,
int * lwork,
int* info);
72 dpotrf_(
char *,
int *,
double *,
int *,
int *);
75 dpotrs_(
char *,
int *,
int *,
double *,
int *,
double *,
int *,
int *);
78 dtrtrs_(
char *,
char*,
char *,
int *,
int *,
double *,
int *,
double *,
int *,
81 dpotri_(
char *,
int *,
double *,
int*,
int *);
97 MFEM_ASSERT(m.data,
"invalid source matrix");
99 std::memcpy(data, m.data,
sizeof(
double)*hw);
105 MFEM_ASSERT(
s >= 0,
"invalid DenseMatrix size: " <<
s);
115 MFEM_ASSERT(m >= 0 && n >= 0,
116 "invalid DenseMatrix size: " << m <<
" x " << n);
117 const int capacity = m*n;
126 :
Matrix(mat.width, mat.height)
128 MFEM_CONTRACT_VAR(ch);
134 for (
int i = 0; i <
height; i++)
136 for (
int j = 0; j <
width; j++)
138 (*this)(i,j) = mat(j,i);
146 MFEM_ASSERT(h >= 0 && w >= 0,
147 "invalid DenseMatrix size: " << h <<
" x " << w);
180 MFEM_ASSERT(
height == y.
Size(),
"incompatible dimensions");
187 MFEM_ASSERT(
width == x.
Size(),
"incompatible dimensions");
195 "incompatible dimensions");
203 "incompatible dimensions");
207 for (
int i = 0; i < hw; i++)
209 a += data[i] * m.data[i];
217 double *d_col =
Data();
218 for (
int col = 0; col <
width; col++)
221 for (
int row = 0; row <
height; row++)
223 y_col += x[row]*d_col[row];
232 MFEM_ASSERT(
width == y.
Size(),
"incompatible dimensions");
239 MFEM_ASSERT(
height == x.
Size(),
"incompatible dimensions");
247 "incompatible dimensions");
260 "incompatible dimensions");
262 const double *xp = x.
GetData(), *d_col = data;
264 for (
int col = 0; col <
width; col++)
266 double x_col = xp[col];
267 for (
int row = 0; row <
height; row++)
269 yp[row] += x_col*d_col[row];
276 const double a)
const 284 "incompatible dimensions");
286 const double *d_col = data;
287 for (
int col = 0; col <
width; col++)
290 for (
int row = 0; row <
height; row++)
292 y_col += x[row]*d_col[row];
302 "incompatible dimensions");
304 const double *xp = x.
GetData(), *d_col = data;
306 for (
int col = 0; col <
width; col++)
308 const double x_col =
a*xp[col];
309 for (
int row = 0; row <
height; row++)
311 yp[row] += x_col*d_col[row];
321 "incompatible dimensions");
323 const double *d_col = data;
324 for (
int col = 0; col <
width; col++)
327 for (
int row = 0; row <
height; row++)
329 y_col += x[row]*d_col[row];
340 for (
int i = 0; i <
height; i++)
343 for (
int j = 0; j <
width; j++)
345 Axi += (*this)(i,j) * x[j];
356 double * it_data = data;
357 for (
int j = 0; j <
width; ++j)
359 for (
int i = 0; i <
height; ++i)
361 *(it_data++) *=
s(i);
369 double * it_data = data;
370 for (
int j = 0; j <
width; ++j)
372 for (
int i = 0; i <
height; ++i)
374 *(it_data++) /=
s(i);
383 double * it_data = data;
384 for (
int j = 0; j <
width; ++j)
387 for (
int i = 0; i <
height; ++i)
397 double * it_data = data;
398 for (
int j = 0; j <
width; ++j)
400 const double sj = 1./
s(j);
401 for (
int i = 0; i <
height; ++i)
413 mfem_error(
"DenseMatrix::SymmetricScaling: dimension mismatch");
416 double * ss =
new double[
width];
417 double * it_s =
s.GetData();
419 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
421 *(it_ss++) = sqrt(*it_s);
424 double * it_data = data;
425 for (
int j = 0; j <
width; ++j)
427 for (
int i = 0; i <
height; ++i)
429 *(it_data++) *= ss[i]*ss[j];
441 mfem_error(
"DenseMatrix::InvSymmetricScaling: dimension mismatch");
444 double * ss =
new double[
width];
445 double * it_s =
s.GetData();
447 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
449 *(it_ss++) = 1./sqrt(*it_s);
452 double * it_data = data;
453 for (
int j = 0; j <
width; ++j)
455 for (
int i = 0; i <
height; ++i)
457 *(it_data++) *= ss[i]*ss[j];
469 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
475 for (
int i = 0; i <
width; i++)
491 "The matrix must be square and " 492 <<
"sized larger than zero to compute the determinant." 493 <<
" Height() = " <<
Height()
494 <<
", Width() = " <<
Width());
502 return data[0] * data[3] - data[1] * data[2];
506 const double *d = data;
508 d[0] * (d[4] * d[8] - d[5] * d[7]) +
509 d[3] * (d[2] * d[7] - d[1] * d[8]) +
510 d[6] * (d[1] * d[5] - d[2] * d[4]);
514 const double *d = data;
516 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
517 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
518 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
520 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
521 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
522 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
524 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
525 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
526 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
528 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
529 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
530 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
539 return lu_factors.
Det();
554 return sqrt(data[0] * data[0] + data[1] * data[1]);
558 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
562 const double *d = data;
563 double E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
564 double G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
565 double F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
566 return sqrt(E * G - F * F);
568 mfem_error(
"DenseMatrix::Weight(): mismatched or unsupported dimensions");
575 for (
int i = 0; i <
s; i++)
577 data[i] =
alpha*A[i];
583 for (
int j = 0; j <
Width(); j++)
585 for (
int i = 0; i <
Height(); i++)
587 (*this)(i,j) += c * A(i,j);
595 for (
int i = 0; i <
s; i++)
604 for (
int i = 0; i <
s; i++)
614 for (
int i = 0; i <
s; i++)
626 for (
int i = 0; i < hw; i++)
643 "incompatible matrix sizes.");
649 for (
int j = 0; j <
width; j++)
651 for (
int i = 0; i <
height; i++)
653 (*this)(i, j) -= m(i, j);
663 for (
int i = 0; i <
s; i++)
673 for (
int i = 0; i < hw; i++)
684 mfem_error(
"DenseMatrix::Invert(): dimension mismatch");
688 #ifdef MFEM_USE_LAPACK 689 int *ipiv =
new int[
width];
698 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
704 work =
new double[lwork];
710 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
716 int c, i, j, n =
Width();
720 for (c = 0; c < n; c++)
722 a = fabs((*
this)(c, c));
724 for (j = c + 1; j < n; j++)
726 b = fabs((*
this)(j, c));
735 mfem_error(
"DenseMatrix::Invert() : singular matrix");
738 for (j = 0; j < n; j++)
740 mfem::Swap<double>((*this)(c, j), (*
this)(i, j));
743 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
744 for (j = 0; j < c; j++)
748 for (j++; j < n; j++)
752 for (i = 0; i < c; i++)
754 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
755 for (j = 0; j < c; j++)
757 (*this)(i, j) +=
b * (*
this)(c, j);
759 for (j++; j < n; j++)
761 (*this)(i, j) +=
b * (*
this)(c, j);
764 for (i++; i < n; i++)
766 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
767 for (j = 0; j < c; j++)
769 (*this)(i, j) +=
b * (*
this)(c, j);
771 for (j++; j < n; j++)
773 (*this)(i, j) +=
b * (*
this)(c, j);
778 for (c = n - 1; c >= 0; c--)
781 for (i = 0; i < n; i++)
783 mfem::Swap<double>((*this)(i, c), (*
this)(i, j));
795 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
805 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
807 for (
int j = 0; j < 10; j++)
809 for (
int i = 0; i < 10; i++)
824 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
825 if (tmp2.FNorm() < 1e-10) {
break; }
828 if (tmp2.FNorm() > 1e-10)
830 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
836 for (
int j = 0; j <
Width(); j++)
839 for (
int i = 0; i <
Height(); i++)
841 v[j] += (*this)(i,j)*(*
this)(i,j);
850 const double *d = data;
851 double norm = 0.0, abs_entry;
853 for (
int i = 0; i < hw; i++)
855 abs_entry = fabs(d[i]);
856 if (norm < abs_entry)
868 double max_norm = 0.0, entry, fnorm2;
870 for (i = 0; i < hw; i++)
872 entry = fabs(data[i]);
873 if (entry > max_norm)
881 scale_factor = scaled_fnorm2 = 0.0;
886 for (i = 0; i < hw; i++)
888 entry = data[i] / max_norm;
889 fnorm2 += entry * entry;
892 scale_factor = max_norm;
893 scaled_fnorm2 = fnorm2;
898 #ifdef MFEM_USE_LAPACK 905 double *A =
new double[N*N];
916 int *ISUPPZ =
new int[2*N];
934 int hw =
a.Height() *
a.Width();
935 double *data =
a.Data();
937 for (
int i = 0; i < hw; i++)
942 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
943 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
944 &QIWORK, &LIWORK, &INFO );
949 WORK =
new double[LWORK];
950 IWORK =
new int[LIWORK];
952 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
953 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
954 IWORK, &LIWORK, &INFO );
958 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: " 966 mfem::err <<
"dsyevr_Eigensystem(...):\n" 967 <<
" DSYEVR did not find all eigenvalues " 968 << M <<
"/" << N << endl;
973 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
977 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
980 for (IL = 0; IL < N; IL++)
981 for (IU = 0; IU <= IL; IU++)
984 for (M = 0; M < N; M++)
986 VL += Z[M+IL*N] * Z[M+IU*N];
1003 <<
" Z^t Z - I deviation = " << VU
1004 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1005 << W[0] <<
", N = " << N << endl;
1012 <<
" Z^t Z - I deviation = " << VU
1013 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1014 << W[0] <<
", N = " << N << endl;
1018 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1021 for (IL = 0; IL < N; IL++)
1022 for (IU = 0; IU < N; IU++)
1025 for (M = 0; M < N; M++)
1027 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
1029 VL = fabs(VL-data[IL+N*IU]);
1038 <<
" max matrix deviation = " << VU
1039 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1040 << W[0] <<
", N = " << N << endl;
1044 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1053 MFEM_CONTRACT_VAR(
a);
1054 MFEM_CONTRACT_VAR(ev);
1055 MFEM_CONTRACT_VAR(evect);
1061 #ifdef MFEM_USE_LAPACK 1073 double *WORK = NULL;
1084 A =
new double[N*N];
1087 int hw =
a.Height() *
a.Width();
1088 double *data =
a.Data();
1089 for (
int i = 0; i < hw; i++)
1094 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1096 LWORK = (int) QWORK;
1097 WORK =
new double[LWORK];
1099 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1103 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1108 if (evect == NULL) {
delete [] A; }
1110 MFEM_CONTRACT_VAR(
a);
1111 MFEM_CONTRACT_VAR(ev);
1112 MFEM_CONTRACT_VAR(evect);
1116 void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1118 #ifdef MFEM_USE_LAPACK 1126 MFEM_CONTRACT_VAR(ev);
1127 MFEM_CONTRACT_VAR(evect);
1128 mfem_error(
"DenseMatrix::Eigensystem: Compiled without LAPACK");
1136 #ifdef MFEM_USE_LAPACK 1149 double *B =
new double[N*N];
1151 double *WORK = NULL;
1162 A =
new double[N*N];
1165 int hw =
a.Height() *
a.Width();
1166 double *a_data =
a.Data();
1167 double *b_data =
b.Data();
1168 for (
int i = 0; i < hw; i++)
1174 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1176 LWORK = (int) QWORK;
1177 WORK =
new double[LWORK];
1179 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1183 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1189 if (evect == NULL) {
delete [] A; }
1191 MFEM_CONTRACT_VAR(
a);
1192 MFEM_CONTRACT_VAR(
b);
1193 MFEM_CONTRACT_VAR(ev);
1194 MFEM_CONTRACT_VAR(evect);
1198 void DenseMatrix::Eigensystem(DenseMatrix &
b, Vector &ev,
1201 #ifdef MFEM_USE_LAPACK 1206 MFEM_CONTRACT_VAR(
b);
1207 MFEM_CONTRACT_VAR(ev);
1208 MFEM_CONTRACT_VAR(evect);
1209 mfem_error(
"DenseMatrix::Eigensystem(generalized): Compiled without LAPACK");
1215 #ifdef MFEM_USE_LAPACK 1221 double *
a = copy_of_this.data;
1226 double *work = NULL;
1231 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1232 s,
u, &m, vt, &n, &qwork, &lwork, &info);
1234 lwork = (int) qwork;
1235 work =
new double[lwork];
1237 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1238 s,
u, &m, vt, &n, work, &lwork, &info);
1243 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1247 MFEM_CONTRACT_VAR(sv);
1249 mfem_error(
"DenseMatrix::SingularValues: Compiled without LAPACK");
1259 for (
int i=0; i < sv.
Size(); ++i)
1271 "The matrix must be square and sized 1, 2, or 3 to compute the" 1273 <<
" Height() = " <<
Height()
1274 <<
", Width() = " <<
Width());
1277 const double *d = data;
1303 const double *d = data;
1321 const double* rp = data + r;
1324 for (
int i = 0; i < n; i++)
1336 double *cp =
Data() + c * m;
1339 for (
int i = 0; i < m; i++)
1353 for (
int i = 0; i <
height; ++i)
1355 d(i) = (*this)(i,i);
1369 for (
int j = 0; j <
width; ++j)
1370 for (
int i = 0; i <
height; ++i)
1372 l(i) += fabs((*
this)(i,j));
1379 for (
int i = 0; i <
height; i++)
1382 for (
int j = 0; j <
width; j++)
1395 for (
int i = 0; i < N; i++)
1399 for (
int i = 0; i < n; i++)
1410 for (i = 0; i < N; i++)
1414 for (i = 0; i < n; i++)
1416 data[i*(n+1)] = diag[i];
1427 for (i = 0; i <
Height(); i++)
1428 for (j = i+1; j <
Width(); j++)
1431 (*this)(i,j) = (*
this)(j,i);
1446 for (
int i = 0; i <
Height(); i++)
1447 for (
int j = 0; j <
Width(); j++)
1449 (*this)(i,j) = A(j,i);
1458 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1466 for (
int i = 0; i <
Height(); i++)
1469 for (
int j = 0; j <
Width(); j++)
1472 (*this)(i, j) = 0.0;
1486 mfem_error(
"DenseMatrix::GradToCurl(...): dimension mismatch");
1492 for (
int i = 0; i < n; i++)
1495 double x = (*this)(i,0);
1496 double y = (*this)(i,1);
1509 for (
int i = 0; i < n; i++)
1512 double x = (*this)(i,0);
1513 double y = (*this)(i,1);
1514 double z = (*this)(i,2);
1539 MFEM_VERIFY(
Width() == 2,
1540 "DenseMatrix::GradToVectorCurl2D(...): dimension must be 2")
1544 for (
int i = 0; i < n; i++)
1546 curl(i,0) = (*this)(i,1);
1547 curl(i,1) = -(*this)(i,0);
1553 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1558 double *ddata = div.
GetData();
1560 for (
int i = 0; i < n; i++)
1570 for (
int j = 0; j <
Width(); j++)
1572 for (
int i = row1; i <= row2; i++)
1574 (*this)(i-row1,j) = A(i,j);
1583 for (
int j = col1; j <= col2; j++)
1585 for (
int i = 0; i <
Height(); i++)
1587 (*this)(i,j-col1) = A(i,j);
1596 for (
int j = 0; j < n; j++)
1598 for (
int i = 0; i < m; i++)
1600 (*this)(i,j) = A(Aro+i,Aco+j);
1607 double *v = A.
Data();
1609 for (
int j = 0; j < A.
Width(); j++)
1611 for (
int i = 0; i < A.
Height(); i++)
1613 (*this)(row_offset+i,col_offset+j) = *(v++);
1620 double *v = A.
Data();
1622 for (
int i = 0; i < A.
Width(); i++)
1624 for (
int j = 0; j < A.
Height(); j++)
1626 (*this)(row_offset+i,col_offset+j) = *(v++);
1632 int row_offset,
int col_offset)
1634 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1635 "this DenseMatrix is too small to accommodate the submatrix. " 1636 <<
"row_offset = " << row_offset
1638 <<
", this->Height() = " << this->
Height()
1639 <<
", col_offset = " << col_offset
1641 <<
", this->Width() = " << this->
Width()
1643 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1644 "The A DenseMatrix is too small to accommodate the submatrix. " 1647 <<
", A.Height() = " << A.
Height()
1648 <<
", Aco = " << Aco
1650 <<
", A.Width() = " << A.
Width()
1653 for (
int j = 0; j < n; j++)
1655 for (
int i = 0; i < m; i++)
1657 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1664 for (
int i = 0; i < n; i++)
1666 for (
int j = i+1; j < n; j++)
1668 (*this)(row_offset+i,col_offset+j) =
1669 (*
this)(row_offset+j,col_offset+i) = 0.0;
1673 for (
int i = 0; i < n; i++)
1675 (*this)(row_offset+i,col_offset+i) = c;
1682 for (
int i = 0; i < n; i++)
1684 for (
int j = i+1; j < n; j++)
1686 (*this)(row_offset+i,col_offset+j) =
1687 (*
this)(row_offset+j,col_offset+i) = 0.0;
1691 for (
int i = 0; i < n; i++)
1693 (*this)(row_offset+i,col_offset+i) = diag[i];
1701 int i, j, i_off = 0, j_off = 0;
1703 for (j = 0; j < A.
Width(); j++)
1710 for (i = 0; i < A.
Height(); i++)
1717 (*this)(i-i_off,j-j_off) = A(i,j);
1733 if (co+aw >
Width() || ro+ah > h)
1735 mfem_error(
"DenseMatrix::AddMatrix(...) 1 : dimension mismatch");
1739 p = data + ro + co * h;
1742 for (
int c = 0; c < aw; c++)
1744 for (
int r = 0; r < ah; r++)
1763 if (co+aw >
Width() || ro+ah > h)
1765 mfem_error(
"DenseMatrix::AddMatrix(...) 2 : dimension mismatch");
1769 p = data + ro + co * h;
1772 for (
int c = 0; c < aw; c++)
1774 for (
int r = 0; r < ah; r++)
1786 int idx_max = idx.
Max();
1787 MFEM_VERIFY(idx.
Min() >=0 && idx_max < this->
height && idx_max < this->
width,
1788 "DenseMatrix::GetSubMatrix: Index out of bounds");
1790 double * adata = A.
Data();
1793 for (
int i = 0; i<k; i++)
1796 for (
int j = 0; j<k; j++)
1799 adata[i+j*k] = this->data[ii+jj*
height];
1807 int k = idx_i.
Size();
1808 int l = idx_j.
Size();
1810 MFEM_VERIFY(idx_i.
Min() >=0 && idx_i.
Max() < this->
height,
1811 "DenseMatrix::GetSubMatrix: Row index out of bounds");
1812 MFEM_VERIFY(idx_j.
Min() >=0 && idx_j.
Max() < this->
width,
1813 "DenseMatrix::GetSubMatrix: Col index out of bounds");
1816 double * adata = A.
Data();
1819 for (
int i = 0; i<k; i++)
1822 for (
int j = 0; j<l; j++)
1825 adata[i+j*k] = this->data[ii+jj*
height];
1832 MFEM_VERIFY(iend >= ibeg,
"DenseMatrix::GetSubMatrix: Inconsistent range");
1833 MFEM_VERIFY(ibeg >=0,
1834 "DenseMatrix::GetSubMatrix: Negative index");
1835 MFEM_VERIFY(iend <= this->
height && iend <= this->
width,
1836 "DenseMatrix::GetSubMatrix: Index bigger than upper bound");
1838 int k = iend - ibeg;
1840 double * adata = A.
Data();
1843 for (
int i = 0; i<k; i++)
1846 for (
int j = 0; j<k; j++)
1849 adata[i+j*k] = this->data[ii+jj*
height];
1857 MFEM_VERIFY(iend >= ibeg,
1858 "DenseMatrix::GetSubMatrix: Inconsistent row range");
1859 MFEM_VERIFY(jend >= jbeg,
1860 "DenseMatrix::GetSubMatrix: Inconsistent col range");
1861 MFEM_VERIFY(ibeg >=0,
1862 "DenseMatrix::GetSubMatrix: Negative row index");
1863 MFEM_VERIFY(jbeg >=0,
1864 "DenseMatrix::GetSubMatrix: Negative row index");
1865 MFEM_VERIFY(iend <= this->
height,
1866 "DenseMatrix::GetSubMatrix: Index bigger than row upper bound");
1867 MFEM_VERIFY(jend <= this->
width,
1868 "DenseMatrix::GetSubMatrix: Index bigger than col upper bound");
1870 int k = iend - ibeg;
1871 int l = jend - jbeg;
1873 double * adata = A.
Data();
1876 for (
int i = 0; i<k; i++)
1879 for (
int j = 0; j<l; j++)
1882 adata[i+j*k] = this->data[ii+jj*
height];
1891 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1893 int idx_max = idx.
Max();
1895 MFEM_VERIFY(idx.
Min() >=0,
1896 "DenseMatrix::SetSubMatrix: Negative index");
1897 MFEM_VERIFY(idx_max < this->
height,
1898 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1899 MFEM_VERIFY(idx_max < this->
width,
1900 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1902 double * adata = A.
Data();
1905 for (
int i = 0; i<k; i++)
1908 for (
int j = 0; j<k; j++)
1911 this->data[ii+jj*
height] = adata[i+j*k];
1919 int k = idx_i.
Size();
1920 int l = idx_j.
Size();
1922 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1923 MFEM_VERIFY(idx_i.
Min() >=0,
1924 "DenseMatrix::SetSubMatrix: Negative row index");
1925 MFEM_VERIFY(idx_j.
Min() >=0,
1926 "DenseMatrix::SetSubMatrix: Negative col index");
1928 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1929 MFEM_VERIFY(idx_j.
Max() < this->
width,
1930 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1932 double * adata = A.
Data();
1935 for (
int i = 0; i<k; i++)
1938 for (
int j = 0; j<l; j++)
1941 this->data[ii+jj*
height] = adata[i+j*k];
1950 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::SetSubmatrix: A is not square");
1951 MFEM_VERIFY(ibeg >=0,
1952 "DenseMatrix::SetSubmatrix: Negative index");
1953 MFEM_VERIFY(ibeg + k <= this->
height,
1954 "DenseMatrix::SetSubmatrix: index bigger than row upper bound");
1955 MFEM_VERIFY(ibeg + k <= this->
width,
1956 "DenseMatrix::SetSubmatrix: index bigger than col upper bound");
1958 double * adata = A.
Data();
1961 for (
int i = 0; i<k; i++)
1964 for (
int j = 0; j<k; j++)
1967 this->data[ii+jj*
height] = adata[i+j*k];
1977 MFEM_VERIFY(ibeg>=0,
1978 "DenseMatrix::SetSubmatrix: Negative row index");
1979 MFEM_VERIFY(jbeg>=0,
1980 "DenseMatrix::SetSubmatrix: Negative col index");
1981 MFEM_VERIFY(ibeg + k <= this->
height,
1982 "DenseMatrix::SetSubmatrix: Index bigger than row upper bound");
1983 MFEM_VERIFY(jbeg + l <= this->
width,
1984 "DenseMatrix::SetSubmatrix: Index bigger than col upper bound");
1986 double * adata = A.
Data();
1989 for (
int i = 0; i<k; i++)
1992 for (
int j = 0; j<l; j++)
1995 this->data[ii+jj*
height] = adata[i+j*k];
2004 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2006 int idx_max = idx.
Max();
2008 MFEM_VERIFY(idx.
Min() >=0,
"DenseMatrix::AddSubMatrix: Negative index");
2009 MFEM_VERIFY(idx_max < this->
height,
2010 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2011 MFEM_VERIFY(idx_max < this->
width,
2012 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2014 double * adata = A.
Data();
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::AddSubMatrix:Inconsistent matrix dimensions");
2036 MFEM_VERIFY(idx_i.
Min() >=0,
2037 "DenseMatrix::AddSubMatrix: Negative row index");
2038 MFEM_VERIFY(idx_j.
Min() >=0,
2039 "DenseMatrix::AddSubMatrix: Negative col index");
2041 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2042 MFEM_VERIFY(idx_j.
Max() < this->
width,
2043 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2045 double * adata = A.
Data();
2048 for (
int i = 0; i<k; i++)
2051 for (
int j = 0; j<l; j++)
2054 this->data[ii+jj*
height] += adata[i+j*k];
2062 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::AddSubmatrix: A is not square");
2064 MFEM_VERIFY(ibeg>=0,
2065 "DenseMatrix::AddSubmatrix: Negative index");
2066 MFEM_VERIFY(ibeg + k <= this->
Height(),
2067 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2068 MFEM_VERIFY(ibeg + k <= this->
Width(),
2069 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2071 double * adata = A.
Data();
2074 for (
int i = 0; i<k; i++)
2077 for (
int j = 0; j<k; j++)
2080 this->data[ii+jj*
height] += adata[i+j*k];
2090 MFEM_VERIFY(ibeg>=0,
2091 "DenseMatrix::AddSubmatrix: Negative row index");
2092 MFEM_VERIFY(jbeg>=0,
2093 "DenseMatrix::AddSubmatrix: Negative col index");
2094 MFEM_VERIFY(ibeg + k <= this->
height,
2095 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2096 MFEM_VERIFY(jbeg + l <= this->
width,
2097 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2099 double * adata = A.
Data();
2102 for (
int i = 0; i<k; i++)
2105 for (
int j = 0; j<l; j++)
2108 this->data[ii+jj*
height] += adata[i+j*k];
2116 double *vdata = v.
GetData() + offset;
2118 for (
int i = 0; i < n; i++)
2120 vdata[i] += data[i];
2127 const double *vdata = v.
GetData() + offset;
2129 for (
int i = 0; i < n; i++)
2142 mfem_error(
"DenseMatrix::AdjustDofDirection(...): dimension mismatch");
2147 for (
int i = 0; i < n-1; i++)
2149 const int s = (dof[i] < 0) ? (-1) : (1);
2150 for (
int j = i+1; j < n; j++)
2152 const int t = (dof[j] < 0) ? (-
s) : (
s);
2155 (*this)(i,j) = -(*
this)(i,j);
2156 (*this)(j,i) = -(*
this)(j,i);
2164 for (
int j = 0; j <
Width(); j++)
2166 (*this)(row, j) = value;
2172 for (
int i = 0; i <
Height(); i++)
2174 (*this)(i, col) = value;
2180 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
2181 for (
int j = 0; j <
Width(); j++)
2183 (*this)(r, j) = row[j];
2195 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
2196 for (
int i = 0; i <
Height(); i++)
2198 (*this)(i, c) = col[i];
2210 for (
int col = 0; col <
Width(); col++)
2212 for (
int row = 0; row <
Height(); row++)
2214 if (std::abs(
operator()(row,col)) <= eps)
2225 ios::fmtflags old_flags = os.flags();
2227 os << setiosflags(ios::scientific | ios::showpos);
2228 for (
int i = 0; i <
height; i++)
2230 os <<
"[row " << i <<
"]\n";
2231 for (
int j = 0; j <
width; j++)
2234 if (j+1 ==
width || (j+1) % width_ == 0)
2245 os.flags(old_flags);
2251 ios::fmtflags old_flags = os.flags();
2253 os << setiosflags(ios::scientific | ios::showpos);
2254 for (
int i = 0; i <
height; i++)
2256 for (
int j = 0; j <
width; j++)
2264 os.flags(old_flags);
2270 ios::fmtflags old_flags = os.flags();
2272 os << setiosflags(ios::scientific | ios::showpos);
2273 for (
int j = 0; j <
width; j++)
2275 os <<
"[col " << j <<
"]\n";
2276 for (
int i = 0; i <
height; i++)
2279 if (i+1 ==
height || (i+1) % width_ == 0)
2290 os.flags(old_flags);
2299 for (
int i = 0; i <
width; i++)
2304 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2345 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
2346 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
2347 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
2355 double det = A(0,0);
2356 if (std::abs(det) <= TOL) {
return false; }
2363 double det = A.
Det();
2364 if (std::abs(det) <= TOL) {
return false; }
2366 double invdet = 1. / det;
2371 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
2372 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
2381 if (!lu.Factor(N,TOL)) {
return false; }
2393 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2394 b.Width() == c.
Height(),
"incompatible dimensions");
2396 #ifdef MFEM_USE_LAPACK 2397 static char transa =
'N', transb =
'N';
2398 static double alpha = 1.0, beta = 0.0;
2399 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2401 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2402 c.
Data(), &k, &beta,
a.Data(), &m);
2404 const int ah =
a.Height();
2405 const int aw =
a.Width();
2406 const int bw =
b.Width();
2407 double *ad =
a.Data();
2408 const double *bd =
b.Data();
2409 const double *cd = c.
Data();
2417 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2418 b.Width() == c.
Height(),
"incompatible dimensions");
2420 #ifdef MFEM_USE_LAPACK 2421 static char transa =
'N', transb =
'N';
2422 static double beta = 1.0;
2423 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2425 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2426 c.
Data(), &k, &beta,
a.Data(), &m);
2428 const int ah =
a.Height();
2429 const int aw =
a.Width();
2430 const int bw =
b.Width();
2431 double *ad =
a.Data();
2432 const double *bd =
b.Data();
2433 const double *cd = c.
Data();
2434 for (
int j = 0; j < aw; j++)
2436 for (
int k = 0; k < bw; k++)
2438 for (
int i = 0; i < ah; i++)
2440 ad[i+j*ah] +=
alpha * bd[i+k*ah] * cd[k+j*bw];
2449 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2450 b.Width() == c.
Height(),
"incompatible dimensions");
2452 #ifdef MFEM_USE_LAPACK 2453 static char transa =
'N', transb =
'N';
2454 static double alpha = 1.0, beta = 1.0;
2455 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2457 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2458 c.
Data(), &k, &beta,
a.Data(), &m);
2460 const int ah =
a.Height();
2461 const int aw =
a.Width();
2462 const int bw =
b.Width();
2463 double *ad =
a.Data();
2464 const double *bd =
b.Data();
2465 const double *cd = c.
Data();
2466 for (
int j = 0; j < aw; j++)
2468 for (
int k = 0; k < bw; k++)
2470 for (
int i = 0; i < ah; i++)
2472 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2482 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
2484 mfem_error(
"CalcAdjugate(...): unsupported dimensions");
2486 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
2488 mfem_error(
"CalcAdjugate(...): dimension mismatch");
2492 if (
a.Width() <
a.Height())
2494 const double *d =
a.Data();
2495 double *ad = adja.
Data();
2501 if (
a.Height() == 3)
2510 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2511 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2512 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2514 ad[0] = d[0]*g - d[3]*
f;
2515 ad[1] = d[3]*e - d[0]*
f;
2516 ad[2] = d[1]*g - d[4]*
f;
2517 ad[3] = d[4]*e - d[1]*
f;
2518 ad[4] = d[2]*g - d[5]*
f;
2519 ad[5] = d[5]*e - d[2]*
f;
2528 else if (
a.Width() == 2)
2531 adja(0,1) = -
a(0,1);
2532 adja(1,0) = -
a(1,0);
2537 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2538 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2539 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2541 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2542 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2543 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2545 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2546 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2547 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2554 if (
a.Height() !=
a.Width() || adjat.
Height() != adjat.
Width() ||
2555 a.Width() != adjat.
Width() ||
a.Width() < 1 ||
a.Width() > 3)
2557 mfem_error(
"CalcAdjugateTranspose(...): dimension mismatch");
2564 else if (
a.Width() == 2)
2566 adjat(0,0) =
a(1,1);
2567 adjat(1,0) = -
a(0,1);
2568 adjat(0,1) = -
a(1,0);
2569 adjat(1,1) =
a(0,0);
2573 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2574 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2575 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2577 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2578 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2579 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2581 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2582 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2583 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2589 MFEM_ASSERT(
a.Width() <=
a.Height() &&
a.Width() >= 1 &&
a.Height() <= 3,
"");
2590 MFEM_ASSERT(inva.
Height() ==
a.Width(),
"incorrect dimensions");
2591 MFEM_ASSERT(inva.
Width() ==
a.Height(),
"incorrect dimensions");
2595 if (
a.Width() <
a.Height())
2597 const double *d =
a.Data();
2598 double *
id = inva.
Data();
2599 if (
a.Height() == 2)
2601 t = 1.0 / (d[0]*d[0] + d[1]*d[1]);
2609 t = 1.0 / (d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
2617 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2618 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2619 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2620 t = 1.0 / (e*g -
f*
f);
2621 e *=
t; g *=
t;
f *=
t;
2623 id[0] = d[0]*g - d[3]*
f;
2624 id[1] = d[3]*e - d[0]*
f;
2625 id[2] = d[1]*g - d[4]*
f;
2626 id[3] = d[4]*e - d[1]*
f;
2627 id[4] = d[2]*g - d[5]*
f;
2628 id[5] = d[5]*e - d[2]*
f;
2636 MFEM_ASSERT(std::abs(
t) > 1.0e-14 * pow(
a.FNorm()/
a.Width(),
a.Width()),
2637 "singular matrix!");
2643 inva(0,0) = 1.0 /
a.Det();
2646 kernels::CalcInverse<2>(
a.Data(), inva.
Data());
2649 kernels::CalcInverse<3>(
a.Data(), inva.
Data());
2657 if ( (
a.Width() !=
a.Height()) || ( (
a.Height()!= 1) && (
a.Height()!= 2)
2658 && (
a.Height()!= 3) ) )
2660 mfem_error(
"CalcInverseTranspose(...): dimension mismatch");
2664 double t = 1. /
a.Det() ;
2669 inva(0,0) = 1.0 /
a(0,0);
2672 inva(0,0) =
a(1,1) *
t ;
2673 inva(1,0) = -
a(0,1) *
t ;
2674 inva(0,1) = -
a(1,0) *
t ;
2675 inva(1,1) =
a(0,0) *
t ;
2678 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*
t;
2679 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*
t;
2680 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*
t;
2682 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*
t;
2683 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*
t;
2684 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*
t;
2686 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*
t;
2687 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*
t;
2688 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*
t;
2698 "Matrix must be 3x2 or 2x1, " 2699 <<
"and the Vector must be sized with the rows. " 2700 <<
" J.Height() = " << J.
Height()
2701 <<
", J.Width() = " << J.
Width()
2702 <<
", n.Size() = " << n.
Size()
2705 const double *d = J.
Data();
2713 n(0) = d[1]*d[5] - d[2]*d[4];
2714 n(1) = d[2]*d[3] - d[0]*d[5];
2715 n(2) = d[0]*d[4] - d[1]*d[3];
2721 const int height =
a.Height();
2722 const int width =
a.Width();
2723 for (
int i = 0; i < height; i++)
2725 for (
int j = 0; j <= i; j++)
2728 for (
int k = 0; k < width; k++)
2730 temp +=
a(i,k) *
a(j,k);
2732 aat(j,i) = aat(i,j) = temp;
2739 for (
int i = 0; i < A.
Height(); i++)
2741 for (
int j = 0; j < i; j++)
2744 for (
int k = 0; k < A.
Width(); k++)
2746 t += D(k) * A(i, k) * A(j, k);
2754 for (
int i = 0; i < A.
Height(); i++)
2757 for (
int k = 0; k < A.
Width(); k++)
2759 t += D(k) * A(i, k) * A(i, k);
2767 for (
int i = 0; i < A.
Height(); i++)
2769 for (
int j = 0; j <= i; j++)
2772 for (
int k = 0; k < A.
Width(); k++)
2774 t += D(k) * A(i, k) * A(j, k);
2776 ADAt(j, i) = ADAt(i, j) =
t;
2787 mfem_error(
"MultABt(...): dimension mismatch");
2791 #ifdef MFEM_USE_LAPACK 2792 static char transa =
'N', transb =
'T';
2793 static double alpha = 1.0, beta = 0.0;
2797 B.
Data(), &n, &beta, ABt.
Data(), &m);
2799 const int ah = A.
Height();
2800 const int bh = B.
Height();
2801 const int aw = A.
Width();
2802 const double *ad = A.
Data();
2803 const double *bd = B.
Data();
2804 double *cd = ABt.
Data();
2808 const int ah = A.
Height();
2809 const int bh = B.
Height();
2810 const int aw = A.
Width();
2811 const double *ad = A.
Data();
2812 const double *bd = B.
Data();
2813 double *cd = ABt.
Data();
2815 for (
int j = 0; j < bh; j++)
2816 for (
int i = 0; i < ah; i++)
2819 const double *ap = ad + i;
2820 const double *bp = bd + j;
2821 for (
int k = 0; k < aw; k++)
2833 for (i = 0; i < A.
Height(); i++)
2834 for (j = 0; j < B.
Height(); j++)
2837 for (k = 0; k < A.
Width(); k++)
2839 d += A(i, k) * B(j, k);
2853 mfem_error(
"MultADBt(...): dimension mismatch");
2857 const int ah = A.
Height();
2858 const int bh = B.
Height();
2859 const int aw = A.
Width();
2860 const double *ad = A.
Data();
2861 const double *bd = B.
Data();
2862 const double *dd = D.
GetData();
2863 double *cd = ADBt.
Data();
2865 for (
int i = 0,
s = ah*bh; i <
s; i++)
2869 for (
int k = 0; k < aw; k++)
2872 for (
int j = 0; j < bh; j++)
2874 const double dk_bjk = dd[k] * bd[j];
2875 for (
int i = 0; i < ah; i++)
2877 cp[i] += ad[i] * dk_bjk;
2892 mfem_error(
"AddMultABt(...): dimension mismatch");
2896 #ifdef MFEM_USE_LAPACK 2897 static char transa =
'N', transb =
'T';
2898 static double alpha = 1.0, beta = 1.0;
2902 B.
Data(), &n, &beta, ABt.
Data(), &m);
2904 const int ah = A.
Height();
2905 const int bh = B.
Height();
2906 const int aw = A.
Width();
2907 const double *ad = A.
Data();
2908 const double *bd = B.
Data();
2909 double *cd = ABt.
Data();
2911 for (
int k = 0; k < aw; k++)
2914 for (
int j = 0; j < bh; j++)
2916 const double bjk = bd[j];
2917 for (
int i = 0; i < ah; i++)
2919 cp[i] += ad[i] * bjk;
2930 for (i = 0; i < A.
Height(); i++)
2931 for (j = 0; j < B.
Height(); j++)
2934 for (k = 0; k < A.
Width(); k++)
2936 d += A(i, k) * B(j, k);
2950 mfem_error(
"AddMultADBt(...): dimension mismatch");
2954 const int ah = A.
Height();
2955 const int bh = B.
Height();
2956 const int aw = A.
Width();
2957 const double *ad = A.
Data();
2958 const double *bd = B.
Data();
2959 const double *dd = D.
GetData();
2960 double *cd = ADBt.
Data();
2962 for (
int k = 0; k < aw; k++)
2965 for (
int j = 0; j < bh; j++)
2967 const double dk_bjk = dd[k] * bd[j];
2968 for (
int i = 0; i < ah; i++)
2970 cp[i] += ad[i] * dk_bjk;
2986 mfem_error(
"AddMult_a_ABt(...): dimension mismatch");
2990 #ifdef MFEM_USE_LAPACK 2991 static char transa =
'N', transb =
'T';
2993 static double beta = 1.0;
2997 B.
Data(), &n, &beta, ABt.
Data(), &m);
2999 const int ah = A.
Height();
3000 const int bh = B.
Height();
3001 const int aw = A.
Width();
3002 const double *ad = A.
Data();
3003 const double *bd = B.
Data();
3004 double *cd = ABt.
Data();
3006 for (
int k = 0; k < aw; k++)
3009 for (
int j = 0; j < bh; j++)
3011 const double bjk =
a * bd[j];
3012 for (
int i = 0; i < ah; i++)
3014 cp[i] += ad[i] * bjk;
3025 for (i = 0; i < A.
Height(); i++)
3026 for (j = 0; j < B.
Height(); j++)
3029 for (k = 0; k < A.
Width(); k++)
3031 d += A(i, k) * B(j, k);
3044 mfem_error(
"MultAtB(...): dimension mismatch");
3048 #ifdef MFEM_USE_LAPACK 3049 static char transa =
'T', transb =
'N';
3050 static double alpha = 1.0, beta = 0.0;
3054 B.
Data(), &k, &beta, AtB.
Data(), &m);
3056 const int ah = A.
Height();
3057 const int aw = A.
Width();
3058 const int bw = B.
Width();
3059 const double *ad = A.
Data();
3060 const double *bd = B.
Data();
3061 double *cd = AtB.
Data();
3063 for (
int j = 0; j < bw; j++)
3065 const double *ap = ad;
3066 for (
int i = 0; i < aw; i++)
3069 for (
int k = 0; k < ah; k++)
3082 for (i = 0; i < A.
Width(); i++)
3083 for (j = 0; j < B.
Width(); j++)
3086 for (k = 0; k < A.
Height(); k++)
3088 d += A(k, i) * B(k, j);
3099 for (
int i = 0; i < A.
Height(); i++)
3101 for (
int j = 0; j < i; j++)
3104 for (
int k = 0; k < A.
Width(); k++)
3106 d += A(i,k) * A(j,k);
3108 AAt(i, j) += (d *=
a);
3112 for (
int k = 0; k < A.
Width(); k++)
3114 d += A(i,k) * A(i,k);
3122 for (
int i = 0; i < A.
Height(); i++)
3124 for (
int j = 0; j <= i; j++)
3127 for (
int k = 0; k < A.
Width(); k++)
3129 d += A(i,k) * A(j,k);
3131 AAt(i, j) = AAt(j, i) =
a * d;
3138 for (
int i = 0; i < v.
Size(); i++)
3140 for (
int j = 0; j <= i; j++)
3142 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3152 mfem_error(
"MultVWt(...): dimension mismatch");
3156 for (
int i = 0; i < v.
Size(); i++)
3158 const double vi = v(i);
3159 for (
int j = 0; j < w.
Size(); j++)
3161 VWt(i, j) = vi * w(j);
3168 const int m = v.
Size(), n = w.
Size();
3173 mfem_error(
"AddMultVWt(...): dimension mismatch");
3177 for (
int i = 0; i < m; i++)
3179 const double vi = v(i);
3180 for (
int j = 0; j < n; j++)
3182 VWt(i, j) += vi * w(j);
3189 const int n = v.
Size();
3194 mfem_error(
"AddMultVVt(...): dimension mismatch");
3198 for (
int i = 0; i < n; i++)
3200 const double vi = v(i);
3201 for (
int j = 0; j < i; j++)
3203 const double vivj = vi * v(j);
3207 VVt(i, i) += vi * vi;
3214 const int m = v.
Size(), n = w.
Size();
3219 mfem_error(
"AddMult_a_VWt(...): dimension mismatch");
3223 for (
int j = 0; j < n; j++)
3225 const double awj =
a * w(j);
3226 for (
int i = 0; i < m; i++)
3228 VWt(i, j) += v(i) * awj;
3236 "incompatible dimensions!");
3238 const int n = v.
Size();
3239 for (
int i = 0; i < n; i++)
3241 double avi =
a * v(i);
3242 for (
int j = 0; j < i; j++)
3244 const double avivj = avi * v(j);
3248 VVt(i, i) += avi * v(i);
3256 RAP.SetSize(RA.Height(), P.
Width());
3265 RAP.SetSize(RA.Height(), P.
Width());
3271 #ifdef MFEM_USE_LAPACK 3277 double *data_ptr = this->
data;
3278 for (
int i = 0; i < m; i++)
3283 double a = std::abs(data_ptr[piv+i*m]);
3284 for (
int j = i+1; j < m; j++)
3286 const double b = std::abs(data_ptr[j+i*m]);
3297 for (
int j = 0; j < m; j++)
3299 mfem::Swap<double>(data_ptr[i+j*m], data_ptr[piv+j*m]);
3304 if (abs(data_ptr[i + i*m]) <= TOL)
3309 const double a_ii_inv = 1.0 / data_ptr[i+i*m];
3310 for (
int j = i+1; j < m; j++)
3312 data_ptr[j+i*m] *= a_ii_inv;
3314 for (
int k = i+1; k < m; k++)
3316 const double a_ik = data_ptr[i+k*m];
3317 for (
int j = i+1; j < m; j++)
3319 data_ptr[j+k*m] -= a_ik * data_ptr[j+i*m];
3331 for (
int i=0; i<m; i++)
3335 det *= -
data[m * i + i];
3339 det *=
data[m * i + i];
3348 for (
int k = 0; k < n; k++)
3351 for (
int i = 0; i < m; i++)
3353 double x_i = x[i] *
data[i+i*m];
3354 for (
int j = i+1; j < m; j++)
3356 x_i += x[j] *
data[i+j*m];
3361 for (
int i = m-1; i >= 0; i--)
3364 for (
int j = 0; j < i; j++)
3366 x_i += x[j] *
data[i+j*m];
3371 for (
int i = m-1; i >= 0; i--)
3382 for (
int k = 0; k < n; k++)
3385 for (
int i = 0; i < m; i++)
3390 for (
int j = 0; j < m; j++)
3392 const double x_j = x[j];
3393 for (
int i = j+1; i < m; i++)
3395 x[i] -=
data[i+j*m] * x_j;
3406 for (
int k = 0; k < n; k++)
3408 for (
int j = m-1; j >= 0; j--)
3410 const double x_j = ( x[j] /=
data[j+j*m] );
3411 for (
int i = 0; i < j; i++)
3413 x[i] -=
data[i+j*m] * x_j;
3422 #ifdef MFEM_USE_LAPACK 3426 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3437 #ifdef MFEM_USE_LAPACK 3438 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3442 dtrsm_(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3443 dtrsm_(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3449 for (
int k = 0; k < n; k++)
3451 for (
int j = 0; j < m; j++)
3453 const double x_j = ( x[j*n] /=
data[j+j*m]);
3454 for (
int i = j+1; i < m; i++)
3456 x[i*n] -=
data[j + i*m] * x_j;
3464 for (
int k = 0; k < n; k++)
3466 for (
int j = m-1; j >= 0; j--)
3468 const double x_j = x[j*n];
3469 for (
int i = 0; i < j; i++)
3471 x[i*n] -=
data[j + i*m] * x_j;
3479 for (
int k = 0; k < n; k++)
3481 for (
int i = m-1; i >= 0; --i)
3494 for (
int k = 0; k < m; k++)
3496 const double minus_x_k = -( x[k] = 1.0/
data[k+k*m] );
3497 for (
int i = 0; i < k; i++)
3499 x[i] =
data[i+k*m] * minus_x_k;
3501 for (
int j = k-1; j >= 0; j--)
3503 const double x_j = ( x[j] /=
data[j+j*m] );
3504 for (
int i = 0; i < j; i++)
3506 x[i] -=
data[i+j*m] * x_j;
3514 for (
int j = 0; j < k; j++)
3516 const double minus_L_kj = -
data[k+j*m];
3517 for (
int i = 0; i <= j; i++)
3519 X[i+j*m] += X[i+k*m] * minus_L_kj;
3521 for (
int i = j+1; i < m; i++)
3523 X[i+j*m] = X[i+k*m] * minus_L_kj;
3527 for (
int k = m-2; k >= 0; k--)
3529 for (
int j = 0; j < k; j++)
3531 const double L_kj =
data[k+j*m];
3532 for (
int i = 0; i < m; i++)
3534 X[i+j*m] -= X[i+k*m] * L_kj;
3539 for (
int k = m-1; k >= 0; k--)
3544 for (
int i = 0; i < m; i++)
3546 Swap<double>(X[i+k*m], X[i+piv_k*m]);
3553 const double *X1,
double *X2)
3556 for (
int k = 0; k < r; k++)
3558 for (
int j = 0; j < m; j++)
3560 const double x1_jk = X1[j+k*m];
3561 for (
int i = 0; i < n; i++)
3563 X2[i+k*n] -= A21[i+j*n] * x1_jk;
3570 int m,
int n,
double *A12,
double *A21,
double *A22)
const 3575 for (
int j = 0; j < m; j++)
3577 const double u_jj_inv = 1.0/
data[j+j*m];
3578 for (
int i = 0; i < n; i++)
3580 A21[i+j*n] *= u_jj_inv;
3582 for (
int k = j+1; k < m; k++)
3584 const double u_jk =
data[j+k*m];
3585 for (
int i = 0; i < n; i++)
3587 A21[i+k*n] -= A21[i+j*n] * u_jk;
3592 SubMult(m, n, n, A21, A12, A22);
3596 double *B1,
double *B2)
const 3601 SubMult(m, n, r, L21, B1, B2);
3605 const double *X2,
double *Y1)
const 3608 SubMult(n, m, r, U12, X2, Y1);
3616 #ifdef MFEM_USE_LAPACK 3619 MFEM_VERIFY(
data,
"Matrix data not set");
3624 for (
int j = 0; j<m; j++)
3627 for (
int k = 0; k<j; k++)
3632 MFEM_VERIFY(
data[j+j*m] -
a > 0.,
3633 "CholeskyFactors::Factor: The matrix is not SPD");
3635 data[j+j*m] = std::sqrt(
data[j+j*m] -
a);
3637 if (
data[j + j*m] <= TOL)
3642 for (
int i = j+1; i<m; i++)
3645 for (
int k = 0; k<j; k++)
3659 for (
int i=0; i<m; i++)
3661 det *=
data[i + i*m];
3670 for (
int k = 0; k < n; k++)
3672 for (
int j = m-1; j >= 0; j--)
3674 double x_j = x[j] *
data[j+j*m];
3675 for (
int i = 0; i < j; i++)
3677 x_j += x[i] *
data[j+i*m];
3688 for (
int k = 0; k < n; k++)
3690 for (
int i = 0; i < m; i++)
3692 double x_i = x[i] *
data[i+i*m];
3693 for (
int j = i+1; j < m; j++)
3695 x_i += x[j] *
data[j+i*m];
3706 #ifdef MFEM_USE_LAPACK 3713 MFEM_VERIFY(!info,
"CholeskyFactors:LSolve:: info");
3717 for (
int k = 0; k < n; k++)
3720 for (
int j = 0; j < m; j++)
3722 const double x_j = (x[j] /=
data[j+j*m]);
3723 for (
int i = j+1; i < m; i++)
3725 x[i] -=
data[i+j*m] * x_j;
3735 #ifdef MFEM_USE_LAPACK 3743 MFEM_VERIFY(!info,
"CholeskyFactors:USolve:: info");
3748 for (
int k = 0; k < n; k++)
3750 for (
int j = m-1; j >= 0; j--)
3752 const double x_j = ( x[j] /=
data[j+j*m] );
3753 for (
int i = 0; i < j; i++)
3755 x[i] -=
data[j+i*m] * x_j;
3765 #ifdef MFEM_USE_LAPACK 3769 MFEM_VERIFY(!info,
"CholeskyFactors:Solve:: info");
3779 #ifdef MFEM_USE_LAPACK 3789 dtrsm_(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3790 dtrsm_(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3795 for (
int k = 0; k < n; k++)
3797 for (
int j = 0; j < m; j++)
3799 const double x_j = ( x[j*n] /=
data[j+j*m]);
3800 for (
int i = j+1; i < m; i++)
3802 x[i*n] -=
data[i + j*m] * x_j;
3809 for (
int k = 0; k < n; k++)
3811 for (
int j = m-1; j >= 0; j--)
3813 const double x_j = (x[j*n] /=
data[j+j*m]);
3814 for (
int i = 0; i < j; i++)
3816 x[i*n] -=
data[j + i*m] * x_j;
3827 #ifdef MFEM_USE_LAPACK 3829 for (
int i = 0; i<m; i++)
3831 for (
int j = i; j<m; j++)
3833 X[j+i*m] =
data[j+i*m];
3838 dpotri_(&uplo, &m, X, &m, &info);
3839 MFEM_VERIFY(!info,
"CholeskyFactors:GetInverseMatrix:: info");
3841 for (
int i = 0; i<m; i++)
3843 for (
int j = i+1; j<m; j++)
3845 X[i+j*m] = X[j+i*m];
3850 for (
int k = 0; k<m; k++)
3852 X[k+k*m] = 1./
data[k+k*m];
3853 for (
int i = k+1; i < m; i++)
3856 for (
int j=k; j<i; j++)
3858 s -=
data[i+j*m] * X[j+k*m]/
data[i+i*m];
3863 for (
int i = 0; i < m; i++)
3865 for (
int j = i; j < m; j++)
3868 for (
int k=j; k<m; k++)
3870 s += X[k+i*m] * X[k+j*m];
3872 X[i+j*m] = X[j+i*m] =
s;
3879 void DenseMatrixInverse::Init(
int m)
3887 factors =
new LUFactors();
3891 factors->
data =
new double[m*m];
3894 dynamic_cast<LUFactors *
>(factors)->ipiv =
new int[m];
3903 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3912 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3919 MFEM_ASSERT(a,
"DenseMatrix is not given");
3920 const double *adata = a->data;
3922 for (
int i = 0; i <
s; i++)
3924 factors->
data[i] = adata[i];
3937 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
3941 if (own_data) {
delete [] factors->
data; }
3947 if (own_data) {
delete [] lu->
ipiv; }
3959 MFEM_VERIFY(
p != NULL,
"Operator is not a DenseMatrix!");
3965 for (
int row = 0; row <
height; row++)
3988 for (
int i = 0; i <
width; i++)
3999 delete [] factors->
data;
4002 delete []
dynamic_cast<LUFactors *
>(factors)->ipiv;
4008 #ifdef MFEM_USE_LAPACK 4023 &qwork, &lwork, &info);
4025 lwork = (int) qwork;
4026 work =
new double[lwork];
4031 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4036 lwork = other.lwork;
4038 work =
new double[lwork];
4044 if (mat.
Width() != n)
4046 mfem_error(
"DenseMatrixEigensystem::Eval(): dimension mismatch");
4052 work, &lwork, &info);
4056 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: " 4070 bool left_eigen_vectors,
4071 bool right_eigen_vectors)
4074 MFEM_VERIFY(A.
Height() == A.
Width(),
"A has to be a square matrix");
4075 MFEM_VERIFY(B.
Height() == B.
Width(),
"B has to be a square matrix");
4077 MFEM_VERIFY(B.
Height() == n,
"A and B dimension mismatch");
4083 if (left_eigen_vectors)
4088 if (right_eigen_vectors)
4097 alphar =
new double[n];
4098 alphai =
new double[n];
4099 beta =
new double[n];
4101 int nl = max(1,Vl.
Height());
4102 int nr = max(1,Vr.
Height());
4104 dggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4105 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4106 &qwork, &lwork, &info);
4108 lwork = (int) qwork;
4109 work =
new double[lwork];
4114 int nl = max(1,Vl.
Height());
4115 int nr = max(1,Vr.
Height());
4119 dggev_(&jobvl,&jobvr,&n,A_copy.Data(),&n,B_copy.
Data(),&n,alphar,
4120 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4121 work, &lwork, &info);
4125 mfem::err <<
"DenseMatrixGeneralizedEigensystem::Eval(): DGGEV error code: " 4131 for (
int i = 0; i<n; i++)
4135 evalues_r(i) = alphar[i]/beta[i];
4136 evalues_i(i) = alphai[i]/beta[i];
4155 bool left_singular_vectors,
4156 bool right_singular_vectors)
4160 jobu = (left_singular_vectors)?
'S' :
'N';
4161 jobvt = (right_singular_vectors)?
'S' :
'N';
4166 bool left_singular_vectors,
4167 bool right_singular_vectors)
4171 jobu = (left_singular_vectors)?
'S' :
'N';
4172 jobvt = (right_singular_vectors)?
'S' :
'N';
4176 void DenseMatrixSVD::Init()
4182 NULL, &n, &qwork, &lwork, &info);
4184 lwork = (int) qwork;
4185 work =
new double[lwork];
4196 double * datau =
nullptr;
4197 double * datavt =
nullptr;
4210 datavt, &n, work, &lwork, &info);
4214 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4224 #endif // if MFEM_USE_LAPACK 4231 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4239 for (
int i = 0; i < ne; i++)
4242 for (
int col = 0; col < n; col++)
4244 x_col = xp[dofs[col]];
4245 for (
int row = 0; row < n; row++)
4247 yp[dofs[row]] += x_col*d_col[row];
4256 for (
int i = 0; i < ne; i++)
4259 x_col = xp[dofs[0]];
4260 for (
int row = 0; row < n; row++)
4262 ye(row) = x_col*d_col[row];
4265 for (
int col = 1; col < n; col++)
4267 x_col = xp[dofs[col]];
4268 for (
int row = 0; row < n; row++)
4270 ye(row) += x_col*d_col[row];
4274 for (
int row = 0; row < n; row++)
4276 yp[dofs[row]] += ye(row);
4285 for (
int i=0; i<
s; i++)
4301 const int m = Mlu.
SizeI();
4302 const int NE = Mlu.
SizeK();
4308 pivot_flag[0] =
true;
4309 bool *d_pivot_flag = pivot_flag.ReadWrite();
4313 for (
int i = 0; i < m; i++)
4318 double a = fabs(data_all(piv,i,e));
4319 for (
int j = i+1; j < m; j++)
4321 const double b = fabs(data_all(j,i,e));
4328 ipiv_all(i,e) = piv;
4332 for (
int j = 0; j < m; j++)
4334 mfem::kernels::internal::Swap<double>(data_all(i,j,e), data_all(piv,j,e));
4339 if (abs(data_all(i,i,e)) <= TOL)
4341 d_pivot_flag[0] =
false;
4344 const double a_ii_inv = 1.0 / data_all(i,i,e);
4345 for (
int j = i+1; j < m; j++)
4347 data_all(j,i,e) *= a_ii_inv;
4350 for (
int k = i+1; k < m; k++)
4352 const double a_ik = data_all(i,k,e);
4353 for (
int j = i+1; j < m; j++)
4355 data_all(j,k,e) -= a_ik * data_all(j,i,e);
4363 MFEM_ASSERT(pivot_flag.HostRead()[0],
"Batch LU factorization failed \n");
4369 const int m = Mlu.
SizeI();
4370 const int NE = Mlu.
SizeK();
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void dsyevr_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
DenseMatrix & operator-=(const DenseMatrix &m)
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
void SquareRootInverse()
Replaces the current matrix with its square root inverse.
void RightSolve(int m, int n, double *X) const
void RightSolve(int m, int n, double *X) const
int CheckFinite(const double *v, const int n)
void trans(const Vector &u, Vector &x)
void BatchLUFactor(DenseTensor &Mlu, Array< int > &P, const double TOL)
Compute the LU factorization of a batch of matrices.
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
DenseMatrix & operator*=(double c)
void SetCol(int c, const double *col)
DenseTensor & operator=(double c)
Sets the tensor elements equal to constant c.
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void SetRow(int r, const double *row)
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
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...
void dtrtrs_(char *, char *, char *, int *, int *, double *, int *, double *, int *, int *)
void Mult(int m, int n, double *X) const
void dsyev_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
void SetSize(int s)
Resize the vector to size s.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
virtual double Det(int m) const
void Delete()
Delete the owned pointers and reset the Memory object.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void AddMultTranspose_a(double a, const Vector &x, Vector &y) const
y += a * A^t x
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
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...
void dpotrf_(char *, int *, double *, int *, int *)
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
DenseMatrixSVD(DenseMatrix &M, bool left_singular_vectors=false, bool right_singlular_vectors=false)
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
virtual void GetInverseMatrix(int m, double *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
virtual void Solve(int m, int n, double *X) const
int Size() const
Returns the size of the vector.
void dgetri_(int *N, double *A, int *LDA, int *IPIV, double *WORK, int *LWORK, int *INFO)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void TestInversion()
Invert and print the numerical conditioning of the inversion.
Data type dense matrix using column-major storage.
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
double * Data() const
Returns the matrix data array.
void Swap(DenseTensor &t)
void LSolve(int m, int n, double *X) const
void Eval(DenseMatrix &M)
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
Abstract data type for matrix inverse.
double Det() const
Compute the determinant of the original DenseMatrix using the LU factors.
void AddMult_a_ABt(double a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
void Factor()
Factor the current DenseMatrix, *a.
virtual void Solve(int m, int n, double *X) const
MFEM_HOST_DEVICE double CalcSingularvalue< 3 >(const double *data, const int i)
Return the i'th singular value of the matrix of size 3 with given data.
void GradToVectorCurl2D(DenseMatrix &curl)
void CalcOrtho(const DenseMatrix &J, Vector &n)
DenseMatrix & operator=(double c)
Sets the matrix elements equal to constant c.
void Set(double alpha, const double *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
double Trace() const
Trace of a square matrix.
void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
void BlockForwSolve(int m, int n, int r, const double *L21, double *B1, double *B2) const
void GetRowSums(Vector &l) const
Compute the row sums of the DenseMatrix.
void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, double *alpha, double *a, int *lda, double *b, int *ldb)
virtual double Det(int m) const
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_Eigensystem(DenseMatrix &a, DenseMatrix &b, Vector &ev, DenseMatrix *evect)
void Getl1Diag(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
static void SubMult(int m, int n, int r, const double *A21, const double *X1, double *X2)
virtual void GetInverseMatrix(int m, double *X) const
virtual void Solve(int m, int n, double *X) const
virtual void PrintMatlab(std::ostream &out=mfem::out) const
Prints operator in Matlab format.
void USolve(int m, int n, double *X) const
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)
virtual void PrintT(std::ostream &out=mfem::out, int width_=4) const
Prints the transpose matrix to stream out.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
double & operator()(int i, int j)
Returns reference to a_{ij}.
MFEM_HOST_DEVICE void CalcEigenvalues< 2 >(const double *data, double *lambda, double *vec)
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
friend class DenseMatrixInverse
double f(const Vector &xvec)
double * GetData() const
Returns the matrix data array.
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void Norm2(double *v) const
Take the 2-norm of the columns of A and store in v.
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
Abstract data type matrix.
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
void MultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
void Invert()
Replaces the current matrix with its inverse.
bool LinearSolve(DenseMatrix &A, double *X, double TOL)
Solves the dense linear system, A * X = B for X
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
void UMult(int m, int n, double *X) const
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
void dpotrs_(char *, int *, int *, double *, int *, double *, int *, int *)
DenseMatrixGeneralizedEigensystem(DenseMatrix &a, DenseMatrix &b, bool left_eigen_vectors=false, bool right_eigen_vectors=false)
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
void AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
void AddMultVVt(const Vector &v, DenseMatrix &VVt)
VVt += v v^t.
void CopyMNDiag(double 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 dgetrf_(int *, int *, double *, int *, int *, int *)
void SingularValues(Vector &sv) const
~DenseMatrixEigensystem()
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void Neg()
(*this) = -(*this)
void GetColumn(int c, Vector &col) const
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
MFEM_HOST_DEVICE void LUSolve(const double *data, const int m, const int *ipiv, double *x)
Assuming L.U = P.A for a factored matrix (m x m),.
int Capacity() const
Return the size of the allocated memory.
void LSolve(int m, int n, double *X) const
double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void Mult(const double *x, double *y) const
Matrix vector multiplication.
void LMult(int m, int n, double *X) const
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *)
double * GetData() const
Return a pointer to the beginning of the Vector data.
void Threshold(double eps)
Replace small entries, abs(a_ij) <= eps, with zero.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void TestInversion()
Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
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...
void Swap(Array< T > &, Array< T > &)
double p(const Vector &x, double t)
void CalcEigenvalues(double *lambda, double *vec) const
void Transpose()
(*this) = (*this)^t
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += a * A.x
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
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 AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *)
void BatchLUSolve(const DenseTensor &Mlu, const Array< int > &P, Vector &X)
Solve batch linear systems.
void GetRow(int r, Vector &row) const
virtual bool Factor(int m, double TOL=0.0)
Compute the Cholesky factorization of the current matrix.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
void USolve(int m, int n, double *X) const
void Swap(DenseMatrix &other)
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i<A.Height, 0<=j<A.Width.
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
A class to initialize the size of a Tensor.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
MFEM_HOST_DEVICE double CalcSingularvalue< 2 >(const double *data, const int i)
Return the i'th singular value of the matrix of size 2 with given data.
void SetSubMatrix(const Array< int > &idx, const DenseMatrix &A)
Set (*this)(idx[i],idx[j]) = A(i,j)
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 MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
int height
Dimension of the output / number of rows in the matrix.
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
const T * HostRead(const Memory< T > &mem, int size)
Shortcut to Read(const Memory<T> &mem, int size, false)
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void AddMultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
virtual ~DenseMatrix()
Destroys dense matrix.
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 CopyExceptMN(const DenseMatrix &A, int m, int n)
Copy All rows and columns except m and n from A.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
MFEM_HOST_DEVICE void CalcEigenvalues< 3 >(const double *data, double *lambda, double *vec)
virtual bool Factor(int m, double TOL=0.0)
Compute the LU factorization of the current matrix.
DenseMatrixInverse(bool spd_=false)
Default constructor.
static const int ipiv_base
void GradToCurl(DenseMatrix &curl)
int Rank(double tol) const
virtual void GetInverseMatrix(int m, double *X) const
Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual bool Factor(int m, double TOL=0.0)
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
int Size() const
Return the logical size of the array.
bool IsSquare() const
Returns whether the matrix is a square matrix.
DenseMatrixEigensystem(DenseMatrix &m)
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)
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
double operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
void dpotri_(char *, int *, double *, int *, int *)
void BlockFactor(int m, int n, double *A12, double *A21, double *A22) const
void BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt += A D A^t, where D is diagonal.
void GetFromVector(int offset, const Vector &v)
Get the matrix 'data' from the Vector 'v' at the given 'offset'.
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
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.
~DenseMatrixGeneralizedEigensystem()
double u(const Vector &xvec)
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void AddMult_a(double alpha, const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += alpha * B * C.
Rank 3 tensor (array of matrices)
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void AdjustDofDirection(Array< int > &dofs)
MFEM_HOST_DEVICE void Symmetrize(const int size, T *data)
Symmetrize a square matrix with given size and data: A -> (A+A^T)/2.
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void GradToDiv(Vector &div)
void AddMult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
int width
Dimension of the input / number of columns in the matrix.
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += a * A^t x
void AddSubMatrix(const Array< int > &idx, const DenseMatrix &A)
(*this)(idx[i],idx[j]) += A(i,j)
void dsyev_(char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *W, double *WORK, int *LWORK, int *INFO)
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
double FNorm() const
Compute the Frobenius norm of the matrix.
DenseMatrix & operator+=(const double *m)