// @(#)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.             *
 *************************************************************************/

///////////////////////////////////////////////////////////////////////////
//                                                                       //
// Decomposition Base class                                              //
//                                                                       //
// This class forms the base for all the decompositions methods in the   //
// linear algebra package .                                              //
// It or its derived classes have installed the methods to solve         //
// equations,invert matrices and calculate determinants while monitoring //
// the accuracy.                                                         //
//                                                                       //
// Each derived class has always the following methods available:        //
//                                                                       //
// Condition() :                                                         //
//   In an iterative scheme the condition number for matrix inversion is //
//   calculated . This number is of interest for estimating the accuracy //
//   of x in the equation Ax=b                                           //
//   For example:                                                        //
//     A is a (10x10) Hilbert matrix which looks deceivingly innocent    //
//     and simple, A(i,j) = 1/(i+j+1)                                    //
//     b(i) = Sum_j A(i,j), so a sum of a row in A                       //
//                                                                       //
//     the solution is x(i) = 1. i=0,.,9                                 //
//                                                                       //
//   However,                                                            //
//     TMatrixD m....; TVectorD b.....                                   //
//     TDecompLU lu(m); lu.SetTol(1.0e-12); lu.Solve(b); b.Print()       //
//   gives,                                                              //
//                                                                       //
//   {1.000,1.000,1.000,1.000,0.998,1.000,0.993,1.001,0.996,1.000}       //
//                                                                       //
//   Looking at the condition number, this is in line with expected the  //
//   accuracy . The condition number is 3.957e+12 . As a simple rule of  //
//   thumb, a condition number of 1.0e+n means that you lose up to n     //
//   digits of accuracy in a solution . Since doubles are stored with 15 //
//   digits, we can expect the accuracy to be as small as 3 digits .     //
//                                                                       //
// Det(Double_t &d1,Double_t &d2)                                        //
//   The determinant is d1*TMath::Power(2.,d2)                           //
//   Expressing the determinant this way makes under/over-flow very      //
//   unlikely .                                                          //
//                                                                       //
// Decompose()                                                           //
//   Here the actually decomposition is performed . One can change the   //
//   matrix A after the decomposition constructor has been called        //
//   without effecting the decomposition result                          //
//                                                                       //
// Solve(TVectorD &b)                                                    //
//  Solve A x = b . x is supplied through the argument and replaced with //
//  the solution .                                                       //
//                                                                       //
// TransSolve(TVectorD &b)                                               //
//  Solve A^T x = b . x is supplied through the argument and replaced    //
//  with the solution .                                                  //
//                                                                       //
// MultiSolve(TMatrixD    &B)                                            //
//  Solve A X = B . where X and are now matrices . X is supplied through //
//  the argument and replaced with the solution .                        //
//                                                                       //
// Invert(TMatrixD &inv)                                                 //
//  This is of course just a call to MultiSolve with as input argument   //
//  the unit matrix . Note that for a matrix a(m,n) with m > n  a        //
//  pseudo-inverse is calculated .                                       //
//                                                                       //
// Tolerances and Scaling                                                //
// ----------------------                                                //
// The tolerance parameter (which is a member of this base class) plays  //
// a crucial role in all operations of the decomposition classes . It    //
// gives the user a powerful tool to monitor and steer the operations    //
// Its default value is sqrt(epsilon) where 1+epsilon = 1                //
//                                                                       //
// If you do not want to be bothered by the following considerations,    //
// like in most other linear algebra packages, just set the tolerance    //
// with SetTol to an arbitrary small number .                            //
//                                                                       //
// The tolerance number is used by each decomposition method to decide   //
// whether the matrix is near singular, except of course SVD which can   //
// handle singular matrices .                                            //
// For each decomposition this will be checked in a different way; in LU //
// the matrix is considered singular when, at some point in the          //
// decomposition, a diagonal element < fTol . Therefore, we had to set in//
// the example above of the (10x10) Hilbert, which is near singular, the //
// tolerance on 10e-12 . (The fact that we have to set the tolerance <   //
// sqrt(epsilon) is a clear indication that we are losing precision .)   //
//                                                                       //
// If the matrix is flagged as being singular, operations with the       //
// decomposition will fail and will return matrices/vectors that are     //
// invalid .                                                             //
//                                                                       //
// The observant reader will notice that by scaling the complete matrix  //
// by some small number the decomposition will detect a singular matrix .//
// In this case the user will have to reduce the tolerance number by this//
// factor . (For CPU time saving we decided not to make this an automatic//
// procedure) .                                                          //
//                                                                       //
// Code for this could look as follows:                                  //
// const Double_t max_abs = Abs(a).Max();                                //
// const Double_t scale = TMath::Min(max_abs,1.);                        //
// a.SetTol(a.GetTol()*scale);                                           //
//                                                                       //
// For usage examples see $ROOTSYS/test/stressLinear.cxx                 //
///////////////////////////////////////////////////////////////////////////

