eigendecomposition.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Class
25  Foam::eigendecomposition
26 
27 Description
28  Eigen decomposition of a square matrix.
29 
30  Calculates the eigenvalues and eigenvectors of a square scalar matrix
31  matrix.
32 
33  If the matrix \f$ A \f$ is symmetric, then \f$ A = VDV^-1 \f$ where the
34  eigenvalue matrix \f$ D \f$ is diagonal and the eigenvector matrix \f$ V \f$
35  is orthogonal. That is, the diagonal values of \f$ D \f$ are the
36  eigenvalues, and \f$ VV^-1 = I \f$, where \f$ I \f$ is the identity matrix.
37  The columns of V represent the eigenvectors in the sense that \f$ AV = VD
38  \f$.
39 
40  If \f$ A \f$ is not symmetric, then the eigenvalue matrix \f$ D \f$ is
41  block diagonal with the real eigenvalues in 1-by-1 blocks and any complex
42  eigenvalues, \f$ a + ib \f$, in 2-by-2 blocks, \f$ [a, b; -b, a] \f$. That
43  is, if the complex eigenvalues look like
44  \verbatim
45  u + iv . . . . .
46  . u - iv . . . .
47  . . a + ib . . .
48  . . . a - ib . .
49  . . . . x .
50  . . . . . y
51  \endverbatim
52  then \f$ D \f$ looks like
53  \verbatim
54  u v . . . .
55  -v u . . . .
56  . . a b . .
57  . . -b a . .
58  . . . . x .
59  . . . . . y
60  \endverbatim
61  This keeps \f$ V \f$ a real matrix in both symmetric and non-symmetric
62  cases, and \f$ AV = VD \f$.
63 
64  The matrix \f$ V \f$ may be badly conditioned, or even singular, so the
65  validity of the equation \f$ A = VDV^-1 \f$ depends upon the condition
66  number of \f$ V \f$.
67 
68  Adapted from the TNT C++ implementation (http://math.nist.gov/tnt) of the
69  JAMA Java implementation (http://math.nist.gov/javanumerics/jama) of the
70  algorithms in:
71  \verbatim
72  Wilkinson, J. H., & Reinsch, C. (1971).
73  Handbook for Automatic Computation: Volume II:
74  Linear Algebra (Vol. 186). Springer-Verlag.
75  \endverbatim
76 
77 SourceFiles
78  eigendecomposition.C
79 
80 \*---------------------------------------------------------------------------*/
81 
82 #ifndef eigendecomposition_H
83 #define eigendecomposition_H
84 
85 #include "scalarMatrices.H"
86 
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
88 
89 namespace Foam
90 {
91 
92 /*---------------------------------------------------------------------------* \
93  Class eigendecomposition Declaration
94 \*---------------------------------------------------------------------------*/
95 
97 {
98  // Private Data
99 
100  //- Is the matrix A symmetric
101  bool symmetric_;
102 
103  //- Real part of the eigenvalues
104  scalarField d_;
105 
106  //- Imaginary part of the eigenvalues
107  scalarField e_;
108 
109  //- Matrix for eigenvectors
111 
112  //- Matrix for the asymmetric Hessenberg form
113  // Allocated if required
115 
116  //- Working storage for asymmetric algorithm
117  // Allocated if required
118  scalarField ort_;
119 
120 
121  // Private Member Functions
122 
123  //- Symmetric Householder reduction to tridiagonal form
124  void tred2();
125 
126  //- Symmetric tridiagonal QL algorithm
127  void tql2();
128 
129  //- Asymmetric reduction to Hessenberg form
130  void orthes();
131 
132  //- Complex scalar division
133  inline void cdiv
134  (
135  scalar& cdivr,
136  scalar& cdivi,
137  const scalar xr,
138  const scalar xi,
139  const scalar yr,
140  const scalar yi
141  );
142 
143  //- Asymmetric reduction from Hessenberg to real Schur form.
144  void hqr2();
145 
146 
147 public:
148 
149  // Constructors
150 
151  //- Construct the eigen decomposition of matrix A
153 
154 
155  // Member Functions
156 
157  //- Return the real part of the eigenvalues
158  const scalarField& d() const
159  {
160  return d_;
161  }
162 
163  //- Return the imaginary part of the eigenvalues
164  const scalarField& e() const
165  {
166  return e_;
167  }
168 
169  //- Return the block diagonal eigenvalue matrix in D
170  void D(scalarSquareMatrix& D) const;
171 
172  //- Return the eigenvector matrix
173  const scalarSquareMatrix& V() const
174  {
175  return V_;
176  }
177 };
178 
179 
180 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
181 
182 } // End namespace Foam
183 
184 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
185 
186 #endif
187 
188 // ************************************************************************* //
Eigen decomposition of a square matrix.
eigendecomposition(const scalarSquareMatrix &A)
Construct the eigen decomposition of matrix A.
void D(scalarSquareMatrix &D) const
Return the block diagonal eigenvalue matrix in D.
const scalarSquareMatrix & V() const
Return the eigenvector matrix.
const scalarField & d() const
Return the real part of the eigenvalues.
const scalarField & e() const
Return the imaginary part of the eigenvalues.
static const coefficient A("A", dimPressure, 611.21)
Namespace for OpenFOAM.