21 #ifndef SYMMETRIC_MATRIX_3X3_IMPL_H 22 #define SYMMETRIC_MATRIX_3X3_IMPL_H 24 #ifndef SHEAF_DLL_SPEC_H 25 #include "SheafSystem/sheaf_dll_spec.h" 28 #ifndef ASSERT_CONTRACT_H 29 #include "SheafSystem/assert_contract.h" 32 #ifndef ERROR_MESSAGE_H 33 #include "SheafSystem/error_message.h" 36 #ifndef GENERAL_MATRIX_1x3_H 37 #include "SheafSystem/general_matrix_1x3.h" 40 #ifndef GENERAL_MATRIX_3X1_H 41 #include "SheafSystem/general_matrix_3x1.h" 44 #ifndef GENERAL_MATRIX_3X2_H 45 #include "SheafSystem/general_matrix_3x2.h" 48 #ifndef GENERAL_MATRIX_3X3_H 49 #include "SheafSystem/general_matrix_3x3.h" 52 #ifndef SYMMETRIC_MATRIX_3X3_H 53 #include "SheafSystem/symmetric_matrix_3x3.h" 57 #include "SheafSystem/std_sstream.h" 61 #include "SheafSystem/std_cmath.h" 64 #ifndef STD_ALGORITHM_H 65 #include "SheafSystem/std_algorithm.h" 72 using namespace sheaf;
80 symmetric_matrix_3x3<T>::
87 T* lcomps =
const_cast<T*
>(components);
106 T* lcomps =
const_cast<T*
>(components);
116 template <
typename T>
133 template <
typename T>
150 template <
typename T>
167 template <
typename T>
174 require(nrow >= 0 && nrow < number_of_rows());
178 T* result = &components[row_index(nrow)];
189 template <
typename T>
196 require(nrow >= 0 && nrow < number_of_rows());
200 const T* result = &components[row_index(nrow)];
212 template <
typename T>
222 T* result = components;
234 template <
typename T>
236 operator
const T* ()
const 244 const T* result = components;
256 template <
typename T>
264 require(xrow >= 0 && xrow < number_of_rows());
268 int nrows = number_of_rows();
269 int result = (xrow*(2*nrows-1-xrow))/2;
275 ensure(result == (xrow*(2*number_of_rows()-1-xrow))/2);
283 template <
typename T>
295 result[0][0] = lm[0][0];
296 result[0][1] = lm[0][1];
297 result[0][2] = lm[0][2];
299 result[1][0] = lm[0][1];
300 result[1][1] = lm[1][1];
301 result[1][2] = lm[1][2];
303 result[2][0] = lm[0][2];
304 result[2][1] = lm[1][2];
305 result[2][2] = lm[2][2];
309 ensure(unexecutable(
"result == *this"));
317 template <
typename T>
324 require(xrow >= 0 && xrow < number_of_rows());
360 template <
typename T>
367 require(xcolumn >= 0 && xcolumn < number_of_columns());
381 else if(xcolumn == 1)
402 template <
typename T>
425 T c00 = a11*a22 - a12*a21;
429 T c10 = a02*a21 - a01*a22;
430 T c11 = a00*a22 - a02*a20;
433 T c20 = a01*a12 - a02*a11;
434 T c21 = a02*a10 - a00*a12;
435 T c22 = a00*a11 - a01*a10;
458 template <
typename T>
478 template <
typename T>
487 for(
int i=0; i<d(); ++i)
489 components[i] = xvalue;
494 ensure_for_all(i, 0, d(), components[i] == xvalue);
501 template <
typename T>
522 T c00 = a11*a22 - a12*a21;
523 T c01 = a12*a20 - a10*a22;
524 T c02 = a10*a21 - a11*a20;
526 xresult = a00*c00 + a01*c01 + a02*c02;
535 template <
typename T>
556 template <
typename T>
595 T c = a00*(a11 + a22) + a11*a22 - a01*a10 - a02*a20 - a12*a21;
596 T b = -(a00 + a11 + a22);
604 T discriminant = b*b - 4.0*c;
606 if(discriminant < 0.0)
608 post_fatal_error_message(
"Matrix has 2 complex roots.");
611 T sqrt_discriminant =
sqrt(discriminant);
614 lambda_1 = 0.5*(-b+sqrt_discriminant);;
615 lambda_2 = 0.5*(-b-sqrt_discriminant);
619 T q = (3.0*c - b*b)/9.0;
620 T r = (b*(9.0*c - 2.0*b*b) - 27.0*d) / 54.0;
622 T discriminant = q*q*q + r*r;
625 if(discriminant > 0.0)
629 post_fatal_error_message(
"Matrix has 2 complex roots.");
631 else if(discriminant == 0.0)
635 T powr = (r < 0) ? -
pow(-r, 1.0/3.0) :
pow(r, 1.0/3.0);
636 lambda_0 = (2.0*powr) - b3;
637 lambda_1 = (-powr) - b3;
646 static const T L_PI =
acos(T(-1.0));
651 lambda_0 = t2*
cos(t1/3.0) - b3;
652 lambda_1 = t2*
cos((t1 + 2.0*L_PI)/3.0) - b3;
653 lambda_2 = t2*
cos((t1 + 4.0*L_PI)/3.0) - b3;
663 T tmp[3] = {lambda_0, lambda_1, lambda_2};
665 std::sort(&tmp[0], &tmp[3]);
667 xresult[0][0] = tmp[0];
668 xresult[1][1] = tmp[1];
669 xresult[2][2] = tmp[2];
675 ensure(unexecutable(
"for_all i, 0, 2, xresult[i][i] == real number"));
682 template <
typename T>
692 diagonalization(result);
697 ensure(unexecutable(
"for_all i, 0, 2, result[i][i] == real number"));
705 template <
typename T>
731 template <
typename T>
754 template <
typename T>
777 T c00 = a11*a22 - a12*a21;
778 T c01 = a12*a20 - a10*a22;
779 T c02 = a10*a21 - a11*a20;
783 if(determinant == 0.0)
785 post_fatal_error_message(
"No inverse; determinant is zero.");
788 T c10 = a02*a21 - a01*a22;
789 T c11 = a00*a22 - a02*a20;
792 T c20 = a01*a12 - a02*a11;
793 T c21 = a02*a10 - a00*a12;
794 T c22 = a00*a11 - a01*a10;
814 template <
typename T>
834 template <
typename T>
845 bool result = (lm[0][1]==0.0) && (lm[0][2]==0.0) && (lm[1][2]==0.0);
856 template <
typename T>
867 bool result = is_diagonal() &&
868 (lm[0][0]==1.0) && (lm[1][1]==1.0) && (lm[2][2]==1.0);
879 template <
typename T>
899 for(
int i=0; i<number_of_rows(); ++i)
916 template <
typename T>
925 for(
int i=0; i<d(); ++i)
927 xresult.
components[i] = xscalar*components[i];
941 template <
typename T>
961 template <
typename T>
985 T b00 = xother[0][0];
986 T b10 = xother[1][0];
987 T b20 = xother[2][0];
989 xresult[0][0] = a00*b00 + a01*b10 + a02*b20;
990 xresult[1][0] = a10*b00 + a11*b10 + a12*b20;
991 xresult[2][0] = a20*b00 + a21*b10 + a22*b20;
1000 template <
typename T>
1020 template <
typename T>
1044 T b00 = xother[0][0];
1045 T b01 = xother[0][1];
1047 T b10 = xother[1][0];
1048 T b11 = xother[1][1];
1050 T b20 = xother[2][0];
1051 T b21 = xother[1][1];
1053 xresult[0][0] = a00*b00 + a01*b10 + a02*b20;
1054 xresult[0][1] = a00*b01 + a01*b11 + a02*b21;
1056 xresult[1][0] = a10*b00 + a11*b10 + a12*b20;
1057 xresult[1][1] = a10*b01 + a11*b11 + a12*b21;
1059 xresult[2][0] = a20*b00 + a21*b10 + a22*b20;
1060 xresult[2][1] = a20*b01 + a21*b11 + a22*b21;
1069 template <
typename T>
1089 template <
typename T>
1113 T b00 = xother[0][0];
1114 T b01 = xother[0][1];
1115 T b02 = xother[0][2];
1117 T b10 = xother[1][0];
1118 T b11 = xother[1][1];
1119 T b12 = xother[1][2];
1121 T b20 = xother[2][0];
1122 T b21 = xother[2][1];
1123 T b22 = xother[2][2];
1125 xresult[0][0] = a00*b00 + a01*b10 + a02*b20;
1126 xresult[0][1] = a00*b01 + a01*b11 + a02*b21;
1127 xresult[0][2] = a00*b02 + a01*b12 + a02*b22;
1129 xresult[1][0] = a10*b00 + a11*b10 + a12*b20;
1130 xresult[1][1] = a10*b01 + a11*b11 + a12*b21;
1131 xresult[1][2] = a10*b02 + a11*b12 + a12*b22;
1133 xresult[2][0] = a20*b00 + a21*b10 + a22*b20;
1134 xresult[2][1] = a20*b01 + a21*b11 + a22*b21;
1135 xresult[2][2] = a20*b02 + a21*b12 + a22*b22;
1144 template <
typename T>
1164 template <
typename T>
1188 T b00 = xother[0][0];
1189 T b01 = xother[0][1];
1190 T b02 = xother[0][2];
1192 T b11 = xother[1][1];
1193 T b12 = xother[1][2];
1196 T b22 = xother[2][2];
1198 xresult[0][0] = a00*b00 + a01*b10 + a02*b20;
1199 xresult[0][1] = a00*b01 + a01*b11 + a02*b21;
1200 xresult[0][2] = a00*b02 + a01*b12 + a02*b22;
1202 xresult[1][0] = a10*b00 + a11*b10 + a12*b20;
1203 xresult[1][1] = a10*b01 + a11*b11 + a12*b21;
1204 xresult[1][2] = a10*b02 + a11*b12 + a12*b22;
1206 xresult[2][0] = a20*b00 + a21*b10 + a22*b20;
1207 xresult[2][1] = a20*b01 + a21*b11 + a22*b21;
1208 xresult[2][2] = a20*b02 + a21*b12 + a22*b22;
1217 template <
typename T>
1237 template <
typename T>
1250 xresult = lm[0][0] + lm[1][1] + lm[2][2];
1258 template <
typename T>
1279 template <
typename T>
1294 for(
int i=0; i<ld; ++i)
1306 template <
typename T>
1329 #ifndef DOXYGEN_SKIP_IMPLEMENTATIONS 1332 template <
typename T>
1333 std::ostream& operator<<(std::ostream& xos, const symmetric_matrix_3x3<T>& xm)
1343 int ncols = xm.number_of_columns();
1345 for(
int i=0; i<nrows; ++i)
1347 for(
int j=0; j<ncols; ++j)
1367 #endif // ifndef DOXYGEN_SKIP_IMPLEMENTATIONS 1370 template <
typename T>
1388 for(
int i=0; i<3; ++i)
1390 xdiagonal[i][i] = eigenvalues[i];
1400 template <
typename T>
1416 static const int n = 3;
1418 static const int max_iterations = 50;
1419 static const T zero = 0.0;
1432 xeigenvectors = xeigenvectors.
identity();
1440 for(
int i=0; i<n; ++i)
1443 xeigenvalues[i] = lmii;
1449 for(i=0; i<max_iterations; ++i)
1453 T sum =
fabs(lm[0][1]) +
fabs(lm[0][2]) +
fabs(lm[1][2]);
1467 T tresh = (i>=3) ? 0.0 : (0.2*sum/(n*n));
1469 for(
int ip=0; ip<n-1; ++ip)
1471 for(
int iq=ip+1; iq<n; ++iq)
1473 T g = 100.0*
fabs(lm[ip][iq]);
1478 && (
fabs(xeigenvalues[ip])+g) ==
fabs(xeigenvalues[ip])
1479 && (
fabs(xeigenvalues[iq])+g) ==
fabs(xeigenvalues[iq]))
1483 else if(
fabs(lm[ip][iq]) > tresh)
1486 T h = xeigenvalues[iq] - xeigenvalues[ip];
1493 T theta = 0.5*h/(lm[ip][iq]);
1494 t = 1.0/(
fabs(theta) +
sqrt(1.0+theta*theta));
1495 if(theta < 0.0) t = -t;
1500 T tau = sin/(1.0 +
cos);
1505 xeigenvalues[ip] -= h;
1506 xeigenvalues[iq] += h;
1510 for(
int j=0; j<ip; ++j)
1514 lm[j][ip] = g - (sin * (h + (g * tau)));
1515 lm[j][iq] = h + (sin * (g - (h * tau)));
1518 for(
int j=ip+1; j<iq; ++j)
1522 lm[ip][j] = g - (sin * (h + (g * tau)));
1523 lm[j][iq] = h + (sin * (g - (h * tau)));
1526 for(
int j=iq+1; j<n; ++j)
1530 lm[ip][j] = g - (sin * (h + (g * tau)));
1531 lm[iq][j] = h + (sin * (g - (h * tau)));
1534 for(
int j=0; j<n; ++j)
1536 g = xeigenvectors[j][ip];
1537 h = xeigenvectors[j][iq];
1538 xeigenvectors[j][ip] = g - (sin * (h + (g * tau)));
1539 xeigenvectors[j][iq] = h + (sin * (g - (h * tau)));
1549 for(
int ip=0; ip<3; ++ip)
1552 xeigenvalues[ip] = b[ip];
1558 if(i >= max_iterations)
1560 post_fatal_error_message(
"Too many Jacobi iterations");
1578 template <
typename T>
1590 static const int n = 3;
1592 for(
int i=0; i<n; ++i)
1594 T ev_min = xeigenvalues[i];
1598 for(j=i+1; j<n; ++j)
1600 if(ev_min > xeigenvalues[j])
1602 ev_min = xeigenvalues[j];
1611 xeigenvalues[k] = xeigenvalues[i];
1612 xeigenvalues[i] = ev_min;
1616 for(
int j=0; j<n; ++j)
1618 T temp = xeigenvectors[j][i];
1619 xeigenvectors[j][i] = xeigenvectors[j][k];
1620 xeigenvectors[j][k] = temp;
1636 #endif // SYMMETRIC_MATRIX_3X3_IMPL_H SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
void jacobi_transformation(const symmetric_matrix_3x3< T > &xm, general_matrix_3x3< T > &xeigenvectors, T xeigenvalues[3])
Determine the eigenvectors and eigenvalues of a real symmetric matrix xm.
bool is_identity() const
True if this is an identity matrix.
Row dofs type for class st2_e3.
T trace() const
The trace of the matrix (auto-allocated).
static int d()
Dimension of the underlying elements.
General matrix with 3 rows and 2 columns.
static int number_of_rows()
The number of rows.
void sort_eigenvalues(general_matrix_3x3< T > &xeigenvectors, T xeigenvalues[3])
Utility function to sort the eigenvalues into ascending order. Called from jacobi_transformation.
void assign(const T &xscalar)
Assign all elements of this matrix to the value xvalue.
int row_index(int xrow) const
Index for row xrow in the linear storage array.
T * operator[](int xrow)
Pointer to the first element in row xrow of this matrix. Facilitates accessing elements via matrix[i]...
void trace(const S0 &x0, SR &xresult, bool xauto_access)
general_matrix_3x1< T > column(int xcolumn) const
A 3x1 matrix containing the elements or column xcolumn.
symmetric_matrix_3x3< T > identity() const
The identity matrix (auto-allocated).
General matrix with 3 rows and 1 column.
Row dofs type for class met_e3.
T components[6]
Linear storage array.
bool is_positive_definite() const
True if this matrix is positive definite.
SHEAF_DLL_SPEC void fabs(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute fabs of x0 (fabs(x0)) (pre-allocated version).
symmetric_matrix_3x3< T > inverse() const
The inverse of the matrix (auto-allocated).
T components[3]
Linear storage array.
symmetric_matrix_3x3< T > adjoint() const
The adjoint of the matrix (auto-allocated).
void identity(general_matrix_3x3< T > &xresult) const
The identity matrix (pre-allocated).
SHEAF_DLL_SPEC void cos(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute cos of x0 (cos(x0)) (pre-allocated version).
void determinant(const S0 &x0, SR &xresult, bool xauto_access)
symmetric_matrix_3x3< T > transpose() const
The transpose of the matrix (auto-allocated).
bool is_diagonal() const
True if this matrix is diagonal.
SHEAF_DLL_SPEC void acos(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute acos of x0 (acos(x0)) (pre-allocated version).
static int number_of_columns()
The number of columns.
General matrix with 3 rows and 3 columns.
General matrix with 1 row and 3 columns.
Namespace for the sheaves component of the sheaf system.
general_matrix_1x3< T > row(int xrow) const
A 1x3 matrix containing the elements or row xrow.
void multiply(const T &xscalar, symmetric_matrix_3x3< T > &xresult) const
This matrix multiplied by a scalar (pre-allocated).
T determinant() const
The determinant of the matrix (auto-allocated).
T components[3]
Linear storage array.
SHEAF_DLL_SPEC void multiply(const vd &x0, const vd_value_type &x1, vd &xresult, bool xauto_access)
Vector x0 multiplied by scalar x1 (pre-allocated version for persistent types).
Namespace for the fiber_bundles component of the sheaf system.
SHEAF_DLL_SPEC void pow(const sec_at0 &x0, const vd_value_type &xexponent, sec_at0 &xresult, bool xauto_access)
Compute x0 to power xexponent (pow(x0, xexponent)) (pre-allocated version).
SHEAF_DLL_SPEC void inverse(const gl2_lite &xlite, gl2_lite &xresult)
Inverse (pre-allocated version for volatile type).
SHEAF_DLL_SPEC void sin(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sin of x0 (sin(x0)) (pre-allocated version).
symmetric_matrix_3x3< T > diagonalization() const
The diagonalization of the matrix (auto-allocated).
A tensor of degree 2 over an abstract vector space (persistent version).
Symmetric matrix with 3 rows and 3 columns.