#include "TDecompBase.h"
#include "TMath.h"
#include "TError.h"

ClassImp(TDecompBase)

//______________________________________________________________________________
TDecompBase::TDecompBase()
{
// Default constructor

   fTol       = std::numeric_limits<double>::epsilon();
   fDet1      = 0;
   fDet2      = 0;
   fCondition = -1.0;
   fRowLwb    = 0;
   fColLwb    = 0;
}

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

   *this = another;
}

//______________________________________________________________________________
Int_t TDecompBase::Hager(Double_t &est,Int_t iter)
{

// Estimates lower bound for norm1 of inverse of A. Returns norm
// estimate in est.  iter sets the maximum number of iterations to be used.
// The return value indicates the number of iterations remaining on exit from
// loop, hence if this is non-zero the processed "converged".
// This routine uses Hager's Convex Optimisation Algorithm.
// See Applied Numerical Linear Algebra, p139 & SIAM J Sci Stat Comp 1984 pp 311-16

   est = -1.0;

   const TMatrixDBase &m = GetDecompMatrix();
   if (!m.IsValid())
      return iter;

   const Int_t n = m.GetNrows();

   TVectorD b(n); TVectorD y(n); TVectorD z(n);
   b = Double_t(1.0/n);
   Double_t inv_norm1 = 0.0;
   Bool_t stop = kFALSE;
   do {
      y = b;
      if (!Solve(y))
         return iter;
      const Double_t ynorm1 = y.Norm1();
      if ( ynorm1 <= inv_norm1 ) {
         stop = kTRUE;
      } else {
         inv_norm1 = ynorm1;
         Int_t i;
         for (i = 0; i < n; i++)
            z(i) = ( y(i) >= 0.0 ? 1.0 : -1.0 );
         if (!TransSolve(z))
            return iter;
         Int_t imax = 0;
         Double_t maxz = TMath::Abs(z(0));
         for (i = 1; i < n; i++) {
            const Double_t absz = TMath::Abs(z(i));
            if ( absz > maxz ) {
               maxz = absz;
               imax = i;
            }
         }
         stop = (maxz <= b*z);
         if (!stop) {
            b = 0.0;
            b(imax) = 1.0;
         }
      }
      iter--;
   } while (!stop && iter);
   est = inv_norm1;

   return iter;
}

//______________________________________________________________________________
void TDecompBase::DiagProd(const TVectorD &diag,Double_t tol,Double_t &d1,Double_t &d2)
{

// Returns product of matrix diagonal elements in d1 and d2. d1 is a mantissa and d2
// an exponent for powers of 2. If matrix is in diagonal or triangular-matrix form this
// will be the determinant.
// Based on Bowler, Martin, Peters and Wilkinson in HACLA

   const Double_t zero      = 0.0;
   const Double_t one       = 1.0;
   const Double_t four      = 4.0;
   const Double_t sixteen   = 16.0;
   const Double_t sixteenth = 0.0625;

   const Int_t n = diag.GetNrows();

   Double_t t1 = 1.0;
   Double_t t2 = 0.0;
   Int_t niter2 =0;
   Int_t niter3 =0;
   for (Int_t i = 0; (((i < n) && (t1 !=zero ))); i++) {
      if (TMath::Abs(diag(i)) > tol) {
         t1 *= (Double_t) diag(i);
         while ( TMath::Abs(t1) < one) {
            t1 *= sixteenth;
            t2 += four;
            niter2++;
            if ( niter2>100) break;
         }
         while ( TMath::Abs(t1) < sixteenth)  {
            t1 *= sixteen;
            t2 -= four;
            niter3++;
            if (niter3>100) break;
         }
      } else {
         t1 = zero;
         t2 = zero;
      }
   }
   d1 = t1;
   d2 = t2;

   return;
}

