// @(#)root/matrix:$Id$
// Authors: Fons Rademakers, Eddy Offermann  Dec 2003

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

///////////////////////////////////////////////////////////////////////////
//                                                                       //
// Cholesky Decomposition class                                          //
//                                                                       //
// Decompose a symmetric, positive definite matrix A = U^T * U           //
//                                                                       //
// where U is a upper triangular matrix                                  //
//                                                                       //
// The decomposition fails if a diagonal element of fU is <= 0, the      //
// matrix is not positive negative . The matrix fU is made invalid .     //
//                                                                       //
// fU has the same index range as A .                                    //
//                                                                       //
///////////////////////////////////////////////////////////////////////////

#include "TDecompChol.h"
#include "TMath.h"

ClassImp(TDecompChol)

//______________________________________________________________________________
TDecompChol::TDecompChol(Int_t nrows)
{
// Constructor for (nrows x nrows) matrix

   fU.ResizeTo(nrows,nrows);
}

//______________________________________________________________________________
TDecompChol::TDecompChol(Int_t row_lwb,Int_t row_upb)
{
// Constructor for ([row_lwb..row_upb] x [row_lwb..row_upb]) matrix

   const Int_t nrows = row_upb-row_lwb+1;
   fRowLwb = row_lwb;
   fColLwb = row_lwb;
   fU.ResizeTo(row_lwb,row_lwb+nrows-1,row_lwb,row_lwb+nrows-1);
}

//______________________________________________________________________________
TDecompChol::TDecompChol(const TMatrixDSym &a,Double_t tol)
{
// Constructor for symmetric matrix A . Matrix should be positive definite

   R__ASSERT(a.IsValid());

   SetBit(kMatrixSet);
   fCondition = a.Norm1();
   fTol = a.GetTol();
   if (tol > 0)
      fTol = tol;

   fRowLwb = a.GetRowLwb();
   fColLwb = a.GetColLwb();
   fU.ResizeTo(a);
   fU = a;
}

//______________________________________________________________________________
TDecompChol::TDecompChol(const TMatrixD &a,Double_t tol)
{
// Constructor for general matrix A . Matrix should be symmetric positive definite

   R__ASSERT(a.IsValid());

   if (a.GetNrows() != a.GetNcols() || a.GetRowLwb() != a.GetColLwb()) {
      Error("TDecompChol(const TMatrixD &","matrix should be square");
      return;
   }

   SetBit(kMatrixSet);
   fCondition = a.Norm1();
   fTol = a.GetTol();
   if (tol > 0)
      fTol = tol;

   fRowLwb = a.GetRowLwb();
   fColLwb = a.GetColLwb();
   fU.ResizeTo(a);
   fU = a;
}

//______________________________________________________________________________
TDecompChol::TDecompChol(const TDecompChol &another) : TDecompBase(another)
{
// Copy constructor

   *this = another;
}

//______________________________________________________________________________
Bool_t TDecompChol::Decompose()
{
// Matrix A is decomposed in component U so that A = U^T*U^T
// If the decomposition succeeds, bit kDecomposed is set , otherwise kSingular

   if (TestBit(kDecomposed)) return kTRUE;

   if ( !TestBit(kMatrixSet) ) {
      Error("Decompose()","Matrix has not been set");
      return kFALSE;
   }

   Int_t i,j,icol,irow;
   const Int_t     n  = fU.GetNrows();
         Double_t *pU = fU.GetMatrixArray();
   for (icol = 0; icol < n; icol++) {
      const Int_t rowOff = icol*n;

      //Compute fU(j,j) and test for non-positive-definiteness.
      Double_t ujj = pU[rowOff+icol];
      for (irow = 0; irow < icol; irow++) {
         const Int_t pos_ij = irow*n+icol;
         ujj -= pU[pos_ij]*pU[pos_ij];
      }
      if (ujj <= 0) {
         Error("Decompose()","matrix not positive definite");
         return kFALSE;
      }
      ujj = TMath::Sqrt(ujj);
      pU[rowOff+icol] = ujj;

      if (icol < n-1) {
         for (j = icol+1; j < n; j++) {
            for (i = 0; i < icol; i++) {
               const Int_t rowOff2 = i*n;
               pU[rowOff+j] -= pU[rowOff2+j]*pU[rowOff2+icol];
            }
         }
         for (j = icol+1; j < n; j++)
            pU[rowOff+j] /= ujj;
      }
   }

   for (irow = 0; irow < n; irow++) {
      const Int_t rowOff = irow*n;
      for (icol = 0; icol < irow; icol++)
         pU[rowOff+icol] = 0.;
   }

   SetBit(kDecomposed);

   return kTRUE;
}

