00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "TMatrixDEigen.h"
00045 #include "TMath.h"
00046
00047 ClassImp(TMatrixDEigen)
00048
00049
00050 TMatrixDEigen::TMatrixDEigen(const TMatrixD &a)
00051 {
00052
00053
00054 R__ASSERT(a.IsValid());
00055
00056 const Int_t nRows = a.GetNrows();
00057 const Int_t nCols = a.GetNcols();
00058 const Int_t rowLwb = a.GetRowLwb();
00059 const Int_t colLwb = a.GetColLwb();
00060
00061 if (nRows != nCols || rowLwb != colLwb)
00062 {
00063 Error("TMatrixDEigen(TMatrixD &)","matrix should be square");
00064 return;
00065 }
00066
00067 const Int_t rowUpb = rowLwb+nRows-1;
00068 fEigenVectors.ResizeTo(rowLwb,rowUpb,rowLwb,rowUpb);
00069 fEigenValuesRe.ResizeTo(rowLwb,rowUpb);
00070 fEigenValuesIm.ResizeTo(rowLwb,rowUpb);
00071
00072 TVectorD ortho;
00073 Double_t work[kWorkMax];
00074 if (nRows > kWorkMax) ortho.ResizeTo(nRows);
00075 else ortho.Use(nRows,work);
00076
00077 TMatrixD mH = a;
00078
00079
00080 MakeHessenBerg(fEigenVectors,ortho,mH);
00081
00082
00083 MakeSchurr(fEigenVectors,fEigenValuesRe,fEigenValuesIm,mH);
00084
00085
00086
00087 Sort(fEigenVectors,fEigenValuesRe,fEigenValuesIm);
00088 }
00089
00090
00091 TMatrixDEigen::TMatrixDEigen(const TMatrixDEigen &another)
00092 {
00093
00094
00095 *this = another;
00096 }
00097
00098
00099 void TMatrixDEigen::MakeHessenBerg(TMatrixD &v,TVectorD &ortho,TMatrixD &H)
00100 {
00101
00102
00103
00104
00105
00106 Double_t *pV = v.GetMatrixArray();
00107 Double_t *pO = ortho.GetMatrixArray();
00108 Double_t *pH = H.GetMatrixArray();
00109
00110 const Int_t n = v.GetNrows();
00111
00112 const Int_t low = 0;
00113 const Int_t high = n-1;
00114
00115 Int_t i,j,m;
00116 for (m = low+1; m <= high-1; m++) {
00117 const Int_t off_m = m*n;
00118
00119
00120
00121 Double_t scale = 0.0;
00122 for (i = m; i <= high; i++) {
00123 const Int_t off_i = i*n;
00124 scale = scale + TMath::Abs(pH[off_i+m-1]);
00125 }
00126 if (scale != 0.0) {
00127
00128
00129
00130 Double_t h = 0.0;
00131 for (i = high; i >= m; i--) {
00132 const Int_t off_i = i*n;
00133 pO[i] = pH[off_i+m-1]/scale;
00134 h += pO[i]*pO[i];
00135 }
00136 Double_t g = TMath::Sqrt(h);
00137 if (pO[m] > 0)
00138 g = -g;
00139 h = h-pO[m]*g;
00140 pO[m] = pO[m]-g;
00141
00142
00143
00144
00145 for (j = m; j < n; j++) {
00146 Double_t f = 0.0;
00147 for (i = high; i >= m; i--) {
00148 const Int_t off_i = i*n;
00149 f += pO[i]*pH[off_i+j];
00150 }
00151 f = f/h;
00152 for (i = m; i <= high; i++) {
00153 const Int_t off_i = i*n;
00154 pH[off_i+j] -= f*pO[i];
00155 }
00156 }
00157
00158 for (i = 0; i <= high; i++) {
00159 const Int_t off_i = i*n;
00160 Double_t f = 0.0;
00161 for (j = high; j >= m; j--)
00162 f += pO[j]*pH[off_i+j];
00163 f = f/h;
00164 for (j = m; j <= high; j++)
00165 pH[off_i+j] -= f*pO[j];
00166 }
00167 pO[m] = scale*pO[m];
00168 pH[off_m+m-1] = scale*g;
00169 }
00170 }
00171
00172
00173
00174 for (i = 0; i < n; i++) {
00175 const Int_t off_i = i*n;
00176 for (j = 0; j < n; j++)
00177 pV[off_i+j] = (i == j ? 1.0 : 0.0);
00178 }
00179
00180 for (m = high-1; m >= low+1; m--) {
00181 const Int_t off_m = m*n;
00182 if (pH[off_m+m-1] != 0.0) {
00183 for (i = m+1; i <= high; i++) {
00184 const Int_t off_i = i*n;
00185 pO[i] = pH[off_i+m-1];
00186 }
00187 for (j = m; j <= high; j++) {
00188 Double_t g = 0.0;
00189 for (i = m; i <= high; i++) {
00190 const Int_t off_i = i*n;
00191 g += pO[i]*pV[off_i+j];
00192 }
00193
00194 g = (g/pO[m])/pH[off_m+m-1];
00195 for (i = m; i <= high; i++) {
00196 const Int_t off_i = i*n;
00197 pV[off_i+j] += g*pO[i];
00198 }
00199 }
00200 }
00201 }
00202 }
00203
00204
00205 static Double_t gCdivr, gCdivi;
00206 static void cdiv(Double_t xr,Double_t xi,Double_t yr,Double_t yi) {
00207
00208 Double_t r,d;
00209 if (TMath::Abs(yr) > TMath::Abs(yi)) {
00210 r = yi/yr;
00211 d = yr+r*yi;
00212 gCdivr = (xr+r*xi)/d;
00213 gCdivi = (xi-r*xr)/d;
00214 } else {
00215 r = yr/yi;
00216 d = yi+r*yr;
00217 gCdivr = (r*xr+xi)/d;
00218 gCdivi = (r*xi-xr)/d;
00219 }
00220 }
00221
00222
00223 void TMatrixDEigen::MakeSchurr(TMatrixD &v,TVectorD &d,TVectorD &e,TMatrixD &H)
00224 {
00225
00226
00227
00228
00229
00230
00231
00232 const Int_t nn = v.GetNrows();
00233 Int_t n = nn-1;
00234 const Int_t low = 0;
00235 const Int_t high = nn-1;
00236 const Double_t eps = TMath::Power(2.0,-52.0);
00237 Double_t exshift = 0.0;
00238 Double_t p=0,q=0,r=0,s=0,z=0,t,w,x,y;
00239
00240 Double_t *pV = v.GetMatrixArray();
00241 Double_t *pD = d.GetMatrixArray();
00242 Double_t *pE = e.GetMatrixArray();
00243 Double_t *pH = H.GetMatrixArray();
00244
00245
00246
00247 Double_t norm = 0.0;
00248 Int_t i,j,k;
00249 for (i = 0; i < nn; i++) {
00250 const Int_t off_i = i*nn;
00251 if ((i < low) || (i > high)) {
00252 pD[i] = pH[off_i+i];
00253 pE[i] = 0.0;
00254 }
00255 for (j = TMath::Max(i-1,0); j < nn; j++)
00256 norm += TMath::Abs(pH[off_i+j]);
00257 }
00258
00259
00260
00261 Int_t iter = 0;
00262 while (n >= low) {
00263 const Int_t off_n = n*nn;
00264 const Int_t off_n1 = (n-1)*nn;
00265
00266
00267
00268 Int_t l = n;
00269 while (l > low) {
00270 const Int_t off_l1 = (l-1)*nn;
00271 const Int_t off_l = l*nn;
00272 s = TMath::Abs(pH[off_l1+l-1])+TMath::Abs(pH[off_l+l]);
00273 if (s == 0.0)
00274 s = norm;
00275 if (TMath::Abs(pH[off_l+l-1]) < eps*s)
00276 break;
00277 l--;
00278 }
00279
00280
00281
00282
00283 if (l == n) {
00284 pH[off_n+n] = pH[off_n+n]+exshift;
00285 pD[n] = pH[off_n+n];
00286 pE[n] = 0.0;
00287 n--;
00288 iter = 0;
00289
00290
00291
00292 } else if (l == n-1) {
00293 w = pH[off_n+n-1]*pH[off_n1+n];
00294 p = (pH[off_n1+n-1]-pH[off_n+n])/2.0;
00295 q = p*p+w;
00296 z = TMath::Sqrt(TMath::Abs(q));
00297 pH[off_n+n] = pH[off_n+n]+exshift;
00298 pH[off_n1+n-1] = pH[off_n1+n-1]+exshift;
00299 x = pH[off_n+n];
00300
00301
00302
00303 if (q >= 0) {
00304 if (p >= 0)
00305 z = p+z;
00306 else
00307 z = p-z;
00308 pD[n-1] = x+z;
00309 pD[n] = pD[n-1];
00310 if (z != 0.0)
00311 pD[n] = x-w/z;
00312 pE[n-1] = 0.0;
00313 pE[n] = 0.0;
00314 x = pH[off_n+n-1];
00315 s = TMath::Abs(x)+TMath::Abs(z);
00316 p = x/s;
00317 q = z/s;
00318 r = TMath::Sqrt((p*p)+(q*q));
00319 p = p/r;
00320 q = q/r;
00321
00322
00323
00324 for (j = n-1; j < nn; j++) {
00325 z = pH[off_n1+j];
00326 pH[off_n1+j] = q*z+p*pH[off_n+j];
00327 pH[off_n+j] = q*pH[off_n+j]-p*z;
00328 }
00329
00330
00331
00332 for (i = 0; i <= n; i++) {
00333 const Int_t off_i = i*nn;
00334 z = pH[off_i+n-1];
00335 pH[off_i+n-1] = q*z+p*pH[off_i+n];
00336 pH[off_i+n] = q*pH[off_i+n]-p*z;
00337 }
00338
00339
00340
00341 for (i = low; i <= high; i++) {
00342 const Int_t off_i = i*nn;
00343 z = pV[off_i+n-1];
00344 pV[off_i+n-1] = q*z+p*pV[off_i+n];
00345 pV[off_i+n] = q*pV[off_i+n]-p*z;
00346 }
00347
00348
00349
00350 } else {
00351 pD[n-1] = x+p;
00352 pD[n] = x+p;
00353 pE[n-1] = z;
00354 pE[n] = -z;
00355 }
00356 n = n-2;
00357 iter = 0;
00358
00359
00360
00361 } else {
00362
00363
00364
00365 x = pH[off_n+n];
00366 y = 0.0;
00367 w = 0.0;
00368 if (l < n) {
00369 y = pH[off_n1+n-1];
00370 w = pH[off_n+n-1]*pH[off_n1+n];
00371 }
00372
00373
00374
00375 if (iter == 10) {
00376 exshift += x;
00377 for (i = low; i <= n; i++) {
00378 const Int_t off_i = i*nn;
00379 pH[off_i+i] -= x;
00380 }
00381 s = TMath::Abs(pH[off_n+n-1])+TMath::Abs(pH[off_n1+n-2]);
00382 x = y = 0.75*s;
00383 w = -0.4375*s*s;
00384 }
00385
00386
00387
00388 if (iter == 30) {
00389 s = (y-x)/2.0;
00390 s = s*s+w;
00391 if (s > 0) {
00392 s = TMath::Sqrt(s);
00393 if (y<x)
00394 s = -s;
00395 s = x-w/((y-x)/2.0+s);
00396 for (i = low; i <= n; i++) {
00397 const Int_t off_i = i*nn;
00398 pH[off_i+i] -= s;
00399 }
00400 exshift += s;
00401 x = y = w = 0.964;
00402 }
00403 }
00404
00405 if (iter++ == 50) {
00406 Error("MakeSchurr","too many iterations");
00407 break;
00408 }
00409
00410
00411
00412 Int_t m = n-2;
00413 while (m >= l) {
00414 const Int_t off_m = m*nn;
00415 const Int_t off_m_1 = (m-1)*nn;
00416 const Int_t off_m1 = (m+1)*nn;
00417 const Int_t off_m2 = (m+2)*nn;
00418 z = pH[off_m+m];
00419 r = x-z;
00420 s = y-z;
00421 p = (r*s-w)/pH[off_m1+m]+pH[off_m+m+1];
00422 q = pH[off_m1+m+1]-z-r-s;
00423 r = pH[off_m2+m+1];
00424 s = TMath::Abs(p)+TMath::Abs(q)+TMath::Abs(r);
00425 p = p /s;
00426 q = q/s;
00427 r = r/s;
00428 if (m == l)
00429 break;
00430 if (TMath::Abs(pH[off_m+m-1])*(TMath::Abs(q)+TMath::Abs(r)) <
00431 eps*(TMath::Abs(p)*(TMath::Abs(pH[off_m_1+m-1])+TMath::Abs(z)+
00432 TMath::Abs(pH[off_m1+m+1]))))
00433 break;
00434 m--;
00435 }
00436
00437 for (i = m+2; i <= n; i++) {
00438 const Int_t off_i = i*nn;
00439 pH[off_i+i-2] = 0.0;
00440 if (i > m+2)
00441 pH[off_i+i-3] = 0.0;
00442 }
00443
00444
00445
00446 for (k = m; k <= n-1; k++) {
00447 const Int_t off_k = k*nn;
00448 const Int_t off_k1 = (k+1)*nn;
00449 const Int_t off_k2 = (k+2)*nn;
00450 const Int_t notlast = (k != n-1);
00451 if (k != m) {
00452 p = pH[off_k+k-1];
00453 q = pH[off_k1+k-1];
00454 r = (notlast ? pH[off_k2+k-1] : 0.0);
00455 x = TMath::Abs(p)+TMath::Abs(q)+TMath::Abs(r);
00456 if (x != 0.0) {
00457 p = p/x;
00458 q = q/x;
00459 r = r/x;
00460 }
00461 }
00462 if (x == 0.0)
00463 break;
00464 s = TMath::Sqrt(p*p+q*q+r*r);
00465 if (p < 0) {
00466 s = -s;
00467 }
00468 if (s != 0) {
00469 if (k != m)
00470 pH[off_k+k-1] = -s*x;
00471 else if (l != m)
00472 pH[off_k+k-1] = -pH[off_k+k-1];
00473 p = p+s;
00474 x = p/s;
00475 y = q/s;
00476 z = r/s;
00477 q = q/p;
00478 r = r/p;
00479
00480
00481
00482 for (j = k; j < nn; j++) {
00483 p = pH[off_k+j]+q*pH[off_k1+j];
00484 if (notlast) {
00485 p = p+r*pH[off_k2+j];
00486 pH[off_k2+j] = pH[off_k2+j]-p*z;
00487 }
00488 pH[off_k+j] = pH[off_k+j]-p*x;
00489 pH[off_k1+j] = pH[off_k1+j]-p*y;
00490 }
00491
00492
00493
00494 for (i = 0; i <= TMath::Min(n,k+3); i++) {
00495 const Int_t off_i = i*nn;
00496 p = x*pH[off_i+k]+y*pH[off_i+k+1];
00497 if (notlast) {
00498 p = p+z*pH[off_i+k+2];
00499 pH[off_i+k+2] = pH[off_i+k+2]-p*r;
00500 }
00501 pH[off_i+k] = pH[off_i+k]-p;
00502 pH[off_i+k+1] = pH[off_i+k+1]-p*q;
00503 }
00504
00505
00506
00507 for (i = low; i <= high; i++) {
00508 const Int_t off_i = i*nn;
00509 p = x*pV[off_i+k]+y*pV[off_i+k+1];
00510 if (notlast) {
00511 p = p+z*pV[off_i+k+2];
00512 pV[off_i+k+2] = pV[off_i+k+2]-p*r;
00513 }
00514 pV[off_i+k] = pV[off_i+k]-p;
00515 pV[off_i+k+1] = pV[off_i+k+1]-p*q;
00516 }
00517 }
00518 }
00519 }
00520 }
00521
00522
00523
00524 if (norm == 0.0)
00525 return;
00526
00527 for (n = nn-1; n >= 0; n--) {
00528 p = pD[n];
00529 q = pE[n];
00530
00531
00532
00533 const Int_t off_n = n*nn;
00534 if (q == 0) {
00535 Int_t l = n;
00536 pH[off_n+n] = 1.0;
00537 for (i = n-1; i >= 0; i--) {
00538 const Int_t off_i = i*nn;
00539 const Int_t off_i1 = (i+1)*nn;
00540 w = pH[off_i+i]-p;
00541 r = 0.0;
00542 for (j = l; j <= n; j++) {
00543 const Int_t off_j = j*nn;
00544 r = r+pH[off_i+j]*pH[off_j+n];
00545 }
00546 if (pE[i] < 0.0) {
00547 z = w;
00548 s = r;
00549 } else {
00550 l = i;
00551 if (pE[i] == 0.0) {
00552 if (w != 0.0)
00553 pH[off_i+n] = -r/w;
00554 else
00555 pH[off_i+n] = -r/(eps*norm);
00556
00557
00558
00559 } else {
00560 x = pH[off_i+i+1];
00561 y = pH[off_i1+i];
00562 q = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i];
00563 t = (x*s-z*r)/q;
00564 pH[off_i+n] = t;
00565 if (TMath::Abs(x) > TMath::Abs(z))
00566 pH[i+1+n] = (-r-w*t)/x;
00567 else
00568 pH[i+1+n] = (-s-y*t)/z;
00569 }
00570
00571
00572
00573 t = TMath::Abs(pH[off_i+n]);
00574 if ((eps*t)*t > 1) {
00575 for (j = i; j <= n; j++) {
00576 const Int_t off_j = j*nn;
00577 pH[off_j+n] = pH[off_j+n]/t;
00578 }
00579 }
00580 }
00581 }
00582
00583
00584
00585 } else if (q < 0) {
00586 Int_t l = n-1;
00587 const Int_t off_n1 = (n-1)*nn;
00588
00589
00590
00591 if (TMath::Abs(pH[off_n+n-1]) > TMath::Abs(pH[off_n1+n])) {
00592 pH[off_n1+n-1] = q/pH[off_n+n-1];
00593 pH[off_n1+n] = -(pH[off_n+n]-p)/pH[off_n+n-1];
00594 } else {
00595 cdiv(0.0,-pH[off_n1+n],pH[off_n1+n-1]-p,q);
00596 pH[off_n1+n-1] = gCdivr;
00597 pH[off_n1+n] = gCdivi;
00598 }
00599 pH[off_n+n-1] = 0.0;
00600 pH[off_n+n] = 1.0;
00601 for (i = n-2; i >= 0; i--) {
00602 const Int_t off_i = i*nn;
00603 const Int_t off_i1 = (i+1)*nn;
00604 Double_t ra = 0.0;
00605 Double_t sa = 0.0;
00606 for (j = l; j <= n; j++) {
00607 const Int_t off_j = j*nn;
00608 ra += pH[off_i+j]*pH[off_j+n-1];
00609 sa += pH[off_i+j]*pH[off_j+n];
00610 }
00611 w = pH[off_i+i]-p;
00612
00613 if (pE[i] < 0.0) {
00614 z = w;
00615 r = ra;
00616 s = sa;
00617 } else {
00618 l = i;
00619 if (pE[i] == 0) {
00620 cdiv(-ra,-sa,w,q);
00621 pH[off_i+n-1] = gCdivr;
00622 pH[off_i+n] = gCdivi;
00623 } else {
00624
00625
00626
00627 x = pH[off_i+i+1];
00628 y = pH[off_i1+i];
00629 Double_t vr = (pD[i]-p)*(pD[i]-p)+pE[i]*pE[i]-q*q;
00630 Double_t vi = (pD[i]-p)*2.0*q;
00631 if ((vr == 0.0) && (vi == 0.0)) {
00632 vr = eps*norm*(TMath::Abs(w)+TMath::Abs(q)+
00633 TMath::Abs(x)+TMath::Abs(y)+TMath::Abs(z));
00634 }
00635 cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
00636 pH[off_i+n-1] = gCdivr;
00637 pH[off_i+n] = gCdivi;
00638 if (TMath::Abs(x) > (TMath::Abs(z)+TMath::Abs(q))) {
00639 pH[off_i1+n-1] = (-ra-w*pH[off_i+n-1]+q*pH[off_i+n])/x;
00640 pH[off_i1+n] = (-sa-w*pH[off_i+n]-q*pH[off_i+n-1])/x;
00641 } else {
00642 cdiv(-r-y*pH[off_i+n-1],-s-y*pH[off_i+n],z,q);
00643 pH[off_i1+n-1] = gCdivr;
00644 pH[off_i1+n] = gCdivi;
00645 }
00646 }
00647
00648
00649
00650 t = TMath::Max(TMath::Abs(pH[off_i+n-1]),TMath::Abs(pH[off_i+n]));
00651 if ((eps*t)*t > 1) {
00652 for (j = i; j <= n; j++) {
00653 const Int_t off_j = j*nn;
00654 pH[off_j+n-1] = pH[off_j+n-1]/t;
00655 pH[off_j+n] = pH[off_j+n]/t;
00656 }
00657 }
00658 }
00659 }
00660 }
00661 }
00662
00663
00664
00665 for (i = 0; i < nn; i++) {
00666 if (i < low || i > high) {
00667 const Int_t off_i = i*nn;
00668 for (j = i; j < nn; j++)
00669 pV[off_i+j] = pH[off_i+j];
00670 }
00671 }
00672
00673
00674
00675 for (j = nn-1; j >= low; j--) {
00676 for (i = low; i <= high; i++) {
00677 const Int_t off_i = i*nn;
00678 z = 0.0;
00679 for (k = low; k <= TMath::Min(j,high); k++) {
00680 const Int_t off_k = k*nn;
00681 z = z+pV[off_i+k]*pH[off_k+j];
00682 }
00683 pV[off_i+j] = z;
00684 }
00685 }
00686
00687 }
00688
00689
00690 void TMatrixDEigen::Sort(TMatrixD &v,TVectorD &d,TVectorD &e)
00691 {
00692
00693
00694
00695
00696 Double_t *pV = v.GetMatrixArray();
00697 Double_t *pD = d.GetMatrixArray();
00698 Double_t *pE = e.GetMatrixArray();
00699
00700 const Int_t n = v.GetNrows();
00701
00702 for (Int_t i = 0; i < n-1; i++) {
00703 Int_t k = i;
00704 Double_t norm = pD[i]*pD[i]+pE[i]*pE[i];
00705 Int_t j;
00706 for (j = i+1; j < n; j++) {
00707 const Double_t norm_new = pD[j]*pD[j]+pE[j]*pE[j];
00708 if (norm_new > norm) {
00709 k = j;
00710 norm = norm_new;
00711 }
00712 }
00713 if (k != i) {
00714 Double_t tmp;
00715 tmp = pD[k];
00716 pD[k] = pD[i];
00717 pD[i] = tmp;
00718 tmp = pE[k];
00719 pE[k] = pE[i];
00720 pE[i] = tmp;
00721 for (j = 0; j < n; j++) {
00722 const Int_t off_j = j*n;
00723 tmp = pV[off_j+i];
00724 pV[off_j+i] = pV[off_j+k];
00725 pV[off_j+k] = tmp;
00726 }
00727 }
00728 }
00729 }
00730
00731
00732 TMatrixDEigen &TMatrixDEigen::operator=(const TMatrixDEigen &source)
00733 {
00734
00735
00736 if (this != &source) {
00737 fEigenVectors.ResizeTo(source.fEigenVectors);
00738 fEigenValuesRe.ResizeTo(source.fEigenValuesRe);
00739 fEigenValuesIm.ResizeTo(source.fEigenValuesIm);
00740 }
00741 return *this;
00742 }
00743
00744
00745 const TMatrixD TMatrixDEigen::GetEigenValues() const
00746 {
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 const Int_t nrows = fEigenVectors.GetNrows();
00781 const Int_t rowLwb = fEigenVectors.GetRowLwb();
00782 const Int_t rowUpb = rowLwb+nrows-1;
00783
00784 TMatrixD mD(rowLwb,rowUpb,rowLwb,rowUpb);
00785
00786 Double_t *pD = mD.GetMatrixArray();
00787 const Double_t * const pd = fEigenValuesRe.GetMatrixArray();
00788 const Double_t * const pe = fEigenValuesIm.GetMatrixArray();
00789
00790 for (Int_t i = 0; i < nrows; i++) {
00791 const Int_t off_i = i*nrows;
00792 for (Int_t j = 0; j < nrows; j++)
00793 pD[off_i+j] = 0.0;
00794 pD[off_i+i] = pd[i];
00795 if (pe[i] > 0) {
00796 pD[off_i+i+1] = pe[i];
00797 } else if (pe[i] < 0) {
00798 pD[off_i+i-1] = pe[i];
00799 }
00800 }
00801
00802 return mD;
00803 }