19 #include "../general/table.hpp"
20 #include "../general/globals.hpp"
27 #if defined(_MSC_VER) && (_MSC_VER < 1800)
29 #define copysign _copysign
33 #ifdef MFEM_USE_LAPACK
35 dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
36 int *,
double *,
int *,
double *,
double *,
int *);
38 dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
40 dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
42 dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
43 int *LWORK,
int *INFO);
45 dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
46 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
47 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
48 int *IWORK,
int *LIWORK,
int *INFO);
50 dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
51 double *WORK,
int *LWORK,
int *INFO);
53 dsygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
double *A,
int *LDA,
54 double *B,
int *LDB,
double *W,
double *WORK,
int *LWORK,
int *INFO);
56 dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
57 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
58 int *LWORK,
int *INFO);
78 MFEM_ASSERT(m.data,
"invalid source matrix");
79 data =
new double[hw];
81 std::memcpy(data, m.data,
sizeof(
double)*hw);
92 MFEM_ASSERT(s >= 0,
"invalid DenseMatrix size: " << s);
96 data =
new double[capacity]();
106 MFEM_ASSERT(m >= 0 && n >= 0,
107 "invalid DenseMatrix size: " << m <<
" x " << n);
111 data =
new double[capacity]();
120 :
Matrix(mat.width, mat.height)
125 data =
new double[capacity];
127 for (
int i = 0; i <
height; i++)
129 for (
int j = 0; j <
width; j++)
131 (*this)(i,j) = mat(j,i);
143 MFEM_ASSERT(h >= 0 && w >= 0,
144 "invalid DenseMatrix size: " << h <<
" x " << w);
152 if (hw > std::abs(capacity))
159 data =
new double[hw]();
177 for (
int row = 0; row <
height; row++)
183 double *d_col = data;
185 for (
int row = 0; row <
height; row++)
187 y[row] = x_col*d_col[row];
190 for (
int col = 1; col <
width; col++)
193 for (
int row = 0; row <
height; row++)
195 y[row] += x_col*d_col[row];
204 "incompatible dimensions");
206 Mult((
const double *)x, (
double *)y);
212 "incompatible dimensions");
216 for (
int i = 0; i < hw; i++)
218 a += data[i] * m.data[i];
226 double *d_col = data;
227 for (
int col = 0; col <
width; col++)
230 for (
int row = 0; row <
height; row++)
232 y_col += x[row]*d_col[row];
242 "incompatible dimensions");
250 "incompatible dimensions");
252 const double *xp = x, *d_col = data;
254 for (
int col = 0; col <
width; col++)
256 double x_col = xp[col];
257 for (
int row = 0; row <
height; row++)
259 yp[row] += x_col*d_col[row];
268 "incompatible dimensions");
270 const double *d_col = data;
271 for (
int col = 0; col <
width; col++)
274 for (
int row = 0; row <
height; row++)
276 y_col += x[row]*d_col[row];
286 "incompatible dimensions");
288 const double *xp = x, *d_col = data;
290 for (
int col = 0; col <
width; col++)
292 const double x_col = a*xp[col];
293 for (
int row = 0; row <
height; row++)
295 yp[row] += x_col*d_col[row];
305 "incompatible dimensions");
307 const double *d_col = data;
308 for (
int col = 0; col <
width; col++)
311 for (
int row = 0; row <
height; row++)
313 y_col += x[row]*d_col[row];
324 for (
int i = 0; i <
height; i++)
327 for (
int j = 0; j <
width; j++)
329 Axi += (*this)(i,j) * x[j];
340 double * it_data = data;
341 for (
int j = 0; j <
width; ++j)
343 for (
int i = 0; i <
height; ++i)
345 *(it_data++) *= s(i);
353 double * it_data = data;
354 for (
int j = 0; j <
width; ++j)
356 for (
int i = 0; i <
height; ++i)
358 *(it_data++) /= s(i);
367 double * it_data = data;
368 for (
int j = 0; j <
width; ++j)
371 for (
int i = 0; i <
height; ++i)
381 double * it_data = data;
382 for (
int j = 0; j <
width; ++j)
384 const double sj = 1./s(j);
385 for (
int i = 0; i <
height; ++i)
400 double * ss =
new double[
width];
403 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
405 *(it_ss++) = sqrt(*it_s);
408 double * it_data = data;
409 for (
int j = 0; j <
width; ++j)
411 for (
int i = 0; i <
height; ++i)
413 *(it_data++) *= ss[i]*ss[j];
428 double * ss =
new double[
width];
431 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
433 *(it_ss++) = 1./sqrt(*it_s);
436 double * it_data = data;
437 for (
int j = 0; j <
width; ++j)
439 for (
int i = 0; i <
height; ++i)
441 *(it_data++) *= ss[i]*ss[j];
453 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
459 for (
int i = 0; i <
width; i++)
475 "The matrix must be square and "
476 <<
"sized larger than zero to compute the determinant."
477 <<
" Height() = " <<
Height()
478 <<
", Width() = " <<
Width());
486 return data[0] * data[3] - data[1] * data[2];
490 const double *d = data;
492 d[0] * (d[4] * d[8] - d[5] * d[7]) +
493 d[3] * (d[2] * d[7] - d[1] * d[8]) +
494 d[6] * (d[1] * d[5] - d[2] * d[4]);
498 const double *d = data;
500 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
501 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
502 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
504 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
505 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
506 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
508 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
509 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
510 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
512 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
513 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
514 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
523 return lu_factors.
Det();
538 return sqrt(data[0] * data[0] + data[1] * data[1]);
542 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
546 const double *d = data;
547 double E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
548 double G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
549 double F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
550 return sqrt(E * G - F * F);
559 for (
int i = 0; i < s; i++)
561 data[i] = alpha*A[i];
567 for (
int j = 0; j <
Width(); j++)
569 for (
int i = 0; i <
Height(); i++)
571 (*this)(i,j) += c * A(i,j);
579 for (
int i = 0; i < s; i++)
589 for (
int i = 0; i < s; i++)
601 for (
int i = 0; i < hw; i++)
612 for (
int i = 0; i < hw; i++)
622 "incompatible matrix sizes.");
628 for (
int j = 0; j <
width; j++)
630 for (
int i = 0; i <
height; i++)
632 (*this)(i, j) -= m(i, j);
642 for (
int i = 0; i < s; i++)
652 for (
int i = 0; i < hw; i++)
667 #ifdef MFEM_USE_LAPACK
668 int *ipiv =
new int[
width];
677 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
683 work =
new double[lwork];
689 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
695 int c, i, j, n =
Width();
699 for (c = 0; c < n; c++)
701 a = fabs((*
this)(c, c));
703 for (j = c + 1; j < n; j++)
705 b = fabs((*
this)(j, c));
714 mfem_error(
"DenseMatrix::Invert() : singular matrix");
717 for (j = 0; j < n; j++)
719 Swap<double>((*this)(c, j), (*
this)(i, j));
722 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
723 for (j = 0; j < c; j++)
727 for (j++; j < n; j++)
731 for (i = 0; i < c; i++)
733 (*this)(i, c) = a * (b = -(*
this)(i, c));
734 for (j = 0; j < c; j++)
736 (*this)(i, j) += b * (*
this)(c, j);
738 for (j++; j < n; j++)
740 (*this)(i, j) += b * (*
this)(c, j);
743 for (i++; i < n; i++)
745 (*this)(i, c) = a * (b = -(*
this)(i, c));
746 for (j = 0; j < c; j++)
748 (*this)(i, j) += b * (*
this)(c, j);
750 for (j++; j < n; j++)
752 (*this)(i, j) += b * (*
this)(c, j);
757 for (c = n - 1; c >= 0; c--)
760 for (i = 0; i < n; i++)
762 Swap<double>((*this)(i, c), (*
this)(i, j));
774 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
784 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
786 for (
int j = 0; j < 10; j++)
788 for (
int i = 0; i < 10; i++)
803 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
804 if (tmp2.FNorm() < 1e-10) {
break; }
807 if (tmp2.FNorm() > 1e-10)
809 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
815 for (
int j = 0; j <
Width(); j++)
818 for (
int i = 0; i <
Height(); i++)
820 v[j] += (*this)(i,j)*(*
this)(i,j);
829 const double *d = data;
830 double norm = 0.0, abs_entry;
832 for (
int i = 0; i < hw; i++)
834 abs_entry = fabs(d[i]);
835 if (norm < abs_entry)
847 double max_norm = 0.0, entry, fnorm2;
849 for (i = 0; i < hw; i++)
851 entry = fabs(data[i]);
852 if (entry > max_norm)
860 scale_factor = scaled_fnorm2 = 0.0;
865 for (i = 0; i < hw; i++)
867 entry = data[i] / max_norm;
868 fnorm2 += entry * entry;
871 scale_factor = max_norm;
872 scaled_fnorm2 = fnorm2;
877 #ifdef MFEM_USE_LAPACK
884 double *A =
new double[N*N];
895 int *ISUPPZ =
new int[2*N];
914 double *data = a.
Data();
916 for (
int i = 0; i < hw; i++)
921 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
922 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
923 &QIWORK, &LIWORK, &INFO );
928 WORK =
new double[LWORK];
929 IWORK =
new int[LIWORK];
931 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
932 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
933 IWORK, &LIWORK, &INFO );
937 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: "
945 mfem::err <<
"dsyevr_Eigensystem(...):\n"
946 <<
" DSYEVR did not find all eigenvalues "
947 << M <<
"/" << N << endl;
952 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
956 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
959 for (IL = 0; IL < N; IL++)
960 for (IU = 0; IU <= IL; IU++)
963 for (M = 0; M < N; M++)
965 VL += Z[M+IL*N] * Z[M+IU*N];
982 <<
" Z^t Z - I deviation = " << VU
983 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
984 << W[0] <<
", N = " << N << endl;
991 <<
" Z^t Z - I deviation = " << VU
992 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
993 << W[0] <<
", N = " << N << endl;
997 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1000 for (IL = 0; IL < N; IL++)
1001 for (IU = 0; IU < N; IU++)
1004 for (M = 0; M < N; M++)
1006 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
1008 VL = fabs(VL-data[IL+N*IU]);
1017 <<
" max matrix deviation = " << VU
1018 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
1019 << W[0] <<
", N = " << N << endl;
1023 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1037 #ifdef MFEM_USE_LAPACK
1049 double *WORK = NULL;
1060 A =
new double[N*N];
1064 double *data = a.
Data();
1065 for (
int i = 0; i < hw; i++)
1070 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1072 LWORK = (int) QWORK;
1073 WORK =
new double[LWORK];
1075 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1079 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1084 if (evect == NULL) {
delete [] A; }
1088 void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1090 #ifdef MFEM_USE_LAPACK
1106 #ifdef MFEM_USE_LAPACK
1119 double *B =
new double[N*N];
1121 double *WORK = NULL;
1132 A =
new double[N*N];
1136 double *a_data = a.
Data();
1137 double *b_data = b.
Data();
1138 for (
int i = 0; i < hw; i++)
1144 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1146 LWORK = (int) QWORK;
1147 WORK =
new double[LWORK];
1149 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1153 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1159 if (evect == NULL) {
delete [] A; }
1163 void DenseMatrix::Eigensystem(DenseMatrix &b, Vector &ev,
1166 #ifdef MFEM_USE_LAPACK
1172 mfem_error(
"DenseMatrix::Eigensystem for generalized eigenvalues");
1178 #ifdef MFEM_USE_LAPACK
1184 double *a = copy_of_this.data;
1189 double *work = NULL;
1194 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
1195 s, u, &m, vt, &n, &qwork, &lwork, &info);
1197 lwork = (int) qwork;
1198 work =
new double[lwork];
1200 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
1201 s, u, &m, vt, &n, work, &lwork, &info);
1206 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1221 for (
int i=0; i < sv.
Size(); ++i)
1237 double t, zeta = (d2 - d1)/(2*d12);
1238 if (fabs(zeta) < sqrt_1_eps)
1240 t = d12*copysign(1./(fabs(zeta) + sqrt(1. + zeta*zeta)), zeta);
1244 t = d12*copysign(0.5/fabs(zeta), zeta);
1252 double &c,
double &s)
1262 double t, zeta = (d2 - d1)/(2*d12);
1263 if (fabs(zeta) < sqrt_1_eps)
1265 t = copysign(1./(fabs(zeta) + sqrt(1. + zeta*zeta)), zeta);
1269 t = copysign(0.5/fabs(zeta), zeta);
1272 c = sqrt(1./(1. + t*t));
1281 const double &x1,
const double &x2,
const double &x3,
1282 double &n1,
double &n2,
double &n3)
1290 t = sqrt(1./(t + r*r));
1291 n1 = copysign(t, x1);
1298 double &n1,
double &n2,
double &n3)
1302 if (fabs(x1) >= fabs(x2))
1304 if (fabs(x1) >= fabs(x3))
1317 else if (fabs(x2) >= fabs(x3))
1327 double &d1,
double &d12,
double &d21,
double &d2)
1338 double n1 = fabs(d1) + fabs(d21);
1339 double n2 = fabs(d2) + fabs(d12);
1341 bool swap_columns = (n2 > n1);
1353 if (fabs(d1) > fabs(d21))
1361 if (fabs(d1) < fabs(d21))
1373 if (fabs(d12) > fabs(d2))
1386 if (fabs(d12) < fabs(d2))
1399 n1 = hypot(d1, d21);
1405 mu = copysign(n1, d1);
1406 n1 = -d21*(d21/(d1 + mu));
1410 if (fabs(n1) <= fabs(d21))
1414 mu = (2./(1. + n1*n1))*(n1*d12 + d2);
1422 mu = (2./(1. + n2*n2))*(d12 + n2*d2);
1444 n2 = 1./(1. + fabs(mu));
1446 if (fabs(d1) <= n2*fabs(d2))
1468 double &d1,
double &d2,
double &d3,
double &c12,
double &c13,
double &c23,
1469 double &c21,
double &c31,
double &c32)
1472 double mu, n1, n2, n3, s1, s2, s3;
1474 s1 = hypot(c21, c31);
1481 mu = copysign(n1, d1);
1482 n1 = -s1*(s1/(d1 + mu));
1487 if (fabs(n1) >= fabs(c21))
1489 if (fabs(n1) >= fabs(c31))
1494 mu = 2./(1. + s2*s2 + s3*s3);
1495 n2 = mu*(c12 + s2*d2 + s3*c32);
1496 n3 = mu*(c13 + s2*c23 + s3*d3);
1506 else if (fabs(c21) >= fabs(c31))
1511 mu = 2./(1. + s1*s1 + s3*s3);
1512 n2 = mu*(s1*c12 + d2 + s3*c32);
1513 n3 = mu*(s1*c13 + c23 + s3*d3);
1525 mu = 2./(1. + s1*s1 + s2*s2);
1526 n2 = mu*(s1*c12 + s2*d2 + c32);
1527 n3 = mu*(s1*c13 + s2*c23 + d3);
1562 d1 = -(c12*d2 + c13*d3)/d1;
1573 const double &d12,
const double &d13,
const double &d23,
1574 double &d1,
double &d2,
double &d3)
1587 double c12 = d12, c13 = d13, c23 = d23;
1588 double c21, c31, c32;
1592 c32 = fabs(d1) + fabs(c12) + fabs(c13);
1593 c31 = fabs(d2) + fabs(c12) + fabs(c23);
1594 c21 = fabs(d3) + fabs(c13) + fabs(c23);
1599 col = (c32 >= c31) ? 1 : 2;
1603 col = (c31 >= c21) ? 2 : 3;
1635 if (fabs(d1) <= fabs(c13))
1637 row = (fabs(d1) <= fabs(c12)) ? 1 : 2;
1641 row = (fabs(c12) <= fabs(c13)) ? 2 : 3;
1646 if (fabs(d1) >= fabs(c13))
1648 row = (fabs(d1) >= fabs(c12)) ? 1 : 2;
1652 row = (fabs(c12) >= fabs(c13)) ? 2 : 3;
1702 double &d1,
double &d2,
double &d3,
double &d12,
double &d13,
double &d23,
1703 double &z1,
double &z2,
double &z3,
double &v1,
double &v2,
double &v3,
1723 double s, w1, w2, w3;
1729 if (fabs(z1) <= fabs(z3))
1731 k = (fabs(z1) <= fabs(z2)) ? 1 : 2;
1735 k = (fabs(z2) <= fabs(z3)) ? 2 : 3;
1741 if (fabs(z1) >= fabs(z3))
1743 k = (fabs(z1) >= fabs(z2)) ? 1 : 2;
1747 k = (fabs(z2) >= fabs(z3)) ? 2 : 3;
1774 g = copysign(1., z1);
1775 v1 = -s*(s/(z1 + g));
1778 if (fabs(z2) > g) { g = fabs(z2); }
1779 if (fabs(z3) > g) { g = fabs(z3); }
1783 g = 2./(v1*v1 + v2*v2 + v3*v3);
1788 w1 = g*( d1*v1 + d12*v2 + d13*v3);
1789 w2 = g*(d12*v1 + d2*v2 + d23*v3);
1790 w3 = g*(d13*v1 + d23*v2 + d3*v3);
1792 s = (g/2)*(v1*w1 + v2*w2 + v3*w3);
1799 d23 -= v2*w3 + v3*w2;
1804 s = d12 - v1*w2 - v2*w1;
1805 s = d13 - v1*w3 - v3*w1;
1827 mult = frexp(d_max, &d_exp);
1828 if (d_exp == numeric_limits<double>::max_exponent)
1830 mult *= numeric_limits<double>::radix;
1845 "The matrix must be square and sized 1, 2, or 3 to compute the"
1847 <<
" Height() = " <<
Height()
1848 <<
", Width() = " <<
Width());
1851 const double *d = data;
1859 double d0, d1, d2, d3;
1866 double d_max = fabs(d0);
1867 if (d_max < fabs(d1)) { d_max = fabs(d1); }
1868 if (d_max < fabs(d2)) { d_max = fabs(d2); }
1869 if (d_max < fabs(d3)) { d_max = fabs(d3); }
1883 double t = 0.5*((d0+d2)*(d0-d2)+(d1-d3)*(d1+d3));
1885 double s = d0*d2 + d1*d3;
1886 s = sqrt(0.5*(d0*d0 + d1*d1 + d2*d2 + d3*d3) + sqrt(t*t + s*s));
1891 t = fabs(d0*d3 - d1*d2) / s;
1908 double d0, d1, d2, d3, d4, d5, d6, d7, d8;
1909 d0 = d[0]; d3 = d[3]; d6 = d[6];
1910 d1 = d[1]; d4 = d[4]; d7 = d[7];
1911 d2 = d[2]; d5 = d[5]; d8 = d[8];
1914 double d_max = fabs(d0);
1915 if (d_max < fabs(d1)) { d_max = fabs(d1); }
1916 if (d_max < fabs(d2)) { d_max = fabs(d2); }
1917 if (d_max < fabs(d3)) { d_max = fabs(d3); }
1918 if (d_max < fabs(d4)) { d_max = fabs(d4); }
1919 if (d_max < fabs(d5)) { d_max = fabs(d5); }
1920 if (d_max < fabs(d6)) { d_max = fabs(d6); }
1921 if (d_max < fabs(d7)) { d_max = fabs(d7); }
1922 if (d_max < fabs(d8)) { d_max = fabs(d8); }
1927 d0 /= mult; d1 /= mult; d2 /= mult;
1928 d3 /= mult; d4 /= mult; d5 /= mult;
1929 d6 /= mult; d7 /= mult; d8 /= mult;
1931 double b11 = d0*d0 + d1*d1 + d2*d2;
1932 double b12 = d0*d3 + d1*d4 + d2*d5;
1933 double b13 = d0*d6 + d1*d7 + d2*d8;
1934 double b22 = d3*d3 + d4*d4 + d5*d5;
1935 double b23 = d3*d6 + d4*d7 + d5*d8;
1936 double b33 = d6*d6 + d7*d7 + d8*d8;
1955 double aa = (b11 + b22 + b33)/3;
1961 double b11_b22 = ((d0-d3)*(d0+d3)+(d1-d4)*(d1+d4)+(d2-d5)*(d2+d5));
1962 double b22_b33 = ((d3-d6)*(d3+d6)+(d4-d7)*(d4+d7)+(d5-d8)*(d5+d8));
1963 double b33_b11 = ((d6-d0)*(d6+d0)+(d7-d1)*(d7+d1)+(d8-d2)*(d8+d2));
1964 c1 = (b11_b22 - b33_b11)/3;
1965 c2 = (b22_b33 - b11_b22)/3;
1966 c3 = (b33_b11 - b22_b33)/3;
1969 Q = (2*(b12*b12 + b13*b13 + b23*b23) + c1*c1 + c2*c2 + c3*c3)/6;
1970 R = (c1*(b23*b23 - c2*c3)+ b12*(b12*c3 - 2*b13*b23) +b13*b13*c2)/2;
2003 double sqrtQ = sqrt(Q);
2004 double sqrtQ3 = Q*sqrtQ;
2009 if (fabs(R) >= sqrtQ3)
2031 aa -= 2*sqrtQ*cos(acos(R)/3);
2035 aa -= 2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
2039 aa -= 2*sqrtQ*cos((acos(R) - 2.0*M_PI)/3);
2046 r = -2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
2055 r = -2*sqrtQ*cos(acos(R)/3);
2102 double v1, v2, v3, g;
2103 Reduce3S(mode, b11, b22, b33, b12, b13, b23,
2104 c1, c2, c3, v1, v2, v3, g);
2115 aa = std::min(std::min(b11, b22), b33);
2121 aa = (b22 <= b33) ? b22 : std::max(b11, b33);
2125 aa = (b11 <= b33) ? b11 : std::max(b33, b22);
2130 aa = std::max(std::max(b11, b22), b33);
2136 return sqrt(fabs(aa))*mult;
2150 const double *d = data;
2190 double d_max = fabs(d11);
2191 if (d_max < fabs(d22)) { d_max = fabs(d22); }
2192 if (d_max < fabs(d33)) { d_max = fabs(d33); }
2193 if (d_max < fabs(d12)) { d_max = fabs(d12); }
2194 if (d_max < fabs(d13)) { d_max = fabs(d13); }
2195 if (d_max < fabs(d23)) { d_max = fabs(d23); }
2200 d11 /= mult; d22 /= mult; d33 /= mult;
2201 d12 /= mult; d13 /= mult; d23 /= mult;
2203 double aa = (d11 + d22 + d33)/3;
2204 double c1 = d11 - aa;
2205 double c2 = d22 - aa;
2206 double c3 = d33 - aa;
2210 Q = (2*(d12*d12 + d13*d13 + d23*d23) + c1*c1 + c2*c2 + c3*c3)/6;
2211 R = (c1*(d23*d23 - c2*c3)+ d12*(d12*c3 - 2*d13*d23) + d13*d13*c2)/2;
2215 lambda[0] = lambda[1] = lambda[2] = aa;
2216 vec[0] = 1.; vec[3] = 0.; vec[6] = 0.;
2217 vec[1] = 0.; vec[4] = 1.; vec[7] = 0.;
2218 vec[2] = 0.; vec[5] = 0.; vec[8] = 1.;
2222 double sqrtQ = sqrt(Q);
2223 double sqrtQ3 = Q*sqrtQ;
2227 if (fabs(R) >= sqrtQ3)
2246 r = -2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
2250 r = -2*sqrtQ*cos(acos(R)/3);
2278 lambda[0] = lambda[1] = lambda[2] = aa;
2279 vec[0] = 1.; vec[3] = 0.; vec[6] = 0.;
2280 vec[1] = 0.; vec[4] = 1.; vec[7] = 0.;
2281 vec[2] = 0.; vec[5] = 0.; vec[8] = 1.;
2295 double v1, v2, v3, g;
2296 int k =
Reduce3S(mode, d11, d22, d33, d12, d13, d23,
2297 c1, c2, c3, v1, v2, v3, g);
2308 double *vec_1, *vec_2, *vec_3;
2313 lambda[0] = d11; vec_1 = vec;
2314 lambda[1] = d22; vec_2 = vec + 3;
2315 lambda[2] = d33; vec_3 = vec + 6;
2317 else if (d11 <= d33)
2319 lambda[0] = d11; vec_1 = vec;
2320 lambda[1] = d33; vec_3 = vec + 3;
2321 lambda[2] = d22; vec_2 = vec + 6;
2325 lambda[0] = d33; vec_3 = vec;
2326 lambda[1] = d11; vec_1 = vec + 3;
2327 lambda[2] = d22; vec_2 = vec + 6;
2334 lambda[0] = d22; vec_2 = vec;
2335 lambda[1] = d11; vec_1 = vec + 3;
2336 lambda[2] = d33; vec_3 = vec + 6;
2338 else if (d22 <= d33)
2340 lambda[0] = d22; vec_2 = vec;
2341 lambda[1] = d33; vec_3 = vec + 3;
2342 lambda[2] = d11; vec_1 = vec + 6;
2346 lambda[0] = d33; vec_3 = vec;
2347 lambda[1] = d22; vec_2 = vec + 3;
2348 lambda[2] = d11; vec_1 = vec + 6;
2355 d22 = g*(v2*c - v3*s);
2356 d33 = g*(v2*s + v3*c);
2357 vec_2[0] = - v1*d22; vec_3[0] = - v1*d33;
2358 vec_2[1] = c - v2*d22; vec_3[1] = s - v2*d33;
2359 vec_2[2] = -s - v3*d22; vec_3[2] = c - v3*d33;
2363 Swap(vec_2[0], vec_2[1]);
2364 Swap(vec_3[0], vec_3[1]);
2368 Swap(vec_2[0], vec_2[2]);
2369 Swap(vec_3[0], vec_3[2]);
2386 const double* rp = data + r;
2389 for (
int i = 0; i < n; i++)
2401 double *cp = data + c * m;
2404 for (
int i = 0; i < m; i++)
2418 for (
int i = 0; i <
height; ++i)
2420 d(i) = (*this)(i,i);
2434 for (
int j = 0; j <
width; ++j)
2435 for (
int i = 0; i <
height; ++i)
2437 l(i) += fabs((*
this)(i,j));
2444 for (
int i = 0; i <
height; i++)
2447 for (
int j = 0; j <
width; j++)
2460 for (
int i = 0; i < N; i++)
2464 for (
int i = 0; i < n; i++)
2475 for (i = 0; i < N; i++)
2479 for (i = 0; i < n; i++)
2481 data[i*(n+1)] = diag[i];
2492 for (i = 0; i <
Height(); i++)
2493 for (j = i+1; j <
Width(); j++)
2496 (*this)(i,j) = (*
this)(j,i);
2511 for (
int i = 0; i <
Height(); i++)
2512 for (
int j = 0; j <
Width(); j++)
2514 (*this)(i,j) = A(j,i);
2523 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
2527 for (
int i = 0; i <
Height(); i++)
2528 for (
int j = 0; j < i; j++)
2530 double a = 0.5 * ((*this)(i,j) + (*
this)(j,i));
2531 (*this)(j,i) = (*
this)(i,j) = a;
2537 for (
int i = 0; i <
Height(); i++)
2540 for (
int j = 0; j <
Width(); j++)
2543 (*this)(i, j) = 0.0;
2563 for (
int i = 0; i < n; i++)
2566 double x = (*this)(i,0);
2567 double y = (*this)(i,1);
2580 for (
int i = 0; i < n; i++)
2583 double x = (*this)(i,0);
2584 double y = (*this)(i,1);
2585 double z = (*this)(i,2);
2610 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
2615 double *ddata = div.
GetData();
2617 for (
int i = 0; i < n; i++)
2627 for (
int j = 0; j <
Width(); j++)
2629 for (
int i = row1; i <= row2; i++)
2631 (*this)(i-row1,j) = A(i,j);
2640 for (
int j = col1; j <= col2; j++)
2642 for (
int i = 0; i <
Height(); i++)
2644 (*this)(i,j-col1) = A(i,j);
2653 for (
int j = 0; j < n; j++)
2655 for (
int i = 0; i < m; i++)
2657 (*this)(i,j) = A(Aro+i,Aco+j);
2666 for (
int j = 0; j < A.
Width(); j++)
2668 for (
int i = 0; i < A.
Height(); i++)
2670 (*this)(row_offset+i,col_offset+j) = *(v++);
2679 for (
int i = 0; i < A.
Width(); i++)
2681 for (
int j = 0; j < A.
Height(); j++)
2683 (*this)(row_offset+i,col_offset+j) = *(v++);
2689 int row_offset,
int col_offset)
2691 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
2692 "this DenseMatrix is too small to accomodate the submatrix. "
2693 <<
"row_offset = " << row_offset
2695 <<
", this->Height() = " << this->
Height()
2696 <<
", col_offset = " << col_offset
2698 <<
", this->Width() = " << this->
Width()
2700 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
2701 "The A DenseMatrix is too small to accomodate the submatrix. "
2704 <<
", A.Height() = " << A.
Height()
2705 <<
", Aco = " << Aco
2707 <<
", A.Width() = " << A.
Width()
2710 for (
int j = 0; j < n; j++)
2712 for (
int i = 0; i < m; i++)
2714 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
2721 for (
int i = 0; i < n; i++)
2723 for (
int j = i+1; j < n; j++)
2725 (*this)(row_offset+i,col_offset+j) =
2726 (*
this)(row_offset+j,col_offset+i) = 0.0;
2730 for (
int i = 0; i < n; i++)
2732 (*this)(row_offset+i,col_offset+i) = c;
2739 for (
int i = 0; i < n; i++)
2741 for (
int j = i+1; j < n; j++)
2743 (*this)(row_offset+i,col_offset+j) =
2744 (*
this)(row_offset+j,col_offset+i) = 0.0;
2748 for (
int i = 0; i < n; i++)
2750 (*this)(row_offset+i,col_offset+i) = diag[i];
2758 int i, j, i_off = 0, j_off = 0;
2760 for (j = 0; j < A.
Width(); j++)
2767 for (i = 0; i < A.
Height(); i++)
2774 (*this)(i-i_off,j-j_off) = A(i,j);
2790 if (co+aw >
Width() || ro+ah > h)
2796 p = data + ro + co * h;
2799 for (
int c = 0; c < aw; c++)
2801 for (
int r = 0; r < ah; r++)
2820 if (co+aw >
Width() || ro+ah > h)
2826 p = data + ro + co * h;
2829 for (
int c = 0; c < aw; c++)
2831 for (
int r = 0; r < ah; r++)
2843 double *vdata = v.
GetData() + offset;
2845 for (
int i = 0; i < n; i++)
2847 vdata[i] += data[i];
2854 const double *vdata = v.
GetData() + offset;
2856 for (
int i = 0; i < n; i++)
2869 mfem_error(
"DenseMatrix::AdjustDofDirection(...)");
2874 for (
int i = 0; i < n-1; i++)
2876 const int s = (dof[i] < 0) ? (-1) : (1);
2877 for (
int j = i+1; j < n; j++)
2879 const int t = (dof[j] < 0) ? (-s) : (s);
2882 (*this)(i,j) = -(*
this)(i,j);
2883 (*this)(j,i) = -(*
this)(j,i);
2891 for (
int j = 0; j <
Width(); j++)
2893 (*this)(row, j) = value;
2899 for (
int i = 0; i <
Height(); i++)
2901 (*this)(i, col) = value;
2907 for (
int j = 0; j <
Width(); j++)
2909 (*this)(r, j) = row[j];
2915 for (
int i = 0; i <
Height(); i++)
2917 (*this)(i, c) = col[i];
2923 for (
int col = 0; col <
Width(); col++)
2925 for (
int row = 0; row <
Height(); row++)
2927 if (std::abs(
operator()(row,col)) <= eps)
2938 ios::fmtflags old_flags = out.flags();
2940 out << setiosflags(ios::scientific | ios::showpos);
2941 for (
int i = 0; i <
height; i++)
2943 out <<
"[row " << i <<
"]\n";
2944 for (
int j = 0; j <
width; j++)
2946 out << (*this)(i,j);
2947 if (j+1 == width || (j+1) % width_ == 0)
2958 out.flags(old_flags);
2964 ios::fmtflags old_flags = out.flags();
2966 out << setiosflags(ios::scientific | ios::showpos);
2967 for (
int i = 0; i <
height; i++)
2969 for (
int j = 0; j <
width; j++)
2971 out << (*this)(i,j);
2977 out.flags(old_flags);
2983 ios::fmtflags old_flags = out.flags();
2985 out << setiosflags(ios::scientific | ios::showpos);
2986 for (
int j = 0; j <
width; j++)
2988 out <<
"[col " << j <<
"]\n";
2989 for (
int i = 0; i <
height; i++)
2991 out << (*this)(i,j);
2992 if (i+1 == height || (i+1) % width_ == 0)
3003 out.flags(old_flags);
3012 for (
int i = 0; i <
width; i++)
3017 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
3033 for (
int j = 0; j < C.
Width(); j++)
3035 for (
int i = 0; i < C.
Height(); i++)
3037 C(i,j) = A(i,j) + alpha * B(i,j);
3047 for (
int i = 0; i < m; i++)
3049 C_data[i] = alpha*A[i] + beta*B[i];
3067 b.
Width() == c.
Height(),
"incompatible dimensions");
3069 #ifdef MFEM_USE_LAPACK
3070 static char transa =
'N', transb =
'N';
3071 static double alpha = 1.0, beta = 0.0;
3074 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
3075 c.
Data(), &k, &beta, a.
Data(), &m);
3077 const int ah = a.
Height();
3078 const int aw = a.
Width();
3079 const int bw = b.
Width();
3080 double *ad = a.
Data();
3081 const double *bd = b.
Data();
3082 const double *cd = c.
Data();
3083 for (
int i = 0; i < ah*aw; i++)
3087 for (
int j = 0; j < aw; j++)
3089 for (
int k = 0; k < bw; k++)
3091 for (
int i = 0; i < ah; i++)
3093 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
3103 b.
Width() == c.
Height(),
"incompatible dimensions");
3105 #ifdef MFEM_USE_LAPACK
3106 static char transa =
'N', transb =
'N';
3107 static double alpha = 1.0, beta = 1.0;
3110 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
3111 c.
Data(), &k, &beta, a.
Data(), &m);
3113 const int ah = a.
Height();
3114 const int aw = a.
Width();
3115 const int bw = b.
Width();
3116 double *ad = a.
Data();
3117 const double *bd = b.
Data();
3118 const double *cd = c.
Data();
3119 for (
int j = 0; j < aw; j++)
3121 for (
int k = 0; k < bw; k++)
3123 for (
int i = 0; i < ah; i++)
3125 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
3147 const double *d = a.
Data();
3148 double *ad = adja.
Data();
3163 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
3164 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
3165 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
3167 ad[0] = d[0]*g - d[3]*f;
3168 ad[1] = d[3]*e - d[0]*f;
3169 ad[2] = d[1]*g - d[4]*f;
3170 ad[3] = d[4]*e - d[1]*f;
3171 ad[4] = d[2]*g - d[5]*f;
3172 ad[5] = d[5]*e - d[2]*f;
3181 else if (a.
Width() == 2)
3184 adja(0,1) = -a(0,1);
3185 adja(1,0) = -a(1,0);
3190 adja(0,0) = a(1,1)*a(2,2)-a(1,2)*a(2,1);
3191 adja(0,1) = a(0,2)*a(2,1)-a(0,1)*a(2,2);
3192 adja(0,2) = a(0,1)*a(1,2)-a(0,2)*a(1,1);
3194 adja(1,0) = a(1,2)*a(2,0)-a(1,0)*a(2,2);
3195 adja(1,1) = a(0,0)*a(2,2)-a(0,2)*a(2,0);
3196 adja(1,2) = a(0,2)*a(1,0)-a(0,0)*a(1,2);
3198 adja(2,0) = a(1,0)*a(2,1)-a(1,1)*a(2,0);
3199 adja(2,1) = a(0,1)*a(2,0)-a(0,0)*a(2,1);
3200 adja(2,2) = a(0,0)*a(1,1)-a(0,1)*a(1,0);
3217 else if (a.
Width() == 2)
3219 adjat(0,0) = a(1,1);
3220 adjat(1,0) = -a(0,1);
3221 adjat(0,1) = -a(1,0);
3222 adjat(1,1) = a(0,0);
3226 adjat(0,0) = a(1,1)*a(2,2)-a(1,2)*a(2,1);
3227 adjat(1,0) = a(0,2)*a(2,1)-a(0,1)*a(2,2);
3228 adjat(2,0) = a(0,1)*a(1,2)-a(0,2)*a(1,1);
3230 adjat(0,1) = a(1,2)*a(2,0)-a(1,0)*a(2,2);
3231 adjat(1,1) = a(0,0)*a(2,2)-a(0,2)*a(2,0);
3232 adjat(2,1) = a(0,2)*a(1,0)-a(0,0)*a(1,2);
3234 adjat(0,2) = a(1,0)*a(2,1)-a(1,1)*a(2,0);
3235 adjat(1,2) = a(0,1)*a(2,0)-a(0,0)*a(2,1);
3236 adjat(2,2) = a(0,0)*a(1,1)-a(0,1)*a(1,0);
3243 MFEM_ASSERT(inva.
Height() == a.
Width(),
"incorrect dimensions");
3244 MFEM_ASSERT(inva.
Width() == a.
Height(),
"incorrect dimensions");
3250 const double *d = a.
Data();
3251 double *
id = inva.
Data();
3254 t = 1.0 / (d[0]*d[0] + d[1]*d[1]);
3262 t = 1.0 / (d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
3270 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
3271 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
3272 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
3273 t = 1.0 / (e*g - f*f);
3274 e *= t; g *= t; f *= t;
3276 id[0] = d[0]*g - d[3]*f;
3277 id[1] = d[3]*e - d[0]*f;
3278 id[2] = d[1]*g - d[4]*f;
3279 id[3] = d[4]*e - d[1]*f;
3280 id[4] = d[2]*g - d[5]*f;
3281 id[5] = d[5]*e - d[2]*f;
3289 MFEM_ASSERT(std::abs(t) > 1.0e-14 * pow(a.FNorm()/a.
Width(), a.
Width()),
3290 "singular matrix!");
3302 inva(0,0) = a(1,1) * t ;
3303 inva(0,1) = -a(0,1) * t ;
3304 inva(1,0) = -a(1,0) * t ;
3305 inva(1,1) = a(0,0) * t ;
3308 inva(0,0) = (a(1,1)*a(2,2)-a(1,2)*a(2,1))*t;
3309 inva(0,1) = (a(0,2)*a(2,1)-a(0,1)*a(2,2))*t;
3310 inva(0,2) = (a(0,1)*a(1,2)-a(0,2)*a(1,1))*t;
3312 inva(1,0) = (a(1,2)*a(2,0)-a(1,0)*a(2,2))*t;
3313 inva(1,1) = (a(0,0)*a(2,2)-a(0,2)*a(2,0))*t;
3314 inva(1,2) = (a(0,2)*a(1,0)-a(0,0)*a(1,2))*t;
3316 inva(2,0) = (a(1,0)*a(2,1)-a(1,1)*a(2,0))*t;
3317 inva(2,1) = (a(0,1)*a(2,0)-a(0,0)*a(2,1))*t;
3318 inva(2,2) = (a(0,0)*a(1,1)-a(0,1)*a(1,0))*t;
3333 double t = 1. / a.
Det() ;
3338 inva(0,0) = 1.0 / a(0,0);
3341 inva(0,0) = a(1,1) * t ;
3342 inva(1,0) = -a(0,1) * t ;
3343 inva(0,1) = -a(1,0) * t ;
3344 inva(1,1) = a(0,0) * t ;
3347 inva(0,0) = (a(1,1)*a(2,2)-a(1,2)*a(2,1))*t;
3348 inva(1,0) = (a(0,2)*a(2,1)-a(0,1)*a(2,2))*t;
3349 inva(2,0) = (a(0,1)*a(1,2)-a(0,2)*a(1,1))*t;
3351 inva(0,1) = (a(1,2)*a(2,0)-a(1,0)*a(2,2))*t;
3352 inva(1,1) = (a(0,0)*a(2,2)-a(0,2)*a(2,0))*t;
3353 inva(2,1) = (a(0,2)*a(1,0)-a(0,0)*a(1,2))*t;
3355 inva(0,2) = (a(1,0)*a(2,1)-a(1,1)*a(2,0))*t;
3356 inva(1,2) = (a(0,1)*a(2,0)-a(0,0)*a(2,1))*t;
3357 inva(2,2) = (a(0,0)*a(1,1)-a(0,1)*a(1,0))*t;
3367 "Matrix must be 3x2 or 2x1, "
3368 <<
"and the Vector must be sized with the rows. "
3369 <<
" J.Height() = " << J.
Height()
3370 <<
", J.Width() = " << J.
Width()
3371 <<
", n.Size() = " << n.
Size()
3374 const double *d = J.
Data();
3382 n(0) = d[1]*d[5] - d[2]*d[4];
3383 n(1) = d[2]*d[3] - d[0]*d[5];
3384 n(2) = d[0]*d[4] - d[1]*d[3];
3390 const int height = a.
Height();
3391 const int width = a.
Width();
3392 for (
int i = 0; i < height; i++)
3394 for (
int j = 0; j <= i; j++)
3397 for (
int k = 0; k < width; k++)
3399 temp += a(i,k) * a(j,k);
3401 aat(j,i) = aat(i,j) = temp;
3408 for (
int i = 0; i < A.
Height(); i++)
3410 for (
int j = 0; j < i; j++)
3413 for (
int k = 0; k < A.
Width(); k++)
3415 t += D(k) * A(i, k) * A(j, k);
3423 for (
int i = 0; i < A.
Height(); i++)
3426 for (
int k = 0; k < A.
Width(); k++)
3428 t += D(k) * A(i, k) * A(i, k);
3436 for (
int i = 0; i < A.
Height(); i++)
3438 for (
int j = 0; j <= i; j++)
3441 for (
int k = 0; k < A.
Width(); k++)
3443 t += D(k) * A(i, k) * A(j, k);
3445 ADAt(j, i) = ADAt(i, j) = t;
3460 #ifdef MFEM_USE_LAPACK
3461 static char transa =
'N', transb =
'T';
3462 static double alpha = 1.0, beta = 0.0;
3465 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
3466 B.
Data(), &n, &beta, ABt.
Data(), &m);
3468 const int ah = A.
Height();
3469 const int bh = B.
Height();
3470 const int aw = A.
Width();
3471 const double *ad = A.
Data();
3472 const double *bd = B.
Data();
3473 double *cd = ABt.
Data();
3475 for (
int i = 0, s = ah*bh; i < s; i++)
3479 for (
int k = 0; k < aw; k++)
3482 for (
int j = 0; j < bh; j++)
3484 const double bjk = bd[j];
3485 for (
int i = 0; i < ah; i++)
3487 cp[i] += ad[i] * bjk;
3495 const int ah = A.
Height();
3496 const int bh = B.
Height();
3497 const int aw = A.
Width();
3498 const double *ad = A.
Data();
3499 const double *bd = B.
Data();
3500 double *cd = ABt.
Data();
3502 for (
int j = 0; j < bh; j++)
3503 for (
int i = 0; i < ah; i++)
3506 const double *ap = ad + i;
3507 const double *bp = bd + j;
3508 for (
int k = 0; k < aw; k++)
3520 for (i = 0; i < A.
Height(); i++)
3521 for (j = 0; j < B.
Height(); j++)
3524 for (k = 0; k < A.
Width(); k++)
3526 d += A(i, k) * B(j, k);
3544 const int ah = A.
Height();
3545 const int bh = B.
Height();
3546 const int aw = A.
Width();
3547 const double *ad = A.
Data();
3548 const double *bd = B.
Data();
3549 const double *dd = D.
GetData();
3550 double *cd = ADBt.
Data();
3552 for (
int i = 0, s = ah*bh; i < s; i++)
3556 for (
int k = 0; k < aw; k++)
3559 for (
int j = 0; j < bh; j++)
3561 const double dk_bjk = dd[k] * bd[j];
3562 for (
int i = 0; i < ah; i++)
3564 cp[i] += ad[i] * dk_bjk;
3583 #ifdef MFEM_USE_LAPACK
3584 static char transa =
'N', transb =
'T';
3585 static double alpha = 1.0, beta = 1.0;
3588 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
3589 B.
Data(), &n, &beta, ABt.
Data(), &m);
3591 const int ah = A.
Height();
3592 const int bh = B.
Height();
3593 const int aw = A.
Width();
3594 const double *ad = A.
Data();
3595 const double *bd = B.
Data();
3596 double *cd = ABt.
Data();
3598 for (
int k = 0; k < aw; k++)
3601 for (
int j = 0; j < bh; j++)
3603 const double bjk = bd[j];
3604 for (
int i = 0; i < ah; i++)
3606 cp[i] += ad[i] * bjk;
3617 for (i = 0; i < A.
Height(); i++)
3618 for (j = 0; j < B.
Height(); j++)
3621 for (k = 0; k < A.
Width(); k++)
3623 d += A(i, k) * B(j, k);
3641 const int ah = A.
Height();
3642 const int bh = B.
Height();
3643 const int aw = A.
Width();
3644 const double *ad = A.
Data();
3645 const double *bd = B.
Data();
3646 const double *dd = D.
GetData();
3647 double *cd = ADBt.
Data();
3649 for (
int k = 0; k < aw; k++)
3652 for (
int j = 0; j < bh; j++)
3654 const double dk_bjk = dd[k] * bd[j];
3655 for (
int i = 0; i < ah; i++)
3657 cp[i] += ad[i] * dk_bjk;
3677 #ifdef MFEM_USE_LAPACK
3678 static char transa =
'N', transb =
'T';
3680 static double beta = 1.0;
3683 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
3684 B.
Data(), &n, &beta, ABt.
Data(), &m);
3686 const int ah = A.
Height();
3687 const int bh = B.
Height();
3688 const int aw = A.
Width();
3689 const double *ad = A.
Data();
3690 const double *bd = B.
Data();
3691 double *cd = ABt.
Data();
3693 for (
int k = 0; k < aw; k++)
3696 for (
int j = 0; j < bh; j++)
3698 const double bjk = a * bd[j];
3699 for (
int i = 0; i < ah; i++)
3701 cp[i] += ad[i] * bjk;
3712 for (i = 0; i < A.
Height(); i++)
3713 for (j = 0; j < B.
Height(); j++)
3716 for (k = 0; k < A.
Width(); k++)
3718 d += A(i, k) * B(j, k);
3735 #ifdef MFEM_USE_LAPACK
3736 static char transa =
'T', transb =
'N';
3737 static double alpha = 1.0, beta = 0.0;
3740 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &k,
3741 B.
Data(), &k, &beta, AtB.
Data(), &m);
3743 const int ah = A.
Height();
3744 const int aw = A.
Width();
3745 const int bw = B.
Width();
3746 const double *ad = A.
Data();
3747 const double *bd = B.
Data();
3748 double *cd = AtB.
Data();
3750 for (
int j = 0; j < bw; j++)
3752 const double *ap = ad;
3753 for (
int i = 0; i < aw; i++)
3756 for (
int k = 0; k < ah; k++)
3769 for (i = 0; i < A.
Width(); i++)
3770 for (j = 0; j < B.
Width(); j++)
3773 for (k = 0; k < A.
Height(); k++)
3775 d += A(k, i) * B(k, j);
3786 for (
int i = 0; i < A.
Height(); i++)
3788 for (
int j = 0; j < i; j++)
3791 for (
int k = 0; k < A.
Width(); k++)
3793 d += A(i,k) * A(j,k);
3795 AAt(i, j) += (d *= a);
3799 for (
int k = 0; k < A.
Width(); k++)
3801 d += A(i,k) * A(i,k);
3809 for (
int i = 0; i < A.
Height(); i++)
3811 for (
int j = 0; j <= i; j++)
3814 for (
int k = 0; k < A.
Width(); k++)
3816 d += A(i,k) * A(j,k);
3818 AAt(i, j) = AAt(j, i) = a * d;
3825 for (
int i = 0; i < v.
Size(); i++)
3827 for (
int j = 0; j <= i; j++)
3829 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3843 for (
int i = 0; i < v.
Size(); i++)
3845 const double vi = v(i);
3846 for (
int j = 0; j < w.
Size(); j++)
3848 VWt(i, j) = vi * w(j);
3855 const int m = v.
Size(), n = w.
Size();
3864 for (
int i = 0; i < m; i++)
3866 const double vi = v(i);
3867 for (
int j = 0; j < n; j++)
3869 VWt(i, j) += vi * w(j);
3876 const int n = v.
Size();
3885 for (
int i = 0; i < n; i++)
3887 const double vi = v(i);
3888 for (
int j = 0; j < i; j++)
3890 const double vivj = vi * v(j);
3894 VVt(i, i) += vi * vi;
3901 const int m = v.
Size(), n = w.
Size();
3910 for (
int j = 0; j < n; j++)
3912 const double awj = a * w(j);
3913 for (
int i = 0; i < m; i++)
3915 VWt(i, j) += v(i) * awj;
3923 "incompatible dimensions!");
3925 const int n = v.
Size();
3926 for (
int i = 0; i < n; i++)
3928 double avi = a * v(i);
3929 for (
int j = 0; j < i; j++)
3931 const double avivj = avi * v(j);
3935 VVt(i, i) += avi * v(i);
3942 #ifdef MFEM_USE_LAPACK
3945 MFEM_VERIFY(!info,
"LAPACK: error in DGETRF");
3949 for (
int i = 0; i < m; i++)
3954 double a = std::abs(data[piv+i*m]);
3955 for (
int j = i+1; j < m; j++)
3957 const double b = std::abs(data[j+i*m]);
3968 for (
int j = 0; j < m; j++)
3970 Swap<double>(data[i+j*m], data[piv+j*m]);
3974 MFEM_ASSERT(data[i+i*m] != 0.0,
"division by zero");
3975 const double a_ii_inv = 1.0/data[i+i*m];
3976 for (
int j = i+1; j < m; j++)
3978 data[j+i*m] *= a_ii_inv;
3980 for (
int k = i+1; k < m; k++)
3982 const double a_ik = data[i+k*m];
3983 for (
int j = i+1; j < m; j++)
3985 data[j+k*m] -= a_ik * data[j+i*m];
3995 for (
int i=0; i<m; i++)
3999 det *= -
data[m * i + i];
4003 det *=
data[m * i + i];
4014 for (
int k = 0; k < n; k++)
4017 for (
int i = 0; i < m; i++)
4019 double x_i = x[i] * data[i+i*m];
4020 for (
int j = i+1; j < m; j++)
4022 x_i += x[j] * data[i+j*m];
4027 for (
int i = m-1; i >= 0; i--)
4030 for (
int j = 0; j < i; j++)
4032 x_i += x[j] * data[i+j*m];
4037 for (
int i = m-1; i >= 0; i--)
4039 Swap<double>(x[i], x[ipiv[i]-
ipiv_base]);
4050 for (
int k = 0; k < n; k++)
4053 for (
int i = 0; i < m; i++)
4055 Swap<double>(x[i], x[ipiv[i]-
ipiv_base]);
4058 for (
int j = 0; j < m; j++)
4060 const double x_j = x[j];
4061 for (
int i = j+1; i < m; i++)
4063 x[i] -= data[i+j*m] * x_j;
4075 for (
int k = 0; k < n; k++)
4077 for (
int j = m-1; j >= 0; j--)
4079 const double x_j = ( x[j] /= data[j+j*m] );
4080 for (
int i = 0; i < j; i++)
4082 x[i] -= data[i+j*m] * x_j;
4091 #ifdef MFEM_USE_LAPACK
4094 if (m > 0 && n > 0) {
dgetrs_(&trans, &m, &n,
data, &m,
ipiv, X, &m, &info); }
4095 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
4110 for (
int k = 0; k < m; k++)
4112 const double minus_x_k = -( x[k] = 1.0/data[k+k*m] );
4113 for (
int i = 0; i < k; i++)
4115 x[i] = data[i+k*m] * minus_x_k;
4117 for (
int j = k-1; j >= 0; j--)
4119 const double x_j = ( x[j] /= data[j+j*m] );
4120 for (
int i = 0; i < j; i++)
4122 x[i] -= data[i+j*m] * x_j;
4130 for (
int j = 0; j < k; j++)
4132 const double minus_L_kj = -data[k+j*m];
4133 for (
int i = 0; i <= j; i++)
4135 X[i+j*m] += X[i+k*m] * minus_L_kj;
4137 for (
int i = j+1; i < m; i++)
4139 X[i+j*m] = X[i+k*m] * minus_L_kj;
4143 for (
int k = m-2; k >= 0; k--)
4145 for (
int j = 0; j < k; j++)
4147 const double L_kj = data[k+j*m];
4148 for (
int i = 0; i < m; i++)
4150 X[i+j*m] -= X[i+k*m] * L_kj;
4155 for (
int k = m-1; k >= 0; k--)
4160 for (
int i = 0; i < m; i++)
4162 Swap<double>(X[i+k*m], X[i+piv_k*m]);
4169 const double *X1,
double *X2)
4172 for (
int k = 0; k < r; k++)
4174 for (
int j = 0; j < m; j++)
4176 const double x1_jk = X1[j+k*m];
4177 for (
int i = 0; i < n; i++)
4179 X2[i+k*n] -= A21[i+j*n] * x1_jk;
4186 int m,
int n,
double *A12,
double *A21,
double *A22)
const
4192 for (
int j = 0; j < m; j++)
4194 const double u_jj_inv = 1.0/data[j+j*m];
4195 for (
int i = 0; i < n; i++)
4197 A21[i+j*n] *= u_jj_inv;
4199 for (
int k = j+1; k < m; k++)
4201 const double u_jk = data[j+k*m];
4202 for (
int i = 0; i < n; i++)
4204 A21[i+k*n] -= A21[i+j*n] * u_jk;
4209 SubMult(m, n, n, A21, A12, A22);
4213 double *B1,
double *B2)
const
4218 SubMult(m, n, r, L21, B1, B2);
4222 const double *X2,
double *Y1)
const
4225 SubMult(n, m, r, U12, X2, Y1);
4234 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4244 MFEM_ASSERT(
height ==
width,
"not a square matrix");
4252 MFEM_ASSERT(a,
"DenseMatrix is not given");
4253 const double *adata = a->data;
4255 for (
int i = 0; i < s; i++)
4257 lu.
data[i] = adata[i];
4270 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
4286 MFEM_VERIFY(p != NULL,
"Operator is not a DenseMatrix!");
4306 for (
int i = 0; i <
width; i++)
4328 #ifdef MFEM_USE_LAPACK
4334 &qwork, &lwork, &info);
4336 lwork = (int) qwork;
4337 work =
new double[lwork];
4343 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4346 #ifdef MFEM_USE_LAPACK
4349 lwork = other.lwork;
4351 work =
new double[lwork];
4358 if (mat.
Width() != n)
4360 mfem_error(
"DenseMatrixEigensystem::Eval()");
4364 #ifdef MFEM_USE_LAPACK
4367 work, &lwork, &info);
4371 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
4376 mfem_error(
"DenseMatrixEigensystem::Eval(): Compiled without LAPACK");
4382 #ifdef MFEM_USE_LAPACK
4402 void DenseMatrixSVD::Init()
4404 #ifdef MFEM_USE_LAPACK
4413 NULL, &n, &qwork, &lwork, &info);
4415 lwork = (int) qwork;
4416 work =
new double[lwork];
4418 mfem_error(
"DenseMatrixSVD::Init(): Compiled without LAPACK");
4431 #ifdef MFEM_USE_LAPACK
4433 NULL, &n, work, &lwork, &info);
4437 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4441 mfem_error(
"DenseMatrixSVD::Eval(): Compiled without LAPACK");
4447 #ifdef MFEM_USE_LAPACK
4457 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4458 const double *d_col = tdata;
4459 double *yp = y, x_col;
4460 const double *xp = x;
4464 for (
int i = 0; i < ne; i++)
4467 for (
int col = 0; col < n; col++)
4469 x_col = xp[dofs[col]];
4470 for (
int row = 0; row < n; row++)
4472 yp[dofs[row]] += x_col*d_col[row];
4481 for (
int i = 0; i < ne; i++)
4484 x_col = xp[dofs[0]];
4485 for (
int row = 0; row < n; row++)
4487 ye(row) = x_col*d_col[row];
4490 for (
int col = 1; col < n; col++)
4492 x_col = xp[dofs[col]];
4493 for (
int row = 0; row < n; row++)
4495 ye(row) += x_col*d_col[row];
4499 for (
int row = 0; row < n; row++)
4501 yp[dofs[row]] += ye(row);
4510 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)
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.
bool KernelVector2G(const int &mode, double &d1, double &d12, double &d21, double &d2)
DenseTensor & operator=(double c)
Sets the tensor elements equal to constant c.
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
void Eigenvalues2S(const double &d12, double &d1, double &d2)
void GetScalingFactor(const double &d_max, double &mult)
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 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
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.
void GetInverseMatrix(int m, double *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
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 vec_normalize3_aux(const double &x1, const double &x2, const double &x3, double &n1, double &n2, double &n3)
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...
void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
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.
int KernelVector3G_aux(const int &mode, double &d1, double &d2, double &d3, double &c12, double &c13, double &c23, double &c21, double &c31, double &c32)
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.
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 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.
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 vec_normalize3(const double &x1, const double &x2, const double &x3, double &n1, double &n2, double &n3)
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
int KernelVector3S(const int &mode, const double &d12, const double &d13, const double &d23, double &d1, double &d2, double &d3)
void SetRow(int r, const Vector &row)
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 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||.
void Eigensystem2S(const double &d12, double &d1, double &d2, double &c, double &s)
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
double * Data() const
Returns the matrix data array.
void Swap(Array< T > &, Array< T > &)
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...
int Reduce3S(const int &mode, double &d1, double &d2, double &d3, double &d12, double &d13, double &d23, double &z1, double &z2, double &z3, double &v1, double &v2, double &v3, double &g)
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
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.
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 Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
void Mult(int m, int n, double *X) const
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)
double epsilon(const Vector &x)
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
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 SetCol(int c, const Vector &col)
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...
Rank 3 tensor (array of matrices)
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void AdjustDofDirection(Array< int > &dofs)
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)