//______________________________________________________________________________
const TMatrixDSym TDecompChol::GetMatrix()
{
// Reconstruct the original matrix using the decomposition parts

   if (TestBit(kSingular)) {
      Error("GetMatrix()","Matrix is singular");
      return TMatrixDSym();
   }
   if ( !TestBit(kDecomposed) ) {
      if (!Decompose()) {
         Error("GetMatrix()","Decomposition failed");
         return TMatrixDSym();
      }
   }

   return TMatrixDSym(TMatrixDSym::kAtA,fU);
}

//______________________________________________________________________________
void TDecompChol::SetMatrix(const TMatrixDSym &a)
{
// Set the matrix to be decomposed, decomposition status is reset.

   R__ASSERT(a.IsValid());

   ResetStatus();
   if (a.GetNrows() != a.GetNcols() || a.GetRowLwb() != a.GetColLwb()) {
      Error("SetMatrix(const TMatrixDSym &","matrix should be square");
      return;
   }

   SetBit(kMatrixSet);
   fCondition = -1.0;

   fRowLwb = a.GetRowLwb();
   fColLwb = a.GetColLwb();
   fU.ResizeTo(a);
   fU = a;
}

//______________________________________________________________________________
Bool_t TDecompChol::Solve(TVectorD &b)
{
// Solve equations Ax=b assuming A has been factored by Cholesky. The factor U is
// assumed to be in upper triang of fU. fTol is used to determine if diagonal
// element is zero. The solution is returned in b.

   R__ASSERT(b.IsValid());
   if (TestBit(kSingular)) {
      Error("Solve()","Matrix is singular"); 
      return kFALSE;
   }
   if ( !TestBit(kDecomposed) ) {
      if (!Decompose()) {
         Error("Solve()","Decomposition failed");
         return kFALSE;
      }
   }

   if (fU.GetNrows() != b.GetNrows() || fU.GetRowLwb() != b.GetLwb()) {
      Error("Solve(TVectorD &","vector and matrix incompatible");
      return kFALSE;
   }

   const Int_t n = fU.GetNrows();

   const Double_t *pU = fU.GetMatrixArray();
         Double_t *pb = b.GetMatrixArray();

   Int_t i;
   // step 1: Forward substitution on U^T
   for (i = 0; i < n; i++) {
      const Int_t off_i = i*n;
      if (pU[off_i+i] < fTol)
      {
         Error("Solve(TVectorD &b)","u[%d,%d]=%.4e < %.4e",i,i,pU[off_i+i],fTol);
         return kFALSE;
      }
      Double_t r = pb[i];
      for (Int_t j = 0; j < i; j++) {
         const Int_t off_j = j*n;
         r -= pU[off_j+i]*pb[j];
      }
      pb[i] = r/pU[off_i+i];
   }

   // step 2: Backward substitution on U
   for (i = n-1; i >= 0; i--) {
      const Int_t off_i = i*n;
      Double_t r = pb[i];
      for (Int_t j = i+1; j < n; j++)
         r -= pU[off_i+j]*pb[j];
      pb[i] = r/pU[off_i+i];
   }

   return kTRUE;
}