//______________________________________________________________________________
Double_t TDecompBase::Condition()
{
// Matrix condition number

   if ( !TestBit(kCondition) ) {
      fCondition = -1;
      if (TestBit(kSingular))
         return fCondition;
      if ( !TestBit(kDecomposed) ) {
         if (!Decompose())
            return fCondition;
      }
      Double_t invNorm;
      if (Hager(invNorm))
         fCondition *= invNorm;
      else // no convergence in Hager
         Error("Condition()","Hager procedure did NOT converge");
      SetBit(kCondition);
   }
   return fCondition;
}

//______________________________________________________________________________
Bool_t TDecompBase::MultiSolve(TMatrixD &B)
{
// Solve set of equations with RHS in columns of B

   const TMatrixDBase &m = GetDecompMatrix();
   R__ASSERT(m.IsValid() && B.IsValid());

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

   return status;
}

//______________________________________________________________________________
void TDecompBase::Det(Double_t &d1,Double_t &d2)
{
// Matrix determinant det = d1*TMath::Power(2.,d2)

   if ( !TestBit(kDetermined) ) {
      if ( !TestBit(kDecomposed) )
         Decompose();
      if (TestBit(kSingular) ) {
         fDet1 = 0.0;
         fDet2 = 0.0;
      } else {
         const TMatrixDBase &m = GetDecompMatrix();
         R__ASSERT(m.IsValid());
         TVectorD diagv(m.GetNrows());
         for (Int_t i = 0; i < diagv.GetNrows(); i++)
            diagv(i) = m(i,i);
         DiagProd(diagv,fTol,fDet1,fDet2);
      }
      SetBit(kDetermined);
   }
   d1 = fDet1;
   d2 = fDet2;
}

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

   printf("fTol       = %.4e\n",fTol);
   printf("fDet1      = %.4e\n",fDet1);
   printf("fDet2      = %.4e\n",fDet2);
   printf("fCondition = %.4e\n",fCondition);
   printf("fRowLwb    = %d\n",fRowLwb);
   printf("fColLwb    = %d\n",fColLwb);
}

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

   if (this != &source) {
      TObject::operator=(source);
      fTol       = source.fTol;
      fDet1      = source.fDet1;
      fDet2      = source.fDet2;
      fCondition = source.fCondition;
      fRowLwb    = source.fRowLwb;
      fColLwb    = source.fColLwb;
   }
   return *this;
}

//______________________________________________________________________________
Bool_t DefHouseHolder(const TVectorD &vc,Int_t lp,Int_t l,Double_t &up,Double_t &beta,
                      Double_t tol)
{
// Define a Householder-transformation through the parameters up and b .

   const Int_t n = vc.GetNrows();
   const Double_t * const vp = vc.GetMatrixArray();

   Double_t c = TMath::Abs(vp[lp]);
   Int_t i;
   for (i = l; i < n; i++)
      c = TMath::Max(TMath::Abs(vp[i]),c);

   up   = 0.0;
   beta = 0.0;
   if (c <= tol) {
//     Warning("DefHouseHolder","max vector=%.4e < %.4e",c,tol);
      return kFALSE;
   }

   Double_t sd = vp[lp]/c; sd *= sd;
   for (i = l; i < n; i++) {
      const Double_t tmp = vp[i]/c;
      sd += tmp*tmp;
   }

   Double_t vpprim = c*TMath::Sqrt(sd);
   if (vp[lp] > 0.) vpprim = -vpprim;
   up = vp[lp]-vpprim;
   beta = 1./(vpprim*up);

   return kTRUE;
}

//______________________________________________________________________________
void ApplyHouseHolder(const TVectorD &vc,Double_t up,Double_t beta,
                      Int_t lp,Int_t l,TMatrixDRow &cr)
{
// Apply Householder-transformation.

   const Int_t nv = vc.GetNrows();
   const Int_t nc = (cr.GetMatrix())->GetNcols();

   if (nv > nc) {
      Error("ApplyHouseHolder(const TVectorD &,..,TMatrixDRow &)","matrix row too short");
      return;
   }

   const Int_t inc_c = cr.GetInc();
   const Double_t * const vp = vc.GetMatrixArray();
         Double_t *       cp = cr.GetPtr();

   Double_t s = cp[lp*inc_c]*up;
   Int_t i;
   for (i = l; i < nv; i++)
      s += cp[i*inc_c]*vp[i];

   s = s*beta;
   cp[lp*inc_c] += s*up;
   for (i = l; i < nv; i++)
      cp[i*inc_c] += s*vp[i];
}

