16 #include "kernels.hpp" 20 #include "../general/forall.hpp" 21 #include "../general/table.hpp" 22 #include "../general/globals.hpp" 29 #if defined(_MSC_VER) && (_MSC_VER < 1800) 31 #define copysign _copysign 35 #ifdef MFEM_USE_LAPACK 37 dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
38 int *,
double *,
int *,
double *,
double *,
int *);
40 dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
42 dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
44 dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
45 int *LWORK,
int *INFO);
47 dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
48 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
49 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
50 int *IWORK,
int *LIWORK,
int *INFO);
52 dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
53 double *WORK,
int *LWORK,
int *INFO);
55 dsygv_ (
int *ITYPE,
char *JOBZ,
char *UPLO,
int * N,
double *A,
int *LDA,
56 double *B,
int *LDB,
double *W,
double *WORK,
int *LWORK,
int *INFO);
58 dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
59 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
60 int *LWORK,
int *INFO);
62 dtrsm_(
char *side,
char *uplo,
char *transa,
char *diag,
int *m,
int *n,
63 double *
alpha,
double *
a,
int *lda,
double *
b,
int *ldb);
65 dggev_(
char *jobvl,
char *jobvr,
int *n,
double *
a,
int *lda,
double *B,
66 int *ldb,
double *alphar,
double *alphai,
double *
beta,
double *vl,
67 int * ldvl,
double * vr,
int * ldvr,
double * work,
int * lwork,
int* info);
71 dpotrf_(
char *,
int *,
double *,
int *,
int *);
74 dpotrs_(
char *,
int *,
int *,
double *,
int *,
double *,
int *,
int *);
77 dtrtrs_(
char *,
char*,
char *,
int *,
int *,
double *,
int *,
double *,
int *,
80 dpotri_(
char *,
int *,
double *,
int*,
int *);
96 MFEM_ASSERT(m.data,
"invalid source matrix");
98 std::memcpy(data, m.data,
sizeof(
double)*hw);
104 MFEM_ASSERT(
s >= 0,
"invalid DenseMatrix size: " <<
s);
114 MFEM_ASSERT(m >= 0 && n >= 0,
115 "invalid DenseMatrix size: " << m <<
" x " << n);
116 const int capacity = m*n;
125 :
Matrix(mat.width, mat.height)
127 MFEM_CONTRACT_VAR(ch);
133 for (
int i = 0; i <
height; i++)
135 for (
int j = 0; j <
width; j++)
137 (*this)(i,j) = mat(j,i);
145 MFEM_ASSERT(h >= 0 && w >= 0,
146 "invalid DenseMatrix size: " << h <<
" x " << w);
179 MFEM_ASSERT(
height == y.
Size(),
"incompatible dimensions");
186 MFEM_ASSERT(
width == x.
Size(),
"incompatible dimensions");
194 "incompatible dimensions");
202 "incompatible dimensions");
206 for (
int i = 0; i < hw; i++)
208 a += data[i] * m.data[i];
216 double *d_col =
Data();
217 for (
int col = 0; col <
width; col++)
220 for (
int row = 0; row <
height; row++)
222 y_col += x[row]*d_col[row];
231 MFEM_ASSERT(
width == y.
Size(),
"incompatible dimensions");
238 MFEM_ASSERT(
height == x.
Size(),
"incompatible dimensions");
246 "incompatible dimensions");
259 "incompatible dimensions");
261 const double *xp = x.
GetData(), *d_col = data;
263 for (
int col = 0; col <
width; col++)
265 double x_col = xp[col];
266 for (
int row = 0; row <
height; row++)
268 yp[row] += x_col*d_col[row];
275 const double a)
const 283 "incompatible dimensions");
285 const double *d_col = data;
286 for (
int col = 0; col <
width; col++)
289 for (
int row = 0; row <
height; row++)
291 y_col += x[row]*d_col[row];
301 "incompatible dimensions");
303 const double *xp = x.
GetData(), *d_col = data;
305 for (
int col = 0; col <
width; col++)
307 const double x_col =
a*xp[col];
308 for (
int row = 0; row <
height; row++)
310 yp[row] += x_col*d_col[row];
320 "incompatible dimensions");
322 const double *d_col = data;
323 for (
int col = 0; col <
width; col++)
326 for (
int row = 0; row <
height; row++)
328 y_col += x[row]*d_col[row];
339 for (
int i = 0; i <
height; i++)
342 for (
int j = 0; j <
width; j++)
344 Axi += (*this)(i,j) * x[j];
355 double * it_data = data;
356 for (
int j = 0; j <
width; ++j)
358 for (
int i = 0; i <
height; ++i)
360 *(it_data++) *=
s(i);
368 double * it_data = data;
369 for (
int j = 0; j <
width; ++j)
371 for (
int i = 0; i <
height; ++i)
373 *(it_data++) /=
s(i);
382 double * it_data = data;
383 for (
int j = 0; j <
width; ++j)
386 for (
int i = 0; i <
height; ++i)
396 double * it_data = data;
397 for (
int j = 0; j <
width; ++j)
399 const double sj = 1./
s(j);
400 for (
int i = 0; i <
height; ++i)
412 mfem_error(
"DenseMatrix::SymmetricScaling: dimension mismatch");
415 double * ss =
new double[
width];
416 double * it_s =
s.GetData();
418 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
420 *(it_ss++) = sqrt(*it_s);
423 double * it_data = data;
424 for (
int j = 0; j <
width; ++j)
426 for (
int i = 0; i <
height; ++i)
428 *(it_data++) *= ss[i]*ss[j];
440 mfem_error(
"DenseMatrix::InvSymmetricScaling: dimension mismatch");
443 double * ss =
new double[
width];
444 double * it_s =
s.GetData();
446 for (
double * end_s = it_s +
width; it_s != end_s; ++it_s)
448 *(it_ss++) = 1./sqrt(*it_s);
451 double * it_data = data;
452 for (
int j = 0; j <
width; ++j)
454 for (
int i = 0; i <
height; ++i)
456 *(it_data++) *= ss[i]*ss[j];
468 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
474 for (
int i = 0; i <
width; i++)
490 "The matrix must be square and " 491 <<
"sized larger than zero to compute the determinant." 492 <<
" Height() = " <<
Height()
493 <<
", Width() = " <<
Width());
501 return data[0] * data[3] - data[1] * data[2];
505 const double *d = data;
507 d[0] * (d[4] * d[8] - d[5] * d[7]) +
508 d[3] * (d[2] * d[7] - d[1] * d[8]) +
509 d[6] * (d[1] * d[5] - d[2] * d[4]);
513 const double *d = data;
515 d[ 0] * (d[ 5] * (d[10] * d[15] - d[11] * d[14]) -
516 d[ 9] * (d[ 6] * d[15] - d[ 7] * d[14]) +
517 d[13] * (d[ 6] * d[11] - d[ 7] * d[10])
519 d[ 4] * (d[ 1] * (d[10] * d[15] - d[11] * d[14]) -
520 d[ 9] * (d[ 2] * d[15] - d[ 3] * d[14]) +
521 d[13] * (d[ 2] * d[11] - d[ 3] * d[10])
523 d[ 8] * (d[ 1] * (d[ 6] * d[15] - d[ 7] * d[14]) -
524 d[ 5] * (d[ 2] * d[15] - d[ 3] * d[14]) +
525 d[13] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
527 d[12] * (d[ 1] * (d[ 6] * d[11] - d[ 7] * d[10]) -
528 d[ 5] * (d[ 2] * d[11] - d[ 3] * d[10]) +
529 d[ 9] * (d[ 2] * d[ 7] - d[ 3] * d[ 6])
538 return lu_factors.
Det();
553 return sqrt(data[0] * data[0] + data[1] * data[1]);
557 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
561 const double *d = data;
562 double E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
563 double G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
564 double F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
565 return sqrt(E * G - F * F);
567 mfem_error(
"DenseMatrix::Weight(): mismatched or unsupported dimensions");
574 for (
int i = 0; i <
s; i++)
576 data[i] =
alpha*A[i];
582 for (
int j = 0; j <
Width(); j++)
584 for (
int i = 0; i <
Height(); i++)
586 (*this)(i,j) += c * A(i,j);
594 for (
int i = 0; i <
s; i++)
603 for (
int i = 0; i <
s; i++)
613 for (
int i = 0; i <
s; i++)
625 for (
int i = 0; i < hw; i++)
642 "incompatible matrix sizes.");
648 for (
int j = 0; j <
width; j++)
650 for (
int i = 0; i <
height; i++)
652 (*this)(i, j) -= m(i, j);
662 for (
int i = 0; i <
s; i++)
672 for (
int i = 0; i < hw; i++)
683 mfem_error(
"DenseMatrix::Invert(): dimension mismatch");
687 #ifdef MFEM_USE_LAPACK 688 int *ipiv =
new int[
width];
697 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
703 work =
new double[lwork];
709 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
715 int c, i, j, n =
Width();
719 for (c = 0; c < n; c++)
721 a = fabs((*
this)(c, c));
723 for (j = c + 1; j < n; j++)
725 b = fabs((*
this)(j, c));
734 mfem_error(
"DenseMatrix::Invert() : singular matrix");
737 for (j = 0; j < n; j++)
739 mfem::Swap<double>((*this)(c, j), (*
this)(i, j));
742 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
743 for (j = 0; j < c; j++)
747 for (j++; j < n; j++)
751 for (i = 0; i < c; i++)
753 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
754 for (j = 0; j < c; j++)
756 (*this)(i, j) +=
b * (*
this)(c, j);
758 for (j++; j < n; j++)
760 (*this)(i, j) +=
b * (*
this)(c, j);
763 for (i++; i < n; i++)
765 (*this)(i, c) =
a * (
b = -(*
this)(i, c));
766 for (j = 0; j < c; j++)
768 (*this)(i, j) +=
b * (*
this)(c, j);
770 for (j++; j < n; j++)
772 (*this)(i, j) +=
b * (*
this)(c, j);
777 for (c = n - 1; c >= 0; c--)
780 for (i = 0; i < n; i++)
782 mfem::Swap<double>((*this)(i, c), (*
this)(i, j));
794 mfem_error(
"DenseMatrix::SquareRootInverse() matrix not square.");
804 for (
int v = 0; v <
Height() ; v++) { (*this)(v,v) = 1.0; }
806 for (
int j = 0; j < 10; j++)
808 for (
int i = 0; i < 10; i++)
823 for (
int v = 0; v <
Height() ; v++) { tmp2(v,v) -= 1.0; }
824 if (tmp2.FNorm() < 1e-10) {
break; }
827 if (tmp2.FNorm() > 1e-10)
829 mfem_error(
"DenseMatrix::SquareRootInverse not converged");
835 for (
int j = 0; j <
Width(); j++)
838 for (
int i = 0; i <
Height(); i++)
840 v[j] += (*this)(i,j)*(*
this)(i,j);
849 const double *d = data;
850 double norm = 0.0, abs_entry;
852 for (
int i = 0; i < hw; i++)
854 abs_entry = fabs(d[i]);
855 if (norm < abs_entry)
867 double max_norm = 0.0, entry, fnorm2;
869 for (i = 0; i < hw; i++)
871 entry = fabs(data[i]);
872 if (entry > max_norm)
880 scale_factor = scaled_fnorm2 = 0.0;
885 for (i = 0; i < hw; i++)
887 entry = data[i] / max_norm;
888 fnorm2 += entry * entry;
891 scale_factor = max_norm;
892 scaled_fnorm2 = fnorm2;
897 #ifdef MFEM_USE_LAPACK 904 double *A =
new double[N*N];
915 int *ISUPPZ =
new int[2*N];
933 int hw =
a.Height() *
a.Width();
934 double *data =
a.Data();
936 for (
int i = 0; i < hw; i++)
941 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
942 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
943 &QIWORK, &LIWORK, &INFO );
948 WORK =
new double[LWORK];
949 IWORK =
new int[LIWORK];
951 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
952 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
953 IWORK, &LIWORK, &INFO );
957 mfem::err <<
"dsyevr_Eigensystem(...): DSYEVR error code: " 965 mfem::err <<
"dsyevr_Eigensystem(...):\n" 966 <<
" DSYEVR did not find all eigenvalues " 967 << M <<
"/" << N << endl;
972 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in W");
976 mfem_error(
"dsyevr_Eigensystem(...): inf/nan values in Z");
979 for (IL = 0; IL < N; IL++)
980 for (IU = 0; IU <= IL; IU++)
983 for (M = 0; M < N; M++)
985 VL += Z[M+IL*N] * Z[M+IU*N];
1002 <<
" Z^t Z - I deviation = " << VU
1003 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1004 << W[0] <<
", N = " << N << endl;
1011 <<
" Z^t Z - I deviation = " << VU
1012 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1013 << W[0] <<
", N = " << N << endl;
1017 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1020 for (IL = 0; IL < N; IL++)
1021 for (IU = 0; IU < N; IU++)
1024 for (M = 0; M < N; M++)
1026 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
1028 VL = fabs(VL-data[IL+N*IU]);
1037 <<
" max matrix deviation = " << VU
1038 <<
"\n W[max] = " << W[N-1] <<
", W[min] = " 1039 << W[0] <<
", N = " << N << endl;
1043 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
1052 MFEM_CONTRACT_VAR(
a);
1053 MFEM_CONTRACT_VAR(ev);
1054 MFEM_CONTRACT_VAR(evect);
1060 #ifdef MFEM_USE_LAPACK 1072 double *WORK = NULL;
1083 A =
new double[N*N];
1086 int hw =
a.Height() *
a.Width();
1087 double *data =
a.Data();
1088 for (
int i = 0; i < hw; i++)
1093 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
1095 LWORK = (int) QWORK;
1096 WORK =
new double[LWORK];
1098 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
1102 mfem::err <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
1107 if (evect == NULL) {
delete [] A; }
1109 MFEM_CONTRACT_VAR(
a);
1110 MFEM_CONTRACT_VAR(ev);
1111 MFEM_CONTRACT_VAR(evect);
1115 void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
1117 #ifdef MFEM_USE_LAPACK 1125 MFEM_CONTRACT_VAR(ev);
1126 MFEM_CONTRACT_VAR(evect);
1127 mfem_error(
"DenseMatrix::Eigensystem: Compiled without LAPACK");
1135 #ifdef MFEM_USE_LAPACK 1148 double *B =
new double[N*N];
1150 double *WORK = NULL;
1161 A =
new double[N*N];
1164 int hw =
a.Height() *
a.Width();
1165 double *a_data =
a.Data();
1166 double *b_data =
b.Data();
1167 for (
int i = 0; i < hw; i++)
1173 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, &QWORK, &LWORK, &INFO);
1175 LWORK = (int) QWORK;
1176 WORK =
new double[LWORK];
1178 dsygv_(&ITYPE, &JOBZ, &UPLO, &N, A, &LDA, B, &LDB, W, WORK, &LWORK, &INFO);
1182 mfem::err <<
"dsygv_Eigensystem: DSYGV error code: " << INFO << endl;
1188 if (evect == NULL) {
delete [] A; }
1190 MFEM_CONTRACT_VAR(
a);
1191 MFEM_CONTRACT_VAR(
b);
1192 MFEM_CONTRACT_VAR(ev);
1193 MFEM_CONTRACT_VAR(evect);
1197 void DenseMatrix::Eigensystem(DenseMatrix &
b, Vector &ev,
1200 #ifdef MFEM_USE_LAPACK 1205 MFEM_CONTRACT_VAR(
b);
1206 MFEM_CONTRACT_VAR(ev);
1207 MFEM_CONTRACT_VAR(evect);
1208 mfem_error(
"DenseMatrix::Eigensystem(generalized): Compiled without LAPACK");
1214 #ifdef MFEM_USE_LAPACK 1220 double *
a = copy_of_this.data;
1225 double *work = NULL;
1230 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1231 s,
u, &m, vt, &n, &qwork, &lwork, &info);
1233 lwork = (int) qwork;
1234 work =
new double[lwork];
1236 dgesvd_(&jobu, &jobvt, &m, &n,
a, &m,
1237 s,
u, &m, vt, &n, work, &lwork, &info);
1242 mfem::err <<
"DenseMatrix::SingularValues : info = " << info << endl;
1246 MFEM_CONTRACT_VAR(sv);
1248 mfem_error(
"DenseMatrix::SingularValues: Compiled without LAPACK");
1258 for (
int i=0; i < sv.
Size(); ++i)
1270 "The matrix must be square and sized 1, 2, or 3 to compute the" 1272 <<
" Height() = " <<
Height()
1273 <<
", Width() = " <<
Width());
1276 const double *d = data;
1302 const double *d = data;
1320 const double* rp = data + r;
1323 for (
int i = 0; i < n; i++)
1335 double *cp =
Data() + c * m;
1338 for (
int i = 0; i < m; i++)
1352 for (
int i = 0; i <
height; ++i)
1354 d(i) = (*this)(i,i);
1368 for (
int j = 0; j <
width; ++j)
1369 for (
int i = 0; i <
height; ++i)
1371 l(i) += fabs((*
this)(i,j));
1378 for (
int i = 0; i <
height; i++)
1381 for (
int j = 0; j <
width; j++)
1394 for (
int i = 0; i < N; i++)
1398 for (
int i = 0; i < n; i++)
1409 for (i = 0; i < N; i++)
1413 for (i = 0; i < n; i++)
1415 data[i*(n+1)] = diag[i];
1426 for (i = 0; i <
Height(); i++)
1427 for (j = i+1; j <
Width(); j++)
1430 (*this)(i,j) = (*
this)(j,i);
1445 for (
int i = 0; i <
Height(); i++)
1446 for (
int j = 0; j <
Width(); j++)
1448 (*this)(i,j) = A(j,i);
1457 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
1465 for (
int i = 0; i <
Height(); i++)
1468 for (
int j = 0; j <
Width(); j++)
1471 (*this)(i, j) = 0.0;
1485 mfem_error(
"DenseMatrix::GradToCurl(...): dimension mismatch");
1491 for (
int i = 0; i < n; i++)
1494 double x = (*this)(i,0);
1495 double y = (*this)(i,1);
1508 for (
int i = 0; i < n; i++)
1511 double x = (*this)(i,0);
1512 double y = (*this)(i,1);
1513 double z = (*this)(i,2);
1538 MFEM_VERIFY(
Width() == 2,
1539 "DenseMatrix::GradToVectorCurl2D(...): dimension must be 2")
1543 for (
int i = 0; i < n; i++)
1545 curl(i,0) = (*this)(i,1);
1546 curl(i,1) = -(*this)(i,0);
1552 MFEM_ASSERT(
Width()*
Height() == div.
Size(),
"incompatible Vector 'div'!");
1557 double *ddata = div.
GetData();
1559 for (
int i = 0; i < n; i++)
1569 for (
int j = 0; j <
Width(); j++)
1571 for (
int i = row1; i <= row2; i++)
1573 (*this)(i-row1,j) = A(i,j);
1582 for (
int j = col1; j <= col2; j++)
1584 for (
int i = 0; i <
Height(); i++)
1586 (*this)(i,j-col1) = A(i,j);
1595 for (
int j = 0; j < n; j++)
1597 for (
int i = 0; i < m; i++)
1599 (*this)(i,j) = A(Aro+i,Aco+j);
1606 double *v = A.
Data();
1608 for (
int j = 0; j < A.
Width(); j++)
1610 for (
int i = 0; i < A.
Height(); i++)
1612 (*this)(row_offset+i,col_offset+j) = *(v++);
1619 double *v = A.
Data();
1621 for (
int i = 0; i < A.
Width(); i++)
1623 for (
int j = 0; j < A.
Height(); j++)
1625 (*this)(row_offset+i,col_offset+j) = *(v++);
1631 int row_offset,
int col_offset)
1633 MFEM_VERIFY(row_offset+m <= this->
Height() && col_offset+n <= this->
Width(),
1634 "this DenseMatrix is too small to accommodate the submatrix. " 1635 <<
"row_offset = " << row_offset
1637 <<
", this->Height() = " << this->
Height()
1638 <<
", col_offset = " << col_offset
1640 <<
", this->Width() = " << this->
Width()
1642 MFEM_VERIFY(Aro+m <= A.
Height() && Aco+n <= A.
Width(),
1643 "The A DenseMatrix is too small to accommodate the submatrix. " 1646 <<
", A.Height() = " << A.
Height()
1647 <<
", Aco = " << Aco
1649 <<
", A.Width() = " << A.
Width()
1652 for (
int j = 0; j < n; j++)
1654 for (
int i = 0; i < m; i++)
1656 (*this)(row_offset+i,col_offset+j) = A(Aro+i,Aco+j);
1663 for (
int i = 0; i < n; i++)
1665 for (
int j = i+1; j < n; j++)
1667 (*this)(row_offset+i,col_offset+j) =
1668 (*
this)(row_offset+j,col_offset+i) = 0.0;
1672 for (
int i = 0; i < n; i++)
1674 (*this)(row_offset+i,col_offset+i) = c;
1681 for (
int i = 0; i < n; i++)
1683 for (
int j = i+1; j < n; j++)
1685 (*this)(row_offset+i,col_offset+j) =
1686 (*
this)(row_offset+j,col_offset+i) = 0.0;
1690 for (
int i = 0; i < n; i++)
1692 (*this)(row_offset+i,col_offset+i) = diag[i];
1700 int i, j, i_off = 0, j_off = 0;
1702 for (j = 0; j < A.
Width(); j++)
1709 for (i = 0; i < A.
Height(); i++)
1716 (*this)(i-i_off,j-j_off) = A(i,j);
1732 if (co+aw >
Width() || ro+ah > h)
1734 mfem_error(
"DenseMatrix::AddMatrix(...) 1 : dimension mismatch");
1738 p = data + ro + co * h;
1741 for (
int c = 0; c < aw; c++)
1743 for (
int r = 0; r < ah; r++)
1762 if (co+aw >
Width() || ro+ah > h)
1764 mfem_error(
"DenseMatrix::AddMatrix(...) 2 : dimension mismatch");
1768 p = data + ro + co * h;
1771 for (
int c = 0; c < aw; c++)
1773 for (
int r = 0; r < ah; r++)
1785 int idx_max = idx.
Max();
1786 MFEM_VERIFY(idx.
Min() >=0 && idx_max < this->
height && idx_max < this->
width,
1787 "DenseMatrix::GetSubMatrix: Index out of bounds");
1789 double * adata = A.
Data();
1792 for (
int i = 0; i<k; i++)
1795 for (
int j = 0; j<k; j++)
1798 adata[i+j*k] = this->data[ii+jj*
height];
1806 int k = idx_i.
Size();
1807 int l = idx_j.
Size();
1809 MFEM_VERIFY(idx_i.
Min() >=0 && idx_i.
Max() < this->
height,
1810 "DenseMatrix::GetSubMatrix: Row index out of bounds");
1811 MFEM_VERIFY(idx_j.
Min() >=0 && idx_j.
Max() < this->
width,
1812 "DenseMatrix::GetSubMatrix: Col index out of bounds");
1815 double * adata = A.
Data();
1818 for (
int i = 0; i<k; i++)
1821 for (
int j = 0; j<l; j++)
1824 adata[i+j*k] = this->data[ii+jj*
height];
1831 MFEM_VERIFY(iend >= ibeg,
"DenseMatrix::GetSubMatrix: Inconsistent range");
1832 MFEM_VERIFY(ibeg >=0,
1833 "DenseMatrix::GetSubMatrix: Negative index");
1834 MFEM_VERIFY(iend <= this->
height && iend <= this->
width,
1835 "DenseMatrix::GetSubMatrix: Index bigger than upper bound");
1837 int k = iend - ibeg;
1839 double * adata = A.
Data();
1842 for (
int i = 0; i<k; i++)
1845 for (
int j = 0; j<k; j++)
1848 adata[i+j*k] = this->data[ii+jj*
height];
1856 MFEM_VERIFY(iend >= ibeg,
1857 "DenseMatrix::GetSubMatrix: Inconsistent row range");
1858 MFEM_VERIFY(jend >= jbeg,
1859 "DenseMatrix::GetSubMatrix: Inconsistent col range");
1860 MFEM_VERIFY(ibeg >=0,
1861 "DenseMatrix::GetSubMatrix: Negative row index");
1862 MFEM_VERIFY(jbeg >=0,
1863 "DenseMatrix::GetSubMatrix: Negative row index");
1864 MFEM_VERIFY(iend <= this->
height,
1865 "DenseMatrix::GetSubMatrix: Index bigger than row upper bound");
1866 MFEM_VERIFY(jend <= this->
width,
1867 "DenseMatrix::GetSubMatrix: Index bigger than col upper bound");
1869 int k = iend - ibeg;
1870 int l = jend - jbeg;
1872 double * adata = A.
Data();
1875 for (
int i = 0; i<k; i++)
1878 for (
int j = 0; j<l; j++)
1881 adata[i+j*k] = this->data[ii+jj*
height];
1890 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1892 int idx_max = idx.
Max();
1894 MFEM_VERIFY(idx.
Min() >=0,
1895 "DenseMatrix::SetSubMatrix: Negative index");
1896 MFEM_VERIFY(idx_max < this->
height,
1897 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1898 MFEM_VERIFY(idx_max < this->
width,
1899 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1901 double * adata = A.
Data();
1904 for (
int i = 0; i<k; i++)
1907 for (
int j = 0; j<k; j++)
1910 this->data[ii+jj*
height] = adata[i+j*k];
1918 int k = idx_i.
Size();
1919 int l = idx_j.
Size();
1921 "DenseMatrix::SetSubMatrix:Inconsistent matrix dimensions");
1922 MFEM_VERIFY(idx_i.
Min() >=0,
1923 "DenseMatrix::SetSubMatrix: Negative row index");
1924 MFEM_VERIFY(idx_j.
Min() >=0,
1925 "DenseMatrix::SetSubMatrix: Negative col index");
1927 "DenseMatrix::SetSubMatrix: Index bigger than row upper bound");
1928 MFEM_VERIFY(idx_j.
Max() < this->
width,
1929 "DenseMatrix::SetSubMatrix: Index bigger than col upper bound");
1931 double * adata = A.
Data();
1934 for (
int i = 0; i<k; i++)
1937 for (
int j = 0; j<l; j++)
1940 this->data[ii+jj*
height] = adata[i+j*k];
1949 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::SetSubmatrix: A is not square");
1950 MFEM_VERIFY(ibeg >=0,
1951 "DenseMatrix::SetSubmatrix: Negative index");
1952 MFEM_VERIFY(ibeg + k <= this->
height,
1953 "DenseMatrix::SetSubmatrix: index bigger than row upper bound");
1954 MFEM_VERIFY(ibeg + k <= this->
width,
1955 "DenseMatrix::SetSubmatrix: index bigger than col upper bound");
1957 double * adata = A.
Data();
1960 for (
int i = 0; i<k; i++)
1963 for (
int j = 0; j<k; j++)
1966 this->data[ii+jj*
height] = adata[i+j*k];
1976 MFEM_VERIFY(ibeg>=0,
1977 "DenseMatrix::SetSubmatrix: Negative row index");
1978 MFEM_VERIFY(jbeg>=0,
1979 "DenseMatrix::SetSubmatrix: Negative col index");
1980 MFEM_VERIFY(ibeg + k <= this->
height,
1981 "DenseMatrix::SetSubmatrix: Index bigger than row upper bound");
1982 MFEM_VERIFY(jbeg + l <= this->
width,
1983 "DenseMatrix::SetSubmatrix: Index bigger than col upper bound");
1985 double * adata = A.
Data();
1988 for (
int i = 0; i<k; i++)
1991 for (
int j = 0; j<l; j++)
1994 this->data[ii+jj*
height] = adata[i+j*k];
2003 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2005 int idx_max = idx.
Max();
2007 MFEM_VERIFY(idx.
Min() >=0,
"DenseMatrix::AddSubMatrix: Negative index");
2008 MFEM_VERIFY(idx_max < this->
height,
2009 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2010 MFEM_VERIFY(idx_max < this->
width,
2011 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2013 double * adata = A.
Data();
2016 for (
int i = 0; i<k; i++)
2019 for (
int j = 0; j<k; j++)
2022 this->data[ii+jj*
height] += adata[i+j*k];
2030 int k = idx_i.
Size();
2031 int l = idx_j.
Size();
2033 "DenseMatrix::AddSubMatrix:Inconsistent matrix dimensions");
2035 MFEM_VERIFY(idx_i.
Min() >=0,
2036 "DenseMatrix::AddSubMatrix: Negative row index");
2037 MFEM_VERIFY(idx_j.
Min() >=0,
2038 "DenseMatrix::AddSubMatrix: Negative col index");
2040 "DenseMatrix::AddSubMatrix: Index bigger than row upper bound");
2041 MFEM_VERIFY(idx_j.
Max() < this->
width,
2042 "DenseMatrix::AddSubMatrix: Index bigger than col upper bound");
2044 double * adata = A.
Data();
2047 for (
int i = 0; i<k; i++)
2050 for (
int j = 0; j<l; j++)
2053 this->data[ii+jj*
height] += adata[i+j*k];
2061 MFEM_VERIFY(A.
Width() == k,
"DenseMatrix::AddSubmatrix: A is not square");
2063 MFEM_VERIFY(ibeg>=0,
2064 "DenseMatrix::AddSubmatrix: Negative index");
2065 MFEM_VERIFY(ibeg + k <= this->
Height(),
2066 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2067 MFEM_VERIFY(ibeg + k <= this->
Width(),
2068 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2070 double * adata = A.
Data();
2073 for (
int i = 0; i<k; i++)
2076 for (
int j = 0; j<k; j++)
2079 this->data[ii+jj*
height] += adata[i+j*k];
2089 MFEM_VERIFY(ibeg>=0,
2090 "DenseMatrix::AddSubmatrix: Negative row index");
2091 MFEM_VERIFY(jbeg>=0,
2092 "DenseMatrix::AddSubmatrix: Negative col index");
2093 MFEM_VERIFY(ibeg + k <= this->
height,
2094 "DenseMatrix::AddSubmatrix: Index bigger than row upper bound");
2095 MFEM_VERIFY(jbeg + l <= this->
width,
2096 "DenseMatrix::AddSubmatrix: Index bigger than col upper bound");
2098 double * adata = A.
Data();
2101 for (
int i = 0; i<k; i++)
2104 for (
int j = 0; j<l; j++)
2107 this->data[ii+jj*
height] += adata[i+j*k];
2115 double *vdata = v.
GetData() + offset;
2117 for (
int i = 0; i < n; i++)
2119 vdata[i] += data[i];
2126 const double *vdata = v.
GetData() + offset;
2128 for (
int i = 0; i < n; i++)
2141 mfem_error(
"DenseMatrix::AdjustDofDirection(...): dimension mismatch");
2146 for (
int i = 0; i < n-1; i++)
2148 const int s = (dof[i] < 0) ? (-1) : (1);
2149 for (
int j = i+1; j < n; j++)
2151 const int t = (dof[j] < 0) ? (-
s) : (
s);
2154 (*this)(i,j) = -(*
this)(i,j);
2155 (*this)(j,i) = -(*
this)(j,i);
2163 for (
int j = 0; j <
Width(); j++)
2165 (*this)(row, j) = value;
2171 for (
int i = 0; i <
Height(); i++)
2173 (*this)(i, col) = value;
2179 MFEM_ASSERT(row !=
nullptr,
"supplied row pointer is null");
2180 for (
int j = 0; j <
Width(); j++)
2182 (*this)(r, j) = row[j];
2194 MFEM_ASSERT(col !=
nullptr,
"supplied column pointer is null");
2195 for (
int i = 0; i <
Height(); i++)
2197 (*this)(i, c) = col[i];
2209 for (
int col = 0; col <
Width(); col++)
2211 for (
int row = 0; row <
Height(); row++)
2213 if (std::abs(
operator()(row,col)) <= eps)
2224 ios::fmtflags old_flags = os.flags();
2226 os << setiosflags(ios::scientific | ios::showpos);
2227 for (
int i = 0; i <
height; i++)
2229 os <<
"[row " << i <<
"]\n";
2230 for (
int j = 0; j <
width; j++)
2233 if (j+1 ==
width || (j+1) % width_ == 0)
2244 os.flags(old_flags);
2250 ios::fmtflags old_flags = os.flags();
2252 os << setiosflags(ios::scientific | ios::showpos);
2253 for (
int i = 0; i <
height; i++)
2255 for (
int j = 0; j <
width; j++)
2263 os.flags(old_flags);
2269 ios::fmtflags old_flags = os.flags();
2271 os << setiosflags(ios::scientific | ios::showpos);
2272 for (
int j = 0; j <
width; j++)
2274 os <<
"[col " << j <<
"]\n";
2275 for (
int i = 0; i <
height; i++)
2278 if (i+1 ==
height || (i+1) % width_ == 0)
2289 os.flags(old_flags);
2298 for (
int i = 0; i <
width; i++)
2303 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2344 MFEM_VERIFY(A.
IsSquare(),
"A must be a square matrix!");
2345 MFEM_ASSERT(A.
NumCols() > 0,
"supplied matrix, A, is empty!");
2346 MFEM_ASSERT(X !=
nullptr,
"supplied vector, X, is null!");
2354 double det = A(0,0);
2355 if (std::abs(det) <= TOL) {
return false; }
2362 double det = A.
Det();
2363 if (std::abs(det) <= TOL) {
return false; }
2365 double invdet = 1. / det;
2370 X[0] = ( A(1,1)*b0 - A(0,1)*b1) * invdet;
2371 X[1] = (-A(1,0)*b0 + A(0,0)*b1) * invdet;
2380 if (!lu.Factor(N,TOL)) {
return false; }
2392 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2393 b.Width() == c.
Height(),
"incompatible dimensions");
2395 #ifdef MFEM_USE_LAPACK 2396 static char transa =
'N', transb =
'N';
2398 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2400 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2403 const int ah =
a.Height();
2404 const int aw =
a.Width();
2405 const int bw =
b.Width();
2406 double *ad =
a.Data();
2407 const double *bd =
b.Data();
2408 const double *cd = c.
Data();
2416 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2417 b.Width() == c.
Height(),
"incompatible dimensions");
2419 #ifdef MFEM_USE_LAPACK 2420 static char transa =
'N', transb =
'N';
2421 static double beta = 1.0;
2422 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2424 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2427 const int ah =
a.Height();
2428 const int aw =
a.Width();
2429 const int bw =
b.Width();
2430 double *ad =
a.Data();
2431 const double *bd =
b.Data();
2432 const double *cd = c.
Data();
2433 for (
int j = 0; j < aw; j++)
2435 for (
int k = 0; k < bw; k++)
2437 for (
int i = 0; i < ah; i++)
2439 ad[i+j*ah] +=
alpha * bd[i+k*ah] * cd[k+j*bw];
2448 MFEM_ASSERT(
a.Height() ==
b.Height() &&
a.Width() == c.
Width() &&
2449 b.Width() == c.
Height(),
"incompatible dimensions");
2451 #ifdef MFEM_USE_LAPACK 2452 static char transa =
'N', transb =
'N';
2454 int m =
b.Height(), n = c.
Width(), k =
b.Width();
2456 dgemm_(&transa, &transb, &m, &n, &k, &
alpha,
b.Data(), &m,
2459 const int ah =
a.Height();
2460 const int aw =
a.Width();
2461 const int bw =
b.Width();
2462 double *ad =
a.Data();
2463 const double *bd =
b.Data();
2464 const double *cd = c.
Data();
2465 for (
int j = 0; j < aw; j++)
2467 for (
int k = 0; k < bw; k++)
2469 for (
int i = 0; i < ah; i++)
2471 ad[i+j*ah] += bd[i+k*ah] * cd[k+j*bw];
2481 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
2483 mfem_error(
"CalcAdjugate(...): unsupported dimensions");
2485 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
2487 mfem_error(
"CalcAdjugate(...): dimension mismatch");
2491 if (
a.Width() <
a.Height())
2493 const double *d =
a.Data();
2494 double *ad = adja.
Data();
2500 if (
a.Height() == 3)
2509 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2510 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2511 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2513 ad[0] = d[0]*g - d[3]*
f;
2514 ad[1] = d[3]*e - d[0]*
f;
2515 ad[2] = d[1]*g - d[4]*
f;
2516 ad[3] = d[4]*e - d[1]*
f;
2517 ad[4] = d[2]*g - d[5]*
f;
2518 ad[5] = d[5]*e - d[2]*
f;
2527 else if (
a.Width() == 2)
2530 adja(0,1) = -
a(0,1);
2531 adja(1,0) = -
a(1,0);
2536 adja(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2537 adja(0,1) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2538 adja(0,2) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2540 adja(1,0) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2541 adja(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2542 adja(1,2) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2544 adja(2,0) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2545 adja(2,1) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2546 adja(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2553 if (
a.Height() !=
a.Width() || adjat.
Height() != adjat.
Width() ||
2554 a.Width() != adjat.
Width() ||
a.Width() < 1 ||
a.Width() > 3)
2556 mfem_error(
"CalcAdjugateTranspose(...): dimension mismatch");
2563 else if (
a.Width() == 2)
2565 adjat(0,0) =
a(1,1);
2566 adjat(1,0) = -
a(0,1);
2567 adjat(0,1) = -
a(1,0);
2568 adjat(1,1) =
a(0,0);
2572 adjat(0,0) =
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1);
2573 adjat(1,0) =
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2);
2574 adjat(2,0) =
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1);
2576 adjat(0,1) =
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2);
2577 adjat(1,1) =
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0);
2578 adjat(2,1) =
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2);
2580 adjat(0,2) =
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0);
2581 adjat(1,2) =
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1);
2582 adjat(2,2) =
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0);
2588 MFEM_ASSERT(
a.Width() <=
a.Height() &&
a.Width() >= 1 &&
a.Height() <= 3,
"");
2589 MFEM_ASSERT(inva.
Height() ==
a.Width(),
"incorrect dimensions");
2590 MFEM_ASSERT(inva.
Width() ==
a.Height(),
"incorrect dimensions");
2592 if (
a.Width() <
a.Height())
2594 const double *d =
a.Data();
2595 double *
id = inva.
Data();
2596 if (
a.Height() == 2)
2615 const double t =
a.Det();
2616 MFEM_ASSERT(std::abs(
t) > 1.0e-14 * pow(
a.FNorm()/
a.Width(),
a.Width()),
2617 "singular matrix!");
2623 inva(0,0) = 1.0 /
a.Det();
2626 kernels::CalcInverse<2>(
a.Data(), inva.
Data());
2629 kernels::CalcInverse<3>(
a.Data(), inva.
Data());
2637 if ( (
a.Width() !=
a.Height()) || ( (
a.Height()!= 1) && (
a.Height()!= 2)
2638 && (
a.Height()!= 3) ) )
2640 mfem_error(
"CalcInverseTranspose(...): dimension mismatch");
2644 double t = 1. /
a.Det() ;
2649 inva(0,0) = 1.0 /
a(0,0);
2652 inva(0,0) =
a(1,1) *
t ;
2653 inva(1,0) = -
a(0,1) *
t ;
2654 inva(0,1) = -
a(1,0) *
t ;
2655 inva(1,1) =
a(0,0) *
t ;
2658 inva(0,0) = (
a(1,1)*
a(2,2)-
a(1,2)*
a(2,1))*
t;
2659 inva(1,0) = (
a(0,2)*
a(2,1)-
a(0,1)*
a(2,2))*
t;
2660 inva(2,0) = (
a(0,1)*
a(1,2)-
a(0,2)*
a(1,1))*
t;
2662 inva(0,1) = (
a(1,2)*
a(2,0)-
a(1,0)*
a(2,2))*
t;
2663 inva(1,1) = (
a(0,0)*
a(2,2)-
a(0,2)*
a(2,0))*
t;
2664 inva(2,1) = (
a(0,2)*
a(1,0)-
a(0,0)*
a(1,2))*
t;
2666 inva(0,2) = (
a(1,0)*
a(2,1)-
a(1,1)*
a(2,0))*
t;
2667 inva(1,2) = (
a(0,1)*
a(2,0)-
a(0,0)*
a(2,1))*
t;
2668 inva(2,2) = (
a(0,0)*
a(1,1)-
a(0,1)*
a(1,0))*
t;
2678 "Matrix must be 3x2 or 2x1, " 2679 <<
"and the Vector must be sized with the rows. " 2680 <<
" J.Height() = " << J.
Height()
2681 <<
", J.Width() = " << J.
Width()
2682 <<
", n.Size() = " << n.
Size()
2685 const double *d = J.
Data();
2693 n(0) = d[1]*d[5] - d[2]*d[4];
2694 n(1) = d[2]*d[3] - d[0]*d[5];
2695 n(2) = d[0]*d[4] - d[1]*d[3];
2701 const int height =
a.Height();
2702 const int width =
a.Width();
2703 for (
int i = 0; i < height; i++)
2705 for (
int j = 0; j <= i; j++)
2708 for (
int k = 0; k < width; k++)
2710 temp +=
a(i,k) *
a(j,k);
2712 aat(j,i) = aat(i,j) = temp;
2719 for (
int i = 0; i < A.
Height(); i++)
2721 for (
int j = 0; j < i; j++)
2724 for (
int k = 0; k < A.
Width(); k++)
2726 t += D(k) * A(i, k) * A(j, k);
2734 for (
int i = 0; i < A.
Height(); i++)
2737 for (
int k = 0; k < A.
Width(); k++)
2739 t += D(k) * A(i, k) * A(i, k);
2747 for (
int i = 0; i < A.
Height(); i++)
2749 for (
int j = 0; j <= i; j++)
2752 for (
int k = 0; k < A.
Width(); k++)
2754 t += D(k) * A(i, k) * A(j, k);
2756 ADAt(j, i) = ADAt(i, j) =
t;
2767 mfem_error(
"MultABt(...): dimension mismatch");
2771 #ifdef MFEM_USE_LAPACK 2772 static char transa =
'N', transb =
'T';
2779 const int ah = A.
Height();
2780 const int bh = B.
Height();
2781 const int aw = A.
Width();
2782 const double *ad = A.
Data();
2783 const double *bd = B.
Data();
2784 double *cd = ABt.
Data();
2788 const int ah = A.
Height();
2789 const int bh = B.
Height();
2790 const int aw = A.
Width();
2791 const double *ad = A.
Data();
2792 const double *bd = B.
Data();
2793 double *cd = ABt.
Data();
2795 for (
int j = 0; j < bh; j++)
2796 for (
int i = 0; i < ah; i++)
2799 const double *ap = ad + i;
2800 const double *bp = bd + j;
2801 for (
int k = 0; k < aw; k++)
2813 for (i = 0; i < A.
Height(); i++)
2814 for (j = 0; j < B.
Height(); j++)
2817 for (k = 0; k < A.
Width(); k++)
2819 d += A(i, k) * B(j, k);
2833 mfem_error(
"MultADBt(...): dimension mismatch");
2837 const int ah = A.
Height();
2838 const int bh = B.
Height();
2839 const int aw = A.
Width();
2840 const double *ad = A.
Data();
2841 const double *bd = B.
Data();
2842 const double *dd = D.
GetData();
2843 double *cd = ADBt.
Data();
2845 for (
int i = 0,
s = ah*bh; i <
s; i++)
2849 for (
int k = 0; k < aw; k++)
2852 for (
int j = 0; j < bh; j++)
2854 const double dk_bjk = dd[k] * bd[j];
2855 for (
int i = 0; i < ah; i++)
2857 cp[i] += ad[i] * dk_bjk;
2872 mfem_error(
"AddMultABt(...): dimension mismatch");
2876 #ifdef MFEM_USE_LAPACK 2877 static char transa =
'N', transb =
'T';
2884 const int ah = A.
Height();
2885 const int bh = B.
Height();
2886 const int aw = A.
Width();
2887 const double *ad = A.
Data();
2888 const double *bd = B.
Data();
2889 double *cd = ABt.
Data();
2891 for (
int k = 0; k < aw; k++)
2894 for (
int j = 0; j < bh; j++)
2896 const double bjk = bd[j];
2897 for (
int i = 0; i < ah; i++)
2899 cp[i] += ad[i] * bjk;
2910 for (i = 0; i < A.
Height(); i++)
2911 for (j = 0; j < B.
Height(); j++)
2914 for (k = 0; k < A.
Width(); k++)
2916 d += A(i, k) * B(j, k);
2930 mfem_error(
"AddMultADBt(...): dimension mismatch");
2934 const int ah = A.
Height();
2935 const int bh = B.
Height();
2936 const int aw = A.
Width();
2937 const double *ad = A.
Data();
2938 const double *bd = B.
Data();
2939 const double *dd = D.
GetData();
2940 double *cd = ADBt.
Data();
2942 for (
int k = 0; k < aw; k++)
2945 for (
int j = 0; j < bh; j++)
2947 const double dk_bjk = dd[k] * bd[j];
2948 for (
int i = 0; i < ah; i++)
2950 cp[i] += ad[i] * dk_bjk;
2966 mfem_error(
"AddMult_a_ABt(...): dimension mismatch");
2970 #ifdef MFEM_USE_LAPACK 2971 static char transa =
'N', transb =
'T';
2973 static double beta = 1.0;
2979 const int ah = A.
Height();
2980 const int bh = B.
Height();
2981 const int aw = A.
Width();
2982 const double *ad = A.
Data();
2983 const double *bd = B.
Data();
2984 double *cd = ABt.
Data();
2986 for (
int k = 0; k < aw; k++)
2989 for (
int j = 0; j < bh; j++)
2991 const double bjk =
a * bd[j];
2992 for (
int i = 0; i < ah; i++)
2994 cp[i] += ad[i] * bjk;
3005 for (i = 0; i < A.
Height(); i++)
3006 for (j = 0; j < B.
Height(); j++)
3009 for (k = 0; k < A.
Width(); k++)
3011 d += A(i, k) * B(j, k);
3024 mfem_error(
"MultAtB(...): dimension mismatch");
3028 #ifdef MFEM_USE_LAPACK 3029 static char transa =
'T', transb =
'N';
3036 const int ah = A.
Height();
3037 const int aw = A.
Width();
3038 const int bw = B.
Width();
3039 const double *ad = A.
Data();
3040 const double *bd = B.
Data();
3041 double *cd = AtB.
Data();
3043 for (
int j = 0; j < bw; j++)
3045 const double *ap = ad;
3046 for (
int i = 0; i < aw; i++)
3049 for (
int k = 0; k < ah; k++)
3062 for (i = 0; i < A.
Width(); i++)
3063 for (j = 0; j < B.
Width(); j++)
3066 for (k = 0; k < A.
Height(); k++)
3068 d += A(k, i) * B(k, j);
3079 for (
int i = 0; i < A.
Height(); i++)
3081 for (
int j = 0; j < i; j++)
3084 for (
int k = 0; k < A.
Width(); k++)
3086 d += A(i,k) * A(j,k);
3088 AAt(i, j) += (d *=
a);
3092 for (
int k = 0; k < A.
Width(); k++)
3094 d += A(i,k) * A(i,k);
3102 for (
int i = 0; i < A.
Height(); i++)
3104 for (
int j = 0; j <= i; j++)
3107 for (
int k = 0; k < A.
Width(); k++)
3109 d += A(i,k) * A(j,k);
3111 AAt(i, j) = AAt(j, i) =
a * d;
3118 for (
int i = 0; i < v.
Size(); i++)
3120 for (
int j = 0; j <= i; j++)
3122 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3132 mfem_error(
"MultVWt(...): dimension mismatch");
3136 for (
int i = 0; i < v.
Size(); i++)
3138 const double vi = v(i);
3139 for (
int j = 0; j < w.
Size(); j++)
3141 VWt(i, j) = vi * w(j);
3148 const int m = v.
Size(), n = w.
Size();
3153 mfem_error(
"AddMultVWt(...): dimension mismatch");
3157 for (
int i = 0; i < m; i++)
3159 const double vi = v(i);
3160 for (
int j = 0; j < n; j++)
3162 VWt(i, j) += vi * w(j);
3169 const int n = v.
Size();
3174 mfem_error(
"AddMultVVt(...): dimension mismatch");
3178 for (
int i = 0; i < n; i++)
3180 const double vi = v(i);
3181 for (
int j = 0; j < i; j++)
3183 const double vivj = vi * v(j);
3187 VVt(i, i) += vi * vi;
3194 const int m = v.
Size(), n = w.
Size();
3199 mfem_error(
"AddMult_a_VWt(...): dimension mismatch");
3203 for (
int j = 0; j < n; j++)
3205 const double awj =
a * w(j);
3206 for (
int i = 0; i < m; i++)
3208 VWt(i, j) += v(i) * awj;
3216 "incompatible dimensions!");
3218 const int n = v.
Size();
3219 for (
int i = 0; i < n; i++)
3221 double avi =
a * v(i);
3222 for (
int j = 0; j < i; j++)
3224 const double avivj = avi * v(j);
3228 VVt(i, i) += avi * v(i);
3236 RAP.SetSize(RA.Height(), P.
Width());
3245 RAP.SetSize(RA.Height(), P.
Width());
3251 #ifdef MFEM_USE_LAPACK 3257 double *data_ptr = this->
data;
3258 for (
int i = 0; i < m; i++)
3263 double a = std::abs(data_ptr[piv+i*m]);
3264 for (
int j = i+1; j < m; j++)
3266 const double b = std::abs(data_ptr[j+i*m]);
3277 for (
int j = 0; j < m; j++)
3279 mfem::Swap<double>(data_ptr[i+j*m], data_ptr[piv+j*m]);
3284 if (abs(data_ptr[i + i*m]) <= TOL)
3289 const double a_ii_inv = 1.0 / data_ptr[i+i*m];
3290 for (
int j = i+1; j < m; j++)
3292 data_ptr[j+i*m] *= a_ii_inv;
3294 for (
int k = i+1; k < m; k++)
3296 const double a_ik = data_ptr[i+k*m];
3297 for (
int j = i+1; j < m; j++)
3299 data_ptr[j+k*m] -= a_ik * data_ptr[j+i*m];
3311 for (
int i=0; i<m; i++)
3315 det *= -
data[m * i + i];
3319 det *=
data[m * i + i];
3328 for (
int k = 0; k < n; k++)
3331 for (
int i = 0; i < m; i++)
3333 double x_i = x[i] *
data[i+i*m];
3334 for (
int j = i+1; j < m; j++)
3336 x_i += x[j] *
data[i+j*m];
3341 for (
int i = m-1; i >= 0; i--)
3344 for (
int j = 0; j < i; j++)
3346 x_i += x[j] *
data[i+j*m];
3351 for (
int i = m-1; i >= 0; i--)
3362 for (
int k = 0; k < n; k++)
3365 for (
int i = 0; i < m; i++)
3370 for (
int j = 0; j < m; j++)
3372 const double x_j = x[j];
3373 for (
int i = j+1; i < m; i++)
3375 x[i] -=
data[i+j*m] * x_j;
3386 for (
int k = 0; k < n; k++)
3388 for (
int j = m-1; j >= 0; j--)
3390 const double x_j = ( x[j] /=
data[j+j*m] );
3391 for (
int i = 0; i < j; i++)
3393 x[i] -=
data[i+j*m] * x_j;
3402 #ifdef MFEM_USE_LAPACK 3406 MFEM_VERIFY(!info,
"LAPACK: error in DGETRS");
3417 #ifdef MFEM_USE_LAPACK 3418 char n_ch =
'N', side =
'R', u_ch =
'U', l_ch =
'L';
3422 dtrsm_(&side,&u_ch,&n_ch,&n_ch,&n,&m,&
alpha,
data,&m,X,&n);
3423 dtrsm_(&side,&l_ch,&n_ch,&u_ch,&n,&m,&
alpha,
data,&m,X,&n);
3429 for (
int k = 0; k < n; k++)
3431 for (
int j = 0; j < m; j++)
3433 const double x_j = ( x[j*n] /=
data[j+j*m]);
3434 for (
int i = j+1; i < m; i++)
3436 x[i*n] -=
data[j + i*m] * x_j;
3444 for (
int k = 0; k < n; k++)
3446 for (
int j = m-1; j >= 0; j--)
3448 const double x_j = x[j*n];
3449 for (
int i = 0; i < j; i++)
3451 x[i*n] -=
data[j + i*m] * x_j;
3459 for (
int k = 0; k < n; k++)
3461 for (
int i = m-1; i >= 0; --i)
3474 for (
int k = 0; k < m; k++)
3476 const double minus_x_k = -( x[k] = 1.0/
data[k+k*m] );
3477 for (
int i = 0; i < k; i++)
3479 x[i] =
data[i+k*m] * minus_x_k;
3481 for (
int j = k-1; j >= 0; j--)
3483 const double x_j = ( x[j] /=
data[j+j*m] );
3484 for (
int i = 0; i < j; i++)
3486 x[i] -=
data[i+j*m] * x_j;
3494 for (
int j = 0; j < k; j++)
3496 const double minus_L_kj = -
data[k+j*m];
3497 for (
int i = 0; i <= j; i++)
3499 X[i+j*m] += X[i+k*m] * minus_L_kj;
3501 for (
int i = j+1; i < m; i++)
3503 X[i+j*m] = X[i+k*m] * minus_L_kj;
3507 for (
int k = m-2; k >= 0; k--)
3509 for (
int j = 0; j < k; j++)
3511 const double L_kj =
data[k+j*m];
3512 for (
int i = 0; i < m; i++)
3514 X[i+j*m] -= X[i+k*m] * L_kj;
3519 for (
int k = m-1; k >= 0; k--)
3524 for (
int i = 0; i < m; i++)
3526 Swap<double>(X[i+k*m], X[i+piv_k*m]);
3533 const double *X1,
double *X2)
3536 for (
int k = 0; k < r; k++)
3538 for (
int j = 0; j < m; j++)
3540 const double x1_jk = X1[j+k*m];
3541 for (
int i = 0; i < n; i++)
3543 X2[i+k*n] -= A21[i+j*n] * x1_jk;
3550 int m,
int n,
double *A12,
double *A21,
double *A22)
const 3555 for (
int j = 0; j < m; j++)
3557 const double u_jj_inv = 1.0/
data[j+j*m];
3558 for (
int i = 0; i < n; i++)
3560 A21[i+j*n] *= u_jj_inv;
3562 for (
int k = j+1; k < m; k++)
3564 const double u_jk =
data[j+k*m];
3565 for (
int i = 0; i < n; i++)
3567 A21[i+k*n] -= A21[i+j*n] * u_jk;
3572 SubMult(m, n, n, A21, A12, A22);
3576 double *B1,
double *B2)
const 3581 SubMult(m, n, r, L21, B1, B2);
3585 const double *X2,
double *Y1)
const 3588 SubMult(n, m, r, U12, X2, Y1);
3596 #ifdef MFEM_USE_LAPACK 3599 MFEM_VERIFY(
data,
"Matrix data not set");
3604 for (
int j = 0; j<m; j++)
3607 for (
int k = 0; k<j; k++)
3612 MFEM_VERIFY(
data[j+j*m] -
a > 0.,
3613 "CholeskyFactors::Factor: The matrix is not SPD");
3615 data[j+j*m] = std::sqrt(
data[j+j*m] -
a);
3617 if (
data[j + j*m] <= TOL)
3622 for (
int i = j+1; i<m; i++)
3625 for (
int k = 0; k<j; k++)
3639 for (
int i=0; i<m; i++)
3641 det *=
data[i + i*m];
3650 for (
int k = 0; k < n; k++)
3652 for (
int j = m-1; j >= 0; j--)
3654 double x_j = x[j] *
data[j+j*m];
3655 for (
int i = 0; i < j; i++)
3657 x_j += x[i] *
data[j+i*m];
3668 for (
int k = 0; k < n; k++)
3670 for (
int i = 0; i < m; i++)
3672 double x_i = x[i] *
data[i+i*m];
3673 for (
int j = i+1; j < m; j++)
3675 x_i += x[j] *
data[j+i*m];
3686 #ifdef MFEM_USE_LAPACK 3693 MFEM_VERIFY(!info,
"CholeskyFactors:LSolve:: info");
3697 for (
int k = 0; k < n; k++)
3700 for (
int j = 0; j < m; j++)
3702 const double x_j = (x[j] /=
data[j+j*m]);
3703 for (
int i = j+1; i < m; i++)
3705 x[i] -=
data[i+j*m] * x_j;
3715 #ifdef MFEM_USE_LAPACK 3723 MFEM_VERIFY(!info,
"CholeskyFactors:USolve:: info");
3728 for (
int k = 0; k < n; k++)
3730 for (
int j = m-1; j >= 0; j--)
3732 const double x_j = ( x[j] /=
data[j+j*m] );
3733 for (
int i = 0; i < j; i++)
3735 x[i] -=
data[j+i*m] * x_j;
3745 #ifdef MFEM_USE_LAPACK 3749 MFEM_VERIFY(!info,
"CholeskyFactors:Solve:: info");
3759 #ifdef MFEM_USE_LAPACK 3769 dtrsm_(&side,&uplo,&transt,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3770 dtrsm_(&side,&uplo,&
trans,&diag,&n,&m,&
alpha,
data,&m,X,&n);
3775 for (
int k = 0; k < n; k++)
3777 for (
int j = 0; j < m; j++)
3779 const double x_j = ( x[j*n] /=
data[j+j*m]);
3780 for (
int i = j+1; i < m; i++)
3782 x[i*n] -=
data[i + j*m] * x_j;
3789 for (
int k = 0; k < n; k++)
3791 for (
int j = m-1; j >= 0; j--)
3793 const double x_j = (x[j*n] /=
data[j+j*m]);
3794 for (
int i = 0; i < j; i++)
3796 x[i*n] -=
data[j + i*m] * x_j;
3807 #ifdef MFEM_USE_LAPACK 3809 for (
int i = 0; i<m; i++)
3811 for (
int j = i; j<m; j++)
3813 X[j+i*m] =
data[j+i*m];
3818 dpotri_(&uplo, &m, X, &m, &info);
3819 MFEM_VERIFY(!info,
"CholeskyFactors:GetInverseMatrix:: info");
3821 for (
int i = 0; i<m; i++)
3823 for (
int j = i+1; j<m; j++)
3825 X[i+j*m] = X[j+i*m];
3830 for (
int k = 0; k<m; k++)
3832 X[k+k*m] = 1./
data[k+k*m];
3833 for (
int i = k+1; i < m; i++)
3836 for (
int j=k; j<i; j++)
3838 s -=
data[i+j*m] * X[j+k*m]/
data[i+i*m];
3843 for (
int i = 0; i < m; i++)
3845 for (
int j = i; j < m; j++)
3848 for (
int k=j; k<m; k++)
3850 s += X[k+i*m] * X[k+j*m];
3852 X[i+j*m] = X[j+i*m] =
s;
3859 void DenseMatrixInverse::Init(
int m)
3867 factors =
new LUFactors();
3871 factors->
data =
new double[m*m];
3874 dynamic_cast<LUFactors *
>(factors)->ipiv =
new int[m];
3883 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3892 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3899 MFEM_ASSERT(a,
"DenseMatrix is not given");
3900 const double *adata = a->data;
3902 for (
int i = 0; i <
s; i++)
3904 factors->
data[i] = adata[i];
3917 MFEM_VERIFY(mat.
height == mat.
width,
"DenseMatrix is not square!");
3921 if (own_data) {
delete [] factors->
data; }
3927 if (own_data) {
delete [] lu->
ipiv; }
3939 MFEM_VERIFY(
p != NULL,
"Operator is not a DenseMatrix!");
3945 for (
int row = 0; row <
height; row++)
3968 for (
int i = 0; i <
width; i++)
3979 delete [] factors->
data;
3982 delete []
dynamic_cast<LUFactors *
>(factors)->ipiv;
3988 #ifdef MFEM_USE_LAPACK 4003 &qwork, &lwork, &info);
4005 lwork = (int) qwork;
4006 work =
new double[lwork];
4011 : mat(other.mat), EVal(other.EVal), EVect(other.EVect), ev(NULL, other.n),
4016 lwork = other.lwork;
4018 work =
new double[lwork];
4024 if (mat.
Width() != n)
4026 mfem_error(
"DenseMatrixEigensystem::Eval(): dimension mismatch");
4032 work, &lwork, &info);
4036 mfem::err <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: " 4050 bool left_eigen_vectors,
4051 bool right_eigen_vectors)
4054 MFEM_VERIFY(A.
Height() == A.
Width(),
"A has to be a square matrix");
4055 MFEM_VERIFY(B.
Height() == B.
Width(),
"B has to be a square matrix");
4057 MFEM_VERIFY(B.
Height() == n,
"A and B dimension mismatch");
4063 if (left_eigen_vectors)
4068 if (right_eigen_vectors)
4077 alphar =
new double[n];
4078 alphai =
new double[n];
4079 beta =
new double[n];
4081 int nl = max(1,Vl.
Height());
4082 int nr = max(1,Vr.
Height());
4084 dggev_(&jobvl,&jobvr,&n,A_copy.
Data(),&n,B_copy.
Data(),&n,alphar,
4085 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4086 &qwork, &lwork, &info);
4088 lwork = (int) qwork;
4089 work =
new double[lwork];
4094 int nl = max(1,Vl.
Height());
4095 int nr = max(1,Vr.
Height());
4099 dggev_(&jobvl,&jobvr,&n,A_copy.Data(),&n,B_copy.
Data(),&n,alphar,
4100 alphai, beta, Vl.
Data(), &nl, Vr.
Data(), &nr,
4101 work, &lwork, &info);
4105 mfem::err <<
"DenseMatrixGeneralizedEigensystem::Eval(): DGGEV error code: " 4111 for (
int i = 0; i<n; i++)
4115 evalues_r(i) = alphar[i]/
beta[i];
4116 evalues_i(i) = alphai[i]/
beta[i];
4135 bool left_singular_vectors,
4136 bool right_singular_vectors)
4140 jobu = (left_singular_vectors)?
'S' :
'N';
4141 jobvt = (right_singular_vectors)?
'S' :
'N';
4146 bool left_singular_vectors,
4147 bool right_singular_vectors)
4151 jobu = (left_singular_vectors)?
'S' :
'N';
4152 jobvt = (right_singular_vectors)?
'S' :
'N';
4157 char left_singular_vectors,
4158 char right_singular_vectors)
4162 jobu = left_singular_vectors;
4163 jobvt = right_singular_vectors;
4168 char left_singular_vectors,
4169 char right_singular_vectors)
4173 jobu = left_singular_vectors;
4174 jobvt = right_singular_vectors;
4178 void DenseMatrixSVD::Init()
4184 NULL, &n, &qwork, &lwork, &info);
4186 lwork = (int) qwork;
4187 work =
new double[lwork];
4198 double * datau =
nullptr;
4199 double * datavt =
nullptr;
4205 else if (jobu ==
'S')
4215 else if (jobvt ==
'S')
4222 datavt, &n, work, &lwork, &info);
4226 mfem::err <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
4236 #endif // if MFEM_USE_LAPACK 4243 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
4251 for (
int i = 0; i < ne; i++)
4254 for (
int col = 0; col < n; col++)
4256 x_col = xp[dofs[col]];
4257 for (
int row = 0; row < n; row++)
4259 yp[dofs[row]] += x_col*d_col[row];
4268 for (
int i = 0; i < ne; i++)
4271 x_col = xp[dofs[0]];
4272 for (
int row = 0; row < n; row++)
4274 ye(row) = x_col*d_col[row];
4277 for (
int col = 1; col < n; col++)
4279 x_col = xp[dofs[col]];
4280 for (
int row = 0; row < n; row++)
4282 ye(row) += x_col*d_col[row];
4286 for (
int row = 0; row < n; row++)
4288 yp[dofs[row]] += ye(row);
4297 for (
int i=0; i<
s; i++)
4313 const int m = Mlu.
SizeI();
4314 const int NE = Mlu.
SizeK();
4320 pivot_flag[0] =
true;
4321 bool *d_pivot_flag = pivot_flag.ReadWrite();
4325 for (
int i = 0; i < m; i++)
4330 double a = fabs(data_all(piv,i,e));
4331 for (
int j = i+1; j < m; j++)
4333 const double b = fabs(data_all(j,i,e));
4340 ipiv_all(i,e) = piv;
4344 for (
int j = 0; j < m; j++)
4346 mfem::kernels::internal::Swap<double>(data_all(i,j,e), data_all(piv,j,e));
4351 if (abs(data_all(i,i,e)) <= TOL)
4353 d_pivot_flag[0] =
false;
4356 const double a_ii_inv = 1.0 / data_all(i,i,e);
4357 for (
int j = i+1; j < m; j++)
4359 data_all(j,i,e) *= a_ii_inv;
4362 for (
int k = i+1; k < m; k++)
4364 const double a_ik = data_all(i,k,e);
4365 for (
int j = i+1; j < m; j++)
4367 data_all(j,k,e) -= a_ik * data_all(j,i,e);
4375 MFEM_ASSERT(pivot_flag.HostRead()[0],
"Batch LU factorization failed \n");
4381 const int m = Mlu.
SizeI();
4382 const int NE = Mlu.
SizeK();
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void dsyevr_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
DenseMatrix & operator-=(const DenseMatrix &m)
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
void SquareRootInverse()
Replaces the current matrix with its square root inverse.
void RightSolve(int m, int n, double *X) const
void RightSolve(int m, int n, double *X) const
int CheckFinite(const double *v, const int n)
void trans(const Vector &u, Vector &x)
void BatchLUFactor(DenseTensor &Mlu, Array< int > &P, const double TOL)
Compute the LU factorization of a batch of matrices.
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
DenseMatrix & operator*=(double c)
void SetCol(int c, const double *col)
DenseTensor & operator=(double c)
Sets the tensor elements equal to constant c.
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
void SetRow(int r, const double *row)
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
MFEM_HOST_DEVICE void MultABt(const int Aheight, const int Awidth, const int Bheight, const TA *Adata, const TB *Bdata, TC *ABtdata)
Multiply a matrix of size Aheight x Awidth and data Adata with the transpose of a matrix of size Bhei...
void dtrtrs_(char *, char *, char *, int *, int *, double *, int *, double *, int *, int *)
void Mult(int m, int n, double *X) const
void dsyev_Eigensystem(DenseMatrix &a, Vector &ev, DenseMatrix *evect)
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
void SetSize(int s)
Resize the vector to size s.
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
virtual double Det(int m) const
void Delete()
Delete the owned pointers and reset the Memory object.
virtual const double * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
void AddMultTranspose_a(double a, const Vector &x, Vector &y) const
y += a * A^t x
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
MFEM_HOST_DEVICE void CalcLeftInverse< 3, 1 >(const double *d, double *left_inv)
void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, double *alpha, double *a, int *lda, double *b, int *ldb)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
MFEM_DEPRECATED DenseMatrixSVD(DenseMatrix &M, bool left_singular_vectors=false, bool right_singular_vectors=false)
Constructor for the DenseMatrixSVD.
MFEM_HOST_DEVICE void Add(const int height, const int width, const TALPHA alpha, const TA *Adata, const TB *Bdata, TC *Cdata)
Compute C = A + alpha*B, where the matrices A, B and C are of size height x width with data Adata...
void dpotrf_(char *, int *, double *, int *, int *)
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
virtual void GetInverseMatrix(int m, double *X) const
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
virtual void Solve(int m, int n, double *X) const
int Size() const
Returns the size of the vector.
void dgetri_(int *N, double *A, int *LDA, int *IPIV, double *WORK, int *LWORK, int *INFO)
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void TestInversion()
Invert and print the numerical conditioning of the inversion.
Data type dense matrix using column-major storage.
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
double * Data() const
Returns the matrix data array.
void Swap(DenseTensor &t)
MFEM_HOST_DEVICE void CalcLeftInverse< 2, 1 >(const double *d, double *left_inv)
void LSolve(int m, int n, double *X) const
void Eval(DenseMatrix &M)
Evaluate the SVD.
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
Abstract data type for matrix inverse.
double Det() const
Compute the determinant of the original DenseMatrix using the LU factors.
void AddMult_a_ABt(double a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
void Factor()
Factor the current DenseMatrix, *a.
virtual void Solve(int m, int n, double *X) const
MFEM_HOST_DEVICE double CalcSingularvalue< 3 >(const double *data, const int i)
Return the i'th singular value of the matrix of size 3 with given data.
void GradToVectorCurl2D(DenseMatrix &curl)
void CalcOrtho(const DenseMatrix &J, Vector &n)
DenseMatrix & operator=(double c)
Sets the matrix elements equal to constant c.
void Set(double alpha, const double *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
double Trace() const
Trace of a square matrix.
void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
void BlockForwSolve(int m, int n, int r, const double *L21, double *B1, double *B2) const
void GetRowSums(Vector &l) const
Compute the row sums of the DenseMatrix.
void dtrsm_(char *side, char *uplo, char *transa, char *diag, int *m, int *n, double *alpha, double *a, int *lda, double *b, int *ldb)
virtual double Det(int m) const
void dgesvd_(char *JOBU, char *JOBVT, int *M, int *N, double *A, int *LDA, double *S, double *U, int *LDU, double *VT, int *LDVT, double *WORK, int *LWORK, int *INFO)
void dsygv_Eigensystem(DenseMatrix &a, DenseMatrix &b, Vector &ev, DenseMatrix *evect)
void Getl1Diag(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
static void SubMult(int m, int n, int r, const double *A21, const double *X1, double *X2)
std::function< double(const Vector &)> f(double mass_coeff)
virtual void GetInverseMatrix(int m, double *X) const
virtual void Solve(int m, int n, double *X) const
virtual void PrintMatlab(std::ostream &out=mfem::out) const
Prints operator in Matlab format.
void USolve(int m, int n, double *X) const
void dggev_(char *jobvl, char *jobvr, int *n, double *a, int *lda, double *B, int *ldb, double *alphar, double *alphai, double *beta, double *vl, int *ldvl, double *vr, int *ldvr, double *work, int *lwork, int *info)
virtual void PrintT(std::ostream &out=mfem::out, int width_=4) const
Prints the transpose matrix to stream out.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
double & operator()(int i, int j)
Returns reference to a_{ij}.
MFEM_HOST_DEVICE void CalcEigenvalues< 2 >(const double *data, double *lambda, double *vec)
const double * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
friend class DenseMatrixInverse
double * GetData() const
Returns the matrix data array.
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void Norm2(double *v) const
Take the 2-norm of the columns of A and store in v.
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
Abstract data type matrix.
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
virtual void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
void MultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
void Invert()
Replaces the current matrix with its inverse.
bool LinearSolve(DenseMatrix &A, double *X, double TOL)
Solves the dense linear system, A * X = B for X
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
void UMult(int m, int n, double *X) const
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
void dpotrs_(char *, int *, int *, double *, int *, double *, int *, int *)
DenseMatrixGeneralizedEigensystem(DenseMatrix &a, DenseMatrix &b, bool left_eigen_vectors=false, bool right_eigen_vectors=false)
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
void AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
void AddMultVVt(const Vector &v, DenseMatrix &VVt)
VVt += v v^t.
void CopyMNDiag(double c, int n, int row_offset, int col_offset)
Copy c on the diagonal of size n to *this at row_offset, col_offset.
MFEM_HOST_DEVICE void CalcLeftInverse< 3, 2 >(const double *d, double *left_inv)
void dgetrf_(int *, int *, double *, int *, int *, int *)
void SingularValues(Vector &sv) const
~DenseMatrixEigensystem()
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void Neg()
(*this) = -(*this)
void GetColumn(int c, Vector &col) const
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
MFEM_HOST_DEVICE void LUSolve(const double *data, const int m, const int *ipiv, double *x)
Assuming L.U = P.A for a factored matrix (m x m),.
int Capacity() const
Return the size of the allocated memory.
void LSolve(int m, int n, double *X) const
double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void Mult(const double *x, double *y) const
Matrix vector multiplication.
void LMult(int m, int n, double *X) const
void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *)
double * GetData() const
Return a pointer to the beginning of the Vector data.
void Threshold(double eps)
Replace small entries, abs(a_ij) <= eps, with zero.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void TestInversion()
Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
MFEM_HOST_DEVICE void Mult(const int height, const int width, const TA *data, const TX *x, TY *y)
Matrix vector multiplication: y = A x, where the matrix A is of size height x width with given data...
void Swap(Array< T > &, Array< T > &)
double p(const Vector &x, double t)
void CalcEigenvalues(double *lambda, double *vec) const
void Transpose()
(*this) = (*this)^t
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += a * A.x
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
void forall(int N, lambda &&body)
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *)
void BatchLUSolve(const DenseTensor &Mlu, const Array< int > &P, Vector &X)
Solve batch linear systems.
void GetRow(int r, Vector &row) const
virtual bool Factor(int m, double TOL=0.0)
Compute the Cholesky factorization of the current matrix.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
void USolve(int m, int n, double *X) const
void Swap(DenseMatrix &other)
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i<A.Height, 0<=j<A.Width.
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
A class to initialize the size of a Tensor.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
MFEM_HOST_DEVICE double CalcSingularvalue< 2 >(const double *data, const int i)
Return the i'th singular value of the matrix of size 2 with given data.
void SetSubMatrix(const Array< int > &idx, const DenseMatrix &A)
Set (*this)(idx[i],idx[j]) = A(i,j)
void dsygv_(int *ITYPE, char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *B, int *LDB, double *W, double *WORK, int *LWORK, int *INFO)
void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
int height
Dimension of the output / number of rows in the matrix.
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
const T * HostRead(const Memory< T > &mem, int size)
Shortcut to Read(const Memory<T> &mem, int size, false)
virtual double * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
void AddMultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
virtual ~DenseMatrix()
Destroys dense matrix.
void CopyMNt(const DenseMatrix &A, int row_offset, int col_offset)
Copy matrix A^t to the location in *this at row_offset, col_offset.
void CopyExceptMN(const DenseMatrix &A, int m, int n)
Copy All rows and columns except m and n from A.
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
MFEM_HOST_DEVICE void CalcEigenvalues< 3 >(const double *data, double *lambda, double *vec)
virtual bool Factor(int m, double TOL=0.0)
Compute the LU factorization of the current matrix.
DenseMatrixInverse(bool spd_=false)
Default constructor.
static const int ipiv_base
void GradToCurl(DenseMatrix &curl)
int Rank(double tol) const
virtual void GetInverseMatrix(int m, double *X) const
Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
virtual bool Factor(int m, double TOL=0.0)
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
int Size() const
Return the logical size of the array.
bool IsSquare() const
Returns whether the matrix is a square matrix.
DenseMatrixEigensystem(DenseMatrix &m)
void dsyevr_(char *JOBZ, char *RANGE, char *UPLO, int *N, double *A, int *LDA, double *VL, double *VU, int *IL, int *IU, double *ABSTOL, int *M, double *W, double *Z, int *LDZ, int *ISUPPZ, double *WORK, int *LWORK, int *IWORK, int *LIWORK, int *INFO)
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
double operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
void dpotri_(char *, int *, double *, int *, int *)
void BlockFactor(int m, int n, double *A12, double *A21, double *A22) const
void BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt += A D A^t, where D is diagonal.
void GetFromVector(int offset, const Vector &v)
Get the matrix 'data' from the Vector 'v' at the given 'offset'.
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
~DenseMatrixGeneralizedEigensystem()
double u(const Vector &xvec)
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
void AddMult_a(double alpha, const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += alpha * B * C.
Rank 3 tensor (array of matrices)
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void AdjustDofDirection(Array< int > &dofs)
MFEM_HOST_DEVICE void Symmetrize(const int size, T *data)
Symmetrize a square matrix with given size and data: A -> (A+A^T)/2.
virtual double * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void GradToDiv(Vector &div)
void AddMult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
int width
Dimension of the input / number of columns in the matrix.
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += a * A^t x
void AddSubMatrix(const Array< int > &idx, const DenseMatrix &A)
(*this)(idx[i],idx[j]) += A(i,j)
void dsyev_(char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *W, double *WORK, int *LWORK, int *INFO)
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
double FNorm() const
Compute the Frobenius norm of the matrix.
DenseMatrix & operator+=(const double *m)