//______________________________________________________________________________
Bool_t TDecompChol::Solve(TMatrixDColumn &cb)
{
// Solve equations Ax=b assuming A has been factored by Cholesky. The factor U is
// assumed to be in upper triang of fU. fTol is used to determine if diagonal
// element is zero. The solution is returned in b.

   TMatrixDBase *b = const_cast<TMatrixDBase *>(cb.GetMatrix());
   R__ASSERT(b->IsValid());
   if (TestBit(kSingular)) {
      Error("Solve()","Matrix is singular");
      return kFALSE;
   }
   if ( !TestBit(kDecomposed) ) {
      if (!Decompose()) {
         Error("Solve()","Decomposition failed");
         return kFALSE;
      }
   }

   if (fU.GetNrows() != b->GetNrows() || fU.GetRowLwb() != b->GetRowLwb())
   {
      Error("Solve(TMatrixDColumn &cb","vector and matrix incompatible");
      return kFALSE;
   }

   const Int_t n = fU.GetNrows();

   const Double_t *pU  = fU.GetMatrixArray();
         Double_t *pcb = cb.GetPtr();
   const Int_t     inc = cb.GetInc();

   Int_t i;
   // step 1: Forward substitution U^T
   for (i = 0; i < n; i++) {
      const Int_t off_i  = i*n;
      const Int_t off_i2 = i*inc;
      if (pU[off_i+i] < fTol)
      {
         Error("Solve(TMatrixDColumn &cb)","u[%d,%d]=%.4e < %.4e",i,i,pU[off_i+i],fTol);
         return kFALSE;
      }
      Double_t r = pcb[off_i2];
      for (Int_t j = 0; j < i; j++) {
         const Int_t off_j = j*n;
         r -= pU[off_j+i]*pcb[j*inc];
      }
      pcb[off_i2] = r/pU[off_i+i];
   }

   // step 2: Backward substitution U
   for (i = n-1; i >= 0; i--) {
      const Int_t off_i  = i*n;
      const Int_t off_i2 = i*inc;
      Double_t r = pcb[off_i2];
      for (Int_t j = i+1; j < n; j++)
         r -= pU[off_i+j]*pcb[j*inc];
      pcb[off_i2] = r/pU[off_i+i];
   }

   return kTRUE;
}

//______________________________________________________________________________
void TDecompChol::Det(Double_t &d1,Double_t &d2)
{
// Matrix determinant det = d1*TMath::Power(2.,d2) is square of diagProd
// of cholesky factor

   if ( !TestBit(kDetermined) ) {
      if ( !TestBit(kDecomposed) )
         Decompose();
      TDecompBase::Det(d1,d2);
      // square det as calculated by above
      fDet1 *= fDet1;
      fDet2 += fDet2;
      SetBit(kDetermined);
   }
   d1 = fDet1;
   d2 = fDet2;
}

//______________________________________________________________________________
Bool_t TDecompChol::Invert(TMatrixDSym &inv)
{
// For a symmetric matrix A(m,m), its inverse A_inv(m,m) is returned .

   if (inv.GetNrows() != GetNrows() || inv.GetRowLwb() != GetRowLwb()) {
      Error("Invert(TMatrixDSym &","Input matrix has wrong shape");
      return kFALSE;
   }

   inv.UnitMatrix();

   const Int_t colLwb = inv.GetColLwb();
   const Int_t colUpb = inv.GetColUpb();
   Bool_t status = kTRUE;
   for (Int_t icol = colLwb; icol <= colUpb && status; icol++) {
      TMatrixDColumn b(inv,icol);
      status &= Solve(b);
   }

   return status;
}

//______________________________________________________________________________
TMatrixDSym TDecompChol::Invert(Bool_t &status)
{
// For a symmetric matrix A(m,m), its inverse A_inv(m,m) is returned .

   const Int_t rowLwb = GetRowLwb();
   const Int_t rowUpb = rowLwb+GetNrows()-1;

   TMatrixDSym inv(rowLwb,rowUpb);
   inv.UnitMatrix();
   status = Invert(inv);

   return inv;
}

//______________________________________________________________________________
void TDecompChol::Print(Option_t *opt) const
{
// Print class members .

   TDecompBase::Print(opt);
   fU.Print("fU");
}