//______________________________________________________________________________
void ApplyHouseHolder(const TVectorD &vc,Double_t up,Double_t beta,
                      Int_t lp,Int_t l,TMatrixDColumn &cc)
{
// Apply Householder-transformation.

   const Int_t nv = vc.GetNrows();
   const Int_t nc = (cc.GetMatrix())->GetNrows();

   if (nv > nc) {
      Error("ApplyHouseHolder(const TVectorD &,..,TMatrixDRow &)","matrix column too short");
      return;
   }

   const Int_t inc_c = cc.GetInc();
   const Double_t * const vp = vc.GetMatrixArray();
         Double_t *       cp = cc.GetPtr();

   Double_t s = cp[lp*inc_c]*up;
   Int_t i;
   for (i = l; i < nv; i++)
      s += cp[i*inc_c]*vp[i];

   s = s*beta;
   cp[lp*inc_c] += s*up;
   for (i = l; i < nv; i++)
      cp[i*inc_c] += s*vp[i];
}

//______________________________________________________________________________
void ApplyHouseHolder(const TVectorD &vc,Double_t up,Double_t beta,
                      Int_t lp,Int_t l,TVectorD &cv)
{
//  Apply Householder-transformation.

   const Int_t nv = vc.GetNrows();
   const Int_t nc = cv.GetNrows();

   if (nv > nc) {
      Error("ApplyHouseHolder(const TVectorD &,..,TVectorD &)","vector too short");
      return;
   }

   const Double_t * const vp = vc.GetMatrixArray();
         Double_t *       cp = cv.GetMatrixArray();

   Double_t s = cp[lp]*up;
   Int_t i;
   for (i = l; i < nv; i++)
      s += cp[i]*vp[i];

   s = s*beta;
   cp[lp] += s*up;
   for (i = l; i < nv; i++)
      cp[i] += s*vp[i];
}

//______________________________________________________________________________
void DefGivens(Double_t v1,Double_t v2,Double_t &c,Double_t &s)
{
// Defines a Givens-rotation by calculating 2 rotation parameters c and s.
// The rotation is defined with the vector components v1 and v2.

   const Double_t a1 = TMath::Abs(v1);
   const Double_t a2 = TMath::Abs(v2);
   if (a1 > a2) {
      const Double_t w = v2/v1;
      const Double_t q = TMath::Hypot(1.,w);
      c = 1./q;
      if (v1 < 0.) c = -c;
      s = c*w;
   } else {
      if (v2 != 0) {
         const Double_t w = v1/v2;
         const Double_t q = TMath::Hypot(1.,w);
         s = 1./q;
         if (v2 < 0.) s = -s;
         c = s*w;
      } else {
         c = 1.;
         s = 0.;
      }
   }
}

//______________________________________________________________________________
void DefAplGivens(Double_t &v1,Double_t &v2,Double_t &c,Double_t &s)
{
// Define and apply a Givens-rotation by calculating 2 rotation
// parameters c and s. The rotation is defined with and applied to the vector
// components v1 and v2.

   const Double_t a1 = TMath::Abs(v1);
   const Double_t a2 = TMath::Abs(v2);
   if (a1 > a2) {
      const Double_t w = v2/v1;
      const Double_t q = TMath::Hypot(1.,w);
      c = 1./q;
      if (v1 < 0.) c = -c;
      s  = c*w;
      v1 = a1*q;
      v2 = 0.;
   } else {
      if (v2 != 0) {
         const Double_t w = v1/v2;
         const Double_t q = TMath::Hypot(1.,w);
         s = 1./q;
         if (v2 < 0.) s = -s;
         c  = s*w;
         v1 = a2*q;
         v2 = 0.;
      } else {
         c = 1.;
         s = 0.;
      }
   }
}

//______________________________________________________________________________
void ApplyGivens(Double_t &z1,Double_t &z2,Double_t c,Double_t s)
{
// Apply a Givens transformation as defined by c and s to the vector compenents
// v1 and v2 .

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