56 const Int_t nRows = a.GetNrows();
57 const Int_t nCols = a.GetNcols();
58 const Int_t rowLwb = a.GetRowLwb();
59 const Int_t colLwb = a.GetColLwb();
61 if (nRows != nCols || rowLwb != colLwb)
63 Error(
"TMatrixDEigen(TMatrixD &)",
"matrix should be square");
67 const Int_t rowUpb = rowLwb+nRows-1;
68 fEigenVectors.ResizeTo(rowLwb,rowUpb,rowLwb,rowUpb);
69 fEigenValuesRe.ResizeTo(rowLwb,rowUpb);
70 fEigenValuesIm.ResizeTo(rowLwb,rowUpb);
74 if (nRows > kWorkMax) ortho.
ResizeTo(nRows);
75 else ortho.
Use(nRows,work);
80 MakeHessenBerg(fEigenVectors,ortho,mH);
83 MakeSchurr(fEigenVectors,fEigenValuesRe,fEigenValuesIm,mH);
87 Sort(fEigenVectors,fEigenValuesRe,fEigenValuesIm);
113 const Int_t high = n-1;
116 for (m = low+1; m <= high-1; m++) {
122 for (i = m; i <= high; i++) {
131 for (i = high; i >=
m; i--) {
133 pO[i] = pH[off_i+m-1]/scale;
145 for (j = m; j <
n; j++) {
147 for (i = high; i >=
m; i--) {
149 f += pO[i]*pH[off_i+j];
152 for (i = m; i <= high; i++) {
154 pH[off_i+j] -= f*pO[i];
158 for (i = 0; i <= high; i++) {
161 for (j = high; j >=
m; j--)
162 f += pO[j]*pH[off_i+j];
164 for (j = m; j <= high; j++)
165 pH[off_i+j] -= f*pO[j];
168 pH[off_m+m-1] = scale*
g;
174 for (i = 0; i <
n; i++) {
176 for (j = 0; j <
n; j++)
177 pV[off_i+j] = (i == j ? 1.0 : 0.0);
180 for (m = high-1; m >= low+1; m--) {
182 if (pH[off_m+m-1] != 0.0) {
183 for (i = m+1; i <= high; i++) {
185 pO[i] = pH[off_i+m-1];
187 for (j = m; j <= high; j++) {
189 for (i = m; i <= high; i++) {
191 g += pO[i]*pV[off_i+j];
194 g = (g/pO[
m])/pH[off_m+m-1];
195 for (i = m; i <= high; i++) {
197 pV[off_i+j] += g*pO[i];
236 const Int_t high = nn-1;
250 for (i = 0; i < nn; i++) {
251 const Int_t off_i = i*nn;
252 if ((i < low) || (i > high)) {
264 const Int_t off_n = n*nn;
265 const Int_t off_n1 = (n-1)*nn;
271 const Int_t off_l1 = (l-1)*nn;
272 const Int_t off_l = l*nn;
285 pH[off_n+
n] = pH[off_n+
n]+exshift;
293 }
else if (l == n-1) {
294 w = pH[off_n+n-1]*pH[off_n1+
n];
295 p = (pH[off_n1+n-1]-pH[off_n+
n])/2.0;
298 pH[off_n+
n] = pH[off_n+
n]+exshift;
299 pH[off_n1+n-1] = pH[off_n1+n-1]+exshift;
325 for (j = n-1; j < nn; j++) {
327 pH[off_n1+j] = q*z+p*pH[off_n+j];
328 pH[off_n+j] = q*pH[off_n+j]-p*z;
333 for (i = 0; i <=
n; i++) {
334 const Int_t off_i = i*nn;
336 pH[off_i+n-1] = q*z+p*pH[off_i+
n];
337 pH[off_i+
n] = q*pH[off_i+
n]-p*z;
342 for (i = low; i <= high; i++) {
343 const Int_t off_i = i*nn;
345 pV[off_i+n-1] = q*z+p*pV[off_i+
n];
346 pV[off_i+
n] = q*pV[off_i+
n]-p*z;
371 w = pH[off_n+n-1]*pH[off_n1+
n];
378 for (i = low; i <=
n; i++) {
379 const Int_t off_i = i*nn;
396 s = x-w/((y-
x)/2.0+s);
397 for (i = low; i <=
n; i++) {
398 const Int_t off_i = i*nn;
407 Error(
"MakeSchurr",
"too many iterations");
415 const Int_t off_m = m*nn;
416 const Int_t off_m_1 = (m-1)*nn;
417 const Int_t off_m1 = (m+1)*nn;
418 const Int_t off_m2 = (m+2)*nn;
422 p = (
r*s-w)/pH[off_m1+m]+pH[off_m+m+1];
423 q = pH[off_m1+m+1]-z-
r-s;
438 for (i = m+2; i <=
n; i++) {
439 const Int_t off_i = i*nn;
447 for (k = m; k <= n-1; k++) {
448 const Int_t off_k = k*nn;
449 const Int_t off_k1 = (k+1)*nn;
450 const Int_t off_k2 = (k+2)*nn;
451 const Int_t notlast = (k != n-1);
455 r = (notlast ? pH[off_k2+k-1] : 0.0);
471 pH[off_k+k-1] = -s*
x;
473 pH[off_k+k-1] = -pH[off_k+k-1];
483 for (j = k; j < nn; j++) {
484 p = pH[off_k+j]+
q*pH[off_k1+j];
486 p = p+r*pH[off_k2+j];
487 pH[off_k2+j] = pH[off_k2+j]-p*z;
489 pH[off_k+j] = pH[off_k+j]-p*
x;
490 pH[off_k1+j] = pH[off_k1+j]-p*
y;
496 const Int_t off_i = i*nn;
497 p = x*pH[off_i+k]+y*pH[off_i+k+1];
499 p = p+z*pH[off_i+k+2];
500 pH[off_i+k+2] = pH[off_i+k+2]-p*
r;
502 pH[off_i+k] = pH[off_i+k]-p;
503 pH[off_i+k+1] = pH[off_i+k+1]-p*
q;
508 for (i = low; i <= high; i++) {
509 const Int_t off_i = i*nn;
510 p = x*pV[off_i+k]+y*pV[off_i+k+1];
512 p = p+z*pV[off_i+k+2];
513 pV[off_i+k+2] = pV[off_i+k+2]-p*
r;
515 pV[off_i+k] = pV[off_i+k]-p;
516 pV[off_i+k+1] = pV[off_i+k+1]-p*
q;
528 for (n = nn-1; n >= 0; n--) {
534 const Int_t off_n = n*nn;
538 for (i = n-1; i >= 0; i--) {
539 const Int_t off_i = i*nn;
540 const Int_t off_i1 = (i+1)*nn;
543 for (j = l; j <=
n; j++) {
544 const Int_t off_j = j*nn;
545 r =
r+pH[off_i+j]*pH[off_j+
n];
556 pH[off_i+
n] = -
r/(eps*
norm);
563 q = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i];
567 pH[i+1+n] = (-
r-w*t)/
x;
569 pH[i+1+
n] = (-s-y*t)/z;
576 for (j = i; j <=
n; j++) {
577 const Int_t off_j = j*nn;
578 pH[off_j+
n] = pH[off_j+
n]/t;
588 const Int_t off_n1 = (n-1)*nn;
593 pH[off_n1+n-1] =
q/pH[off_n+n-1];
594 pH[off_n1+
n] = -(pH[off_n+
n]-p)/pH[off_n+n-1];
596 cdiv(0.0,-pH[off_n1+n],pH[off_n1+n-1]-p,
q);
602 for (i = n-2; i >= 0; i--) {
603 const Int_t off_i = i*nn;
604 const Int_t off_i1 = (i+1)*nn;
607 for (j = l; j <=
n; j++) {
608 const Int_t off_j = j*nn;
609 ra += pH[off_i+j]*pH[off_j+n-1];
610 sa += pH[off_i+j]*pH[off_j+
n];
630 Double_t vr = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i]-
q*
q;
632 if ((vr == 0.0) && (vi == 0.0)) {
636 cdiv(x*
r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
640 pH[off_i1+n-1] = (-ra-w*pH[off_i+n-1]+q*pH[off_i+
n])/x;
641 pH[off_i1+
n] = (-sa-w*pH[off_i+
n]-q*pH[off_i+n-1])/x;
643 cdiv(-
r-y*pH[off_i+n-1],-s-y*pH[off_i+n],z,q);
653 for (j = i; j <=
n; j++) {
654 const Int_t off_j = j*nn;
655 pH[off_j+n-1] = pH[off_j+n-1]/t;
656 pH[off_j+
n] = pH[off_j+
n]/t;
666 for (i = 0; i < nn; i++) {
667 if (i < low || i > high) {
668 const Int_t off_i = i*nn;
669 for (j = i; j < nn; j++)
670 pV[off_i+j] = pH[off_i+j];
676 for (j = nn-1; j >= low; j--) {
677 for (i = low; i <= high; i++) {
678 const Int_t off_i = i*nn;
681 const Int_t off_k = k*nn;
682 z = z+pV[off_i+k]*pH[off_k+j];
703 for (
Int_t i = 0; i < n-1; i++) {
707 for (j = i+1; j <
n; j++) {
708 const Double_t norm_new = pD[j]*pD[j]+pE[j]*pE[j];
709 if (norm_new > norm) {
722 for (j = 0; j <
n; j++) {
725 pV[off_j+i] = pV[off_j+k];
737 if (
this != &source) {
784 const Int_t rowUpb = rowLwb+nrows-1;
786 TMatrixD mD(rowLwb,rowUpb,rowLwb,rowUpb);
792 for (
Int_t i = 0; i < nrows; i++) {
793 const Int_t off_i = i*nrows;
794 for (
Int_t j = 0; j < nrows; j++)
798 pD[off_i+i+1] = pe[i];
799 }
else if (pe[i] < 0) {
800 pD[off_i+i-1] = pe[i];
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
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].
std::map< std::string, std::string >::const_iterator iter
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)
const TMatrixD GetEigenValues() const
Computes the block diagonal eigenvalue matrix.
void Error(const char *location, const char *msgfmt,...)
Element * GetMatrixArray()
static void MakeSchurr(TMatrixD &v, TVectorD &d, TVectorD &e, TMatrixD &H)
Nonsymmetric reduction from Hessenberg to real Schur form.
ClassImp(TMatrixDEigen) TMatrixDEigen
Constructor for eigen-problem of matrix A .
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...
virtual const Element * GetMatrixArray() const
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)