//______________________________________________________________________________
TDecompChol &TDecompChol::operator=(const TDecompChol &source)
{
// Assignment operator

   if (this != &source) {
      TDecompBase::operator=(source);
      fU.ResizeTo(source.fU);
      fU = source.fU;
   }
   return *this;
}

//______________________________________________________________________________
TVectorD NormalEqn(const TMatrixD &A,const TVectorD &b)
{
// Solve min {(A . x - b)^T (A . x - b)} for vector x where
//   A : (m x n) matrix, m >= n
//   b : (m)     vector
//   x : (n)     vector

   TDecompChol ch(TMatrixDSym(TMatrixDSym::kAtA,A));
   Bool_t ok;
   return ch.Solve(TMatrixD(TMatrixD::kTransposed,A)*b,ok);
}

//______________________________________________________________________________
TVectorD NormalEqn(const TMatrixD &A,const TVectorD &b,const TVectorD &std)
{
// Solve min {(A . x - b)^T W (A . x - b)} for vector x where
//   A : (m x n) matrix, m >= n
//   b : (m)     vector
//   x : (n)     vector
//   W : (m x m) weight matrix with W(i,j) = 1/std(i)^2  for i == j
//                                         = 0           fir i != j

   if (!AreCompatible(b,std)) {
      ::Error("NormalEqn","vectors b and std are not compatible");
      return TVectorD();
   }

   TMatrixD mAw = A;
   TVectorD mBw = b;
   for (Int_t irow = 0; irow < A.GetNrows(); irow++) {
      TMatrixDRow(mAw,irow) *= 1/std(irow);
      mBw(irow) /= std(irow);
   }
   TDecompChol ch(TMatrixDSym(TMatrixDSym::kAtA,mAw));
   Bool_t ok;
   return ch.Solve(TMatrixD(TMatrixD::kTransposed,mAw)*mBw,ok);
}

//______________________________________________________________________________
TMatrixD NormalEqn(const TMatrixD &A,const TMatrixD &B)
{
// Solve min {(A . X_j - B_j)^T (A . X_j - B_j)} for each column j in
// B and X
//   A : (m x n ) matrix, m >= n
//   B : (m x nb) matrix, nb >= 1
//  mX : (n x nb) matrix

   TDecompChol ch(TMatrixDSym(TMatrixDSym::kAtA,A));
   TMatrixD mX(A,TMatrixD::kTransposeMult,B);
   ch.MultiSolve(mX);
   return mX;
}

