1#ifndef CLASSIC_FDoubleEigen_HH
2#define CLASSIC_FDoubleEigen_HH
78 int high,
int index[N]);
87 void balbak(
int low,
int high,
double scale[N]);
103void cdiv(
double ar,
double ai,
double br,
double bi,
104 double &cr,
double &ci)
114 s = brs * brs + bis * bis;
116 cr = (ars * brs + ais * bis) / s;
117 ci = (ais * brs - ars * bis) / s;
131 lambda(M.lambda), vectors(M.vectors)
145 for(
int i = 0; i < N; ++i)
vectors(i, i) = 1.0;
157 elmhes(h, low, upp, index);
162 if(
hqr2(h, low, upp) != 0) {
164 "Unable to find all eigenvalues.");
169 if(
hqr(h, low, upp) != 0) {
171 "Unable to find all eigenvalues.");
196 for(
int i = 0; i < N; i++) {
199 for(
int j = 0; j < N; j++) {
200 R[j][i] = std::complex<double>(vectors[j][i]);
204 for(
int j = 0; j < N; j++) {
205 R[j][i] = std::complex<double>(vectors[j][i], + vectors[j][i+1]);
206 R[j][i+1] = std::complex<double>(vectors[j][i], - vectors[j][i+1]);
265 for(
int j = upp; j >= 0; j--) {
266 for(
int i = 0; i <= upp; i++) {
267 if(i != j && copy[j][i] != 0.0)
goto next_column;
271 exchange(copy, j, upp, low, upp);
272 scale[upp] = double(j);
281 for(
int j = low; j < upp; j++) {
282 for(
int i = low; i <= upp; i++) {
283 if(i != j && copy[i][j] != 0.0)
goto next_row;
287 exchange(copy, j, low, low, upp);
288 scale[low] = double(j);
297 for(
int i = low; i <= upp; i++) scale[i] = 1.0;
300 const double radix = 16.0;
301 const double b2 = radix * radix;
307 for(
int i = low; i <= upp; i++) {
311 for(
int j = low; j <= upp; j++) {
319 if(
c != 0.0 && r == 0.0) {
320 double g = r / radix;
337 if((
c + r) / f < s * .95) {
341 for(
int j = low; j < N; j++) copy[i][j] *= g;
342 for(
int j = 0; j <= upp; j++) copy[j][i] *= f;
374 for(
int i = low; i <= upp; i++) {
376 for(
int j = 0; j < N; j++) vectors[i][j] *= s;
381 for(
int i = low; i-- > 0;) {
382 int k = int(scale[i]);
383 if(k != i) vectors.swapRows(i, k);
386 for(
int i = upp + 1; i < N; i++) {
387 int k = int(scale[i]);
388 if(k != i) vectors.swapRows(i, k);
395 int upp,
int index[N])
419 for(
int m = low + 1; m < upp; m++) {
423 for(
int j = m; j <= upp; j++) {
434 for(
int j = m - 1; j < N; j++) std::swap(copy[i][j], copy[m][j]);
435 for(
int j = 0; j <= upp; j++) std::swap(copy[j][i], copy[j][m]);
439 for(i = m + 1; i <= upp; i++) {
440 double y = copy[i][m-1];
444 for(
int j = m; j < N; j++) copy[i][j] -= y * copy[m][j];
445 for(
int j = 0; j <= upp; j++) copy[j][m] += y * copy[j][i];
455 int upp,
int index[N])
482 for(
int mp = upp; --mp > low;) {
484 for(i = mp + 1; i <= upp; i++) vectors[i][mp] = copy[i][mp-1];
488 for(
int j = mp; j <= upp; j++) {
489 vectors[mp][j] = vectors[i][j];
493 vectors[i][mp] = 1.0;
501 int j,
int m,
int low,
int upp) {
503 for(
int i = 0; i <= upp; i++) std::swap(copy[i][j], copy[i][m]);
504 for(
int i = low; i < N; i++) std::swap(copy[j][i], copy[m][i]);
545 for(
int i = 0; i < low; i++) lambda[i] = std::complex<double>(h[i][i]);
546 for(
int i = upp + 1; i < N; i++) lambda[i] = std::complex<double>(h[i][i]);
551 for(
int i = 0; i < N; i++) {
552 for(
int j = k; j < N; j++) norm +=
std::abs(h[i][j]);
558 double p = 0.0, q = 0.0, r = 0.0, s = 0.0;
559 double w = 0.0, x = 0.0, y = 0.0, z = 0.0;
561 for(
int en = upp + 1; en-- > low;) {
568 for(l = en; l > low; l--) {
570 if(s == 0.0) s = norm;
571 if((s +
std::abs(h[l][l-1])) == s)
break;
576 if(l == en)
goto one_root;
579 w = h[en][en-1] * h[en-1][en];
580 if(l == en - 1)
goto two_roots;
583 if(itn == 0)
return (en + 1);
586 if(its == 10 || its == 20) {
588 for(
int i = low; i <= en; i++) h[i][i] -= x;
599 for(m = en - 1; m-- > l;) {
603 p = (r * s - w) / h[m+1][m] + h[m][m+1];
604 q = h[m+1][m+1] - z - r - s;
613 if(tst2 == tst1)
break;
617 for(
int i = m + 3; i <= en; i++) h[i][i-2] = h[i][i-3] = 0.0;
620 for(k = m; k < en; k++) {
621 bool notLast = (k != en - 1);
626 r = notLast ? h[k+2][k-1] : 0.0;
628 if(x == 0.0)
continue;
640 h[k][k-1] = - h[k][k-1];
650 for(
int j = k; j <= en; j++) {
651 p = h[k][j] + q * h[k+1][j];
661 int j = (en < k + 3) ? en : (k + 3);
662 for(
int i = l; i <= j; i++) {
663 p = x * h[i][k] + y * h[i][k+1];
675 lambda[en] = std::complex<double>(x + t);
686 z = (p > 0.0) ? (p + z) : (p - z);
687 lambda[en-1] = std::complex<double>(x + z);
688 lambda[en] = std::complex<double>((z != 0.0) ? (x - w / z) : x + z);
691 lambda[en-1] = std::complex<double>(x + p, + z);
692 lambda[en] = std::complex<double>(x + p, - z);
754 for(
int i = 0; i < low; i++) lambda[i] = std::complex<double>(h[i][i]);
755 for(
int i = upp + 1; i < N; i++) lambda[i] = std::complex<double>(h[i][i]);
760 for(
int i = 0; i < N; i++) {
761 for(
int j = k; j < N; j++) norm +=
std::abs(h[i][j]);
766 double p = 0.0, q = 0.0, r = 0.0, s = 0.0;
767 double w = 0.0, x = 0.0, y = 0.0, z = 0.0;
771 for(
int en = upp + 1; en-- > low;) {
777 for(l = en; l > low; l--) {
779 if(s == 0.0) s = norm;
780 if((s +
std::abs(h[l][l-1])) == s)
break;
785 if(l == en)
goto one_root;
788 w = h[en][en-1] * h[en-1][en];
789 if(l == en - 1)
goto two_roots;
792 if(itn == 0)
return (en + 1);
795 if(its == 10 || its == 20) {
797 for(
int i = low; i <= en; i++) h[i][i] -= x;
808 for(m = en - 1; m-- > l;) {
812 p = (r * s - w) / h[m+1][m] + h[m][m+1];
813 q = h[m+1][m+1] - z - r - s;
822 if(tst2 == tst1)
break;
826 for(
int i = m + 3; i <= en; i++) h[i][i-2] = h[i][i-3] = 0.0;
829 for(k = m; k < en; k++) {
830 bool notLast = (k != en - 1);
835 r = notLast ? h[k+2][k-1] : 0.0;
837 if(x == 0.0)
continue;
849 h[k][k-1] = - h[k][k-1];
859 for(
int j = k; j < N; j++) {
860 p = h[k][j] + q * h[k+1][j];
870 int j = (en < k + 3) ? en : (k + 3);
871 for(
int i = 0; i <= j; i++) {
872 p = x * h[i][k] + y * h[i][k+1];
882 for(
int i = low; i <= upp; i++) {
883 p = x * vectors[i][k] + y * vectors[i][k+1];
885 p += z * vectors[i][k+2];
886 vectors[i][k+2] -= p * r;
889 vectors[i][k+1] -= p * q;
895 lambda[en] = std::complex<double>(h[en][en] = x + t);
902 h[en][en] = x = x + t;
903 h[en-1][en-1] = y + t;
907 z = (p > 0.0) ? (p + z) : (p - z);
908 lambda[en-1] = x + z;
909 lambda[en] = (z != 0.0) ? (x - w / z) : (x + z);
919 for(
int j = en - 1; j < N; j++) {
921 h[en-1][j] = q * z + p * h[en][j];
922 h[en][j] = q * h[en][j] - p * z;
926 for(
int i = 0; i <= en; i++) {
928 h[i][en-1] = q * z + p * h[i][en];
929 h[i][en] = q * h[i][en] - p * z;
933 for(
int i = low; i <= upp; i++) {
934 z = vectors[i][en-1];
935 vectors[i][en-1] = q * z + p * vectors[i][en];
936 vectors[i][en] = q * vectors[i][en] - p * z;
940 lambda[en-1] = std::complex<double>(x + p, + z);
941 lambda[en] = std::complex<double>(x + p, - z);
949 if(norm == 0.0)
return 0;
951 for(
int en = N; en-- > 0;) {
962 h[en-1][en-1] = q / h[en][en-1];
963 h[en-1][en] = - (h[en][en] - p) / h[en][en-1];
965 cdiv(0.0, - h[en-1][en], h[en-1][en-1] - p, q,
966 h[en-1][en-1], h[en-1][en]);
973 for(
int i = en - 1; i-- > 0;) {
978 for(
int j = m; j <= en; j++) {
979 ra += h[i][j] * h[j][en-1];
980 sa += h[i][j] * h[j][en];
990 cdiv(- ra, -sa, w, q, h[i][en-1], h[i][en]);
997 double vi =
std::real(lambda[i] - p) * 2.0 * q;
999 if(vr == 0.0 && vi == 0.0) {
1007 }
while(tst2 > tst1);
1010 cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi,
1011 h[i][en-1], h[i][en]);
1014 h[i+1][en-1] = (- ra - w * h[i][en-1] + q * h[i][en]) / x;
1015 h[i+1][en] = (- sa - w * h[i][en] - q * h[i][en-1]) / x;
1017 cdiv(- r - y * h[i][en-1], - s - y * h[i][en], z, q,
1018 h[i+1][en-1], h[i+1][en]);
1025 if(t != 0.0 && (t + 1.0 / t) <= t) {
1026 for(
int j = i; j <= en; j++) {
1041 for(
int i = en; i-- > 0;) {
1044 for(
int j = m; j <= en; j++) r += h[i][j] * h[j][en];
1059 }
while(tst2 > tst1);
1069 t = (x * s - z * r) / q;
1072 (- r - w * t) / x : (- s - y * t) / z;
1077 if(t != 0.0 && (t + 1.0 / t) <= t) {
1078 for(
int j = i; j <= en; j++) h[j][en] /= t;
1088 for(
int i = 0; i < low; i++) {
1089 for(
int j = i; j < N; j++) vectors[i][j] = h[i][j];
1092 for(
int i = upp + 1; i < N; i++) {
1093 for(
int j = i; j < N; j++) vectors[i][j] = h[i][j];
1098 for(
int j = N; j-- > low;) {
1099 int m = (j < upp) ? j : upp;
1101 for(
int i = low; i <= upp; i++) {
1103 for(k = low; k <= m; k++) z += vectors[i][k] * h[k][j];
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
FLieGenerator< T, N > imag(const FLieGenerator< std::complex< T >, N > &)
Take imaginary part of a complex generator.
void cdiv(double ar, double ai, double br, double bi, double &cr, double &ci)
Tps< T > sqrt(const Tps< T > &x)
Square root.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double c
The velocity of light in m/s.
Eigenvalues and eigenvectors for a real general matrix.
static void exchange(FMatrix< double, N, N > &, int j, int m, int low, int high)
void elmtran(FMatrix< double, N, N > &, int low, int high, int index[N])
FMatrix< std::complex< double >, N, N > eigenVectors() const
Get eigenvectors.
FMatrix< double, N, N > vectors
static void balance(FMatrix< double, N, N > &, int &low, int &high, double scale[N])
FVector< std::complex< double >, N > eigenValues() const
Get eigenvalues.
void operator=(const FDoubleEigen &)
FVector< std::complex< double >, N > lambda
void balbak(int low, int high, double scale[N])
static void elmhes(FMatrix< double, N, N > &, int low, int high, int index[N])
FMatrix< double, N, N > packedEigenVectors() const
Get eigenvectors.
int hqr(FMatrix< double, N, N > &, int low, int high)
int hqr2(FMatrix< double, N, N > &, int low, int high)
A templated representation for vectors.
Eigenvalue error exception.