1 #ifndef REDUKT_EIGENVALUE_H
2 #define REDUKT_EIGENVALUE_H
11 #include <boost/numeric/ublas/matrix.hpp>
12 #include <boost/numeric/ublas/vector.hpp>
13 #include <boost/numeric/ublas/operation.hpp>
59 template <
class ValueType>
63 typedef boost::numeric::ublas::matrix<ValueType>
Matrix;
64 typedef boost::numeric::ublas::vector<ValueType>
Vector;
72 bool symmetric =
true;
73 for(
unsigned int j = 0; (j < A.size1()) && symmetric; ++j )
74 for(
unsigned int i = 0; (i < A.size2()) && symmetric; ++i )
75 symmetric = ( A(i,j) == A(j,i) );
96 for (
int i = 0; i < n; i++)
97 for (
int j = 0; j < n; j++)
112 for (
int j = 0; j < n; j++)
113 for (
int i = 0; i < n; i++)
125 for(
int i=0; i < n/2; ++i )
131 Vector v = boost::numeric::ublas::column(V,i);
132 boost::numeric::ublas::column(V,i) = boost::numeric::ublas::column(V,j);
133 boost::numeric::ublas::column(V,j) = v;
207 for (
int i = 0; i < n; i++)
209 for (
int j = 0; j < n; j++)
259 for (
int j = 0; j < n; j++) {
265 for (
int i = n-1; i > 0; i--) {
269 ValueType scale = 0.0;
271 for (
int k = 0; k < i; k++) {
272 scale = scale + abs(d[k]);
276 for (
int j = 0; j < i; j++) {
285 for (
int k = 0; k < i; k++) {
289 ValueType f = d[i-1];
290 ValueType g = sqrt(h);
297 for (
int j = 0; j < i; j++) {
303 for (
int j = 0; j < i; j++) {
306 g = e[j] + V(j,j) * f;
307 for (
int k = j+1; k <= i-1; k++) {
314 for (
int j = 0; j < i; j++) {
318 ValueType hh = f / (h + h);
319 for (
int j = 0; j < i; j++) {
322 for (
int j = 0; j < i; j++) {
325 for (
int k = j; k <= i-1; k++) {
326 V(k,j) -= (f * e[k] + g * d[k]);
337 for (
int i = 0; i < n-1; i++) {
340 ValueType h = d[i+1];
342 for (
int k = 0; k <= i; k++) {
345 for (
int j = 0; j <= i; j++) {
347 for (
int k = 0; k <= i; k++) {
348 g += V(k,i+1) * V(k,j);
350 for (
int k = 0; k <= i; k++) {
355 for (
int k = 0; k <= i; k++) {
359 for (
int j = 0; j < n; j++) {
376 for (
int i = 1; i < n; i++) {
382 ValueType tst1 = 0.0;
383 ValueType eps = pow(2.0,-52.0);
384 for (
int l = 0; l < n; l++) {
388 tst1 = max(tst1,abs(d[l]) + abs(e[l]));
393 if (abs(e[m]) <= eps*tst1) {
411 ValueType p = (d[l+1] - g) / (2.0 * e[l]);
412 ValueType r = hypot(p,1.0);
416 d[l] = e[l] / (p + r);
417 d[l+1] = e[l] * (p + r);
418 ValueType dl1 = d[l+1];
419 ValueType h = g - d[l];
420 for (
int i = l+2; i < n; i++) {
431 ValueType el1 = e[l+1];
434 for (
int i = m-1; i >= l; i--) {
444 p = c * d[i] - s * g;
445 d[i+1] = h + s * (c * g + s * d[i]);
449 for (
int k = 0; k < n; k++) {
451 V(k,i+1) = s * V(k,i) + c * h;
452 V(k,i) = c * V(k,i) - s * h;
455 p = -s * s2 * c3 * el1 * e[l] / dl1;
461 }
while (abs(e[l]) > eps*tst1);
469 for (
int i = 0; i < n-1; i++) {
472 for (
int j = i+1; j < n; j++) {
481 for (
int j = 0; j < n; j++) {
502 for (
int m = low+1; m <= high-1; m++) {
506 ValueType scale = 0.0;
507 for (
int i = m; i <= high; i++) {
508 scale = scale + abs(H(i,m-1));
515 for (
int i = high; i >= m; i--) {
516 ort[i] = H(i,m-1)/scale;
517 h += ort[i] * ort[i];
519 ValueType g = sqrt(h);
529 for (
int j = m; j < n; j++) {
531 for (
int i = high; i >= m; i--) {
535 for (
int i = m; i <= high; i++) {
540 for (
int i = 0; i <= high; i++) {
542 for (
int j = high; j >= m; j--) {
546 for (
int j = m; j <= high; j++) {
550 ort[m] = scale*ort[m];
557 for (
int i = 0; i < n; i++) {
558 for (
int j = 0; j < n; j++) {
559 V(i,j) = (i == j ? 1.0 : 0.0);
563 for (
int m = high-1; m >= low+1; m--) {
564 if (H(m,m-1) != 0.0) {
565 for (
int i = m+1; i <= high; i++) {
568 for (
int j = m; j <= high; j++) {
570 for (
int i = m; i <= high; i++) {
571 g += ort[i] * V(i,j);
574 g = (g / ort[m]) / H(m,m-1);
575 for (
int i = m; i <= high; i++) {
576 V(i,j) += g * ort[i];
586 ValueType cdivr, cdivi;
587 void cdiv(ValueType xr, ValueType xi, ValueType yr, ValueType yi) {
589 if (abs(yr) > abs(yi)) {
592 cdivr = (xr + r*xi)/d;
593 cdivi = (xi - r*xr)/d;
597 cdivr = (r*xr + xi)/d;
598 cdivi = (r*xi - xr)/d;
618 ValueType eps = pow(2.0,-52.0);
619 ValueType exshift = 0.0;
620 ValueType p=0,q=0,r=0,s=0,z=0,t,w,x,y;
624 ValueType norm = 0.0;
625 for (
int i = 0; i < nn; i++) {
626 if ((i < low) || (i > high)) {
630 for (
int j = max(i-1,0); j < nn; j++) {
631 norm = norm + abs(H(i,j));
644 s = abs(H(l-1,l-1)) + abs(H(l,l));
648 if (abs(H(l,l-1)) < eps * s) {
658 H(n,n) = H(n,n) + exshift;
666 }
else if (l == n-1) {
667 w = H(n,n-1) * H(n-1,n);
668 p = (H(n-1,n-1) - H(n,n)) / 2.0;
671 H(n,n) = H(n,n) + exshift;
672 H(n-1,n-1) = H(n-1,n-1) + exshift;
694 r = sqrt(p * p+q * q);
700 for (
int j = n-1; j < nn; j++) {
702 H(n-1,j) = q * z + p * H(n,j);
703 H(n,j) = q * H(n,j) - p * z;
708 for (
int i = 0; i <= n; i++) {
710 H(i,n-1) = q * z + p * H(i,n);
711 H(i,n) = q * H(i,n) - p * z;
716 for (
int i = low; i <= high; i++) {
718 V(i,n-1) = q * z + p * V(i,n);
719 V(i,n) = q * V(i,n) - p * z;
744 w = H(n,n-1) * H(n-1,n);
751 for (
int i = low; i <= n; i++) {
754 s = abs(H(n,n-1)) + abs(H(n-1,n-2));
769 s = x - w / ((y - x) / 2.0 + s);
770 for (
int i = low; i <= n; i++) {
787 p = (r * s - w) / H(m+1,m) + H(m,m+1);
788 q = H(m+1,m+1) - z - r - s;
790 s = abs(p) + abs(q) + abs(r);
797 if (abs(H(m,m-1)) * (abs(q) + abs(r)) <
798 eps * (abs(p) * (abs(H(m-1,m-1)) + abs(z) +
805 for (
int i = m+2; i <= n; i++) {
814 for (
int k = m; k <= n-1; k++) {
815 int notlast = (k != n-1);
819 r = (notlast ? H(k+2,k-1) : 0.0);
820 x = abs(p) + abs(q) + abs(r);
830 s = sqrt(p * p + q * q + r * r);
838 H(k,k-1) = -H(k,k-1);
849 for (
int j = k; j < nn; j++) {
850 p = H(k,j) + q * H(k+1,j);
852 p = p + r * H(k+2,j);
853 H(k+2,j) = H(k+2,j) - p * z;
855 H(k,j) = H(k,j) - p * x;
856 H(k+1,j) = H(k+1,j) - p * y;
861 for (
int i = 0; i <= min(n,k+3); i++) {
862 p = x * H(i,k) + y * H(i,k+1);
864 p = p + z * H(i,k+2);
865 H(i,k+2) = H(i,k+2) - p * r;
868 H(i,k+1) = H(i,k+1) - p * q;
873 for (
int i = low; i <= high; i++) {
874 p = x * V(i,k) + y * V(i,k+1);
876 p = p + z * V(i,k+2);
877 V(i,k+2) = V(i,k+2) - p * r;
880 V(i,k+1) = V(i,k+1) - p * q;
893 for (n = nn-1; n >= 0; n--) {
902 for (
int i = n-1; i >= 0; i--) {
905 for (
int j = l; j <= n; j++) {
906 r = r + H(i,j) * H(j,n);
917 H(i,n) = -r / (eps * norm);
925 q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
926 t = (x * s - z * r) / q;
928 if (abs(x) > abs(z)) {
929 H(i+1,n) = (-r - w * t) / x;
931 H(i+1,n) = (-s - y * t) / z;
938 if ((eps * t) * t > 1) {
939 for (
int j = i; j <= n; j++) {
953 if (abs(H(n,n-1)) > abs(H(n-1,n))) {
954 H(n-1,n-1) = q / H(n,n-1);
955 H(n-1,n) = -(H(n,n) - p) / H(n,n-1);
957 cdiv(0.0,-H(n-1,n),H(n-1,n-1)-p,q);
963 for (
int i = n-2; i >= 0; i--) {
964 ValueType ra,sa,vr,vi;
967 for (
int j = l; j <= n; j++) {
968 ra = ra + H(i,j) * H(j,n-1);
969 sa = sa + H(i,j) * H(j,n);
989 vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
990 vi = (d[i] - p) * 2.0 * q;
991 if ((vr == 0.0) && (vi == 0.0)) {
992 vr = eps * norm * (abs(w) + abs(q) +
993 abs(x) + abs(y) + abs(z));
995 cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
998 if (abs(x) > (abs(z) + abs(q))) {
999 H(i+1,n-1) = (-ra - w * H(i,n-1) + q * H(i,n)) / x;
1000 H(i+1,n) = (-sa - w * H(i,n) - q * H(i,n-1)) / x;
1002 cdiv(-r-y*H(i,n-1),-s-y*H(i,n),z,q);
1010 t = max(abs(H(i,n-1)),abs(H(i,n)));
1011 if ((eps * t) * t > 1) {
1012 for (
int j = i; j <= n; j++) {
1013 H(j,n-1) = H(j,n-1) / t;
1014 H(j,n) = H(j,n) / t;
1024 for (
int i = 0; i < nn; i++) {
1025 if (i < low || i > high) {
1026 for (
int j = i; j < nn; j++) {
1034 for (
int j = nn-1; j >= low; j--) {
1035 for (
int i = low; i <= high; i++) {
1037 for (
int k = low; k <= min(j,high); k++) {
1038 z = z + V(i,k) * H(k,j);
1048 #endif // REDUKT_EIGENVALUE_H
boost::numeric::ublas::vector< ValueType > Vector
Definition: Eigenvalue.h:64
const Matrix & getV() const
Definition: Eigenvalue.h:150
Definition: Eigenvalue.h:60
boost::numeric::ublas::matrix< ValueType > Matrix
Definition: Eigenvalue.h:63
Eigenvalue(const Matrix &A)
Definition: Eigenvalue.h:87
static bool isSymmetric(const Matrix &A)
Definition: Eigenvalue.h:70
const Vector & getRealEigenvalues() const
Definition: Eigenvalue.h:158
const Vector & getImagEigenvalues() const
Definition: Eigenvalue.h:166
void getD(Matrix &D)
Definition: Eigenvalue.h:204