61 const Int_t nRows = a.GetNrows();
62 const Int_t nCols = a.GetNcols();
63 const Int_t rowLwb = a.GetRowLwb();
64 const Int_t colLwb = a.GetColLwb();
66 if (nRows != nCols || rowLwb != colLwb)
68 Error(
"TMatrixDEigen(TMatrixD &)",
"matrix should be square");
72 const Int_t rowUpb = rowLwb+nRows-1;
73 fEigenVectors.ResizeTo(rowLwb,rowUpb,rowLwb,rowUpb);
74 fEigenValuesRe.ResizeTo(rowLwb,rowUpb);
75 fEigenValuesIm.ResizeTo(rowLwb,rowUpb);
79 if (nRows > kWorkMax) ortho.
ResizeTo(nRows);
80 else ortho.
Use(nRows,work);
85 MakeHessenBerg(fEigenVectors,ortho,mH);
88 MakeSchurr(fEigenVectors,fEigenValuesRe,fEigenValuesIm,mH);
92 Sort(fEigenVectors,fEigenValuesRe,fEigenValuesIm);
118 const Int_t high = n-1;
121 for (m = low+1; m <= high-1; m++) {
127 for (i = m; i <= high; i++) {
136 for (i = high; i >=
m; i--) {
138 pO[i] = pH[off_i+m-1]/scale;
150 for (j = m; j <
n; j++) {
152 for (i = high; i >=
m; i--) {
154 f += pO[i]*pH[off_i+j];
157 for (i = m; i <= high; i++) {
159 pH[off_i+j] -= f*pO[i];
163 for (i = 0; i <= high; i++) {
166 for (j = high; j >=
m; j--)
167 f += pO[j]*pH[off_i+j];
169 for (j = m; j <= high; j++)
170 pH[off_i+j] -= f*pO[j];
173 pH[off_m+m-1] = scale*g;
179 for (i = 0; i <
n; i++) {
181 for (j = 0; j <
n; j++)
182 pV[off_i+j] = (i == j ? 1.0 : 0.0);
185 for (m = high-1; m >= low+1; m--) {
187 if (pH[off_m+m-1] != 0.0) {
188 for (i = m+1; i <= high; i++) {
190 pO[i] = pH[off_i+m-1];
192 for (j = m; j <= high; j++) {
194 for (i = m; i <= high; i++) {
196 g += pO[i]*pV[off_i+j];
199 g = (g/pO[
m])/pH[off_m+m-1];
200 for (i = m; i <= high; i++) {
202 pV[off_i+j] += g*pO[i];
241 const Int_t high = nn-1;
255 for (i = 0; i <
nn; i++) {
257 if ((i < low) || (i > high)) {
270 const Int_t off_n1 = (n-1)*nn;
276 const Int_t off_l1 = (l-1)*nn;
290 pH[off_n+
n] = pH[off_n+
n]+exshift;
298 }
else if (l == n-1) {
299 w = pH[off_n+n-1]*pH[off_n1+
n];
300 p = (pH[off_n1+n-1]-pH[off_n+
n])/2.0;
303 pH[off_n+
n] = pH[off_n+
n]+exshift;
304 pH[off_n1+n-1] = pH[off_n1+n-1]+exshift;
330 for (j = n-1; j <
nn; j++) {
332 pH[off_n1+j] = q*z+p*pH[off_n+j];
333 pH[off_n+j] = q*pH[off_n+j]-p*
z;
338 for (i = 0; i <=
n; i++) {
341 pH[off_i+n-1] = q*z+p*pH[off_i+
n];
342 pH[off_i+
n] = q*pH[off_i+
n]-p*
z;
347 for (i = low; i <= high; i++) {
350 pV[off_i+n-1] = q*z+p*pV[off_i+
n];
351 pV[off_i+
n] = q*pV[off_i+
n]-p*
z;
376 w = pH[off_n+n-1]*pH[off_n1+
n];
383 for (i = low; i <=
n; i++) {
401 s = x-w/((y-
x)/2.0+s);
402 for (i = low; i <=
n; i++) {
412 Error(
"MakeSchurr",
"too many iterations");
421 const Int_t off_m_1 = (m-1)*nn;
422 const Int_t off_m1 = (m+1)*nn;
423 const Int_t off_m2 = (m+2)*nn;
427 p = (
r*s-w)/pH[off_m1+m]+pH[off_m+m+1];
428 q = pH[off_m1+m+1]-z-
r-s;
443 for (i = m+2; i <=
n; i++) {
452 for (k = m; k <= n-1; k++) {
454 const Int_t off_k1 = (k+1)*nn;
455 const Int_t off_k2 = (k+2)*nn;
456 const Int_t notlast = (k != n-1);
460 r = (notlast ? pH[off_k2+k-1] : 0.0);
476 pH[off_k+k-1] = -s*
x;
478 pH[off_k+k-1] = -pH[off_k+k-1];
488 for (j = k; j <
nn; j++) {
489 p = pH[off_k+j]+
q*pH[off_k1+j];
491 p = p+r*pH[off_k2+j];
492 pH[off_k2+j] = pH[off_k2+j]-p*
z;
494 pH[off_k+j] = pH[off_k+j]-p*
x;
495 pH[off_k1+j] = pH[off_k1+j]-p*
y;
502 p = x*pH[off_i+k]+y*pH[off_i+k+1];
504 p = p+
z*pH[off_i+k+2];
505 pH[off_i+k+2] = pH[off_i+k+2]-p*
r;
507 pH[off_i+k] = pH[off_i+k]-p;
508 pH[off_i+k+1] = pH[off_i+k+1]-p*
q;
513 for (i = low; i <= high; i++) {
515 p = x*pV[off_i+k]+y*pV[off_i+k+1];
517 p = p+
z*pV[off_i+k+2];
518 pV[off_i+k+2] = pV[off_i+k+2]-p*
r;
520 pV[off_i+k] = pV[off_i+k]-p;
521 pV[off_i+k+1] = pV[off_i+k+1]-p*
q;
533 for (n = nn-1; n >= 0; n--) {
543 for (i = n-1; i >= 0; i--) {
545 const Int_t off_i1 = (i+1)*nn;
548 for (j = l; j <=
n; j++) {
550 r =
r+pH[off_i+j]*pH[off_j+
n];
561 pH[off_i+
n] = -
r/(eps*
norm);
568 q = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i];
572 pH[i+1+n] = (-
r-w*t)/
x;
574 pH[i+1+
n] = (-s-y*t)/
z;
581 for (j = i; j <=
n; j++) {
583 pH[off_j+
n] = pH[off_j+
n]/t;
593 const Int_t off_n1 = (n-1)*nn;
598 pH[off_n1+n-1] =
q/pH[off_n+n-1];
599 pH[off_n1+
n] = -(pH[off_n+
n]-p)/pH[off_n+n-1];
601 cdiv(0.0,-pH[off_n1+n],pH[off_n1+n-1]-p,
q);
607 for (i = n-2; i >= 0; i--) {
609 const Int_t off_i1 = (i+1)*nn;
612 for (j = l; j <=
n; j++) {
614 ra += pH[off_i+j]*pH[off_j+n-1];
615 sa += pH[off_i+j]*pH[off_j+
n];
635 Double_t vr = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i]-
q*
q;
637 if ((vr == 0.0) && (vi == 0.0)) {
641 cdiv(x*
r-
z*ra+q*sa,x*s-
z*sa-q*ra,vr,vi);
645 pH[off_i1+n-1] = (-ra-w*pH[off_i+n-1]+q*pH[off_i+
n])/x;
646 pH[off_i1+
n] = (-sa-w*pH[off_i+
n]-q*pH[off_i+n-1])/x;
648 cdiv(-
r-y*pH[off_i+n-1],-s-y*pH[off_i+n],
z,q);
658 for (j = i; j <=
n; j++) {
660 pH[off_j+n-1] = pH[off_j+n-1]/t;
661 pH[off_j+
n] = pH[off_j+
n]/t;
671 for (i = 0; i <
nn; i++) {
672 if (i < low || i > high) {
674 for (j = i; j <
nn; j++)
675 pV[off_i+j] = pH[off_i+j];
681 for (j = nn-1; j >= low; j--) {
682 for (i = low; i <= high; i++) {
687 z =
z+pV[off_i+k]*pH[off_k+j];
708 for (
Int_t i = 0; i < n-1; i++) {
712 for (j = i+1; j <
n; j++) {
713 const Double_t norm_new = pD[j]*pD[j]+pE[j]*pE[j];
714 if (norm_new > norm) {
727 for (j = 0; j <
n; j++) {
730 pV[off_j+i] = pV[off_j+k];
742 if (
this != &source) {
793 const Int_t rowUpb = rowLwb+nrows-1;
795 TMatrixD mD(rowLwb,rowUpb,rowLwb,rowUpb);
801 for (
Int_t i = 0; i < nrows; i++) {
802 const Int_t off_i = i*nrows;
803 for (
Int_t j = 0; j < nrows; j++)
807 pD[off_i+i+1] = pe[i];
808 }
else if (pe[i] < 0) {
809 pD[off_i+i-1] = pe[i];
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
virtual const Element * GetMatrixArray() const
static Double_t gCdivr
Complex scalar division.
static void MakeHessenBerg(TMatrixD &v, TVectorD &ortho, TMatrixD &H)
Nonsymmetric reduction to Hessenberg form.
Short_t Min(Short_t a, Short_t b)
virtual TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1)
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
TVectorT< Element > & Use(Int_t lwb, Int_t upb, Element *data)
Use the array data to fill the vector lwb..upb].
static void cdiv(Double_t xr, Double_t xi, Double_t yr, Double_t yi)
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
void Error(const char *location, const char *msgfmt,...)
Element * GetMatrixArray()
const TMatrixD GetEigenValues() const
Computes the block diagonal eigenvalue matrix.
static void MakeSchurr(TMatrixD &v, TVectorD &d, TVectorD &e, TMatrixD &H)
Nonsymmetric reduction from Hessenberg to real Schur form.
static void Sort(TMatrixD &v, TVectorD &d, TVectorD &e)
Sort eigenvalues and corresponding vectors in descending order of Re^2+Im^2 of the complex eigenvalue...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
you should not use this method at all Int_t Int_t z
Short_t Max(Short_t a, Short_t b)
TMatrixDEigen & operator=(const TMatrixDEigen &source)
Assignment operator.
Double_t Sqrt(Double_t x)
double norm(double *x, double *p)