19 #include "../general/table.hpp"
40 data =
new double[hw];
41 for (
int i = 0; i < hw; i++)
47 data =
new double[s*s];
49 for (
int i = 0; i < s; i++)
50 for (
int j = 0; j < s; j++)
56 data =
new double[m*n];
58 for (
int i = 0; i < m; i++)
59 for (
int j = 0; j < n; j++)
64 :
Matrix(mat.width, mat.height)
68 for (
int i = 0; i <
height; i++)
69 for (
int j = 0; j <
width; j++)
70 (*
this)(i,j) = mat(j,i);
83 data =
new double[ss];
84 for (
int i = 0; i < ss; i++)
102 data =
new double[hw];
103 for (
int i = 0; i < hw; i++)
122 double *d_col = data;
124 for (
int row = 0; row <
height; row++)
125 y[row] = x_col*d_col[row];
127 for (
int col = 1; col <
width; col++)
130 for (
int row = 0; row <
height; row++)
131 y[row] += x_col*d_col[row];
143 Mult((
const double *)x, (
double *)y);
155 for (
int i = 0; i < hw; i++)
156 a += data[i] * m.data[i];
163 double *d_col = data;
164 for (
int col = 0; col <
width; col++)
167 for (
int row = 0; row <
height; row++)
168 y_col += x[row]*d_col[row];
191 const double *xp = x;
192 double *d_col = data, *yp = y;
193 for (
int col = 0; col <
width; col++)
195 double x_col = xp[col];
196 for (
int row = 0; row <
height; row++)
197 yp[row] += x_col*d_col[row];
206 for (
int i = 0; i <
height; i++)
209 for (
int j = 0; j <
width; j++)
210 Axi += (*
this)(i,j) * x[j];
220 double * it_data = data;
221 for (
int j = 0; j <
width; ++j)
222 for (
int i = 0; i <
height; ++i)
223 *(it_data++) *= s(i);
229 double * it_data = data;
230 for (
int j = 0; j <
width; ++j)
231 for (
int i = 0; i <
height; ++i)
232 *(it_data++) /= s(i);
239 double * it_data = data;
240 for (
int j = 0; j <
width; ++j)
243 for (
int i = 0; i <
height; ++i)
252 double * it_data = data;
253 for (
int j = 0; j <
width; ++j)
256 for (
int i = 0; i <
height; ++i)
267 double * ss =
new double[
width];
270 for(
double * end_s = it_s +
width; it_s != end_s; ++it_s)
271 *(it_ss++) = sqrt(*it_s);
273 double * it_data = data;
274 for (
int j = 0; j <
width; ++j)
275 for (
int i = 0; i <
height; ++i)
276 *(it_data++) *= ss[i]*ss[j];
287 double * ss =
new double[
width];
290 for(
double * end_s = it_s +
width; it_s != end_s; ++it_s)
291 *(it_ss++) = 1./sqrt(*it_s);
293 double * it_data = data;
294 for (
int j = 0; j <
width; ++j)
295 for (
int i = 0; i <
height; ++i)
296 *(it_data++) *= ss[i]*ss[j];
305 mfem_error(
"DenseMatrix::Trace() : not a square matrix!");
310 for (
int i = 0; i <
width; i++)
334 return data[0] * data[3] - data[1] * data[2];
338 const double *d = data;
340 d[0] * (d[4] * d[8] - d[5] * d[7]) +
341 d[3] * (d[2] * d[7] - d[1] * d[8]) +
342 d[6] * (d[1] * d[5] - d[2] * d[4]);
357 return sqrt(data[0] * data[0] + data[1] * data[1]);
361 return sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2]);
365 const double *d = data;
366 double E = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
367 double G = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
368 double F = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
369 return sqrt(E * G - F * F);
377 for (
int i = 0; i <
Height(); i++)
378 for (
int j = 0; j <
Width(); j++)
379 (*
this)(i,j) += c * A(i,j);
386 for (
int i = 0; i < s; i++)
396 for (
int i = 0; i < s; i++)
409 for (i = 0; i < hw; i++)
418 "incompatible matrix sizes.");
420 for (
int i = 0; i <
height; i++)
421 for (
int j = 0; j <
width; j++)
422 (*
this)(i, j) += m(i, j);
431 for (i = 0; i <
height; i++)
432 for (j = 0; j <
width; j++)
433 (*
this)(i, j) -= m(i, j);
442 for (
int i = 0; i < s; i++)
451 for (i = 0; i < hw; i++)
455 #ifdef MFEM_USE_LAPACK
457 dgetrf_(
int *,
int *,
double *,
int *,
int *,
int *);
459 dgetrs_(
char *,
int *,
int *,
double *,
int *,
int *,
double *,
int *,
int *);
461 dgetri_(
int *N,
double *A,
int *LDA,
int *IPIV,
double *WORK,
462 int *LWORK,
int *INFO);
472 #ifdef MFEM_USE_LAPACK
473 int *ipiv =
new int[
width];
481 mfem_error(
"DenseMatrix::Invert() : Error in DGETRF");
486 work =
new double[lwork];
491 mfem_error(
"DenseMatrix::Invert() : Error in DGETRI");
496 int c, i, j, n =
Width();
500 for (c = 0; c < n; c++)
502 a = fabs((*
this)(c, c));
504 for (j = c + 1; j < n; j++)
506 b = fabs((*
this)(j, c));
514 mfem_error(
"DenseMatrix::Invert() : singular matrix");
516 for (j = 0; j < n; j++)
517 Swap<double>((*
this)(c, j), (*
this)(i, j));
519 a = (*this)(c, c) = 1.0 / (*
this)(c, c);
520 for (j = 0; j < c; j++)
522 for (j++; j < n; j++)
524 for (i = 0; i < c; i++)
526 (*this)(i, c) = a * (b = -(*
this)(i, c));
527 for (j = 0; j < c; j++)
528 (*
this)(i, j) += b * (*
this)(c, j);
529 for (j++; j < n; j++)
530 (*
this)(i, j) += b * (*
this)(c, j);
532 for (i++; i < n; i++)
534 (*this)(i, c) = a * (b = -(*
this)(i, c));
535 for (j = 0; j < c; j++)
536 (*
this)(i, j) += b * (*
this)(c, j);
537 for (j++; j < n; j++)
538 (*
this)(i, j) += b * (*
this)(c, j);
542 for (c = n - 1; c >= 0; c--)
545 for (i = 0; i < n; i++)
546 Swap<double>((*
this)(i, c), (*
this)(i, j));
553 for (
int j = 0; j <
Width(); j++)
556 for (
int i = 0; i <
Height(); i++)
557 v[j] += (*
this)(i,j)*(*
this)(i,j);
565 const double *d = data;
566 double norm = 0.0, abs_entry;
568 for (
int i = 0; i < hw; i++)
570 abs_entry = fabs(d[i]);
571 if (norm < abs_entry)
581 double max_norm = 0.0, entry, fnorm2;
583 for (i = 0; i < hw; i++)
585 entry = fabs(data[i]);
586 if (entry > max_norm)
594 for (i = 0; i < hw; i++)
596 entry = data[i] / max_norm;
597 fnorm2 += entry * entry;
600 return max_norm * sqrt(fnorm2);
603 #ifdef MFEM_USE_LAPACK
605 dsyevr_(
char *JOBZ,
char *RANGE,
char *UPLO,
int *N,
double *A,
int *LDA,
606 double *VL,
double *VU,
int *IL,
int *IU,
double *ABSTOL,
int *M,
607 double *W,
double *Z,
int *LDZ,
int *ISUPPZ,
double *WORK,
int *LWORK,
608 int *IWORK,
int *LIWORK,
int *INFO);
610 dsyev_(
char *JOBZ,
char *UPLO,
int *N,
double *A,
int *LDA,
double *W,
611 double *WORK,
int *LWORK,
int *INFO);
613 dgesvd_(
char *JOBU,
char *JOBVT,
int *M,
int *N,
double *A,
int *LDA,
614 double *S,
double *U,
int *LDU,
double *VT,
int *LDVT,
double *WORK,
615 int *LWORK,
int *INFO);
621 #ifdef MFEM_USE_LAPACK
629 double *A =
new double[N*N];
640 int *ISUPPZ =
new int[2*N];
659 double *data = a.
Data();
661 for (
int i = 0; i < hw; i++)
664 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
665 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, &QWORK, &LWORK,
666 &QIWORK, &LIWORK, &INFO );
671 WORK =
new double[LWORK];
672 IWORK =
new int[LIWORK];
674 dsyevr_( &JOBZ, &RANGE, &UPLO, &N, A, &LDA, &VL, &VU, &IL, &IU,
675 &ABSTOL, &M, W, Z, &LDZ, ISUPPZ, WORK, &LWORK,
676 IWORK, &LIWORK, &INFO );
680 cerr <<
"dsyevr_Eigensystem(...): DSYEVR error code: "
688 cerr <<
"dsyevr_Eigensystem(...):\n"
689 <<
" DSYEVR did not find all eigenvalues "
690 << M <<
"/" << N << endl;
693 for (IL = 0; IL < N; IL++)
695 mfem_error(
"dsyevr_Eigensystem(...): !finite value in W");
696 for (IL = 0; IL < N*N; IL++)
698 mfem_error(
"dsyevr_Eigensystem(...): !finite value in Z");
700 for (IL = 0; IL < N; IL++)
701 for (IU = 0; IU <= IL; IU++)
704 for (M = 0; M < N; M++)
705 VL += Z[M+IL*N] * Z[M+IU*N];
714 cerr <<
"dsyevr_Eigensystem(...):"
715 <<
" Z^t Z - I deviation = " << VU
716 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
717 << W[0] <<
", N = " << N << endl;
723 cerr <<
"dsyevr_Eigensystem(...):"
724 <<
" Z^t Z - I deviation = " << VU
725 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
726 << W[0] <<
", N = " << N << endl;
729 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
731 for (IL = 0; IL < N; IL++)
732 for (IU = 0; IU < N; IU++)
735 for (M = 0; M < N; M++)
736 VL += Z[IL+M*N] * W[M] * Z[IU+M*N];
737 VL = fabs(VL-data[IL+N*IU]);
743 cerr <<
"dsyevr_Eigensystem(...):"
744 <<
" max matrix deviation = " << VU
745 <<
"\n W[max] = " << W[N-1] <<
", W[min] = "
746 << W[0] <<
", N = " << N << endl;
749 mfem_error(
"dsyevr_Eigensystem(...): ERROR: ...");
763 #ifdef MFEM_USE_LAPACK
791 double *data = a.
Data();
792 for (
int i = 0; i < hw; i++)
795 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, &QWORK, &LWORK, &INFO);
798 WORK =
new double[LWORK];
800 dsyev_(&JOBZ, &UPLO, &N, A, &LDA, W, WORK, &LWORK, &INFO);
804 cerr <<
"dsyev_Eigensystem: DSYEV error code: " << INFO << endl;
809 if (evect == NULL)
delete [] A;
814 void DenseMatrix::Eigensystem(Vector &ev, DenseMatrix *evect)
816 #ifdef MFEM_USE_LAPACK
831 #ifdef MFEM_USE_LAPACK
837 double *a = copy_of_this.data;
847 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
848 s, u, &m, vt, &n, &qwork, &lwork, &info);
851 work =
new double[lwork];
853 dgesvd_(&jobu, &jobvt, &m, &n, a, &m,
854 s, u, &m, vt, &n, work, &lwork, &info);
859 cerr <<
"DenseMatrix::SingularValues : info = " << info << endl;
874 for (
int i=0; i < sv.
Size(); ++i)
881 static const double sqrt_1_eps = sqrt(1./numeric_limits<double>::epsilon());
888 double t, zeta = (d2 - d1)/(2*d12);
889 if (fabs(zeta) < sqrt_1_eps)
890 t = d12*copysign(1./(fabs(zeta) + sqrt(1. + zeta*zeta)), zeta);
892 t = d12*copysign(0.5/fabs(zeta), zeta);
899 double &c,
double &s)
909 double t, zeta = (d2 - d1)/(2*d12);
910 if (fabs(zeta) < sqrt_1_eps)
911 t = copysign(1./(fabs(zeta) + sqrt(1. + zeta*zeta)), zeta);
913 t = copysign(0.5/fabs(zeta), zeta);
915 c = sqrt(1./(1. + t*t));
924 const double &x1,
const double &x2,
const double &x3,
925 double &n1,
double &n2,
double &n3)
933 t = sqrt(1./(t + r*r));
934 n1 = copysign(t, x1);
941 double &n1,
double &n2,
double &n3)
945 if (fabs(x1) >= fabs(x2))
947 if (fabs(x1) >= fabs(x3))
960 else if (fabs(x2) >= fabs(x3))
970 double &d1,
double &d12,
double &d21,
double &d2)
981 double n1 = fabs(d1) + fabs(d21);
982 double n2 = fabs(d2) + fabs(d12);
984 bool swap_columns = (n2 > n1);
994 if (fabs(d1) > fabs(d21))
1002 if (fabs(d1) < fabs(d21))
1014 if (fabs(d12) > fabs(d2))
1027 if (fabs(d12) < fabs(d2))
1040 n1 = hypot(d1, d21);
1046 mu = copysign(n1, d1);
1047 n1 = -d21*(d21/(d1 + mu));
1051 if (fabs(n1) <= fabs(d21))
1055 mu = (2./(1. + n1*n1))*(n1*d12 + d2);
1063 mu = (2./(1. + n2*n2))*(d12 + n2*d2);
1085 n2 = 1./(1. + fabs(mu));
1087 if (fabs(d1) <= n2*fabs(d2))
1107 double &d1,
double &d2,
double &d3,
double &c12,
double &c13,
double &c23,
1108 double &c21,
double &c31,
double &c32)
1111 double mu, n1, n2, n3, s1, s2, s3;
1113 s1 = hypot(c21, c31);
1120 mu = copysign(n1, d1);
1121 n1 = -s1*(s1/(d1 + mu));
1126 if (fabs(n1) >= fabs(c21))
1128 if (fabs(n1) >= fabs(c31))
1133 mu = 2./(1. + s2*s2 + s3*s3);
1134 n2 = mu*(c12 + s2*d2 + s3*c32);
1135 n3 = mu*(c13 + s2*c23 + s3*d3);
1145 else if (fabs(c21) >= fabs(c31))
1150 mu = 2./(1. + s1*s1 + s3*s3);
1151 n2 = mu*(s1*c12 + d2 + s3*c32);
1152 n3 = mu*(s1*c13 + c23 + s3*d3);
1164 mu = 2./(1. + s1*s1 + s2*s2);
1165 n2 = mu*(s1*c12 + s2*d2 + c32);
1166 n3 = mu*(s1*c13 + s2*c23 + d3);
1201 d1 = -(c12*d2 + c13*d3)/d1;
1212 const double &d12,
const double &d13,
const double &d23,
1213 double &d1,
double &d2,
double &d3)
1226 double c12 = d12, c13 = d13, c23 = d23;
1227 double c21, c31, c32;
1231 c32 = fabs(d1) + fabs(c12) + fabs(c13);
1232 c31 = fabs(d2) + fabs(c12) + fabs(c23);
1233 c21 = fabs(d3) + fabs(c13) + fabs(c23);
1237 col = (c32 >= c31) ? 1 : 2;
1239 col = (c31 >= c21) ? 2 : 3;
1264 if (fabs(d1) <= fabs(c13))
1265 row = (fabs(d1) <= fabs(c12)) ? 1 : 2;
1267 row = (fabs(c12) <= fabs(c13)) ? 2 : 3;
1271 if (fabs(d1) >= fabs(c13))
1272 row = (fabs(d1) >= fabs(c12)) ? 1 : 2;
1274 row = (fabs(c12) >= fabs(c13)) ? 2 : 3;
1323 double &d1,
double &d2,
double &d3,
double &d12,
double &d13,
double &d23,
1324 double &z1,
double &z2,
double &z3,
double &v1,
double &v2,
double &v3,
1344 double s, w1, w2, w3;
1350 if (fabs(z1) <= fabs(z3))
1351 k = (fabs(z1) <= fabs(z2)) ? 1 : 2;
1353 k = (fabs(z2) <= fabs(z3)) ? 2 : 3;
1358 if (fabs(z1) >= fabs(z3))
1359 k = (fabs(z1) >= fabs(z2)) ? 1 : 2;
1361 k = (fabs(z2) >= fabs(z3)) ? 2 : 3;
1387 g = copysign(1., z1);
1388 v1 = -s*(s/(z1 + g));
1391 if (fabs(z2) > g) g = fabs(z2);
1392 if (fabs(z3) > g) g = fabs(z3);
1396 g = 2./(v1*v1 + v2*v2 + v3*v3);
1401 w1 = g*( d1*v1 + d12*v2 + d13*v3);
1402 w2 = g*(d12*v1 + d2*v2 + d23*v3);
1403 w3 = g*(d13*v1 + d23*v2 + d3*v3);
1405 s = (g/2)*(v1*w1 + v2*w2 + v3*w3);
1412 d23 -= v2*w3 + v3*w2;
1417 s = d12 - v1*w2 - v2*w1;
1418 s = d13 - v1*w3 - v3*w1;
1440 mult = frexp(d_max, &d_exp);
1441 if (d_exp == numeric_limits<double>::max_exponent)
1442 mult *= numeric_limits<double>::radix;
1455 mfem_error(
"DenseMatrix::CalcSingularvalue");
1459 const double *d = data;
1467 double d0, d1, d2, d3;
1474 double d_max = fabs(d0);
1475 if (d_max < fabs(d1)) d_max = fabs(d1);
1476 if (d_max < fabs(d2)) d_max = fabs(d2);
1477 if (d_max < fabs(d3)) d_max = fabs(d3);
1491 double t = 0.5*((d0+d2)*(d0-d2)+(d1-d3)*(d1+d3));
1493 double s = d0*d2 + d1*d3;
1494 s = sqrt(0.5*(d0*d0 + d1*d1 + d2*d2 + d3*d3) + sqrt(t*t + s*s));
1497 t = fabs(d0*d3 - d1*d2) / s;
1510 double d0, d1, d2, d3, d4, d5, d6, d7, d8;
1511 d0 = d[0]; d3 = d[3]; d6 = d[6];
1512 d1 = d[1]; d4 = d[4]; d7 = d[7];
1513 d2 = d[2]; d5 = d[5]; d8 = d[8];
1516 double d_max = fabs(d0);
1517 if (d_max < fabs(d1)) d_max = fabs(d1);
1518 if (d_max < fabs(d2)) d_max = fabs(d2);
1519 if (d_max < fabs(d3)) d_max = fabs(d3);
1520 if (d_max < fabs(d4)) d_max = fabs(d4);
1521 if (d_max < fabs(d5)) d_max = fabs(d5);
1522 if (d_max < fabs(d6)) d_max = fabs(d6);
1523 if (d_max < fabs(d7)) d_max = fabs(d7);
1524 if (d_max < fabs(d8)) d_max = fabs(d8);
1529 d0 /= mult; d1 /= mult; d2 /= mult;
1530 d3 /= mult; d4 /= mult; d5 /= mult;
1531 d6 /= mult; d7 /= mult; d8 /= mult;
1533 double b11 = d0*d0 + d1*d1 + d2*d2;
1534 double b12 = d0*d3 + d1*d4 + d2*d5;
1535 double b13 = d0*d6 + d1*d7 + d2*d8;
1536 double b22 = d3*d3 + d4*d4 + d5*d5;
1537 double b23 = d3*d6 + d4*d7 + d5*d8;
1538 double b33 = d6*d6 + d7*d7 + d8*d8;
1557 double aa = (b11 + b22 + b33)/3;
1563 double b11_b22 = ((d0-d3)*(d0+d3)+(d1-d4)*(d1+d4)+(d2-d5)*(d2+d5));
1564 double b22_b33 = ((d3-d6)*(d3+d6)+(d4-d7)*(d4+d7)+(d5-d8)*(d5+d8));
1565 double b33_b11 = ((d6-d0)*(d6+d0)+(d7-d1)*(d7+d1)+(d8-d2)*(d8+d2));
1566 c1 = (b11_b22 - b33_b11)/3;
1567 c2 = (b22_b33 - b11_b22)/3;
1568 c3 = (b33_b11 - b22_b33)/3;
1571 Q = (2*(b12*b12 + b13*b13 + b23*b23) + c1*c1 + c2*c2 + c3*c3)/6;
1572 R = (c1*(b23*b23 - c2*c3)+ b12*(b12*c3 - 2*b13*b23) +b13*b13*c2)/2;
1608 double sqrtQ = sqrt(Q);
1609 double sqrtQ3 = Q*sqrtQ;
1614 if (fabs(R) >= sqrtQ3)
1635 aa -= 2*sqrtQ*cos(acos(R)/3);
1637 aa -= 2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
1639 aa -= 2*sqrtQ*cos((acos(R) - 2.0*M_PI)/3);
1645 r = -2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
1654 r = -2*sqrtQ*cos(acos(R)/3);
1701 double v1, v2, v3, g;
1702 Reduce3S(mode, b11, b22, b33, b12, b13, b23,
1703 c1, c2, c3, v1, v2, v3, g);
1714 aa = fmin(fmin(b11, b22), b33);
1720 aa = (b22 <= b33) ? b22 : fmax(b11, b33);
1724 aa = (b11 <= b33) ? b11 : fmax(b33, b22);
1729 aa = fmax(fmax(b11, b22), b33);
1735 return sqrt(fabs(aa))*mult;
1747 const double *d = data;
1787 double d_max = fabs(d11);
1788 if (d_max < fabs(d22)) d_max = fabs(d22);
1789 if (d_max < fabs(d33)) d_max = fabs(d33);
1790 if (d_max < fabs(d12)) d_max = fabs(d12);
1791 if (d_max < fabs(d13)) d_max = fabs(d13);
1792 if (d_max < fabs(d23)) d_max = fabs(d23);
1797 d11 /= mult; d22 /= mult; d33 /= mult;
1798 d12 /= mult; d13 /= mult; d23 /= mult;
1800 double aa = (d11 + d22 + d33)/3;
1801 double c1 = d11 - aa;
1802 double c2 = d22 - aa;
1803 double c3 = d33 - aa;
1807 Q = (2*(d12*d12 + d13*d13 + d23*d23) + c1*c1 + c2*c2 + c3*c3)/6;
1808 R = (c1*(d23*d23 - c2*c3)+ d12*(d12*c3 - 2*d13*d23) + d13*d13*c2)/2;
1812 lambda[0] = lambda[1] = lambda[2] = aa;
1813 vec[0] = 1.; vec[3] = 0.; vec[6] = 0.;
1814 vec[1] = 0.; vec[4] = 1.; vec[7] = 0.;
1815 vec[2] = 0.; vec[5] = 0.; vec[8] = 1.;
1819 double sqrtQ = sqrt(Q);
1820 double sqrtQ3 = Q*sqrtQ;
1824 if (fabs(R) >= sqrtQ3)
1843 r = -2*sqrtQ*cos((acos(R) + 2.0*M_PI)/3);
1847 r = -2*sqrtQ*cos(acos(R)/3);
1875 lambda[0] = lambda[1] = lambda[2] = aa;
1876 vec[0] = 1.; vec[3] = 0.; vec[6] = 0.;
1877 vec[1] = 0.; vec[4] = 1.; vec[7] = 0.;
1878 vec[2] = 0.; vec[5] = 0.; vec[8] = 1.;
1892 double v1, v2, v3, g;
1893 int k =
Reduce3S(mode, d11, d22, d33, d12, d13, d23,
1894 c1, c2, c3, v1, v2, v3, g);
1905 double *vec_1, *vec_2, *vec_3;
1910 lambda[0] = d11; vec_1 = vec;
1911 lambda[1] = d22; vec_2 = vec + 3;
1912 lambda[2] = d33; vec_3 = vec + 6;
1914 else if (d11 <= d33)
1916 lambda[0] = d11; vec_1 = vec;
1917 lambda[1] = d33; vec_3 = vec + 3;
1918 lambda[2] = d22; vec_2 = vec + 6;
1922 lambda[0] = d33; vec_3 = vec;
1923 lambda[1] = d11; vec_1 = vec + 3;
1924 lambda[2] = d22; vec_2 = vec + 6;
1931 lambda[0] = d22; vec_2 = vec;
1932 lambda[1] = d11; vec_1 = vec + 3;
1933 lambda[2] = d33; vec_3 = vec + 6;
1935 else if (d22 <= d33)
1937 lambda[0] = d22; vec_2 = vec;
1938 lambda[1] = d33; vec_3 = vec + 3;
1939 lambda[2] = d11; vec_1 = vec + 6;
1943 lambda[0] = d33; vec_3 = vec;
1944 lambda[1] = d22; vec_2 = vec + 3;
1945 lambda[2] = d11; vec_1 = vec + 6;
1952 d22 = g*(v2*c - v3*s);
1953 d33 = g*(v2*s + v3*c);
1954 vec_2[0] = - v1*d22; vec_3[0] = - v1*d33;
1955 vec_2[1] = c - v2*d22; vec_3[1] = s - v2*d33;
1956 vec_2[2] = -s - v3*d22; vec_3[2] = c - v3*d33;
1960 Swap(vec_2[0], vec_2[1]);
1961 Swap(vec_3[0], vec_3[1]);
1965 Swap(vec_2[0], vec_2[2]);
1966 Swap(vec_3[0], vec_3[2]);
1987 for (
int i = 0; i < n; i++)
1997 for (
int i = 0; i <
height; ++i)
1998 d(i) = (*this)(i,i);
2009 for (
int j = 0; j <
width; ++j)
2010 for (
int i = 0; i <
height; ++i)
2011 l(i) += fabs((*
this)(i,j));
2019 for (i = 0; i < N; i++)
2021 for (i = 0; i < n; i++)
2030 for (i = 0; i < N; i++)
2032 for (i = 0; i < n; i++)
2033 data[i*(n+1)] = diag[i];
2043 for (i = 0; i <
Height(); i++)
2044 for (j = i+1; j <
Width(); j++)
2047 (*this)(i,j) = (*
this)(j,i);
2062 for (
int i = 0; i <
Height(); i++)
2063 for (
int j = 0; j <
Width(); j++)
2064 (*
this)(i,j) = A(j,i);
2071 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
2074 for (
int i = 0; i <
Height(); i++)
2075 for (
int j = 0; j < i; j++)
2077 double a = 0.5 * ((*this)(i,j) + (*
this)(j,i));
2078 (*this)(j,i) = (*
this)(i,j) = a;
2084 for (
int i = 0; i <
Height(); i++)
2087 for (
int j = 0; j <
Width(); j++)
2090 (*this)(i, j) = 0.0;
2108 for (
int i = 0; i < n; i++)
2111 double x = (*this)(i,0);
2112 double y = (*this)(i,1);
2125 for (
int i = 0; i < n; i++)
2128 double x = (*this)(i,0);
2129 double y = (*this)(i,1);
2130 double z = (*this)(i,2);
2164 double *ddata = div.
GetData();
2166 for (
int i = 0; i < n; i++)
2174 for (
int i = row1; i <= row2; i++)
2175 for (
int j = 0; j <
Width(); j++)
2176 (*
this)(i-row1,j) = A(i,j);
2183 for (
int i = 0; i <
Height(); i++)
2184 for (
int j = col1; j <= col2; j++)
2185 (*
this)(i,j-col1) = A(i,j);
2194 for (j = 0; j < n; j++)
2195 for (i = 0; i < m; i++)
2196 (*
this)(i,j) = A(Aro+i,Aco+j);
2204 for (j = 0; j < A.
Width(); j++)
2205 for (i = 0; i < A.
Height(); i++)
2206 (*
this)(row_offset+i,col_offset+j) = *(v++);
2214 for (i = 0; i < A.
Width(); i++)
2215 for (j = 0; j < A.
Height(); j++)
2216 (*
this)(row_offset+i,col_offset+j) = *(v++);
2223 for (i = 0; i < n; i++)
2224 for (j = i+1; j < n; j++)
2225 (*
this)(row_offset+i,col_offset+j) =
2226 (*
this)(row_offset+j,col_offset+i) = 0.0;
2228 for (i = 0; i < n; i++)
2229 (*
this)(row_offset+i,col_offset+i) = c;
2237 for (i = 0; i < n; i++)
2238 for (j = i+1; j < n; j++)
2239 (*
this)(row_offset+i,col_offset+j) =
2240 (*
this)(row_offset+j,col_offset+i) = 0.0;
2242 for (i = 0; i < n; i++)
2243 (*
this)(row_offset+i,col_offset+i) = diag[i];
2256 if (co+aw >
Width() || ro+ah > h)
2260 p = data + ro + co * h;
2263 for (
int c = 0; c < aw; c++)
2265 for (
int r = 0; r < ah; r++)
2282 if (co+aw >
Width() || ro+ah > h)
2286 p = data + ro + co * h;
2289 for (
int c = 0; c < aw; c++)
2291 for (
int r = 0; r < ah; r++)
2301 double *vdata = v.
GetData() + offset;
2303 for (i = 0; i < n; i++)
2304 vdata[i] += data[i];
2310 const double *vdata = v.
GetData() + offset;
2312 for (i = 0; i < n; i++)
2322 mfem_error(
"DenseMatrix::AdjustDofDirection(...)");
2326 for (
int i = 0; i < n-1; i++)
2328 int s = (dof[i] < 0) ? (-1) : (1);
2329 for (
int j = i+1; j < n; j++)
2331 int t = (dof[j] < 0) ? (-s) : (s);
2334 (*this)(i,j) = -(*
this)(i,j);
2335 (*this)(j,i) = -(*
this)(j,i);
2343 for (
int j = 0; j <
Width(); j++)
2344 (*
this)(row, j) = value;
2349 for (
int i = 0; i <
Height(); i++)
2350 (*
this)(i, col) = value;
2356 out << setiosflags(ios::scientific | ios::showpos);
2357 for (
int i = 0; i <
height; i++)
2359 out <<
"[row " << i <<
"]\n";
2360 for (
int j = 0; j <
width; j++)
2362 out << (*this)(i,j);
2363 if (j+1 == width || (j+1) % width_ == 0)
2374 out << setiosflags(ios::scientific | ios::showpos);
2375 for (
int i = 0; i <
height; i++)
2377 for (
int j = 0; j <
width; j++)
2379 out << (*this)(i,j);
2389 out << setiosflags(ios::scientific | ios::showpos);
2390 for (
int j = 0; j <
width; j++)
2392 out <<
"[col " << j <<
"]\n";
2393 for (
int i = 0; i <
height; i++)
2395 out << (*this)(i,j);
2396 if (i+1 == height || (i+1) % width_ == 0)
2411 for (
int j = 0; j <
width; j++)
2412 for (
int i = 0; i <
width; i++)
2416 i_max = fmax(i_max, fabs(C(i, j)));
2418 cout <<
"size = " << width <<
", i_max = " << i_max
2419 <<
", cond_F = " <<
FNorm()*copy.FNorm() << endl;
2433 for (
int i = 0; i < C.
Height(); i++)
2434 for (
int j = 0; j < C.
Width(); j++)
2435 C(i,j) = A(i,j) + alpha * B(i,j);
2439 #ifdef MFEM_USE_LAPACK
2441 dgemm_(
char *,
char *,
int *,
int *,
int *,
double *,
double *,
2442 int *,
double *,
int *,
double *,
double *,
int *);
2449 mfem_error(
"Mult (product of DenseMatrices)");
2452 #ifdef MFEM_USE_LAPACK
2453 static char transa =
'N', transb =
'N';
2454 static double alpha = 1.0, beta = 0.0;
2457 dgemm_(&transa, &transb, &m, &n, &k, &alpha, b.
Data(), &m,
2458 c.
Data(), &k, &beta, a.
Data(), &m);
2463 double *ad = a.data;
2464 double *bd = b.data;
2465 double *cd = c.data;
2467 double d, *bdd, *cdd;
2469 for (j = 0; j < as; j++, cd += bs)
2471 for (i = 0; i < ah; i++, ad++)
2476 for (k = 0 ; k < bs; k++)
2478 d += (*bdd) * (*cdd);
2499 const double *d = a.
Data();
2500 double *ad = adja.
Data();
2513 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2514 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2515 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2517 ad[0] = d[0]*g - d[3]*f;
2518 ad[1] = d[3]*e - d[0]*f;
2519 ad[2] = d[1]*g - d[4]*f;
2520 ad[3] = d[4]*e - d[1]*f;
2521 ad[4] = d[2]*g - d[5]*f;
2522 ad[5] = d[5]*e - d[2]*f;
2531 else if (a.
Width() == 2)
2534 adja(0,1) = -a(0,1);
2535 adja(1,0) = -a(1,0);
2540 adja(0,0) = a(1,1)*a(2,2)-a(1,2)*a(2,1);
2541 adja(0,1) = a(0,2)*a(2,1)-a(0,1)*a(2,2);
2542 adja(0,2) = a(0,1)*a(1,2)-a(0,2)*a(1,1);
2544 adja(1,0) = a(1,2)*a(2,0)-a(1,0)*a(2,2);
2545 adja(1,1) = a(0,0)*a(2,2)-a(0,2)*a(2,0);
2546 adja(1,2) = a(0,2)*a(1,0)-a(0,0)*a(1,2);
2548 adja(2,0) = a(1,0)*a(2,1)-a(1,1)*a(2,0);
2549 adja(2,1) = a(0,1)*a(2,0)-a(0,0)*a(2,1);
2550 adja(2,2) = a(0,0)*a(1,1)-a(0,1)*a(1,0);
2565 else if (a.
Width() == 2)
2567 adjat(0,0) = a(1,1);
2568 adjat(1,0) = -a(0,1);
2569 adjat(0,1) = -a(1,0);
2570 adjat(1,1) = a(0,0);
2574 adjat(0,0) = a(1,1)*a(2,2)-a(1,2)*a(2,1);
2575 adjat(1,0) = a(0,2)*a(2,1)-a(0,1)*a(2,2);
2576 adjat(2,0) = a(0,1)*a(1,2)-a(0,2)*a(1,1);
2578 adjat(0,1) = a(1,2)*a(2,0)-a(1,0)*a(2,2);
2579 adjat(1,1) = a(0,0)*a(2,2)-a(0,2)*a(2,0);
2580 adjat(2,1) = a(0,2)*a(1,0)-a(0,0)*a(1,2);
2582 adjat(0,2) = a(1,0)*a(2,1)-a(1,1)*a(2,0);
2583 adjat(1,2) = a(0,1)*a(2,0)-a(0,0)*a(2,1);
2584 adjat(2,2) = a(0,0)*a(1,1)-a(0,1)*a(1,0);
2599 const double *d = a.
Data();
2600 double *
id = inva.
Data();
2603 t = 1.0 / (d[0]*d[0] + d[1]*d[1]);
2611 t = 1.0 / (d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
2619 e = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
2620 g = d[3]*d[3] + d[4]*d[4] + d[5]*d[5];
2621 f = d[0]*d[3] + d[1]*d[4] + d[2]*d[5];
2622 t = 1.0 / (e*g - f*f);
2623 e *= t; g *= t; f *= t;
2625 id[0] = d[0]*g - d[3]*f;
2626 id[1] = d[3]*e - d[0]*f;
2627 id[2] = d[1]*g - d[4]*f;
2628 id[3] = d[4]*e - d[1]*f;
2629 id[4] = d[2]*g - d[5]*f;
2630 id[5] = d[5]*e - d[2]*f;
2639 cerr <<
"CalcInverse(...) : singular matrix!"
2652 inva(0,0) = a(1,1) * t ;
2653 inva(0,1) = -a(0,1) * t ;
2654 inva(1,0) = -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(0,1) = (a(0,2)*a(2,1)-a(0,1)*a(2,2))*t;
2660 inva(0,2) = (a(0,1)*a(1,2)-a(0,2)*a(1,1))*t;
2662 inva(1,0) = (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(1,2) = (a(0,2)*a(1,0)-a(0,0)*a(1,2))*t;
2666 inva(2,0) = (a(1,0)*a(2,1)-a(1,1)*a(2,0))*t;
2667 inva(2,1) = (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;
2681 double t = 1. / a.
Det() ;
2686 inva(0,0) = 1.0 / a(0,0);
2689 inva(0,0) = a(1,1) * t ;
2690 inva(1,0) = -a(0,1) * t ;
2691 inva(0,1) = -a(1,0) * t ;
2692 inva(1,1) = a(0,0) * t ;
2695 inva(0,0) = (a(1,1)*a(2,2)-a(1,2)*a(2,1))*t;
2696 inva(1,0) = (a(0,2)*a(2,1)-a(0,1)*a(2,2))*t;
2697 inva(2,0) = (a(0,1)*a(1,2)-a(0,2)*a(1,1))*t;
2699 inva(0,1) = (a(1,2)*a(2,0)-a(1,0)*a(2,2))*t;
2700 inva(1,1) = (a(0,0)*a(2,2)-a(0,2)*a(2,0))*t;
2701 inva(2,1) = (a(0,2)*a(1,0)-a(0,0)*a(1,2))*t;
2703 inva(0,2) = (a(1,0)*a(2,1)-a(1,1)*a(2,0))*t;
2704 inva(1,2) = (a(0,1)*a(2,0)-a(0,0)*a(2,1))*t;
2705 inva(2,2) = (a(0,0)*a(1,1)-a(0,1)*a(1,0))*t;
2718 const double *d = J.
Data();
2726 n(0) = d[1]*d[5] - d[2]*d[4];
2727 n(1) = d[2]*d[3] - d[0]*d[5];
2728 n(2) = d[0]*d[4] - d[1]*d[3];
2734 for (
int i = 0; i < a.
Height(); i++)
2735 for (
int j = 0; j <= i; j++)
2738 for (
int k = 0; k < a.
Width(); k++)
2739 temp += a(i,k) * a(j,k);
2740 aat(j,i) = aat(i,j) = temp;
2746 for (
int i = 0; i < A.
Height(); i++)
2748 for (
int j = 0; j < i; j++)
2751 for (
int k = 0; k < A.
Width(); k++)
2752 t += D(k) * A(i, k) * A(j, k);
2759 for (
int i = 0; i < A.
Height(); i++)
2762 for (
int k = 0; k < A.
Width(); k++)
2763 t += D(k) * A(i, k) * A(i, k);
2770 for (
int i = 0; i < A.
Height(); i++)
2772 for (
int j = 0; j <= i; j++)
2775 for (
int k = 0; k < A.
Width(); k++)
2776 t += D(k) * A(i, k) * A(j, k);
2777 ADAt(j, i) = ADAt(i, j) = t;
2790 #ifdef MFEM_USE_LAPACK
2791 static char transa =
'N', transb =
'T';
2792 static double alpha = 1.0, beta = 0.0;
2795 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
2796 B.
Data(), &n, &beta, ABt.
Data(), &m);
2798 const int ah = A.
Height();
2799 const int bh = B.
Height();
2800 const int aw = A.
Width();
2801 const double *ad = A.
Data();
2802 const double *bd = B.
Data();
2803 double *cd = ABt.
Data();
2805 for (
int i = 0, s = ah*bh; i < s; i++)
2807 for (
int k = 0; k < aw; k++)
2810 for (
int j = 0; j < bh; j++)
2812 const double bjk = bd[j];
2813 for (
int i = 0; i < ah; i++)
2815 cp[i] += ad[i] * bjk;
2823 const int ah = A.
Height();
2824 const int bh = B.
Height();
2825 const int aw = A.
Width();
2826 const double *ad = A.
Data();
2827 const double *bd = B.
Data();
2828 double *cd = ABt.
Data();
2830 for (
int j = 0; j < bh; j++)
2831 for (
int i = 0; i < ah; i++)
2834 const double *ap = ad + i;
2835 const double *bp = bd + j;
2836 for (
int k = 0; k < aw; k++)
2848 for (i = 0; i < A.
Height(); i++)
2849 for (j = 0; j < B.
Height(); j++)
2852 for (k = 0; k < A.
Width(); k++)
2853 d += A(i, k) * B(j, k);
2867 #ifdef MFEM_USE_LAPACK
2868 static char transa =
'N', transb =
'T';
2869 static double alpha = 1.0, beta = 1.0;
2872 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &m,
2873 B.
Data(), &n, &beta, ABt.
Data(), &m);
2875 const int ah = A.
Height();
2876 const int bh = B.
Height();
2877 const int aw = A.
Width();
2878 const double *ad = A.
Data();
2879 const double *bd = B.
Data();
2880 double *cd = ABt.
Data();
2882 for (
int k = 0; k < aw; k++)
2885 for (
int j = 0; j < bh; j++)
2887 const double bjk = bd[j];
2888 for (
int i = 0; i < ah; i++)
2890 cp[i] += ad[i] * bjk;
2901 for (i = 0; i < A.
Height(); i++)
2902 for (j = 0; j < B.
Height(); j++)
2905 for (k = 0; k < A.
Width(); k++)
2906 d += A(i, k) * B(j, k);
2920 #ifdef MFEM_USE_LAPACK
2921 static char transa =
'T', transb =
'N';
2922 static double alpha = 1.0, beta = 0.0;
2925 dgemm_(&transa, &transb, &m, &n, &k, &alpha, A.
Data(), &k,
2926 B.
Data(), &k, &beta, AtB.
Data(), &m);
2928 const int ah = A.
Height();
2929 const int aw = A.
Width();
2930 const int bw = B.
Width();
2931 const double *ad = A.
Data();
2932 const double *bd = B.
Data();
2933 double *cd = AtB.
Data();
2935 for (
int j = 0; j < bw; j++)
2937 const double *ap = ad;
2938 for (
int i = 0; i < aw; i++)
2941 for (
int k = 0; k < ah; k++)
2954 for (i = 0; i < A.
Width(); i++)
2955 for (j = 0; j < B.
Width(); j++)
2958 for (k = 0; k < A.
Height(); k++)
2959 d += A(k, i) * B(k, j);
2969 for (
int i = 0; i < A.
Height(); i++)
2971 for (
int j = 0; j < i; j++)
2974 for (
int k = 0; k < A.
Width(); k++)
2975 d += A(i,k) * A(j,k);
2976 AAt(i, j) += (d *= a);
2980 for (
int k = 0; k < A.
Width(); k++)
2981 d += A(i,k) * A(i,k);
2988 for (
int i = 0; i < A.
Height(); i++)
2989 for (
int j = 0; j <= i; j++)
2992 for (
int k = 0; k < A.
Width(); k++)
2993 d += A(i,k) * A(j,k);
2994 AAt(i, j) = AAt(j, i) = a * d;
3000 for (
int i = 0; i < v.
Size(); i++)
3001 for (
int j = 0; j <= i; j++)
3003 vvt(i,j) = vvt(j,i) = v(i) * v(j);
3017 for (i = 0; i < v.
Size(); i++)
3020 for (j = 0; j < w.
Size(); j++)
3021 VWt(i, j) = vi * w(j);
3034 for (
int i = 0; i < m; i++)
3037 for (
int j = 0; j < n; j++)
3038 VWt(i, j) += vi * w(j);
3051 for (
int i = 0; i < m; i++)
3053 double avi = a * v(i);
3054 for (
int j = 0; j < n; j++)
3055 VWt(i, j) += avi * w(j);
3068 for (
int i = 0; i < n; i++)
3070 double avi = a * v(i);
3071 for (
int j = 0; j < i; j++)
3073 double avivj = avi * v(j);
3077 VVt(i, i) += avi * v(i);
3085 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3088 #ifdef MFEM_USE_LAPACK
3089 ipiv =
new int[
width];
3097 MFEM_ASSERT(
height ==
width,
"not a square matrix");
3100 #ifdef MFEM_USE_LAPACK
3101 ipiv =
new int[
width];
3107 const double *adata = a->data;
3109 #ifdef MFEM_USE_LAPACK
3114 dgetrf_(&width, &width, data, &width, ipiv, &info);
3117 mfem_error(
"DenseMatrixInverse::Factor : Error in DGETRF");
3123 for (i = 0; i <
width; i++)
3126 if (i > 0 && data[i-1+width*(i-1)] == 0.0)
3129 for (j = 0; j < i; j++)
3131 data[i+width*j] = adata[i+width*j];
3132 for (k = 0; k < j; k++)
3133 data[i+width*j] -= data[i+width*k] * data[k+width*j];
3134 data[i+width*j] /= data[j+width*j];
3137 for (j = i; j <
width; j++)
3139 data[i+width*j] = adata[i+width*j];
3140 for (k = 0; k < i; k++)
3141 data[i+width*j] -= data[i+width*k] * data[k+width*j];
3163 MFEM_VERIFY(a != NULL,
"Operator is not a DenseMatrix!");
3164 MFEM_VERIFY(a->
height == a->
width,
"DenseMatrix is not square!");
3170 #ifdef MFEM_USE_LAPACK
3172 ipiv =
new int[
width];
3180 #ifdef MFEM_USE_LAPACK
3186 dgetrs_(&trans, &n, &nrhs, data, &n, ipiv, y.
GetData(), &n, &info);
3195 for (i = 0; i <
width; i++)
3198 for (j = 0; j < i; j++)
3199 y(i) -= data[i+width*j] * y(j);
3203 for (i = width-1; i >= 0; i--)
3205 for (j = i+1; j <
width; j++)
3206 y(i) -= data[i+width*j] * y(j);
3208 if ((data[i+width*i]) == 0.0)
3211 y(i) /= data[i+width*i];
3219 #ifdef MFEM_USE_LAPACK
3233 #ifdef MFEM_USE_LAPACK
3239 &qwork, &lwork, &info);
3241 lwork = (int) qwork;
3242 work =
new double[lwork];
3249 if (mat.
Width() != n)
3250 mfem_error(
"DenseMatrixEigensystem::Eval()");
3253 #ifdef MFEM_USE_LAPACK
3256 work, &lwork, &info);
3260 cerr <<
"DenseMatrixEigensystem::Eval(): DSYEV error code: "
3265 mfem_error(
"DenseMatrixEigensystem::Eval(): Compiled without LAPACK");
3271 #ifdef MFEM_USE_LAPACK
3291 void DenseMatrixSVD::Init()
3293 #ifdef MFEM_USE_LAPACK
3302 NULL, &n, &qwork, &lwork, &info);
3304 lwork = (int) qwork;
3305 work =
new double[lwork];
3307 mfem_error(
"DenseMatrixSVD::Init(): Compiled without LAPACK");
3318 #ifdef MFEM_USE_LAPACK
3320 NULL, &n, work, &lwork, &info);
3324 cerr <<
"DenseMatrixSVD::Eval() : info = " << info << endl;
3328 mfem_error(
"DenseMatrixSVD::Eval(): Compiled without LAPACK");
3334 #ifdef MFEM_USE_LAPACK
3344 const int *I = elem_dof.
GetI(), *J = elem_dof.
GetJ(), *dofs;
3345 double *d_col = tdata, *yp = y, x_col;
3346 const double *xp = x;
3350 for (
int i = 0; i < ne; i++)
3353 for (
int col = 0; col < n; col++)
3355 x_col = xp[dofs[col]];
3356 for (
int row = 0; row < n; row++)
3357 yp[dofs[row]] += x_col*d_col[row];
3365 for (
int i = 0; i < ne; i++)
3368 x_col = xp[dofs[0]];
3369 for (
int row = 0; row < n; row++)
3370 ye(row) = x_col*d_col[row];
3372 for (
int col = 1; col < n; col++)
3374 x_col = xp[dofs[col]];
3375 for (
int row = 0; row < n; row++)
3376 ye(row) += x_col*d_col[row];
3379 for (
int row = 0; row < n; row++)
3380 yp[dofs[row]] += ye(row);
virtual void PrintT(std::ostream &out=std::cout, int width_=4) const
Prints the transpose matrix to stream out.
void GetColumn(int c, Vector &col)
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.
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
DenseMatrix & operator*=(double c)
bool KernelVector2G(const int &mode, double &d1, double &d12, double &d21, double &d2)
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
DenseMatrix & operator+=(DenseMatrix &m)
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)
Resizes the vector if the new size is different.
double Det() const
Calculates the determinant of the matrix (for 2x2 or 3x3 matrices)
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.
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
void CopyRows(DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
void TestInversion()
Invert and print the numerical conditioning of the inversion.
int Size() const
Returns the size of the vector.
void Eval(DenseMatrix &M)
Abstract data type for matrix inverse.
void CopyMN(DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at (Aro)ffset, (Aco)loffset to *this.
void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *)
void SetCol(int col, double value)
Set all entries of a column to the specified value.
void Factor()
Factor the current DenseMatrix, *a.
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 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 Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
void dgetri_(int *N, double *A, int *LDA, int *IPIV, double *WORK, int *LWORK, int *INFO)
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with 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.
friend void Mult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A = B * C.
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 dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *)
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 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))
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 Invert()
Replaces the current matrix with its inverse.
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
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)
virtual void PrintMatlab(std::ostream &out=std::cout) const
~DenseMatrixEigensystem()
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void Neg()
(*this) = -(*this)
virtual void Print(std::ostream &out=std::cout, int width_=4) const
Prints matrix to stream out.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
int KernelVector3S(const int &mode, const double &d12, const double &d13, const double &d23, double &d1, double &d2, double &d3)
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
void AddMult(const Vector &x, Vector &y) const
y += A.x
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void Eigensystem2S(const double &d12, double &d1, double &d2, double &c, double &s)
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
void dsyev_(char *JOBZ, char *UPLO, int *N, double *A, int *LDA, double *W, double *WORK, int *LWORK, int *INFO)
double * Data() const
Returns vector of the elements.
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 mfem_error(const char *msg)
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 dgetrf_(int *, int *, double *, int *, int *, int *)
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)
void SetDataAndSize(double *d, int s)
DenseMatrix & operator-=(DenseMatrix &m)
void CopyMNt(DenseMatrix &A, int row_offset, int col_offset)
Copy matrix A^t to the location in *this at row_offset, col_offset.
void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
virtual ~DenseMatrix()
Destroys dense matrix.
void GetDiag(Vector &d)
Returns the diagonal of the matrix.
void Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
void GradToCurl(DenseMatrix &curl)
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)
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
void CalcEigenvalues(double *lambda, double *vec) const
void Getl1Diag(Vector &l)
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
DenseMatrixEigensystem(DenseMatrix &m)
int Rank(double tol) const
DenseMatrixInverse(const DenseMatrix &mat)
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 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 CopyCols(DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
void SetSize(int s)
If the matrix is not a square matrix of size s then recreate it.
void SetRow(int row, double value)
Set all entries of a row to the specified value.
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.