//______________________________________________________________________________
TMatrixD NormalEqn(const TMatrixD &A,const TMatrixD &B,const TVectorD &std)
{
// Solve min {(A . X_j - B_j)^T W (A . X_j - B_j)} for each column j in
// B and X
//   A : (m x n ) matrix, m >= n
//   B : (m x nb) matrix, nb >= 1
//  mX : (n x nb) matrix
//   W : (m x m) weight matrix with W(i,j) = 1/std(i)^2  for i == j
//                                         = 0           fir i != j

   TMatrixD mAw = A;
   TMatrixD mBw = B;
   for (Int_t irow = 0; irow < A.GetNrows(); irow++) {
      TMatrixDRow(mAw,irow) *= 1/std(irow);
      TMatrixDRow(mBw,irow) *= 1/std(irow);
   }

   TDecompChol ch(TMatrixDSym(TMatrixDSym::kAtA,mAw));
   TMatrixD mX(mAw,TMatrixD::kTransposeMult,mBw);
   ch.MultiSolve(mX);
   return mX;
}
 TDecompChol.cxx:1
 TDecompChol.cxx:2
 TDecompChol.cxx:3
 TDecompChol.cxx:4
 TDecompChol.cxx:5
 TDecompChol.cxx:6
 TDecompChol.cxx:7
 TDecompChol.cxx:8
 TDecompChol.cxx:9
 TDecompChol.cxx:10
 TDecompChol.cxx:11
 TDecompChol.cxx:12
 TDecompChol.cxx:13
 TDecompChol.cxx:14
 TDecompChol.cxx:15
 TDecompChol.cxx:16
 TDecompChol.cxx:17
 TDecompChol.cxx:18
 TDecompChol.cxx:19
 TDecompChol.cxx:20
 TDecompChol.cxx:21
 TDecompChol.cxx:22
 TDecompChol.cxx:23
 TDecompChol.cxx:24
 TDecompChol.cxx:25
 TDecompChol.cxx:26
 TDecompChol.cxx:27
 TDecompChol.cxx:28
 TDecompChol.cxx:29
 TDecompChol.cxx:30
 TDecompChol.cxx:31
 TDecompChol.cxx:32
 TDecompChol.cxx:33
 TDecompChol.cxx:34
 TDecompChol.cxx:35
 TDecompChol.cxx:36
 TDecompChol.cxx:37
 TDecompChol.cxx:38
 TDecompChol.cxx:39
 TDecompChol.cxx:40
 TDecompChol.cxx:41
 TDecompChol.cxx:42
 TDecompChol.cxx:43
 TDecompChol.cxx:44
 TDecompChol.cxx:45
 TDecompChol.cxx:46
 TDecompChol.cxx:47
 TDecompChol.cxx:48
 TDecompChol.cxx:49
 TDecompChol.cxx:50
 TDecompChol.cxx:51
 TDecompChol.cxx:52
 TDecompChol.cxx:53
 TDecompChol.cxx:54
 TDecompChol.cxx:55
 TDecompChol.cxx:56
 TDecompChol.cxx:57
 TDecompChol.cxx:58
 TDecompChol.cxx:59
 TDecompChol.cxx:60
 TDecompChol.cxx:61
 TDecompChol.cxx:62
 TDecompChol.cxx:63
 TDecompChol.cxx:64
 TDecompChol.cxx:65
 TDecompChol.cxx:66
 TDecompChol.cxx:67
 TDecompChol.cxx:68
 TDecompChol.cxx:69
 TDecompChol.cxx:70
 TDecompChol.cxx:71
 TDecompChol.cxx:72
 TDecompChol.cxx:73
 TDecompChol.cxx:74
 TDecompChol.cxx:75
 TDecompChol.cxx:76
 TDecompChol.cxx:77
 TDecompChol.cxx:78
 TDecompChol.cxx:79
 TDecompChol.cxx:80
 TDecompChol.cxx:81
 TDecompChol.cxx:82
 TDecompChol.cxx:83
 TDecompChol.cxx:84
 TDecompChol.cxx:85
 TDecompChol.cxx:86
 TDecompChol.cxx:87
 TDecompChol.cxx:88
 TDecompChol.cxx:89
 TDecompChol.cxx:90
 TDecompChol.cxx:91
 TDecompChol.cxx:92
 TDecompChol.cxx:93
 TDecompChol.cxx:94
 TDecompChol.cxx:95
 TDecompChol.cxx:96
 TDecompChol.cxx:97
 TDecompChol.cxx:98
 TDecompChol.cxx:99
 TDecompChol.cxx:100
 TDecompChol.cxx:101
 TDecompChol.cxx:102
 TDecompChol.cxx:103
 TDecompChol.cxx:104
 TDecompChol.cxx:105
 TDecompChol.cxx:106
 TDecompChol.cxx:107
 TDecompChol.cxx:108
 TDecompChol.cxx:109
 TDecompChol.cxx:110
 TDecompChol.cxx:111
 TDecompChol.cxx:112
 TDecompChol.cxx:113
 TDecompChol.cxx:114
 TDecompChol.cxx:115
 TDecompChol.cxx:116
 TDecompChol.cxx:117
 TDecompChol.cxx:118
 TDecompChol.cxx:119
 TDecompChol.cxx:120
 TDecompChol.cxx:121
 TDecompChol.cxx:122
 TDecompChol.cxx:123
 TDecompChol.cxx:124
 TDecompChol.cxx:125
 TDecompChol.cxx:126
 TDecompChol.cxx:127
 TDecompChol.cxx:128
 TDecompChol.cxx:129
 TDecompChol.cxx:130
 TDecompChol.cxx:131
 TDecompChol.cxx:132
 TDecompChol.cxx:133
 TDecompChol.cxx:134
 TDecompChol.cxx:135
 TDecompChol.cxx:136
 TDecompChol.cxx:137
 TDecompChol.cxx:138
 TDecompChol.cxx:139
 TDecompChol.cxx:140
 TDecompChol.cxx:141
 TDecompChol.cxx:142
 TDecompChol.cxx:143
 TDecompChol.cxx:144
 TDecompChol.cxx:145
 TDecompChol.cxx:146
 TDecompChol.cxx:147
 TDecompChol.cxx:148
 TDecompChol.cxx:149
 TDecompChol.cxx:150
 TDecompChol.cxx:151
 TDecompChol.cxx:152
 TDecompChol.cxx:153
 TDecompChol.cxx:154
 TDecompChol.cxx:155
 TDecompChol.cxx:156
 TDecompChol.cxx:157
 TDecompChol.cxx:158
 TDecompChol.cxx:159
 TDecompChol.cxx:160
 TDecompChol.cxx:161
 TDecompChol.cxx:162
 TDecompChol.cxx:163
 TDecompChol.cxx:164
 TDecompChol.cxx:165
 TDecompChol.cxx:166
 TDecompChol.cxx:167
 TDecompChol.cxx:168
 TDecompChol.cxx:169
 TDecompChol.cxx:170
 TDecompChol.cxx:171
 TDecompChol.cxx:172
 TDecompChol.cxx:173
 TDecompChol.cxx:174
 TDecompChol.cxx:175
 TDecompChol.cxx:176
 TDecompChol.cxx:177
 TDecompChol.cxx:178
 TDecompChol.cxx:179
 TDecompChol.cxx:180
 TDecompChol.cxx:181
 TDecompChol.cxx:182
 TDecompChol.cxx:183
 TDecompChol.cxx:184
 TDecompChol.cxx:185
 TDecompChol.cxx:186
 TDecompChol.cxx:187
 TDecompChol.cxx:188
 TDecompChol.cxx:189
 TDecompChol.cxx:190
 TDecompChol.cxx:191
 TDecompChol.cxx:192
 TDecompChol.cxx:193
 TDecompChol.cxx:194
 TDecompChol.cxx:195
 TDecompChol.cxx:196
 TDecompChol.cxx:197
 TDecompChol.cxx:198
 TDecompChol.cxx:199
 TDecompChol.cxx:200
 TDecompChol.cxx:201
 TDecompChol.cxx:202
 TDecompChol.cxx:203
 TDecompChol.cxx:204
 TDecompChol.cxx:205
 TDecompChol.cxx:206
 TDecompChol.cxx:207
 TDecompChol.cxx:208
 TDecompChol.cxx:209
 TDecompChol.cxx:210
 TDecompChol.cxx:211
 TDecompChol.cxx:212
 TDecompChol.cxx:213
 TDecompChol.cxx:214
 TDecompChol.cxx:215
 TDecompChol.cxx:216
 TDecompChol.cxx:217
 TDecompChol.cxx:218
 TDecompChol.cxx:219
 TDecompChol.cxx:220
 TDecompChol.cxx:221
 TDecompChol.cxx:222
 TDecompChol.cxx:223
 TDecompChol.cxx:224
 TDecompChol.cxx:225
 TDecompChol.cxx:226
 TDecompChol.cxx:227
 TDecompChol.cxx:228
 TDecompChol.cxx:229
 TDecompChol.cxx:230
 TDecompChol.cxx:231
 TDecompChol.cxx:232
 TDecompChol.cxx:233
 TDecompChol.cxx:234
 TDecompChol.cxx:235
 TDecompChol.cxx:236
 TDecompChol.cxx:237
 TDecompChol.cxx:238
 TDecompChol.cxx:239
 TDecompChol.cxx:240
 TDecompChol.cxx:241
 TDecompChol.cxx:242
 TDecompChol.cxx:243
 TDecompChol.cxx:244
 TDecompChol.cxx:245
 TDecompChol.cxx:246
 TDecompChol.cxx:247
 TDecompChol.cxx:248
 TDecompChol.cxx:249
 TDecompChol.cxx:250
 TDecompChol.cxx:251
 TDecompChol.cxx:252
 TDecompChol.cxx:253
 TDecompChol.cxx:254
 TDecompChol.cxx:255
 TDecompChol.cxx:256
 TDecompChol.cxx:257
 TDecompChol.cxx:258
 TDecompChol.cxx:259
 TDecompChol.cxx:260
 TDecompChol.cxx:261
 TDecompChol.cxx:262
 TDecompChol.cxx:263
 TDecompChol.cxx:264
 TDecompChol.cxx:265
 TDecompChol.cxx:266
 TDecompChol.cxx:267
 TDecompChol.cxx:268
 TDecompChol.cxx:269
 TDecompChol.cxx:270
 TDecompChol.cxx:271
 TDecompChol.cxx:272
 TDecompChol.cxx:273
 TDecompChol.cxx:274
 TDecompChol.cxx:275
 TDecompChol.cxx:276
 TDecompChol.cxx:277
 TDecompChol.cxx:278
 TDecompChol.cxx:279
 TDecompChol.cxx:280
 TDecompChol.cxx:281
 TDecompChol.cxx:282
 TDecompChol.cxx:283
 TDecompChol.cxx:284
 TDecompChol.cxx:285
 TDecompChol.cxx:286
 TDecompChol.cxx:287
 TDecompChol.cxx:288
 TDecompChol.cxx:289
 TDecompChol.cxx:290
 TDecompChol.cxx:291
 TDecompChol.cxx:292
 TDecompChol.cxx:293
 TDecompChol.cxx:294
 TDecompChol.cxx:295
 TDecompChol.cxx:296
 TDecompChol.cxx:297
 TDecompChol.cxx:298
 TDecompChol.cxx:299
 TDecompChol.cxx:300
 TDecompChol.cxx:301
 TDecompChol.cxx:302
 TDecompChol.cxx:303
 TDecompChol.cxx:304
 TDecompChol.cxx:305
 TDecompChol.cxx:306
 TDecompChol.cxx:307
 TDecompChol.cxx:308
 TDecompChol.cxx:309
 TDecompChol.cxx:310
 TDecompChol.cxx:311
 TDecompChol.cxx:312
 TDecompChol.cxx:313
 TDecompChol.cxx:314
 TDecompChol.cxx:315
 TDecompChol.cxx:316
 TDecompChol.cxx:317
 TDecompChol.cxx:318
 TDecompChol.cxx:319
 TDecompChol.cxx:320
 TDecompChol.cxx:321
 TDecompChol.cxx:322
 TDecompChol.cxx:323
 TDecompChol.cxx:324
 TDecompChol.cxx:325
 TDecompChol.cxx:326
 TDecompChol.cxx:327
 TDecompChol.cxx:328
 TDecompChol.cxx:329
 TDecompChol.cxx:330
 TDecompChol.cxx:331
 TDecompChol.cxx:332
 TDecompChol.cxx:333
 TDecompChol.cxx:334
 TDecompChol.cxx:335
 TDecompChol.cxx:336
 TDecompChol.cxx:337
 TDecompChol.cxx:338
 TDecompChol.cxx:339
 TDecompChol.cxx:340
 TDecompChol.cxx:341
 TDecompChol.cxx:342
 TDecompChol.cxx:343
 TDecompChol.cxx:344
 TDecompChol.cxx:345
 TDecompChol.cxx:346
 TDecompChol.cxx:347
 TDecompChol.cxx:348
 TDecompChol.cxx:349
 TDecompChol.cxx:350
 TDecompChol.cxx:351
 TDecompChol.cxx:352
 TDecompChol.cxx:353
 TDecompChol.cxx:354
 TDecompChol.cxx:355
 TDecompChol.cxx:356
 TDecompChol.cxx:357
 TDecompChol.cxx:358
 TDecompChol.cxx:359
 TDecompChol.cxx:360
 TDecompChol.cxx:361
 TDecompChol.cxx:362
 TDecompChol.cxx:363
 TDecompChol.cxx:364
 TDecompChol.cxx:365
 TDecompChol.cxx:366
 TDecompChol.cxx:367
 TDecompChol.cxx:368
 TDecompChol.cxx:369
 TDecompChol.cxx:370
 TDecompChol.cxx:371
 TDecompChol.cxx:372
 TDecompChol.cxx:373
 TDecompChol.cxx:374
 TDecompChol.cxx:375
 TDecompChol.cxx:376
 TDecompChol.cxx:377
 TDecompChol.cxx:378
 TDecompChol.cxx:379
 TDecompChol.cxx:380
 TDecompChol.cxx:381
 TDecompChol.cxx:382
 TDecompChol.cxx:383
 TDecompChol.cxx:384
 TDecompChol.cxx:385
 TDecompChol.cxx:386
 TDecompChol.cxx:387
 TDecompChol.cxx:388
 TDecompChol.cxx:389
 TDecompChol.cxx:390
 TDecompChol.cxx:391
 TDecompChol.cxx:392
 TDecompChol.cxx:393
 TDecompChol.cxx:394
 TDecompChol.cxx:395
 TDecompChol.cxx:396
 TDecompChol.cxx:397
 TDecompChol.cxx:398
 TDecompChol.cxx:399
 TDecompChol.cxx:400
 TDecompChol.cxx:401
 TDecompChol.cxx:402
 TDecompChol.cxx:403
 TDecompChol.cxx:404
 TDecompChol.cxx:405
 TDecompChol.cxx:406
 TDecompChol.cxx:407
 TDecompChol.cxx:408
 TDecompChol.cxx:409
 TDecompChol.cxx:410
 TDecompChol.cxx:411
 TDecompChol.cxx:412
 TDecompChol.cxx:413
 TDecompChol.cxx:414
 TDecompChol.cxx:415
 TDecompChol.cxx:416
 TDecompChol.cxx:417
 TDecompChol.cxx:418
 TDecompChol.cxx:419
 TDecompChol.cxx:420
 TDecompChol.cxx:421
 TDecompChol.cxx:422
 TDecompChol.cxx:423
 TDecompChol.cxx:424
 TDecompChol.cxx:425
 TDecompChol.cxx:426
 TDecompChol.cxx:427
 TDecompChol.cxx:428
 TDecompChol.cxx:429
 TDecompChol.cxx:430
 TDecompChol.cxx:431
 TDecompChol.cxx:432
 TDecompChol.cxx:433
 TDecompChol.cxx:434
 TDecompChol.cxx:435
 TDecompChol.cxx:436
 TDecompChol.cxx:437
 TDecompChol.cxx:438
 TDecompChol.cxx:439
 TDecompChol.cxx:440
 TDecompChol.cxx:441
 TDecompChol.cxx:442
 TDecompChol.cxx:443
 TDecompChol.cxx:444
 TDecompChol.cxx:445
 TDecompChol.cxx:446
 TDecompChol.cxx:447
 TDecompChol.cxx:448
 TDecompChol.cxx:449
 TDecompChol.cxx:450
 TDecompChol.cxx:451
 TDecompChol.cxx:452
 TDecompChol.cxx:453
 TDecompChol.cxx:454
 TDecompChol.cxx:455
 TDecompChol.cxx:456
 TDecompChol.cxx:457
 TDecompChol.cxx:458
 TDecompChol.cxx:459
 TDecompChol.cxx:460
 TDecompChol.cxx:461
 TDecompChol.cxx:462
 TDecompChol.cxx:463
 TDecompChol.cxx:464
 TDecompChol.cxx:465
 TDecompChol.cxx:466
 TDecompChol.cxx:467
 TDecompChol.cxx:468
 TDecompChol.cxx:469
 TDecompChol.cxx:470
 TDecompChol.cxx:471
 TDecompChol.cxx:472
 TDecompChol.cxx:473
 TDecompChol.cxx:474