29 ClassImp(TMatrixDSymEigen);
34 TMatrixDSymEigen::TMatrixDSymEigen(
const TMatrixDSym &a)
36 R__ASSERT(a.IsValid());
38 const Int_t nRows = a.GetNrows();
39 const Int_t rowLwb = a.GetRowLwb();
41 fEigenValues.ResizeTo(rowLwb,rowLwb+nRows-1);
42 fEigenVectors.ResizeTo(a);
47 Double_t work[kWorkMax];
48 if (nRows > kWorkMax) offDiag.ResizeTo(nRows);
49 else offDiag.Use(nRows,work);
52 MakeTridiagonal(fEigenVectors,fEigenValues,offDiag);
55 MakeEigenVectors(fEigenVectors,fEigenValues,offDiag);
61 TMatrixDSymEigen::TMatrixDSymEigen(
const TMatrixDSymEigen &another)
71 void TMatrixDSymEigen::MakeTridiagonal(TMatrixD &v,TVectorD &d,TVectorD &e)
73 Double_t *pV = v.GetMatrixArray();
74 Double_t *pD = d.GetMatrixArray();
75 Double_t *pE = e.GetMatrixArray();
77 const Int_t n = v.GetNrows();
80 Int_t off_n1 = (n-1)*n;
81 for (j = 0; j < n; j++)
86 for (i = n-1; i > 0; i--) {
87 const Int_t off_i1 = (i-1)*n;
88 const Int_t off_i = i*n;
94 for (k = 0; k < i; k++)
95 scale = scale+TMath::Abs(pD[k]);
98 for (j = 0; j < i; j++) {
99 const Int_t off_j = j*n;
100 pD[j] = pV[off_i1+j];
108 for (k = 0; k < i; k++) {
112 Double_t f = pD[i-1];
113 Double_t g = TMath::Sqrt(h);
119 for (j = 0; j < i; j++)
124 for (j = 0; j < i; j++) {
125 const Int_t off_j = j*n;
128 g = pE[j]+pV[off_j+j]*f;
129 for (k = j+1; k <= i-1; k++) {
130 const Int_t off_k = k*n;
131 g += pV[off_k+j]*pD[k];
132 pE[k] += pV[off_k+j]*f;
137 for (j = 0; j < i; j++) {
141 Double_t hh = f/(h+h);
142 for (j = 0; j < i; j++)
144 for (j = 0; j < i; j++) {
147 for (k = j; k <= i-1; k++) {
148 const Int_t off_k = k*n;
149 pV[off_k+j] -= (f*pE[k]+g*pD[k]);
151 pD[j] = pV[off_i1+j];
160 for (i = 0; i < n-1; i++) {
161 const Int_t off_i = i*n;
162 pV[off_n1+i] = pV[off_i+i];
164 Double_t h = pD[i+1];
166 for (k = 0; k <= i; k++) {
167 const Int_t off_k = k*n;
168 pD[k] = pV[off_k+i+1]/h;
170 for (j = 0; j <= i; j++) {
172 for (k = 0; k <= i; k++) {
173 const Int_t off_k = k*n;
174 g += pV[off_k+i+1]*pV[off_k+j];
176 for (k = 0; k <= i; k++) {
177 const Int_t off_k = k*n;
178 pV[off_k+j] -= g*pD[k];
182 for (k = 0; k <= i; k++) {
183 const Int_t off_k = k*n;
187 for (j = 0; j < n; j++) {
188 pD[j] = pV[off_n1+j];
191 pV[off_n1+n-1] = 1.0;
201 void TMatrixDSymEigen::MakeEigenVectors(TMatrixD &v,TVectorD &d,TVectorD &e)
203 Double_t *pV = v.GetMatrixArray();
204 Double_t *pD = d.GetMatrixArray();
205 Double_t *pE = e.GetMatrixArray();
207 const Int_t n = v.GetNrows();
210 for (i = 1; i < n; i++)
216 Double_t eps = TMath::Power(2.0,-52.0);
217 for (l = 0; l < n; l++) {
221 tst1 = TMath::Max(tst1,TMath::Abs(pD[l])+TMath::Abs(pE[l]));
226 if (TMath::Abs(pE[m]) <= eps*tst1) {
239 Error(
"MakeEigenVectors",
"too many iterations");
246 Double_t p = (pD[l+1]-g)/(2.0*pE[l]);
247 Double_t r = TMath::Hypot(p,1.0);
251 pD[l+1] = pE[l]*(p+r);
252 Double_t dl1 = pD[l+1];
253 Double_t h = g-pD[l];
254 for (i = l+2; i < n; i++)
264 Double_t el1 = pE[l+1];
267 for (i = m-1; i >= l; i--) {
273 r = TMath::Hypot(p,pE[i]);
278 pD[i+1] = h+s*(c*g+s*pD[i]);
282 for (k = 0; k < n; k++) {
283 const Int_t off_k = k*n;
285 pV[off_k+i+1] = s*pV[off_k+i]+c*h;
286 pV[off_k+i] = c*pV[off_k+i]-s*h;
289 p = -s*s2*c3*el1*pE[l]/dl1;
295 }
while (TMath::Abs(pE[l]) > eps*tst1);
303 for (i = 0; i < n-1; i++) {
306 for (j = i+1; j < n; j++) {
315 for (j = 0; j < n; j++) {
316 const Int_t off_j = j*n;
318 pV[off_j+i] = pV[off_j+k];
328 TMatrixDSymEigen &TMatrixDSymEigen::operator=(
const TMatrixDSymEigen &source)
330 if (
this != &source) {
331 fEigenVectors.ResizeTo(source.fEigenVectors);
332 fEigenValues.ResizeTo(source.fEigenValues);
333 fEigenVectors = source.fEigenVectors;
334 fEigenValues = source.fEigenValues;