20 #include "../general/table.hpp"
21 #include "../general/globals.hpp"
28 #if defined(_MSC_VER) && (_MSC_VER < 1800)
30 #define copysign _copysign
34 #ifdef MFEM_USE_LAPACK
36 dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
37 int *,
double *,
int *,
double *,
double *,
int *);
39 dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
41 dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
43 dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
44 int *LWORK,
int *INFO);
46 dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
47 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
48 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
49 int *IWORK,
int *LIWORK,
int *INFO);
51 dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
52 double *WORK,
int *LWORK,
int *INFO);
54 dsygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
double *A,
int *LDA,
55 double *B,
int *LDB,
double *W,
double *WORK,
int *LWORK,
int *INFO);
57 dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
58 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
59 int *LWORK,
int *INFO);
61 dtrsm_(
char *side,
char *uplo,
char *transa,
char *diag,
int *m,
int *n,
62 double *
alpha,
double *
a,
int *lda,
double *
b,
int *ldb);
81 MFEM_ASSERT(m.data,
"invalid source matrix");
83 std::memcpy(data, m.data,
sizeof(
double)*hw);
93 MFEM_ASSERT(s >= 0,
"invalid DenseMatrix size: " << s);
107 MFEM_ASSERT(m >= 0 && n >= 0,
108 "invalid DenseMatrix size: " << m <<
" x " << n);
109 const int capacity = m*n;
122 :
Matrix(mat.width, mat.height)
124 MFEM_CONTRACT_VAR(ch);
130 for (
int i = 0; i <
height; i++)
132 for (
int j = 0; j <
width; j++)
134 (*this)(i,j) = mat(j,i);
146 MFEM_ASSERT(h >= 0 && w >= 0,
147 "invalid DenseMatrix size: " << h <<
" x " << w);
181 "incompatible dimensions");
183 Mult((
const double *)x, (
double *)y);
189 "incompatible dimensions");
193 for (
int i = 0; i < hw; i++)
195 a += data[i] * m.data[i];
203 double *d_col =
Data();
204 for (
int col = 0; col <
width; col++)
207 for (
int row = 0; row <
height; row++)
209 y_col += x[row]*d_col[row];
219 "incompatible dimensions");
227 "incompatible dimensions");
229 const double *xp = x, *d_col = data;
231 for (
int col = 0; col <
width; col++)
233 double x_col = xp[col];
234 for (
int row = 0; row <
height; row++)
236 yp[row] += x_col*d_col[row];
245 "incompatible dimensions");
247 const double *d_col = data;
248 for (
int col = 0; col <
width; col++)
251 for (
int row = 0; row <
height; row++)
253 y_col += x[row]*d_col[row];
263 "incompatible dimensions");
265 const double *xp = x, *d_col = data;
267 for (
int col = 0; col <
width; col++)
269 const double x_col = a*xp[col];
270 for (
int row = 0; row <
height; row++)
272 yp[row] += x_col*d_col[row];
282 "incompatible dimensions");
284 const double *d_col = data;
285 for (
int col = 0; col <
width; col++)
288 for (
int row = 0; row <
height; row++)
290 y_col += x[row]*d_col[row];
301 for (
int i = 0; i <
height; i++)
304 for (
int j = 0; j <
width; j++)
306 Axi += (*this)(i,j) * x[j];
317 double * it_data = data;
318 for (
int j = 0; j <
width; ++j)
320 for (
int i = 0; i <
height; ++i)
322 *(it_data++) *= s(i);
330 double * it_data = data;
331 for (
int j = 0; j <
width; ++j)
333 for (
int i = 0; i <
height; ++i)
335 *(it_data++) /= s(i);
344 double * it_data = data;
345 for (
int j = 0; j <
width; ++j)
348 for (
int i = 0; i <
height; ++i)
358 double * it_data = data;
359 for (
int j = 0; j <
width; ++j)
361 const double sj = 1./s(j);
362 for (
int i = 0; i <
height; ++i)
377 double * ss =
new double[
width];
380 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
382 *(it_ss++) = sqrt(*it_s);
385 double * it_data = data;
386 for (
int j = 0; j <
width; ++j)
388 for (
int i = 0; i <
height; ++i)
390 *(it_data++) *= ss[i]*ss[j];
405 double * ss =
new double[
width];
408 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
410 *(it_ss++) = 1./sqrt(*it_s);
413 double * it_data = data;
414 for (
int j = 0; j <
width; ++j)
416 for (
int i = 0; i <
height; ++i)
418 *(it_data++) *= ss[i]*ss[j];
430 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
436 for (
int i = 0; i <
width; i++)
452 "The matrix must be square and "
453 <<
"sized larger than zero to compute the determinant."
454 <<
" Height() = " <<
Height()
455 <<
", Width() = " <<
Width());
463 return data[0] * data[3] - data[1] * data[2];
467 const double *d = data;
469 d[0] * (d[4] * d[8] - d[5] * d[7]) +
470 d[3] * (d[2] * d[7] - d[1] * d[8]) +
471 d[6] * (d[1] * d[5] - d[2] * d[4]);
475 const double *d = data;
477 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
478 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
479 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
481 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
482 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
483 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
485 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
486 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
487 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
489 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
490 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
491 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
500 return lu_factors.
Det();
515 return sqrt(data[0] * data[0] + data[1] * data[1]);
519 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
523 const double *d = data;
524 double E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
525 double G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
526 double F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
527 return sqrt(E * G - F * F);
536 for (
int i = 0; i < s; i++)
538 data[i] = alpha*A[i];
544 for (
int j = 0; j <
Width(); j++)
546 for (
int i = 0; i <
Height(); i++)
548 (*this)(i,j) += c * A(i,j);
556 for (
int i = 0; i < s; i++)
566 for (
int i = 0; i < s; i++)
578 for (
int i = 0; i < hw; i++)
589 for (
int i = 0; i < hw; i++)
599 "incompatible matrix sizes.");
605 for (
int j = 0; j <
width; j++)
607 for (
int i = 0; i <
height; i++)
609 (*this)(i, j) -= m(i, j);
619 for (
int i = 0; i < s; i++)
629 for (
int i = 0; i < hw; i++)
644 #ifdef MFEM_USE_LAPACK
645 int *ipiv =
new int[
width];
654 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
660 work =
new double[lwork];
666 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
672 int c, i, j, n =
Width();
676 for (c = 0; c < n; c++)
678 a = fabs((*
this)(c, c));
680 for (j = c + 1; j < n; j++)
682 b = fabs((*
this)(j, c));
691 mfem_error(
"DenseMatrix::Invert() : singular matrix");
694 for (j = 0; j < n; j++)
696 Swap<double>((*this)(c, j), (*
this)(i, j));
699 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
700 for (j = 0; j < c; j++)
704 for (j++; j < n; j++)
708 for (i = 0; i < c; i++)
710 (*this)(i, c) = a * (b = -(*
this)(i, c));
711 for (j = 0; j < c; j++)
713 (*this)(i, j) += b * (*
this)(c, j);
715 for (j++; j < n; j++)
717 (*this)(i, j) += b * (*
this)(c, j);
720 for (i++; i < n; i++)
722 (*this)(i, c) = a * (b = -(*
this)(i, c));
723 for (j = 0; j < c; j++)
725 (*this)(i, j) += b * (*
this)(c, j);
727 for (j++; j < n; j++)
729 (*this)(i, j) += b * (*
this)(c, j);
734 for (c = n - 1; c >= 0; c--)
737 for (i = 0; i < n; i++)
739 Swap<double>((*this)(i, c), (*
this)(i, j));
751 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
761 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
763 for (
int j = 0; j < 10; j++)
765 for (
int i = 0; i < 10; i++)
780 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
781 if (tmp2.FNorm() < 1e-10) {
break; }
784 if (tmp2.FNorm() > 1e-10)
786 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
792 for (
int j = 0; j <
Width(); j++)
795 for (
int i = 0; i <
Height(); i++)
797 v[j] += (*this)(i,j)*(*
this)(i,j);
806 const double *d = data;
807 double norm = 0.0, abs_entry;
809 for (
int i = 0; i < hw; i++)
811 abs_entry = fabs(d[i]);
812 if (norm < abs_entry)
824 double max_norm = 0.0, entry, fnorm2;
826 for (i = 0; i < hw; i++)
828 entry = fabs(data[i]);
829 if (entry > max_norm)
837 scale_factor = scaled_fnorm2 = 0.0;
842 for (i = 0; i < hw; i++)
844 entry = data[i] / max_norm;
845 fnorm2 += entry * entry;
848 scale_factor = max_norm;
849 scaled_fnorm2 = fnorm2;
854 #ifdef MFEM_USE_LAPACK
861 double *A =
new double[N*N];
872 int *ISUPPZ =
new int[2*N];
891 double *data = a.
Data();
893 for (
int i = 0; i < hw; i++)
898 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
899 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
900 &QIWORK, &LIWORK, &INFO );
905 WORK =
new double[LWORK];
906 IWORK =
new int[LIWORK];
908 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
909 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
910 IWORK, &LIWORK, &INFO );
914 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: "
922 mfem::err <<
"dsyevr_Eigensystem(...):\n"
923 <<
" DSYEVR did not find all eigenvalues "
924 << M <<
"/" << N << endl;
929 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
933 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
936 for (IL = 0; IL < N; IL++)
937 for (IU = 0; IU <= IL; IU++)
940 for (M = 0; M < N; M++)
942 VL += Z[M+IL*N] * Z[M+IU*N];
959 <<
" Z^t Z - I deviation = " << VU
960 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
961 << W[0] <<
", N = " << N << endl;
968 <<
" Z^t Z - I deviation = " << VU
969 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
970 << W[0] <<
", N = " << N << endl;
974 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
977 for (IL = 0; IL < N; IL++)
978 for (IU = 0; IU < N; IU++)
981 for (M = 0; M < N; M++)
983 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
985 VL = fabs(VL-data[IL+N*IU]);
994 <<
" max matrix deviation = " << VU
995 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
996 << W[0] <<
", N = " << N << endl;
1000 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1009 MFEM_CONTRACT_VAR(a);
1010 MFEM_CONTRACT_VAR(ev);
1011 MFEM_CONTRACT_VAR(evect);
1017 #ifdef MFEM_USE_LAPACK
1029 double *WORK = NULL;
1040 A =
new double[N*N];
1044 double *data = a.
Data();
1045 for (
int i = 0; i < hw; i++)
1050 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1052 LWORK = (int) QWORK;
1053 WORK =
new double[LWORK];
1055 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1059 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1064 if (evect == NULL) {
delete [] A; }
1066 MFEM_CONTRACT_VAR(a);
1067 MFEM_CONTRACT_VAR(ev);
1068 MFEM_CONTRACT_VAR(evect);
1072 void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1074 #ifdef MFEM_USE_LAPACK
1082 MFEM_CONTRACT_VAR(ev);
1083 MFEM_CONTRACT_VAR(evect);
1092 #ifdef MFEM_USE_LAPACK
1105 double *B =
new double[N*N];
1107 double *WORK = NULL;
1118 A =
new double[N*N];
1122 double *a_data = a.
Data();
1123 double *b_data = b.
Data();
1124 for (
int i = 0; i < hw; i++)
1130 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1132 LWORK = (int) QWORK;
1133 WORK =
new double[LWORK];
1135 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1139 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1145 if (evect == NULL) {
delete [] A; }
1147 MFEM_CONTRACT_VAR(a);
1148 MFEM_CONTRACT_VAR(b);
1149 MFEM_CONTRACT_VAR(ev);
1150 MFEM_CONTRACT_VAR(evect);
1154 void DenseMatrix::Eigensystem(DenseMatrix &
b, Vector &ev,
1157 #ifdef MFEM_USE_LAPACK
1162 MFEM_CONTRACT_VAR(b);
1163 MFEM_CONTRACT_VAR(ev);
1164 MFEM_CONTRACT_VAR(evect);
1165 mfem_error(
"DenseMatrix::Eigensystem for generalized eigenvalues");
1171 #ifdef MFEM_USE_LAPACK
1177 double *
a = copy_of_this.data;
1182 double *work = NULL;
1187 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
1188 s, u, &m, vt, &n, &qwork, &lwork, &info);
1190 lwork = (int) qwork;
1191 work =
new double[lwork];
1193 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
1194 s, u, &m, vt, &n, work, &lwork, &info);
1199 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1203 MFEM_CONTRACT_VAR(sv);
1215 for (
int i=0; i < sv.
Size(); ++i)
1227 "The matrix must be square and sized 1, 2, or 3 to compute the"
1229 <<
" Height() = " <<
Height()
1230 <<
", Width() = " <<
Width());
1233 const double *d = data;
1259 const double *d = data;
1277 const double* rp = data + r;
1280 for (
int i = 0; i < n; i++)
1292 double *cp =
Data() + c * m;
1295 for (
int i = 0; i < m; i++)
1309 for (
int i = 0; i <
height; ++i)
1311 d(i) = (*this)(i,i);
1325 for (
int j = 0; j <
width; ++j)
1326 for (
int i = 0; i <
height; ++i)
1328 l(i) += fabs((*
this)(i,j));
1335 for (
int i = 0; i <
height; i++)
1338 for (
int j = 0; j <
width; j++)
1351 for (
int i = 0; i < N; i++)
1355 for (
int i = 0; i < n; i++)
1366 for (i = 0; i < N; i++)
1370 for (i = 0; i < n; i++)
1372 data[i*(n+1)] = diag[i];
1383 for (i = 0; i <
Height(); i++)
1384 for (j = i+1; j <
Width(); j++)
1387 (*this)(i,j) = (*
this)(j,i);
1402 for (
int i = 0; i <
Height(); i++)
1403 for (
int j = 0; j <
Width(); j++)
1405 (*this)(i,j) = A(j,i);
1414 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1422 for (
int i = 0; i <
Height(); i++)
1425 for (
int j = 0; j <
Width(); j++)
1428 (*this)(i, j) = 0.0;
1448 for (
int i = 0; i < n; i++)
1451 double x = (*this)(i,0);
1452 double y = (*this)(i,1);
1465 for (
int i = 0; i < n; i++)
1468 double x = (*this)(i,0);
1469 double y = (*this)(i,1);
1470 double z = (*this)(i,2);
1495 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1500 double *ddata = div.
GetData();
1502 for (
int i = 0; i < n; i++)
1512 for (
int j = 0; j <
Width(); j++)
1514 for (
int i = row1; i <= row2; i++)
1516 (*this)(i-row1,j) = A(i,j);
1525 for (
int j = col1; j <= col2; j++)
1527 for (
int i = 0; i <
Height(); i++)
1529 (*this)(i,j-col1) = A(i,j);
1538 for (
int j = 0; j < n; j++)
1540 for (
int i = 0; i < m; i++)
1542 (*this)(i,j) = A(Aro+i,Aco+j);
1549 double *v = A.
Data();
1551 for (
int j = 0; j < A.
Width(); j++)
1553 for (
int i = 0; i < A.
Height(); i++)
1555 (*this)(row_offset+i,col_offset+j) = *(v++);
1562 double *v = A.
Data();
1564 for (
int i = 0; i < A.
Width(); i++)
1566 for (
int j = 0; j < A.
Height(); j++)
1568 (*this)(row_offset+i,col_offset+j) = *(v++);
1574 int row_offset,
int col_offset)
1576 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1577 "this DenseMatrix is too small to accomodate the submatrix. "
1578 <<
"row_offset = " << row_offset
1580 <<
", this->Height() = " << this->
Height()
1581 <<
", col_offset = " << col_offset
1583 <<
", this->Width() = " << this->
Width()
1585 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1586 "The A DenseMatrix is too small to accomodate the submatrix. "
1589 <<
", A.Height() = " << A.
Height()
1590 <<
", Aco = " << Aco
1592 <<
", A.Width() = " << A.
Width()
1595 for (
int j = 0; j < n; j++)
1597 for (
int i = 0; i < m; i++)
1599 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1606 for (
int i = 0; i < n; i++)
1608 for (
int j = i+1; j < n; j++)
1610 (*this)(row_offset+i,col_offset+j) =
1611 (*
this)(row_offset+j,col_offset+i) = 0.0;
1615 for (
int i = 0; i < n; i++)
1617 (*this)(row_offset+i,col_offset+i) = c;
1624 for (
int i = 0; i < n; i++)
1626 for (
int j = i+1; j < n; j++)
1628 (*this)(row_offset+i,col_offset+j) =
1629 (*
this)(row_offset+j,col_offset+i) = 0.0;
1633 for (
int i = 0; i < n; i++)
1635 (*this)(row_offset+i,col_offset+i) = diag[i];
1643 int i, j, i_off = 0, j_off = 0;
1645 for (j = 0; j < A.
Width(); j++)
1652 for (i = 0; i < A.
Height(); i++)
1659 (*this)(i-i_off,j-j_off) = A(i,j);
1675 if (co+aw >
Width() || ro+ah > h)
1681 p = data + ro + co * h;
1684 for (
int c = 0; c < aw; c++)
1686 for (
int r = 0; r < ah; r++)
1705 if (co+aw >
Width() || ro+ah > h)
1711 p = data + ro + co * h;
1714 for (
int c = 0; c < aw; c++)
1716 for (
int r = 0; r < ah; r++)
1728 double *vdata = v.
GetData() + offset;
1730 for (
int i = 0; i < n; i++)
1732 vdata[i] += data[i];
1739 const double *vdata = v.
GetData() + offset;
1741 for (
int i = 0; i < n; i++)
1754 mfem_error(
"DenseMatrix::AdjustDofDirection(...)");
1759 for (
int i = 0; i < n-1; i++)
1761 const int s = (dof[i] < 0) ? (-1) : (1);
1762 for (
int j = i+1; j < n; j++)
1764 const int t = (dof[j] < 0) ? (-s) : (s);
1767 (*this)(i,j) = -(*
this)(i,j);
1768 (*this)(j,i) = -(*
this)(j,i);
1776 for (
int j = 0; j <
Width(); j++)
1778 (*this)(row, j) = value;
1784 for (
int i = 0; i <
Height(); i++)
1786 (*this)(i, col) = value;
1792 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
1793 for (
int j = 0; j <
Width(); j++)
1795 (*this)(r, j) = row[j];
1807 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
1808 for (
int i = 0; i <
Height(); i++)
1810 (*this)(i, c) = col[i];
1822 for (
int col = 0; col <
Width(); col++)
1824 for (
int row = 0; row <
Height(); row++)
1826 if (std::abs(
operator()(row,col)) <= eps)
1837 ios::fmtflags old_flags = out.flags();
1839 out << setiosflags(ios::scientific | ios::showpos);
1840 for (
int i = 0; i <
height; i++)
1842 out <<
"[row " << i <<
"]\n";
1843 for (
int j = 0; j <
width; j++)
1845 out << (*this)(i,j);
1846 if (j+1 == width || (j+1) % width_ == 0)
1857 out.flags(old_flags);
1863 ios::fmtflags old_flags = out.flags();
1865 out << setiosflags(ios::scientific | ios::showpos);
1866 for (
int i = 0; i <
height; i++)
1868 for (
int j = 0; j <
width; j++)
1870 out << (*this)(i,j);
1876 out.flags(old_flags);
1882 ios::fmtflags old_flags = out.flags();
1884 out << setiosflags(ios::scientific | ios::showpos);
1885 for (
int j = 0; j <
width; j++)
1887 out <<
"[col " << j <<
"]\n";
1888 for (
int i = 0; i <
height; i++)
1890 out << (*this)(i,j);
1891 if (i+1 == height || (i+1) % width_ == 0)
1902 out.flags(old_flags);
1911 for (
int i = 0; i <
width; i++)
1916 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
1937 for (
int i = 0; i < m; i++)
1939 C_data[i] = alpha*A[i] + beta*B[i];
1955 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
1956 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
1957 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
1965 double det = A(0,0);
1966 if (std::abs(det) <= TOL) {
return false; }
1973 double det = A.
Det();
1974 if (std::abs(det) <= TOL) {
return false; }
1976 double invdet = 1. / det;
1981 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
1982 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
1991 if (!lu.Factor(N,TOL)) {
return false; }
2004 b.
Width() == c.
Height(),
"incompatible dimensions");
2006 #ifdef MFEM_USE_LAPACK
2007 static char transa =
'N', transb =
'N';
2008 static double alpha = 1.0, beta = 0.0;
2011 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
2012 c.
Data(), &k, &beta, a.
Data(), &m);
2014 const int ah = a.
Height();
2015 const int aw = a.
Width();
2016 const int bw = b.
Width();
2017 double *ad = a.
Data();
2018 const double *bd = b.
Data();
2019 const double *cd = c.
Data();
2028 b.
Width() == c.
Height(),
"incompatible dimensions");
2030 #ifdef MFEM_USE_LAPACK
2031 static char transa =
'N', transb =
'N';
2032 static double beta = 1.0;
2035 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
2036 c.
Data(), &k, &beta, a.
Data(), &m);
2038 const int ah = a.
Height();
2039 const int aw = a.
Width();
2040 const int bw = b.
Width();
2041 double *ad = a.
Data();
2042 const double *bd = b.
Data();
2043 const double *cd = c.
Data();
2044 for (
int j = 0; j < aw; j++)
2046 for (
int k = 0; k < bw; k++)
2048 for (
int i = 0; i < ah; i++)
2050 ad[i+j*ah] += alpha * bd[i+k*ah] * cd[k+j*bw];
2060 b.
Width() == c.
Height(),
"incompatible dimensions");
2062 #ifdef MFEM_USE_LAPACK
2063 static char transa =
'N', transb =
'N';
2064 static double alpha = 1.0, beta = 1.0;
2067 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
2068 c.
Data(), &k, &beta, a.
Data(), &m);
2070 const int ah = a.
Height();
2071 const int aw = a.
Width();
2072 const int bw = b.
Width();
2073 double *ad = a.
Data();
2074 const double *bd = b.
Data();
2075 const double *cd = c.
Data();
2076 for (
int j = 0; j < aw; j++)
2078 for (
int k = 0; k < bw; k++)
2080 for (
int i = 0; i < ah; i++)
2082 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2104 const double *d = a.
Data();
2105 double *ad = adja.
Data();
2120 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2121 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2122 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2124 ad[0] = d[0]*g - d[3]*f;
2125 ad[1] = d[3]*e - d[0]*f;
2126 ad[2] = d[1]*g - d[4]*f;
2127 ad[3] = d[4]*e - d[1]*f;
2128 ad[4] = d[2]*g - d[5]*f;
2129 ad[5] = d[5]*e - d[2]*f;
2138 else if (a.
Width() == 2)
2141 adja(0,1) = -
a(0,1);
2142 adja(1,0) = -
a(1,0);
2147 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2148 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2149 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2151 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2152 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2153 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2155 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2156 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2157 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2174 else if (a.
Width() == 2)
2176 adjat(0,0) =
a(1,1);
2177 adjat(1,0) = -
a(0,1);
2178 adjat(0,1) = -
a(1,0);
2179 adjat(1,1) =
a(0,0);
2183 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2184 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2185 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2187 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2188 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2189 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2191 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2192 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2193 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2200 MFEM_ASSERT(inva.
Height() == a.
Width(),
"incorrect dimensions");
2201 MFEM_ASSERT(inva.
Width() == a.
Height(),
"incorrect dimensions");
2207 const double *d = a.
Data();
2208 double *
id = inva.
Data();
2211 t = 1.0 / (d[0]*d[0] + d[1]*d[1]);
2219 t = 1.0 / (d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
2227 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2228 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2229 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2230 t = 1.0 / (e*g - f*f);
2231 e *= t; g *= t; f *= t;
2233 id[0] = d[0]*g - d[3]*f;
2234 id[1] = d[3]*e - d[0]*f;
2235 id[2] = d[1]*g - d[4]*f;
2236 id[3] = d[4]*e - d[1]*f;
2237 id[4] = d[2]*g - d[5]*f;
2238 id[5] = d[5]*e - d[2]*f;
2246 MFEM_ASSERT(std::abs(t) > 1.0e-14 * pow(a.FNorm()/a.
Width(), a.
Width()),
2247 "singular matrix!");
2253 inva(0,0) = 1.0 / a.
Det();
2256 kernels::CalcInverse<2>(a.
Data(), inva.
Data());
2259 kernels::CalcInverse<3>(a.
Data(), inva.
Data());
2274 double t = 1. / a.
Det() ;
2279 inva(0,0) = 1.0 /
a(0,0);
2282 inva(0,0) =
a(1,1) * t ;
2283 inva(1,0) = -
a(0,1) * t ;
2284 inva(0,1) = -
a(1,0) * t ;
2285 inva(1,1) =
a(0,0) * t ;
2288 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*t;
2289 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*t;
2290 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*t;
2292 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*t;
2293 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*t;
2294 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*t;
2296 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*t;
2297 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*t;
2298 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*t;
2308 "Matrix must be 3x2 or 2x1, "
2309 <<
"and the Vector must be sized with the rows. "
2310 <<
" J.Height() = " << J.
Height()
2311 <<
", J.Width() = " << J.
Width()
2312 <<
", n.Size() = " << n.
Size()
2315 const double *d = J.
Data();
2323 n(0) = d[1]*d[5] - d[2]*d[4];
2324 n(1) = d[2]*d[3] - d[0]*d[5];
2325 n(2) = d[0]*d[4] - d[1]*d[3];
2331 const int height = a.
Height();
2332 const int width = a.
Width();
2333 for (
int i = 0; i < height; i++)
2335 for (
int j = 0; j <= i; j++)
2338 for (
int k = 0; k < width; k++)
2340 temp +=
a(i,k) *
a(j,k);
2342 aat(j,i) = aat(i,j) = temp;
2349 for (
int i = 0; i < A.
Height(); i++)
2351 for (
int j = 0; j < i; j++)
2354 for (
int k = 0; k < A.
Width(); k++)
2356 t += D(k) * A(i, k) * A(j, k);
2364 for (
int i = 0; i < A.
Height(); i++)
2367 for (
int k = 0; k < A.
Width(); k++)
2369 t += D(k) * A(i, k) * A(i, k);
2377 for (
int i = 0; i < A.
Height(); i++)
2379 for (
int j = 0; j <= i; j++)
2382 for (
int k = 0; k < A.
Width(); k++)
2384 t += D(k) * A(i, k) * A(j, k);
2386 ADAt(j, i) = ADAt(i, j) = t;
2401 #ifdef MFEM_USE_LAPACK
2402 static char transa =
'N', transb =
'T';
2403 static double alpha = 1.0, beta = 0.0;
2406 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
2407 B.
Data(), &n, &beta, ABt.
Data(), &m);
2409 const int ah = A.
Height();
2410 const int bh = B.
Height();
2411 const int aw = A.
Width();
2412 const double *ad = A.
Data();
2413 const double *bd = B.
Data();
2414 double *cd = ABt.
Data();
2418 const int ah = A.
Height();
2419 const int bh = B.
Height();
2420 const int aw = A.
Width();
2421 const double *ad = A.
Data();
2422 const double *bd = B.
Data();
2423 double *cd = ABt.
Data();
2425 for (
int j = 0; j < bh; j++)
2426 for (
int i = 0; i < ah; i++)
2429 const double *ap = ad + i;
2430 const double *bp = bd + j;
2431 for (
int k = 0; k < aw; k++)
2443 for (i = 0; i < A.
Height(); i++)
2444 for (j = 0; j < B.
Height(); j++)
2447 for (k = 0; k < A.
Width(); k++)
2449 d += A(i, k) * B(j, k);
2467 const int ah = A.
Height();
2468 const int bh = B.
Height();
2469 const int aw = A.
Width();
2470 const double *ad = A.
Data();
2471 const double *bd = B.
Data();
2472 const double *dd = D.
GetData();
2473 double *cd = ADBt.
Data();
2475 for (
int i = 0, s = ah*bh; i < s; i++)
2479 for (
int k = 0; k < aw; k++)
2482 for (
int j = 0; j < bh; j++)
2484 const double dk_bjk = dd[k] * bd[j];
2485 for (
int i = 0; i < ah; i++)
2487 cp[i] += ad[i] * dk_bjk;
2506 #ifdef MFEM_USE_LAPACK
2507 static char transa =
'N', transb =
'T';
2508 static double alpha = 1.0, beta = 1.0;
2511 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
2512 B.
Data(), &n, &beta, ABt.
Data(), &m);
2514 const int ah = A.
Height();
2515 const int bh = B.
Height();
2516 const int aw = A.
Width();
2517 const double *ad = A.
Data();
2518 const double *bd = B.
Data();
2519 double *cd = ABt.
Data();
2521 for (
int k = 0; k < aw; k++)
2524 for (
int j = 0; j < bh; j++)
2526 const double bjk = bd[j];
2527 for (
int i = 0; i < ah; i++)
2529 cp[i] += ad[i] * bjk;
2540 for (i = 0; i < A.
Height(); i++)
2541 for (j = 0; j < B.
Height(); j++)
2544 for (k = 0; k < A.
Width(); k++)
2546 d += A(i, k) * B(j, k);
2564 const int ah = A.
Height();
2565 const int bh = B.
Height();
2566 const int aw = A.
Width();
2567 const double *ad = A.
Data();
2568 const double *bd = B.
Data();
2569 const double *dd = D.
GetData();
2570 double *cd = ADBt.
Data();
2572 for (
int k = 0; k < aw; k++)
2575 for (
int j = 0; j < bh; j++)
2577 const double dk_bjk = dd[k] * bd[j];
2578 for (
int i = 0; i < ah; i++)
2580 cp[i] += ad[i] * dk_bjk;
2600 #ifdef MFEM_USE_LAPACK
2601 static char transa =
'N', transb =
'T';
2603 static double beta = 1.0;
2606 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
2607 B.
Data(), &n, &beta, ABt.
Data(), &m);
2609 const int ah = A.
Height();
2610 const int bh = B.
Height();
2611 const int aw = A.
Width();
2612 const double *ad = A.
Data();
2613 const double *bd = B.
Data();
2614 double *cd = ABt.
Data();
2616 for (
int k = 0; k < aw; k++)
2619 for (
int j = 0; j < bh; j++)
2621 const double bjk = a * bd[j];
2622 for (
int i = 0; i < ah; i++)
2624 cp[i] += ad[i] * bjk;
2635 for (i = 0; i < A.
Height(); i++)
2636 for (j = 0; j < B.
Height(); j++)
2639 for (k = 0; k < A.
Width(); k++)
2641 d += A(i, k) * B(j, k);
2658 #ifdef MFEM_USE_LAPACK
2659 static char transa =
'T', transb =
'N';
2660 static double alpha = 1.0, beta = 0.0;
2663 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &k,
2664 B.
Data(), &k, &beta, AtB.
Data(), &m);
2666 const int ah = A.
Height();
2667 const int aw = A.
Width();
2668 const int bw = B.
Width();
2669 const double *ad = A.
Data();
2670 const double *bd = B.
Data();
2671 double *cd = AtB.
Data();
2673 for (
int j = 0; j < bw; j++)
2675 const double *ap = ad;
2676 for (
int i = 0; i < aw; i++)
2679 for (
int k = 0; k < ah; k++)
2692 for (i = 0; i < A.
Width(); i++)
2693 for (j = 0; j < B.
Width(); j++)
2696 for (k = 0; k < A.
Height(); k++)
2698 d += A(k, i) * B(k, j);
2709 for (
int i = 0; i < A.
Height(); i++)
2711 for (
int j = 0; j < i; j++)
2714 for (
int k = 0; k < A.
Width(); k++)
2716 d += A(i,k) * A(j,k);
2718 AAt(i, j) += (d *=
a);
2722 for (
int k = 0; k < A.
Width(); k++)
2724 d += A(i,k) * A(i,k);
2732 for (
int i = 0; i < A.
Height(); i++)
2734 for (
int j = 0; j <= i; j++)
2737 for (
int k = 0; k < A.
Width(); k++)
2739 d += A(i,k) * A(j,k);
2741 AAt(i, j) = AAt(j, i) = a * d;
2748 for (
int i = 0; i < v.
Size(); i++)
2750 for (
int j = 0; j <= i; j++)
2752 vvt(i,j) = vvt(j,i) = v(i) * v(j);
2766 for (
int i = 0; i < v.
Size(); i++)
2768 const double vi = v(i);
2769 for (
int j = 0; j < w.
Size(); j++)
2771 VWt(i, j) = vi * w(j);
2778 const int m = v.
Size(), n = w.
Size();
2787 for (
int i = 0; i < m; i++)
2789 const double vi = v(i);
2790 for (
int j = 0; j < n; j++)
2792 VWt(i, j) += vi * w(j);
2799 const int n = v.
Size();
2808 for (
int i = 0; i < n; i++)
2810 const double vi = v(i);
2811 for (
int j = 0; j < i; j++)
2813 const double vivj = vi * v(j);
2817 VVt(i, i) += vi * vi;
2824 const int m = v.
Size(), n = w.
Size();
2833 for (
int j = 0; j < n; j++)
2835 const double awj = a * w(j);
2836 for (
int i = 0; i < m; i++)
2838 VWt(i, j) += v(i) * awj;
2846 "incompatible dimensions!");
2848 const int n = v.
Size();
2849 for (
int i = 0; i < n; i++)
2851 double avi = a * v(i);
2852 for (
int j = 0; j < i; j++)
2854 const double avivj = avi * v(j);
2858 VVt(i, i) += avi * v(i);
2865 #ifdef MFEM_USE_LAPACK
2872 for (
int i = 0; i < m; i++)
2877 double a = std::abs(data[piv+i*m]);
2878 for (
int j = i+1; j < m; j++)
2880 const double b = std::abs(data[j+i*m]);
2891 for (
int j = 0; j < m; j++)
2893 Swap<double>(data[i+j*m], data[piv+j*m]);
2898 if (abs(data[i + i*m]) <= TOL)
2903 const double a_ii_inv = 1.0 / data[i+i*m];
2904 for (
int j = i+1; j < m; j++)
2906 data[j+i*m] *= a_ii_inv;
2908 for (
int k = i+1; k < m; k++)
2910 const double a_ik = data[i+k*m];
2911 for (
int j = i+1; j < m; j++)
2913 data[j+k*m] -= a_ik * data[j+i*m];
2925 for (
int i=0; i<m; i++)
2929 det *= -
data[m * i + i];
2933 det *=
data[m * i + i];
2944 for (
int k = 0; k < n; k++)
2947 for (
int i = 0; i < m; i++)
2949 double x_i = x[i] * data[i+i*m];
2950 for (
int j = i+1; j < m; j++)
2952 x_i += x[j] * data[i+j*m];
2957 for (
int i = m-1; i >= 0; i--)
2960 for (
int j = 0; j < i; j++)
2962 x_i += x[j] * data[i+j*m];
2967 for (
int i = m-1; i >= 0; i--)
2969 Swap<double>(x[i], x[ipiv[i]-
ipiv_base]);
2980 for (
int k = 0; k < n; k++)
2983 for (
int i = 0; i < m; i++)
2985 Swap<double>(x[i], x[ipiv[i]-
ipiv_base]);
2988 for (
int j = 0; j < m; j++)
2990 const double x_j = x[j];
2991 for (
int i = j+1; i < m; i++)
2993 x[i] -= data[i+j*m] * x_j;
3005 for (
int k = 0; k < n; k++)
3007 for (
int j = m-1; j >= 0; j--)
3009 const double x_j = ( x[j] /= data[j+j*m] );
3010 for (
int i = 0; i < j; i++)
3012 x[i] -= data[i+j*m] * x_j;
3021 #ifdef MFEM_USE_LAPACK
3024 if (m > 0 && n > 0) {
dgetrs_(&trans, &m, &n,
data, &m,
ipiv, X, &m, &info); }
3025 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3036 #ifdef MFEM_USE_LAPACK
3037 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3041 dtrsm_(&side,&u_ch,&n_ch,&n_ch,&n,&m,&alpha,
data,&m,X,&n);
3042 dtrsm_(&side,&l_ch,&n_ch,&u_ch,&n,&m,&alpha,
data,&m,X,&n);
3051 for (
int k = 0; k < n; k++)
3053 for (
int j = 0; j < m; j++)
3055 const double x_j = ( x[j*n] /= data[j+j*m]);
3056 for (
int i = j+1; i < m; i++)
3058 x[i*n] -= data[j + i*m] * x_j;
3066 for (
int k = 0; k < n; k++)
3068 for (
int j = m-1; j >= 0; j--)
3070 const double x_j = x[j*n];
3071 for (
int i = 0; i < j; i++)
3073 x[i*n] -= data[j + i*m] * x_j;
3081 for (
int k = 0; k < n; k++)
3083 for (
int i = 0; i < m; i++)
3085 Swap<double>(x[i*n], x[(ipiv[i]-
ipiv_base)*n]);
3098 for (
int k = 0; k < m; k++)
3100 const double minus_x_k = -( x[k] = 1.0/data[k+k*m] );
3101 for (
int i = 0; i < k; i++)
3103 x[i] = data[i+k*m] * minus_x_k;
3105 for (
int j = k-1; j >= 0; j--)
3107 const double x_j = ( x[j] /= data[j+j*m] );
3108 for (
int i = 0; i < j; i++)
3110 x[i] -= data[i+j*m] * x_j;
3118 for (
int j = 0; j < k; j++)
3120 const double minus_L_kj = -data[k+j*m];
3121 for (
int i = 0; i <= j; i++)
3123 X[i+j*m] += X[i+k*m] * minus_L_kj;
3125 for (
int i = j+1; i < m; i++)
3127 X[i+j*m] = X[i+k*m] * minus_L_kj;
3131 for (
int k = m-2; k >= 0; k--)
3133 for (
int j = 0; j < k; j++)
3135 const double L_kj = data[k+j*m];
3136 for (
int i = 0; i < m; i++)
3138 X[i+j*m] -= X[i+k*m] * L_kj;
3143 for (
int k = m-1; k >= 0; k--)
3148 for (
int i = 0; i < m; i++)
3150 Swap<double>(X[i+k*m], X[i+piv_k*m]);
3157 const double *X1,
double *X2)
3160 for (
int k = 0; k < r; k++)
3162 for (
int j = 0; j < m; j++)
3164 const double x1_jk = X1[j+k*m];
3165 for (
int i = 0; i < n; i++)
3167 X2[i+k*n] -= A21[i+j*n] * x1_jk;
3174 int m,
int n,
double *A12,
double *A21,
double *A22)
const
3180 for (
int j = 0; j < m; j++)
3182 const double u_jj_inv = 1.0/data[j+j*m];
3183 for (
int i = 0; i < n; i++)
3185 A21[i+j*n] *= u_jj_inv;
3187 for (
int k = j+1; k < m; k++)
3189 const double u_jk = data[j+k*m];
3190 for (
int i = 0; i < n; i++)
3192 A21[i+k*n] -= A21[i+j*n] * u_jk;
3197 SubMult(m, n, n, A21, A12, A22);
3201 double *B1,
double *B2)
const
3206 SubMult(m, n, r, L21, B1, B2);
3210 const double *X2,
double *Y1)
const
3213 SubMult(n, m, r, U12, X2, Y1);
3222 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3232 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3240 MFEM_ASSERT(a,
"DenseMatrix is not given");
3241 const double *adata = a->data;
3243 for (
int i = 0; i < s; i++)
3245 lu.
data[i] = adata[i];
3258 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
3274 MFEM_VERIFY(p != NULL,
"Operator is not a DenseMatrix!");
3294 for (
int i = 0; i <
width; i++)
3316 #ifdef MFEM_USE_LAPACK
3322 &qwork, &lwork, &info);
3324 lwork = (int) qwork;
3325 work =
new double[lwork];
3331 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
3334 #ifdef MFEM_USE_LAPACK
3337 lwork = other.lwork;
3339 work =
new double[lwork];
3346 if (mat.
Width() != n)
3348 mfem_error(
"DenseMatrixEigensystem::Eval()");
3352 #ifdef MFEM_USE_LAPACK
3355 work, &lwork, &info);
3359 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
3364 mfem_error(
"DenseMatrixEigensystem::Eval(): Compiled without LAPACK");
3370 #ifdef MFEM_USE_LAPACK
3390 void DenseMatrixSVD::Init()
3392 #ifdef MFEM_USE_LAPACK
3401 NULL, &n, &qwork, &lwork, &info);
3403 lwork = (int) qwork;
3404 work =
new double[lwork];
3406 mfem_error(
"DenseMatrixSVD::Init(): Compiled without LAPACK");
3419 #ifdef MFEM_USE_LAPACK
3421 NULL, &n, work, &lwork, &info);
3425 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
3429 mfem_error(
"DenseMatrixSVD::Eval(): Compiled without LAPACK");
3435 #ifdef MFEM_USE_LAPACK
3445 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
3446 const double *d_col = tdata;
3449 const double *xp = x;
3453 for (
int i = 0; i < ne; i++)
3456 for (
int col = 0; col < n; col++)
3458 x_col = xp[dofs[col]];
3459 for (
int row = 0; row < n; row++)
3461 yp[dofs[row]] += x_col*d_col[row];
3470 for (
int i = 0; i < ne; i++)
3473 x_col = xp[dofs[0]];
3474 for (
int row = 0; row < n; row++)
3476 ye(row) = x_col*d_col[row];
3479 for (
int col = 1; col < n; col++)
3481 x_col = xp[dofs[col]];
3482 for (
int row = 0; row < n; row++)
3484 ye(row) += x_col*d_col[row];
3488 for (
int row = 0; row < n; row++)
3490 yp[dofs[row]] += ye(row);
3499 for (
int i=0; i<s; i++)
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^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.
int Size() const
Logical size of the array.
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.
int CheckFinite(const double *v, const int n)
double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
DenseMatrix & operator*=(double c)
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
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)
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 SingularValues(Vector &sv) const
void dsyev_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void SetSize(int s)
Resize the vector to size s.
void Delete()
Delete the owned pointers. The Memory is not reset by this method, i.e. it will, generally, not be Empty() after this call.
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().
void BlockFactor(int m, int n, double *A12, double *A21, double *A22) const
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 BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
void dgetri_(int *N, double *A, int *LDA, int *IPIV, double *WORK, int *LWORK, int *INFO)
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
void TestInversion()
Invert and print the numerical conditioning of the inversion.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
void Eval(DenseMatrix &M)
Abstract data type for matrix inverse.
void AddMult_a_ABt(double a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
void Factor()
Factor the current DenseMatrix, *a.
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 GetInverseMatrix(int m, double *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
bool IsSquare() const
Returns whether the matrix is a square matrix.
double * GetData() const
Returns the matrix data array.
double * GetData() const
Return a pointer to the beginning of the Vector data.
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...
int Capacity() const
Return the size of the allocated memory.
void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
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 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)
static void SubMult(int m, int n, int r, const double *A21, const double *X1, double *X2)
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
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}.
void USolve(int m, int n, double *X) const
double FNorm() const
Compute the Frobenius norm of the matrix.
MFEM_HOST_DEVICE void CalcEigenvalues< 2 >(const double *data, double *lambda, double *vec)
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
friend class DenseMatrixInverse
void RightSolve(int m, int n, double *X) const
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
double operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the 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))
void GetRow(int r, Vector &row) const
void BlockForwSolve(int m, int n, int r, const double *L21, double *B1, double *B2) const
DenseMatrixSVD(DenseMatrix &M)
Abstract data type matrix.
void Norm2(double *v) const
Take the 2-norm of the columns of A and store in v.
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 LSolve(int m, int n, double *X) const
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
double Det() const
Compute the determinant of the original DenseMatrix using the LU factors.
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 *)
~DenseMatrixEigensystem()
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void Neg()
(*this) = -(*this)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
void Solve(int m, int n, double *X) const
void Getl1Diag(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
void GetColumn(int c, Vector &col) const
void AddMult(const Vector &x, Vector &y) const
y += A.x
void trans(const Vector &x, Vector &p)
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *)
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||.
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
double * Data() const
Returns the matrix data array.
void Transpose()
(*this) = (*this)^t
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
double Trace() const
Trace of a square matrix.
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 *)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
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)
A class to initialize the size of a Tensor.
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 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.
virtual void PrintT(std::ostream &out=mfem::out, int width_=4) const
Prints the transpose matrix to stream out.
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
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 AddMultTranspose(const Vector &x, Vector &y) const
y += A^t x
void CopyExceptMN(const DenseMatrix &A, int m, int n)
Copy All rows and columns except m and n from A.
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.
void Mult(int m, int n, double *X) const
MFEM_HOST_DEVICE void CalcEigenvalues< 3 >(const double *data, double *lambda, double *vec)
bool Factor(int m, double TOL=0.0)
Compute the LU factorization of the current matrix.
static const int ipiv_base
void GradToCurl(DenseMatrix &curl)
DenseMatrixInverse()
Default constructor.
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
void GetRowSums(Vector &l) const
Compute the row sums of the DenseMatrix.
void CalcEigenvalues(double *lambda, double *vec) const
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)
int Rank(double tol) const
MFEM_HOST_DEVICE void Mult(const int height, const int width, 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 AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
void Mult(const double *x, double *y) const
Matrix vector multiplication.
void AddMultTranspose_a(double a, const Vector &x, Vector &y) const
y += a * A^t x
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 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 InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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.
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.
void dsyev_(char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *W, double *WORK, int *LWORK, int *INFO)
virtual void PrintMatlab(std::ostream &out=mfem::out) const
DenseMatrix & operator+=(const double *m)