39 inline double abssum(complex<double> a) {
54 lambda(rhs.lambda), vectors(rhs.vectors)
59 lambda(M.nrows()), vectors(M.nrows(), M.nrows(), 1.0) {
63 throw SizeError(
"ComplexEigen::ComplexEigen()",
"Matrix is not square.");
72 orthes(copy, low, upp, ort);
75 if(
hqr2(copy, low, upp, ort) != 0) {
77 "Unable to find all eigenvalues.");
82 if(
hqr(copy, low, upp) != 0) {
84 "Unable to find all eigenvalues.");
142 int n = copy.nrows();
147 for(
int j = upp; ; j--) {
148 for(
int i = 0; i <= upp; i++) {
149 if(i != j && copy[j][i] != 0.0)
goto next_row;
154 scale[upp] = double(j);
163 for(
int j = low; ; j++) {
164 for(
int i = low; i <= upp; i++) {
165 if(i != j && copy[i][j] != 0.0)
goto next_column;
170 scale[low] = double(j);
201 for(
int i = low; i <= upp; i++) scale[i] = 1.0;
204 const double radix = 16.;
205 const double b2 = radix * radix;
212 for(
int i = low; i <= upp; i++) {
216 for(
int j = low; j <= upp; j++) {
218 c = c + abssum(copy[j][i]);
219 r = r + abssum(copy[i][j]);
224 if(c != 0.0 && r != 0.0) {
225 double g = r / radix;
242 if((c + r) / f < s * .95) {
246 for(
int j = low; j <=
n; j++) copy[i][j] *= g;
247 for(
int j = 1; j <= upp; j++) copy[j][i] *= f;
286 for(
int i = low; i <= upp; i++) {
288 for(
int j = 0; j <
n; j++)
vectors[i][j] *= s;
294 for(
int i = low; i-- > 0;) {
295 int k = int(scale[i]);
299 for(
int i = upp + 1; i <
n; i++) {
300 int k = int(scale[i]);
309 (
Matrix<complex<double> > ©,
int j,
int m,
int low,
int upp) {
310 int n = copy.nrows();
313 for(
int i = 0; i <= upp; i++) swap(copy[i][j], copy[i][m]);
314 for(
int i = low; i <=
n; i++) swap(copy[j][i], copy[m][i]);
356 complex<double> s, x, y, z;
359 for(
int i = low + 1; i <= upp; i++) {
360 if(
imag(h[i][i-1]) != 0.0) {
362 y = h[i][i-1] / norm;
363 h[i][i-1] = complex<double>(norm, 0.0);
364 for(
int j = i; j <= upp; j++) h[i][j] =
conj(y) * h[i][j];
365 int ll = (upp <= i) ? upp : (i + 1);
366 for(
int j = low; j <= ll; j++) h[j][i] = y * h[j][i];
371 for(
int i = 0; i <
n; i++) {
372 if(i < low || i < upp)
lambda[i] = h[i][i];
376 complex<double> t = 0.0;
379 for(
int en = upp + 1; en-- > low;) {
385 for(l = en; l > low; l--) {
387 tst1 = abssum(h[l-1][l-1]) + abssum(h[l][l]);
389 if(tst2 == tst1)
break;
396 if(itn == 0)
return (en + 1);
398 if(its != 10 && its != 20) {
400 x = h[en-1][en] *
real(h[en][en-1]);
403 y = (h[en-1][en-1] - s) / 2.0;
417 for(
int i = low; i <= en; i++) h[i][i] -= s;
423 for(
int i = l + 1; i <= en; i++) {
424 double sr =
real(h[i][i-1]);
425 double norm = hypot(
std::abs(h[i-1][i-1]), sr);
426 lambda[i-1] = x = h[i-1][i-1] / norm;
428 double fi = sr / norm;
429 h[i][i-1] = complex<double>(0.0, fi);
431 for(
int j = i; j <= en; j++) {
434 h[i-1][j] =
conj(x) * y + fi * z;
435 h[i][j] = x * z - fi * y;
439 double si =
imag(h[en][en]);
443 s = h[en][en] / norm;
448 for(
int j = l + 1; j <= en; j++) {
449 double fi =
imag(h[j][j-1]);
452 for(
int i = l; i < j; i++) {
455 h[i][j-1] = x * y + fi * z;
456 h[i][j] =
conj(x) * z - fi * y;
459 double yr =
real(h[j][j-1]);
461 h[j][j-1] =
real(x) * yr + fi *
real(z);
462 h[j][j] =
conj(x) * z - fi * yr;
466 for(
int i = l; i <= en; i++) h[i][en] *= s;
471 lambda[en] = h[en][en] + t;
480 int upp,
Array1D<complex<double> > &ort)
529 ssize_t
n = h.nrows();
530 complex<double> s, x, y, z;
534 for(ssize_t i = upp - 1; i > low; i--) {
535 if(ort[i] != 0.0 && h[i][i-1] != 0.0) {
537 double norm =
real(h[i][i-1]) *
real(ort[i]) +
540 for(ssize_t k = i + 1; k <= upp; k++) ort[k] = h[k][i-1];
542 for(ssize_t j = i; j <= upp; j++) {
544 for(ssize_t k = i; k <= upp; k++) s +=
conj(ort[k]) *
vectors[k][j];
546 for(ssize_t k = i; k <= upp; k++)
vectors[k][j] += s * ort[k];
552 for( ssize_t i = low + 1; i <= upp; i++) {
553 if(
imag(h[i][i-1]) != 0.0) {
555 y = h[i][i-1] / norm;
557 for(ssize_t j = i; j <
n; j++) h[i][j] =
conj(y) * h[i][j];
558 int ll = (upp <= i) ? upp : (i + 1);
559 for(ssize_t j = 0; j <= ll; j++) h[j][i] = y * h[j][i];
560 for(ssize_t j = low; j <= upp; j++)
vectors[j][i] = y *
vectors[j][i];
565 for(ssize_t i = 0; i <
n; i++) {
566 if(i < low || i > upp)
lambda[i] = h[i][i];
569 complex<double> t = 0.0;
570 ssize_t itn = n * 30;
573 for(ssize_t en = upp + 1; en-- > low;) {
579 for(; l > low; l--) {
581 tst1 = abssum(h[l-1][l-1]) + abssum(h[l][l]);
583 if(tst2 == tst1)
break;
589 if(itn == 0)
return (en + 1);
591 if(its != 10 && its != 20) {
594 x = h[en-1][en] *
real(h[en][en-1]);
597 y = (h[en-1][en-1] - s) / 2.0;
611 for(ssize_t i = low; i <= en; i++) h[i][i] -= s;
617 for(ssize_t i = l + 1; i <= en; i++) {
618 double sr =
real(h[i][i-1]);
619 double norm = hypot(
std::abs(h[i-1][i-1]), sr);
620 lambda[i-1] = x = h[i-1][i-1] / norm;
622 double fi = sr / norm;
623 h[i][i-1] = complex<double>(0.0, fi);
625 for(ssize_t j = i; j <
n; j++) {
628 h[i-1][j] =
conj(x) * y + fi * z;
629 h[i][j] = x * z - fi * y;
633 double si =
imag(h[en][en]);
637 s = h[en][en] / norm;
639 for(ssize_t j = en + 1; j <
n; j++) h[en][j] *=
conj(s);
643 for(ssize_t j = l + 1; j <= en; j++) {
645 double fi =
imag(h[j][j-1]);
647 for(ssize_t i = 0; i < j; i++) {
650 h[i][j-1] = x * y + fi * z;
651 h[i][j] =
conj(x) * z - fi * y;
654 double yr =
real(h[j][j-1]);
656 h[j][j-1] =
real(x) * yr + fi *
real(z);
657 h[j][j] =
conj(x) * z - fi * yr;
659 for(ssize_t i = low; i <= upp; i++) {
662 vectors[i][j-1] = x * y + fi * z;
668 for(ssize_t i = 0; i <= en; i++) h[i][en] *= s;
669 for(ssize_t i = low; i <= upp; i++)
vectors[i][en] *= s;
682 for(ssize_t i = 0; i <
n; i++) {
683 for(ssize_t j = i; j <
n; j++) {
684 double temp = abssum(h[i][j]);
685 if(temp > norm) norm = temp;
689 if(n == 1 || norm == 0.0)
return 0;
691 for(ssize_t en = n - 1; en > 0; en--) {
695 for(ssize_t i = en; i-- > 0;) {
697 for(ssize_t j = i + 1; j <= en; j++) z += h[i][j] * h[j][en];
707 }
while(tst2 > norm);
715 double temp = abssum(h[i][en]);
719 double tst2 = tst1 + 1.0 / tst1;
722 for(ssize_t j = i; j <= en; j++) h[j][en] /= temp;
729 for(ssize_t i = 0; i <
n; i++) {
730 if(i < low || i > upp) {
731 for(ssize_t j = i; j <=
n; j++)
vectors[i][j] = h[i][j];
736 for(ssize_t j = n; j-- > low;) {
737 ssize_t m = (j < upp) ? j : upp;
739 for(ssize_t i = low; i <= upp; i++) {
741 for(ssize_t k = low; k <= m; k++) z +=
vectors[i][k] * h[k][j];
751 int upp,
Array1D<complex<double> > &ort)
779 int n = copy.nrows();
781 for(
int m = low + 1; m < upp; m++) {
787 for(
int i = m; i <= upp; i++) scale += abssum(copy[i][m-1]);
790 for(
int i = upp + 1; i-- > m;) {
791 ort[i] = copy[i][m-1] / scale;
804 copy[m][m-1] = scale;
808 for(
int j = m; j <
n; j++) {
809 complex<double> f = 0.0;
810 for(
int i = upp + 1; i-- > m;) f +=
conj(ort[i]) * copy[i][j];
812 for(
int i = m; i <= upp; i++) copy[i][j] -= f * ort[i];
816 for(
int i = 0; i <= upp; i++) {
817 complex<double> f = 0.0;
818 for(
int j = upp + 1; j-- > m;) f += ort[j] * copy[i][j];
820 for(
int j = m; j <= upp; j++) copy[i][j] -= f *
conj(ort[j]);
824 copy[m][m-1] = - g * copy[m][m-1];
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Matrix< complex< double > > vectors
Complex eigenvector routines.
const Matrix< complex< double > > & eigenVectors() const
Get eigenvectors.
const Vector< complex< double > > & eigenValues() const
Get eigenvalues.
static void balance(Matrix< complex< double > > &, int &low, int &high, Array1D< double > &)
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
m_complex conj(const m_complex &c)
int hqr(Matrix< complex< double > > &, int low, int high)
constexpr double c
The velocity of light in m/s.
static void exchange(Matrix< complex< double > > &, int j, int m, int low, int high)
Eigenvalue error exception.
Tps< T > sqrt(const Tps< T > &x)
Square root.
Vector< complex< double > > lambda
FLieGenerator< T, N > imag(const FLieGenerator< std::complex< T >, N > &)
Take imaginary part of a complex generator.
void balbak(int low, int high, const Array1D< double > &scale)
int hqr2(Matrix< complex< double > > &, int low, int high, Array1D< complex< double > > &ort)
int nrows() const
Get number of rows.
void swapRows(int row1, int row2)
Exchange rows.
static void orthes(Matrix< complex< double > > &, int low, int high, Array1D< complex< double > > &ort)