/
EigenvalueDecomposition.hpp
141 lines (106 loc) · 3.32 KB
/
EigenvalueDecomposition.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/** Eigenvalues and eigenvectors of a real matrix.
<P>
If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
diagonal and the eigenvector matrix V is orthogonal.
I.e. A = V.times(D.times(V.transpose())) and
V.times(V.transpose()) equals the identity matrix.
<P>
If A is not symmetric, then the eigenvalue matrix D is block diagonal
with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The
columns of V represent the eigenvectors in the sense that A*V = V*D,
i.e. A.times(V) equals V.times(D). The matrix V may be badly
conditioned, or even singular, so the validity of the equation
A = V*D*inverse(V) depends upon V.cond().
**/
#ifndef _BOOST_UBLAS_EIGENVALUEDECOMPOSITION_
#define _BOOST_UBLAS_EIGENVALUEDECOMPOSITION_
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/exception.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
namespace boost { namespace numeric { namespace ublas {
class EigenvalueDecomposition {
typedef vector<double> Vector;
typedef matrix<double> Matrix;
/* ------------------------
Class variables
* ------------------------ */
/** Row and column dimension (square matrix).
@serial matrix dimension.
*/
int n;
/** Symmetry flag.
@serial internal symmetry flag.
*/
bool issymmetric;
/** Arrays for internal storage of eigenvalues.
@serial internal storage of eigenvalues.
*/
Vector d, e;
/** Array for internal storage of eigenvectors.
@serial internal storage of eigenvectors.
*/
Matrix V;
/** Array for internal storage of nonsymmetric Hessenberg form.
@serial internal storage of nonsymmetric Hessenberg form.
*/
Matrix H;
/** Working storage for nonsymmetric algorithm.
@serial working storage for nonsymmetric algorithm.
*/
Vector ort;
/* ------------------------
Private Methods
* ------------------------ */
// Symmetric Householder reduction to tridiagonal form.
void tred2 ();
// Symmetric tridiagonal QL algorithm.
void tql2 ();
// Nonsymmetric reduction to Hessenberg form.
void orthes ();
// Nonsymmetric reduction from Hessenberg to real Schur form.
void hqr2 ();
public:
/* ------------------------
Constructor
* ------------------------ */
/** Check for symmetry, then construct the eigenvalue decomposition
@param A Square matrix
@return Structure to access D and V.
*/
EigenvalueDecomposition (const Matrix& A);
/* ------------------------
Public Methods
* ------------------------ */
/** Is the matrix symmetric?
@return true if A is symmetric.
*/
bool isSymmetric() const {
return issymmetric;
}
/** Return the eigenvector matrix
@return V
*/
const Matrix& getV () const {
return V;
}
/** Return the real parts of the eigenvalues
@return real(diag(D))
*/
const Vector& getRealEigenvalues () const {
return d;
}
/** Return the imaginary parts of the eigenvalues
@return imag(diag(D))
*/
const Vector& getImagEigenvalues () const {
return e;
}
/** Return the block diagonal eigenvalue matrix
@return D
*/
Matrix getD () const;
};
}}}
#endif