42 #ifndef _EIGENVALUE_H_ 43 #define _EIGENVALUE_H_ 44 #define TOST(i) static_cast<size_t>(i) 54 #include "../NumTools.h" 104 template <
class Real>
124 std::vector<Real>
d_;
125 std::vector<Real>
e_;
165 for (
size_t j = 0; j <
n_; j++)
172 for (
size_t i =
n_-1; i > 0; i--)
178 for (
size_t k = 0; k < i; ++k)
180 scale = scale + NumTools::abs<Real>(
d_[k]);
185 for (
size_t j = 0; j < i; ++j)
187 d_[j] =
V_(i - 1, j);
196 for (
size_t k = 0; k < i; ++k)
210 for (
size_t j = 0; j < i; ++j)
217 for (
size_t j = 0; j < i; ++j)
221 g =
e_[j] +
V_(j,j) * f;
222 for (
size_t k = j + 1; k <= i - 1; k++)
224 g +=
V_(k,j) *
d_[k];
225 e_[k] +=
V_(k,j) * f;
230 for (
size_t j = 0; j < i; ++j)
235 Real hh = f / (h + h);
236 for (
size_t j = 0; j < i; ++j)
240 for (
size_t j = 0; j < i; ++j)
244 for (
size_t k = j; k <= i-1; ++k)
246 V_(k,j) -= (f *
e_[k] + g *
d_[k]);
257 for (
size_t i = 0; i <
n_-1; i++)
264 for (
size_t k = 0; k <= i; k++)
266 d_[k] =
V_(k,i+1) / h;
268 for (
size_t j = 0; j <= i; j++)
271 for (
size_t k = 0; k <= i; k++)
273 g +=
V_(k,i+1) *
V_(k,j);
275 for (
size_t k = 0; k <= i; k++)
277 V_(k,j) -= g *
d_[k];
281 for (
size_t k = 0; k <= i; k++)
286 for (
size_t j = 0; j <
n_; j++)
305 for (
size_t i = 1; i <
n_; i++)
313 Real eps = pow(2.0,-52.0);
314 for (
size_t l = 0; l <
n_; ++l)
318 tst1 = std::max(tst1, NumTools::abs<Real>(
d_[l]) + NumTools::abs<Real>(
e_[l]));
324 if (NumTools::abs<Real>(
e_[m]) <= eps*tst1)
344 Real p = (
d_[l + 1] - g) / (2.0 *
e_[l]);
345 Real r = hypot(p,1.0);
350 d_[l] =
e_[l] / (p + r);
351 d_[l + 1] =
e_[l] * (p + r);
352 Real dl1 =
d_[l + 1];
354 for (
size_t i = l + 2; i <
n_; ++i)
366 Real el1 =
e_[l + 1];
370 for (
size_t ii = m; ii > l; --ii)
382 p = c *
d_[i] - s * g;
383 d_[i + 1] = h + s * (c * g + s *
d_[i]);
387 for (
size_t k = 0; k <
n_; k++)
390 V_(k, i + 1) = s *
V_(k, i) + c * h;
391 V_(k, i) = c *
V_(k, i) - s * h;
394 p = -s * s2 * c3 * el1 *
e_[l] / dl1;
400 }
while (NumTools::abs<Real>(
e_[l]) > eps * tst1);
408 for (
size_t i = 0;
n_ > 0 && i <
n_-1; i++)
412 for (
size_t j = i+1; j <
n_; j++)
424 for (
size_t j = 0; j <
n_; j++)
448 for (
size_t m = low + 1; m <= high - 1; ++m)
453 for (
size_t i = m; i <= high; ++i)
455 scale = scale + NumTools::abs<Real>(
H_(i, m - 1));
462 for (
size_t i = high; i >= m; --i)
464 ort_[i] =
H_(i, m - 1)/scale;
478 for (
size_t j = m; j <
n_; ++j)
481 for (
size_t i = high; i >= m; --i)
486 for (
size_t i = m; i <= high; ++i)
492 for (
size_t i = 0; i <= high; ++i)
495 for (
size_t j = high; j >= m; --j)
500 for (
size_t j = m; j <= high; ++j)
506 H_(m, m - 1) = scale * g;
512 for (
size_t i = 0; i <
n_; i++)
514 for (
size_t j = 0; j <
n_; j++)
516 V_(i,j) = (i == j ? 1.0 : 0.0);
520 for (
size_t m = high - 1; m >= low + 1; --m)
522 if (
H_(m, m - 1) != 0.0)
524 for (
size_t i = m + 1; i <= high; ++i)
528 for (
size_t j = m; j <= high; ++j)
531 for (
size_t i = m; i <= high; i++)
536 g = (g /
ort_[m]) /
H_(m, m - 1);
537 for (
size_t i = m; i <= high; ++i)
550 void cdiv(Real xr, Real xi, Real yr, Real yi)
553 if (NumTools::abs<Real>(yr) > NumTools::abs<Real>(yi))
557 cdivr = (xr + r*xi)/d;
558 cdivi = (xi - r*xr)/d;
564 cdivr = (r*xr + xi)/d;
565 cdivi = (r*xi - xr)/d;
581 int nn =
static_cast<int>(this->
n_);
585 Real eps = pow(2.0,-52.0);
587 Real p=0,q=0,r=0,s=0,z=0,t,w,x,y;
592 for (
int i = 0; i < nn; i++)
594 if ((i < low) || (i > high))
599 for (
int j = std::max(i-1,0); j < nn; j++)
601 norm = norm + NumTools::abs<Real>(
H_(
TOST(i),
TOST(j)));
620 if (NumTools::abs<Real>(
H_(
TOST(l),
TOST(l-1))) < eps * s)
646 z = sqrt(NumTools::abs<Real>(q));
672 s = NumTools::abs<Real>(x) + NumTools::abs<Real>(z);
675 r = sqrt(p * p+q * q);
681 for (
int j = n-1; j < nn; j++)
690 for (
int i = 0; i <= n; i++)
699 for (
int i = low; i <= high; i++)
740 for (
int i = low; i <= n; i++)
761 s = x - w / ((y - x) / 2.0 + s);
762 for (
int i = low; i <= n; i++)
784 s = NumTools::abs<Real>(p) + NumTools::abs<Real>(q) + NumTools::abs<Real>(r);
792 if (NumTools::abs<Real>(
H_(
TOST(m),
TOST(m-1))) * (NumTools::abs<Real>(q) + NumTools::abs<Real>(r)) <
793 eps * (NumTools::abs<Real>(p) * (NumTools::abs<Real>(
H_(
TOST(m-1),
TOST(m-1))) + NumTools::abs<Real>(z) +
794 NumTools::abs<Real>(
H_(
TOST(m+1),
TOST(m+1))))))
801 for (
int i = m+2; i <= n; i++)
812 for (
int k = m; k <= n-1; k++)
814 int notlast = (k != n-1);
819 r = (notlast ?
H_(
TOST(k+2),
TOST(k-1)) : 0.0);
820 x = NumTools::abs<Real>(p) + NumTools::abs<Real>(q) + NumTools::abs<Real>(r);
832 s = sqrt(p * p + q * q + r * r);
856 for (
int j = k; j < nn; j++)
870 for (
int i = 0; i <= std::min(n,k+3); i++)
884 for (
int i = low; i <= high; i++)
907 for (n = nn-1; n >= 0; n--)
918 for (
int i = n-1; i >= 0; i--)
922 for (
int j = l; j <= n; j++)
953 t = (x * s - z * r) / q;
955 if (NumTools::abs<Real>(x) > NumTools::abs<Real>(z))
968 if ((eps * t) * t > 1)
970 for (
int j = i; j <= n; j++)
1000 for (
int i = n-2; i >= 0; i--)
1005 for (
int j = l; j <= n; j++)
1034 vi = (
d_[
TOST(i)] - p) * 2.0 * q;
1035 if ((vr == 0.0) && (vi == 0.0))
1037 vr = eps * norm * (NumTools::abs<Real>(w) + NumTools::abs<Real>(q) +
1038 NumTools::abs<Real>(x) + NumTools::abs<Real>(y) + NumTools::abs<Real>(z));
1040 cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
1043 if (NumTools::abs<Real>(x) > (NumTools::abs<Real>(z) + NumTools::abs<Real>(q)))
1057 t = std::max(NumTools::abs<Real>(
H_(
TOST(i),
TOST(n-1))),NumTools::abs<Real>(
H_(
TOST(i),
TOST(n))));
1058 if ((eps * t) * t > 1)
1060 for (
int j = i; j <= n; j++)
1073 for (
int i = 0; i < nn; i++)
1075 if (i < low || i > high)
1077 for (
int j = i; j < nn; j++)
1086 for (
int j = nn-1; j >= low; j--)
1088 for (
int i = low; i <= high; i++)
1091 for (
int k = low; k <= std::min(j,high); k++)
1111 n_(A.getNumberOfColumns()),
1133 for (
size_t i = 0; i <
n_; i++)
1135 for (
size_t j = 0; j <
n_; j++)
1152 for (
size_t j = 0; j <
n_; j++)
1154 for (
size_t i = 0; i <
n_; i++)
1225 for (
size_t i = 0; i <
n_; i++)
1227 for (
size_t j = 0; j <
n_; j++)
1247 #endif //_EIGENVALUE_H_ The matrix template interface.
std::vector< Real > ort_
Working storage for nonsymmetric algorithm.
RowMatrix< Real > V_
Array for internal storage of eigenvectors.
This class allows to perform a correspondence analysis.
static std::string toString(T t)
General template method to convert to a string.
const RowMatrix< Real > & getD() const
Computes the block diagonal eigenvalue matrix.
const RowMatrix< Real > & getV() const
Return the eigenvector matrix.
void orthes()
Nonsymmetric reduction to Hessenberg form.
void resize(size_t nRows, size_t nCols)
Resize the matrix.
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
const std::vector< Real > & getImagEigenValues() const
Return the imaginary parts of the eigenvalues in parameter e.
void tql2()
Symmetric tridiagonal QL algorithm.
const std::vector< Real > & getRealEigenValues() const
Return the real parts of the eigenvalues.
EigenValue(const Matrix< Real > &A)
Check for symmetry, then construct the eigenvalue decomposition.
bool issymmetric_
Tell if the matrix is symmetric.
RowMatrix< Real > D_
Matrix for internal storage of eigen values in a matrix form.
void tred2()
Symmetric Householder reduction to tridiagonal form.
size_t n_
Row and column dimension (square matrix).
void cdiv(Real xr, Real xi, Real yr, Real yi)
RowMatrix< Real > H_
Matrix for internal storage of nonsymmetric Hessenberg form.