1#ifndef LAPACK_GENERAL_EIGEN_SYSTEM_DEFINED
2#define LAPACK_GENERAL_EIGEN_SYSTEM_DEFINED
14template <
typename F =
double>
20 class EigenValueComparator {
23 const std::pair<int, double> &b) {
24 double diff(b.second - a.second);
25 double magnitude(std::abs(a.second) + std::abs(b.second));
26 if (std::real(diff) > +1E-13 * magnitude)
return true;
27 if (std::real(diff) < -1E-13 * magnitude)
return false;
28 return a.first < b.first;
115 bool computeRightEigenvectors =
true,
116 bool computeLeftEigenvectors =
false)
117 : R(computeRightEigenvectors
120 , L(computeLeftEigenvectors
123 , lambdas(A_.getRows()) {
125 throw EXCEPTION(
"EigenSystem requries a square matrix");
130 std::vector<double> realWork(2 * rows);
134 zgeev_(computeLeftEigenvectors ?
"V" :
"N",
135 computeRightEigenvectors ?
"V" :
"N",
140 computeLeftEigenvectors ? L->getValues() :
nullptr,
142 computeRightEigenvectors ? R->getValues() :
nullptr,
149 workCount =
static_cast<int>(std::real(optimalWork) + 0.5);
150 std::vector<complex> work(workCount);
152 zgeev_(computeLeftEigenvectors ?
"V" :
"N",
153 computeRightEigenvectors ?
"V" :
"N",
158 computeLeftEigenvectors ? L->getValues() :
nullptr,
160 computeRightEigenvectors ? R->getValues() :
nullptr,
169 std::vector<std::pair<int, complex>> sortedEigenValues(rows);
170 for (
int i(0); i < rows; ++i) {
171 sortedEigenValues[i] = std::pair<int, complex>(i, lambdas[i]);
173 std::sort(sortedEigenValues.begin(),
174 sortedEigenValues.end(),
175 EigenValueComparator());
177 if (computeRightEigenvectors) { orderEigenVectors(sortedEigenValues, *R); }
178 if (computeLeftEigenvectors) { orderEigenVectors(sortedEigenValues, *L); }
179 for (
int i(0); i < rows; ++i) { lambdas[i] = sortedEigenValues[i].second; }
189 "Right eigenvectors were not computed in constructor.");
197 "Left eigenvectors were not computed in constructor.");
204 for (
int i(0); i < A.
getRows(); ++i) {
205 for (
int k(0); k < A.
getRows(); ++k) {
207 for (
int j(0); j < A.
getRows(); ++j) {
208 element += A(i, j) * (*R)(j, k);
210 element -= lambdas[k] * (*R)(i, k);
211 error += std::real(element * std::conj(element));
218 for (
int j(0); j < A.
getRows(); ++j) {
219 for (
int k(0); k < A.
getRows(); ++k) {
221 for (
int i(0); i < A.
getRows(); ++i) {
222 element += std::conj((*L)(i, k)) * A(i, j);
224 element -= std::conj((*L)(j, k)) * lambdas[k];
225 error += std::real(element * std::conj(element));
233 for (
int i(0); i < R->getRows(); ++i) {
234 for (
int j(0); j < R->getRows(); ++j) {
236 for (
int k(0); k < R->getRows(); ++k) {
237 element += std::conj((*R)(i, k)) * (*R)(j, k);
239 element -= i == j ? 1.0 : 0.0;
240 error += i == j ? 0.0 : std::real(element * std::conj(element));
246 class EigenValueComparator {
249 const std::pair<int, complex> &b) {
251 double inf = std::numeric_limits<double>::infinity();
252 double A(std::abs(a.second) < 1E-4 ? inf : std::real(a.second));
253 double B(std::abs(b.second) < 1E-4 ? inf : std::real(b.second));
255 double magnitude(std::abs(a.second) + std::abs(b.second));
256 if (std::real(diff) > +1E-13 * magnitude)
return true;
261 return a.first < b.first;
270 const std::vector<std::pair<int, complex>> &sortedEigenValues,
273 for (
int j(0); j < U.
getRows(); ++j) {
274 int unsortedJ(sortedEigenValues[j].first);
275 for (
int i(0); i < U.
getRows(); ++i) {
276 U(i, j) = unsortedU(i, unsortedJ);
#define EXCEPTION(message)
Definition Exception.hpp:8
void zgeev_(const char *jobvLeft, const char *jobvRight, const int *n, const sisi4s::Complex64 *a, const int *lda, sisi4s::Complex64 *w, sisi4s::Complex64 *vLeft, const int *ldvLeft, sisi4s::Complex64 *vRight, const int *ldvRight, sisi4s::Complex64 *work, const int *workSize, sisi4s::Float64 *rwork, int *info)
#define NEW(TYPE,...)
Definition SharedPointer.hpp:10
#define PTR(TYPE)
Definition SharedPointer.hpp:8
bool operator()(const std::pair< int, complex > &a, const std::pair< int, complex > &b)
Definition LapackGeneralEigenSystem.hpp:248
void orderEigenVectors(const std::vector< std::pair< int, complex > > &sortedEigenValues, LapackMatrix< complex > &U)
Definition LapackGeneralEigenSystem.hpp:269
const LapackMatrix< complex > & getRightEigenVectors() const
Definition LapackGeneralEigenSystem.hpp:186
std::vector< complex > lambdas
Definition LapackGeneralEigenSystem.hpp:267
L
Definition LapackGeneralEigenSystem.hpp:266
const LapackMatrix< complex > & getLeftEigenVectors() const
Definition LapackGeneralEigenSystem.hpp:194
double leftEigenError(const LapackMatrix< complex > &A)
Definition LapackGeneralEigenSystem.hpp:216
~LapackGeneralEigenSystem()
Definition LapackGeneralEigenSystem.hpp:182
LapackGeneralEigenSystem(const LapackMatrix< complex > &A_, bool computeRightEigenvectors=true, bool computeLeftEigenvectors=false)
Definition LapackGeneralEigenSystem.hpp:114
const std::vector< complex > & getEigenValues() const
Definition LapackGeneralEigenSystem.hpp:184
double rightEigenError(const LapackMatrix< complex > &A)
Definition LapackGeneralEigenSystem.hpp:202
double biorthogonalError()
Definition LapackGeneralEigenSystem.hpp:231
bool operator()(const std::pair< int, double > &a, const std::pair< int, double > &b)
Definition LapackGeneralEigenSystem.hpp:22
Definition LapackGeneralEigenSystem.hpp:15
Definition LapackMatrix.hpp:11
const F * getValues() const
Returns the pointer to the column major data.
Definition LapackMatrix.hpp:69
int getColumns() const
Definition LapackMatrix.hpp:64
int getRows() const
Definition LapackMatrix.hpp:63
Definition Algorithm.hpp:10
Complex< real > complex
Definition Complex.hpp:17