ROOT logo
// Author: Kerstin Tackmann, Andreas Hoecker, Heiko Lacker

/**********************************************************************************
 *                                                                                *
 * Project: TSVDUnfold - data unfolding based on Singular Value Decomposition     *
 * Package: ROOT                                                                  *
 * Class  : TSVDUnfold                                                            *
 *                                                                                *
 * Description:                                                                   *
 *      Single class implementation of SVD data unfolding based on:               *
 *          A. Hoecker, V. Kartvelishvili,                                        *
 *          "SVD approach to data unfolding"                                      *
 *          NIM A372, 469 (1996) [hep-ph/9509307]                                 *
 *                                                                                *
 * Authors:                                                                       *
 *      Kerstin Tackmann <Kerstin.Tackmann@cern.ch>   - CERN, Switzerland         *
 *      Andreas Hoecker  <Andreas.Hoecker@cern.ch>    - CERN, Switzerland         *
 *      Heiko Lacker     <lacker@physik.hu-berlin.de> - Humboldt U, Germany       *
 *                                                                                *
 * Copyright (c) 2010:                                                            *
 *      CERN, Switzerland                                                         *
 *      Humboldt University, Germany                                              *
 *                                                                                *
 **********************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSVDUnfold                                                           //
//                                                                      //
// Data unfolding using Singular Value Decomposition (hep-ph/9509307)   //
// Authors: Kerstin Tackmann, Andreas Hoecker, Heiko Lacker             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//_______________________________________________________________________
/* Begin_Html
<center><h2>SVD Approach to Data Unfolding</h2></center>
<p>
Reference: <a href="http://arXiv.org/abs/hep-ph/9509307">Nucl. Instrum. Meth. A372, 469 (1996) [hep-ph/9509307]</a>
<p>
TSVDUnfold implements the singular value decomposition based unfolding method (see reference). Currently, the unfolding of one-dimensional histograms is supported, with the same number of bins for the measured and the unfolded spectrum.
<p>
The unfolding procedure is based on singular value decomposition of the response matrix. The regularisation of the unfolding is implemented via a discrete minimum-curvature condition.
<p>
Monte Carlo inputs:
<ul>
<li><tt>xini</tt>: true underlying spectrum (TH1D, n bins)
<li><tt>bini</tt>: reconstructed spectrum (TH1D, n bins)
<li><tt>Adet</tt>: response matrix (TH2D, nxn bins)
</ul>
Consider the unfolding of a measured spectrum <tt>bdat</tt>. The corresponding spectrum in the Monte Carlo is given by <tt>bini</tt>, with the true underlying spectrum given by <tt>xini</tt>. The detector response is described by <tt>Adet</tt>, with <tt>Adet</tt> filled with events (not probabilities) with the true observable on the y-axis and the reconstructed observable on the x-axis.
<p>
The measured distribution can be unfolded for any combination of resolution, efficiency and acceptance effects, provided an appropriate definition of <tt>xini</tt> and <tt>Adet</tt>.<br><br>
<p>
The unfolding can be performed by
<ul>
<pre>
TSVDUnfold *tsvdunf = new TSVDUnfold();
tsvdunf->Init( bdat, bini, xini, Adet );
TH1D* unfresult = tsvdunf->Unfold(kreg);
</pre>
</ul>
where <tt>kreg</tt> determines the regularisation of the unfolding. In general, overregularisation (too small <tt>kreg</tt>) will bias the unfolded spectrum towards the Monte Carlo input, while underregularisation (too large <tt>kreg</tt>) will lead to large fluctuations in the unfolded spectrum. The optimal regularisation can be determined following guidelines in <a href="http://arXiv.org/abs/hep-ph/9509307">Nucl. Instrum. Meth. A372, 469 (1996) [hep-ph/9509307]</a> using the distribution of the <tt>|d_i|<\tt> that can be obtained by <tt>tsvdunf->GetD()</tt> and/or using pseudo-experiments.
<p>
Covariance matrices on the measured spectrum can be propagated to covariance matrices using the <tt>GetUnfoldCovMatrix</tt> method, which uses pseudo experiments for the propagation. In addition, <tt>GetAdetCovMatrix</tt> allows for the propagation of the statistical uncertainties on the response matrix using pseudo experiments. In addition, the distribution of singular values can be retrieved using <tt>tsvdunf->GetSV()<\tt>.
End_Html */
//_______________________________________________________________________


#include <iostream>

#include "TSVDUnfold.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TDecompSVD.h"
#include "TRandom3.h"
#include "TMath.h"

ClassImp(TSVDUnfold)

using namespace std;

//_______________________________________________________________________
TSVDUnfold::TSVDUnfold( const TH1D *bdat, const TH1D *bini, const TH1D *xini, const TH2D *Adet )
   : TObject     (),
     fNdim       (0),
     fDdim       (2),
     fNormalize  (kFALSE),
     fKReg       (-1),
     fDHist      (NULL),
     fSVHist     (NULL),
     fBdat       (bdat), 
     fBini       (bini),
     fXini       (xini),
     fAdet       (Adet), 
     fToyhisto   (NULL),
     fToymat     (NULL),
     fToyMode    (kFALSE),
     fMatToyMode (kFALSE) 
{
   // Default constructor

   // Initialisation of TSVDUnfold
   // User provides data and MC test spectra, as well as detector response matrix
   if (bdat->GetNbinsX() != bini->GetNbinsX() || 
       bdat->GetNbinsX() != xini->GetNbinsX() ||
       bdat->GetNbinsX() != Adet->GetNbinsX() ||
       bdat->GetNbinsX() != Adet->GetNbinsY()) {
      TString msg = "All histograms must have equal dimension.\n";
      msg += Form( "  Found: dim(bdat)=%i\n",    bdat->GetNbinsX() );
      msg += Form( "  Found: dim(bini)=%i\n",    bini->GetNbinsX() );
      msg += Form( "  Found: dim(xini)=%i\n",    xini->GetNbinsX() );
      msg += Form( "  Found: dim(Adet)=%i,%i\n", Adet->GetNbinsX(), Adet->GetNbinsY() );
      msg += "Please start again!";

      Fatal( "Init", msg, "%s" );
   }

   // Get the input histos
   fNdim = bdat->GetNbinsX();
   fDdim = 2; // This is the derivative used to compute the curvature matrix
}

//_______________________________________________________________________
TSVDUnfold::TSVDUnfold( const TSVDUnfold& other )
   : TObject     ( other ),
     fNdim       (other.fNdim),
     fDdim       (other.fDdim),
     fNormalize  (other.fNormalize),
     fKReg       (other.fKReg),
     fDHist      (other.fDHist),
     fSVHist     (other.fSVHist),
     fBdat       (other.fBdat),
     fBini       (other.fBini),
     fXini       (other.fXini),
     fAdet       (other.fAdet),
     fToyhisto   (other.fToyhisto),
     fToymat     (other.fToymat),
     fToyMode    (other.fToyMode),
     fMatToyMode (other.fMatToyMode) 
{
   // Copy constructor
}

//_______________________________________________________________________
TSVDUnfold::~TSVDUnfold()
{
   // Destructor
}

//_______________________________________________________________________
TH1D* TSVDUnfold::Unfold( Int_t kreg )
{
   // Perform the unfolding   
   fKReg = kreg;
   
   // Make the histos
   if (!fToyMode && !fMatToyMode) InitHistos( );

   // Create vectors and matrices
   TVectorD vb(fNdim), vbini(fNdim), vxini(fNdim), vberr(fNdim);
   TMatrixD mA(fNdim, fNdim), mCurv(fNdim, fNdim), mC(fNdim, fNdim);

   Double_t eps = 1e-12;
   Double_t sreg;

   // Copy histogams entries into vector
   if (fToyMode) { H2V( fToyhisto, vb ); H2Verr( fToyhisto, vberr ); }
   else          { H2V( fBdat,     vb ); H2Verr( fBdat,     vberr ); }

   H2V( fBini, vbini );
   H2V( fXini, vxini );
   if (fMatToyMode) H2M( fToymat, mA );
   else        H2M( fAdet,   mA );

   // Scale the MC vectors to data norm
   Double_t scale = vb.Sum()/vbini.Sum();
   vbini *= scale;
   vxini *= scale;
   mA    *= scale;
  
   // Fill and invert the second derivative matrix
   FillCurvatureMatrix( mCurv, mC );

   // Inversion of mC by help of SVD
   TDecompSVD CSVD(mC);
   TMatrixD CUort = CSVD.GetU();
   TMatrixD CVort = CSVD.GetV();
   TVectorD CSV   = CSVD.GetSig();

   TMatrixD CSVM(fNdim, fNdim);
   for (Int_t i=0; i<fNdim; i++) CSVM(i,i) = 1/CSV(i);

   CUort.Transpose( CUort );
   TMatrixD mCinv = (CVort*CSVM)*CUort;

   // Rescale matrix and vectors by error of data vector
   vbini = VecDiv   ( vbini, vberr );
   vb    = VecDiv   ( vb,    vberr, 1 );
   mA    = MatDivVec( mA,    vberr, 1 );
   vberr = VecDiv   ( vberr, vberr, 1 );

   // Singular value decomposition and matrix operations
   TDecompSVD ASVD( mA*mCinv );
   TMatrixD Uort = ASVD.GetU();
   TMatrixD Vort = ASVD.GetV();
   TVectorD ASV  = ASVD.GetSig();

   if (!fToyMode && !fMatToyMode) {
      V2H(ASV, *fSVHist);
   }

   TMatrixD Vreg = mCinv*Vort;

   Uort.Transpose(Uort);
   TVectorD vdini = Uort*vbini;
   TVectorD vd    = Uort*vb;

   if (!fToyMode && !fMatToyMode) {
      V2H(vd, *fDHist);
   }

   // Damping coefficient
   Int_t k = GetKReg()-1; 

   TVectorD vx(fNdim); // Return variable

   // Damping factors
   TVectorD vdz(fNdim);
   for (Int_t i=0; i<fNdim; i++) {
     if (ASV(i)<ASV(0)*eps) sreg = ASV(0)*eps;
     else                   sreg = ASV(i);
     vdz(i) = sreg/(sreg*sreg + ASV(k)*ASV(k));
   }
   TVectorD vz = CompProd( vd, vdz );
   
   // Compute the weights
   TVectorD vw = Vreg*vz;
   
   // Rescale by xini
   vx = CompProd( vw, vxini );
   
   if(fNormalize){ // Scale result to unit area
     scale = vx.Sum();
     if (scale > 0) vx *= 1.0/scale;
   }
   
   // Get Curvature and also chi2 in case of MC unfolding
   if (!fToyMode && !fMatToyMode) {
     Info( "Unfold", "Unfolding param: %i",k+1 );
     Info( "Unfold", "Curvature of weight distribution: %f", GetCurvature( vw, mCurv ) );
   }

   TH1D* h = (TH1D*)fBdat->Clone("unfoldingresult");
   for(int i=1; i<=fNdim; i++){
      h->SetBinContent(i,0.);
      h->SetBinError(i,0.);
   }
   V2H( vx, *h );

   return h;
}

//_______________________________________________________________________
TH2D* TSVDUnfold::GetUnfoldCovMatrix( const TH2D* cov, Int_t ntoys, Int_t seed )
{

   fToyMode = true;
   TH1D* unfres = 0;
   TH2D* unfcov = (TH2D*)fAdet->Clone("unfcovmat");
   for(int i=1; i<=fNdim; i++)
      for(int j=1; j<=fNdim; j++)
         unfcov->SetBinContent(i,j,0.);
  
   // Code for generation of toys (taken from RooResult and modified)
   // Calculate the elements of the upper-triangular matrix L that
   // gives Lt*L = C, where Lt is the transpose of L (the "square-root method")  
   TMatrixD L(fNdim,fNdim); L *= 0;

   for (Int_t iPar= 0; iPar < fNdim; iPar++) {

      // Calculate the diagonal term first
      L(iPar,iPar) = cov->GetBinContent(iPar+1,iPar+1);
      for (Int_t k=0; k<iPar; k++) L(iPar,iPar) -= TMath::Power( L(k,iPar), 2 );
      if (L(iPar,iPar) > 0.0) L(iPar,iPar) = TMath::Sqrt(L(iPar,iPar));
      else                    L(iPar,iPar) = 0.0;

      // ...then the off-diagonal terms
      for (Int_t jPar=iPar+1; jPar<fNdim; jPar++) {
         L(iPar,jPar) = cov->GetBinContent(iPar+1,jPar+1);
         for (Int_t k=0; k<iPar; k++) L(iPar,jPar) -= L(k,iPar)*L(k,jPar);
         if (L(iPar,iPar)!=0.) L(iPar,jPar) /= L(iPar,iPar);
         else                  L(iPar,jPar) = 0;
      }
   }

   // Remember it
   TMatrixD *Lt = new TMatrixD(TMatrixD::kTransposed,L);
   TRandom3 random(seed);

   fToyhisto = (TH1D*)fBdat->Clone("toyhisto");
   TH1D *toymean = (TH1D*)fBdat->Clone("toymean");
   for (Int_t j=1; j<=fNdim; j++) toymean->SetBinContent(j,0.);

   // Get the mean of the toys first
   for (int i=1; i<=ntoys; i++) {

      // create a vector of unit Gaussian variables
      TVectorD g(fNdim);
      for (Int_t k= 0; k < fNdim; k++) g(k) = random.Gaus(0.,1.);

      // Multiply this vector by Lt to introduce the appropriate correlations
      g *= (*Lt);

      // Add the mean value offsets and store the results
      for (int j=1; j<=fNdim; j++) {
         fToyhisto->SetBinContent(j,fBdat->GetBinContent(j)+g(j-1));
         fToyhisto->SetBinError(j,fBdat->GetBinError(j));
      }

      unfres = Unfold(GetKReg());

      for (Int_t j=1; j<=fNdim; j++) {
         toymean->SetBinContent(j, toymean->GetBinContent(j) + unfres->GetBinContent(j)/ntoys);
      }
   }

   // Reset the random seed
   random.SetSeed(seed);

   //Now the toys for the covariance matrix
   for (int i=1; i<=ntoys; i++) {

      // Create a vector of unit Gaussian variables
      TVectorD g(fNdim);
      for (Int_t k= 0; k < fNdim; k++) g(k) = random.Gaus(0.,1.);

      // Multiply this vector by Lt to introduce the appropriate correlations
      g *= (*Lt);

      // Add the mean value offsets and store the results
      for (int j=1; j<=fNdim; j++) {
         fToyhisto->SetBinContent( j, fBdat->GetBinContent(j)+g(j-1) );
         fToyhisto->SetBinError  ( j, fBdat->GetBinError(j) );
      }
      unfres = Unfold(GetKReg());

      for (Int_t j=1; j<=fNdim; j++) {
         for (Int_t k=1; k<=fNdim; k++) {
            unfcov->SetBinContent(j,k,unfcov->GetBinContent(j,k) + ( (unfres->GetBinContent(j) - toymean->GetBinContent(j))* (unfres->GetBinContent(k) - toymean->GetBinContent(k))/(ntoys-1)) );
         }
      }
   }
   delete Lt;
   delete unfres;
   fToyMode = kFALSE;
   
   return unfcov;
}

//_______________________________________________________________________
TH2D* TSVDUnfold::GetAdetCovMatrix( Int_t ntoys, Int_t seed )
{

   fMatToyMode = true;
   TH1D* unfres = 0;
   TH2D* unfcov = (TH2D*)fAdet->Clone("unfcovmat");
   for(int i=1; i<=fNdim; i++)
      for(int j=1; j<=fNdim; j++)
         unfcov->SetBinContent(i,j,0.);

   //Now the toys for the detector response matrix
   TRandom3 random(seed);

   fToymat = (TH2D*)fAdet->Clone("toymat");
   TH1D *toymean = (TH1D*)fXini->Clone("toymean");
   for (Int_t j=1; j<=fNdim; j++) toymean->SetBinContent(j,0.);

   for (int i=1; i<=ntoys; i++) {    
      for (Int_t k=1; k<=fNdim; k++) {
         for (Int_t m=1; m<=fNdim; m++) {
            if (fAdet->GetBinContent(k,m)) {
               fToymat->SetBinContent(k, m, random.Poisson(fAdet->GetBinContent(k,m)));
            }
         }
      }

      unfres = Unfold(GetKReg());

      for (Int_t j=1; j<=fNdim; j++) {
         toymean->SetBinContent(j, toymean->GetBinContent(j) + unfres->GetBinContent(j)/ntoys);
      }
   }

   // Reset the random seed
   random.SetSeed(seed);

   for (int i=1; i<=ntoys; i++) {
      for (Int_t k=1; k<=fNdim; k++) {
         for (Int_t m=1; m<=fNdim; m++) {
            if (fAdet->GetBinContent(k,m))
               fToymat->SetBinContent(k, m, random.Poisson(fAdet->GetBinContent(k,m)));
         }
      }

      unfres = Unfold(GetKReg());

      for (Int_t j=1; j<=fNdim; j++) {
         for (Int_t k=1; k<=fNdim; k++) {
            unfcov->SetBinContent(j,k,unfcov->GetBinContent(j,k) + ( (unfres->GetBinContent(j) - toymean->GetBinContent(j))*(unfres->GetBinContent(k) - toymean->GetBinContent(k))/(ntoys-1)) );
         }
      }
   }
   delete unfres;
   fMatToyMode = kFALSE;
   
   return unfcov;
}

//_______________________________________________________________________
TH1D* TSVDUnfold::GetD() const 
{ 
   // Returns d vector
   for (int i=1; i<=fDHist->GetNbinsX(); i++) {
      if (fDHist->GetBinContent(i)<0.) fDHist->SetBinContent(i, TMath::Abs(fDHist->GetBinContent(i))); 
   }
   return fDHist; 
}

//_______________________________________________________________________
TH1D* TSVDUnfold::GetSV() const 
{ 
   // Returns singular values vector
   return fSVHist; 
}

//_______________________________________________________________________
void TSVDUnfold::H2V( const TH1D* histo, TVectorD& vec )
{
   // Fill 1D histogram into vector
   for (Int_t i=0; i<histo->GetNbinsX(); i++) vec(i) = histo->GetBinContent(i+1);
}

//_______________________________________________________________________
void TSVDUnfold::H2Verr( const TH1D* histo, TVectorD& vec )
{
   // Fill 1D histogram errors into vector
   for (Int_t i=0; i<histo->GetNbinsX(); i++) vec(i) = histo->GetBinError(i+1);
}

//_______________________________________________________________________
void TSVDUnfold::V2H( const TVectorD& vec, TH1D& histo )
{
   // Fill vector into 1D histogram
   for(Int_t i=0; i<vec.GetNrows(); i++) histo.SetBinContent(i+1, vec(i));
}

//_______________________________________________________________________
void TSVDUnfold::H2M( const TH2D* histo, TMatrixD& mat )
{
   // Fill 2D histogram into matrix
   for (Int_t j=0; j<histo->GetNbinsX(); j++) {
      for (Int_t i=0; i<histo->GetNbinsY(); i++) {
         mat(i,j) = histo->GetBinContent(i+1,j+1);
      }
   }
}

//_______________________________________________________________________
TVectorD TSVDUnfold::VecDiv( const TVectorD& vec1, const TVectorD& vec2, Int_t zero )
{
   // Divide entries of two vectors
   TVectorD quot(vec1.GetNrows());
   for (Int_t i=0; i<vec1.GetNrows(); i++) {
      if (vec2(i) != 0) quot(i) = vec1(i) / vec2(i);
      else {
         if   (zero) quot(i) = 0;
         else        quot(i) = vec1(i);
      }
   }
   return quot;
}

//_______________________________________________________________________
TMatrixD TSVDUnfold::MatDivVec( const TMatrixD& mat, const TVectorD& vec, Int_t zero )
{
   // Divide matrix entries by vector
   TMatrixD quotmat(mat.GetNrows(), mat.GetNcols());
   for (Int_t i=0; i<mat.GetNrows(); i++) {
      for (Int_t j=0; j<mat.GetNcols(); j++) {
         if (vec(i) != 0) quotmat(i,j) = mat(i,j) / vec(i);
         else {
            if   (zero) quotmat(i,j) = 0;
            else        quotmat(i,j) = mat(i,j);
         }
      }
   }
   return quotmat;
}

//_______________________________________________________________________
TVectorD TSVDUnfold::CompProd( const TVectorD& vec1, const TVectorD& vec2 )
{
   // Multiply entries of two vectors
   TVectorD res(vec1.GetNrows());
   for (Int_t i=0; i<vec1.GetNrows(); i++) res(i) = vec1(i) * vec2(i);
   return res;
}

//_______________________________________________________________________
Double_t TSVDUnfold::GetCurvature(const TVectorD& vec, const TMatrixD& curv) 
{      
   // Compute curvature of vector
   return vec*(curv*vec);
}

//_______________________________________________________________________
void TSVDUnfold::FillCurvatureMatrix( TMatrixD& tCurv, TMatrixD& tC ) const
{
   Double_t eps = 0.00001;

   Int_t ndim = tCurv.GetNrows();

   // Init
   tCurv *= 0;
   tC    *= 0;

   if (fDdim == 0) for (Int_t i=0; i<ndim; i++) tC(i,i) = 1;
   else if (ndim == 1) {
      for (Int_t i=0; i<ndim; i++) {
         if (i < ndim-1) tC(i,i+1) = 1.0;
         tC(i,i) = 1.0;
      }
   }
   else if (fDdim == 2) {
      for (Int_t i=0; i<ndim; i++) {
         if (i > 0)      tC(i,i-1) = 1.0;
         if (i < ndim-1) tC(i,i+1) = 1.0;
         tC(i,i) = -2.0;
      }
      tC(0,0) = -1.0;
      tC(ndim-1,ndim-1) = -1.0;
   }
   else if (fDdim == 3) {
      for (Int_t i=1; i<ndim-2; i++) {
         tC(i,i-1) =  1.0;
         tC(i,i)   = -3.0;
         tC(i,i+1) =  3.0;
         tC(i,i+2) = -1.0;
      }
   }
   else if (fDdim==4) {
      for (Int_t i=0; i<ndim; i++) {
         if (i > 0)      tC(i,i-1) = -4.0;
         if (i < ndim-1) tC(i,i+1) = -4.0;
         if (i > 1)      tC(i,i-2) =  1.0;
         if (i < ndim-2) tC(i,i+2) =  1.0;
         tC(i,i) = 6.0;
      }
      tC(0,0) = 2.0;
      tC(ndim-1,ndim-1) = 2.0;
      tC(0,1) = -3.0;
      tC(ndim-2,ndim-1) = -3.0;
      tC(1,0) = -3.0;
      tC(ndim-1,ndim-2) = -3.0;
      tC(1,1) =  6.0;
      tC(ndim-2,ndim-2) =  6.0;
   }
   else if (fDdim == 5) {
      for (Int_t i=2; i < ndim-3; i++) {
         tC(i,i-2) = 1.0;
         tC(i,i-1) = -5.0;
         tC(i,i)   = 10.0;
         tC(i,i+1) = -10.0;
         tC(i,i+2) = 5.0;
         tC(i,i+3) = -1.0;
      }
   }
   else if (fDdim == 6) {
      for (Int_t i = 3; i < ndim - 3; i++) {
         tC(i,i-3) = 1.0;
         tC(i,i-2) = -6.0;
         tC(i,i-1) = 15.0;
         tC(i,i)   = -20.0;
         tC(i,i+1) = 15.0;
         tC(i,i+2) = -6.0;
         tC(i,i+3) = 1.0;
      }
   }

   // Add epsilon to avoid singularities
   for (Int_t i=0; i<ndim; i++) tC(i,i) = tC(i,i) + eps;

   //Get curvature matrix
   for (Int_t i=0; i<ndim; i++) {
      for (Int_t j=0; j<ndim; j++) {
         for (Int_t k=0; k<ndim; k++) {
            tCurv(i,j) = tCurv(i,j) + tC(k,i)*tC(k,j);
         }
      }
   }
}

//_______________________________________________________________________
void TSVDUnfold::InitHistos( )
{

   fDHist = new TH1D( "dd", "d vector after orthogonal transformation", fNdim, 0, fNdim );  
   fDHist->Sumw2();

   fSVHist = new TH1D( "sv", "Singular values of AC^-1", fNdim, 0, fNdim );  
   fSVHist->Sumw2();
}

//_______________________________________________________________________
void TSVDUnfold::RegularisedSymMatInvert( TMatrixDSym& mat, Double_t eps )
{
   // naive regularised inversion cuts off small elements

   // init reduced matrix
   const UInt_t n = mat.GetNrows();
   UInt_t nn = 0;   

   UInt_t *ipos = new UInt_t[n];
   //   UInt_t ipos[n];

   // find max diagonal entries
   Double_t ymax = 0;
   for (UInt_t i=0; i<n; i++) if (TMath::Abs(mat[i][i]) > ymax) ymax = TMath::Abs(mat[i][i]);

   for (UInt_t i=0; i<n; i++) {

         // save position of accepted entries
      if (TMath::Abs(mat[i][i])/ymax > eps) ipos[nn++] = i;
   }

   // effective matrix
   TMatrixDSym matwork( nn );
   for (UInt_t in=0; in<nn; in++) for (UInt_t jn=0; jn<nn; jn++) matwork(in,jn) = 0;

   // fill non-zero effective working matrix
   for (UInt_t in=0; in<nn; in++) {

      matwork[in][in] = mat[ipos[in]][ipos[in]];
      for (UInt_t jn=in+1; jn<nn; jn++) {
         matwork[in][jn] = mat[ipos[in]][ipos[jn]];
         matwork[jn][in] = matwork[in][jn];
      }
   }

   // invert
   matwork.Invert();

   // reinitialise old matrix
   for (UInt_t i=0; i<n; i++) for (UInt_t j=0; j<n; j++) mat[i][j] = 0;

   // refill inverted matrix in old one
   for (UInt_t in=0; in<nn; in++) {
      mat[ipos[in]][ipos[in]] = matwork[in][in];
      for (UInt_t jn=in+1; jn<nn; jn++) {
         mat[ipos[in]][ipos[jn]] = matwork[in][jn];
         mat[ipos[jn]][ipos[in]] = mat[ipos[in]][ipos[jn]];
      }
   }
   delete []  ipos;
}

//_______________________________________________________________________
Double_t TSVDUnfold::ComputeChiSquared( const TH1D& truspec, const TH1D& unfspec, const TH2D& covmat, Double_t regpar  )
{
   // helper routine to compute chi-squared between distributions
   UInt_t n = truspec.GetNbinsX();
   TMatrixDSym mat( n );
   for (UInt_t i=0; i<n; i++) {
      for (UInt_t j=i; j<n; j++) {
         mat[i][j] = covmat.GetBinContent( i+1, j+1 );
         mat[j][i] = mat[i][j];
      }
   }

   RegularisedSymMatInvert( mat, regpar );

   // compute chi2
   Double_t chi2 = 0;
   for (UInt_t i=0; i<n; i++) {
      for (UInt_t j=0; j<n; j++) {
         chi2 += ( (truspec.GetBinContent( i+1 )-unfspec.GetBinContent( i+1 )) *
                   (truspec.GetBinContent( j+1 )-unfspec.GetBinContent( j+1 )) * mat[i][j] );
      }
   }

   return chi2;
}

 TSVDUnfold.cxx:1
 TSVDUnfold.cxx:2
 TSVDUnfold.cxx:3
 TSVDUnfold.cxx:4
 TSVDUnfold.cxx:5
 TSVDUnfold.cxx:6
 TSVDUnfold.cxx:7
 TSVDUnfold.cxx:8
 TSVDUnfold.cxx:9
 TSVDUnfold.cxx:10
 TSVDUnfold.cxx:11
 TSVDUnfold.cxx:12
 TSVDUnfold.cxx:13
 TSVDUnfold.cxx:14
 TSVDUnfold.cxx:15
 TSVDUnfold.cxx:16
 TSVDUnfold.cxx:17
 TSVDUnfold.cxx:18
 TSVDUnfold.cxx:19
 TSVDUnfold.cxx:20
 TSVDUnfold.cxx:21
 TSVDUnfold.cxx:22
 TSVDUnfold.cxx:23
 TSVDUnfold.cxx:24
 TSVDUnfold.cxx:25
 TSVDUnfold.cxx:26
 TSVDUnfold.cxx:27
 TSVDUnfold.cxx:28
 TSVDUnfold.cxx:29
 TSVDUnfold.cxx:30
 TSVDUnfold.cxx:31
 TSVDUnfold.cxx:32
 TSVDUnfold.cxx:33
 TSVDUnfold.cxx:34
 TSVDUnfold.cxx:35
 TSVDUnfold.cxx:36
 TSVDUnfold.cxx:37
 TSVDUnfold.cxx:38
 TSVDUnfold.cxx:39
 TSVDUnfold.cxx:40
 TSVDUnfold.cxx:41
 TSVDUnfold.cxx:42
 TSVDUnfold.cxx:43
 TSVDUnfold.cxx:44
 TSVDUnfold.cxx:45
 TSVDUnfold.cxx:46
 TSVDUnfold.cxx:47
 TSVDUnfold.cxx:48
 TSVDUnfold.cxx:49
 TSVDUnfold.cxx:50
 TSVDUnfold.cxx:51
 TSVDUnfold.cxx:52
 TSVDUnfold.cxx:53
 TSVDUnfold.cxx:54
 TSVDUnfold.cxx:55
 TSVDUnfold.cxx:56
 TSVDUnfold.cxx:57
 TSVDUnfold.cxx:58
 TSVDUnfold.cxx:59
 TSVDUnfold.cxx:60
 TSVDUnfold.cxx:61
 TSVDUnfold.cxx:62
 TSVDUnfold.cxx:63
 TSVDUnfold.cxx:64
 TSVDUnfold.cxx:65
 TSVDUnfold.cxx:66
 TSVDUnfold.cxx:67
 TSVDUnfold.cxx:68
 TSVDUnfold.cxx:69
 TSVDUnfold.cxx:70
 TSVDUnfold.cxx:71
 TSVDUnfold.cxx:72
 TSVDUnfold.cxx:73
 TSVDUnfold.cxx:74
 TSVDUnfold.cxx:75
 TSVDUnfold.cxx:76
 TSVDUnfold.cxx:77
 TSVDUnfold.cxx:78
 TSVDUnfold.cxx:79
 TSVDUnfold.cxx:80
 TSVDUnfold.cxx:81
 TSVDUnfold.cxx:82
 TSVDUnfold.cxx:83
 TSVDUnfold.cxx:84
 TSVDUnfold.cxx:85
 TSVDUnfold.cxx:86
 TSVDUnfold.cxx:87
 TSVDUnfold.cxx:88
 TSVDUnfold.cxx:89
 TSVDUnfold.cxx:90
 TSVDUnfold.cxx:91
 TSVDUnfold.cxx:92
 TSVDUnfold.cxx:93
 TSVDUnfold.cxx:94
 TSVDUnfold.cxx:95
 TSVDUnfold.cxx:96
 TSVDUnfold.cxx:97
 TSVDUnfold.cxx:98
 TSVDUnfold.cxx:99
 TSVDUnfold.cxx:100
 TSVDUnfold.cxx:101
 TSVDUnfold.cxx:102
 TSVDUnfold.cxx:103
 TSVDUnfold.cxx:104
 TSVDUnfold.cxx:105
 TSVDUnfold.cxx:106
 TSVDUnfold.cxx:107
 TSVDUnfold.cxx:108
 TSVDUnfold.cxx:109
 TSVDUnfold.cxx:110
 TSVDUnfold.cxx:111
 TSVDUnfold.cxx:112
 TSVDUnfold.cxx:113
 TSVDUnfold.cxx:114
 TSVDUnfold.cxx:115
 TSVDUnfold.cxx:116
 TSVDUnfold.cxx:117
 TSVDUnfold.cxx:118
 TSVDUnfold.cxx:119
 TSVDUnfold.cxx:120
 TSVDUnfold.cxx:121
 TSVDUnfold.cxx:122
 TSVDUnfold.cxx:123
 TSVDUnfold.cxx:124
 TSVDUnfold.cxx:125
 TSVDUnfold.cxx:126
 TSVDUnfold.cxx:127
 TSVDUnfold.cxx:128
 TSVDUnfold.cxx:129
 TSVDUnfold.cxx:130
 TSVDUnfold.cxx:131
 TSVDUnfold.cxx:132
 TSVDUnfold.cxx:133
 TSVDUnfold.cxx:134
 TSVDUnfold.cxx:135
 TSVDUnfold.cxx:136
 TSVDUnfold.cxx:137
 TSVDUnfold.cxx:138
 TSVDUnfold.cxx:139
 TSVDUnfold.cxx:140
 TSVDUnfold.cxx:141
 TSVDUnfold.cxx:142
 TSVDUnfold.cxx:143
 TSVDUnfold.cxx:144
 TSVDUnfold.cxx:145
 TSVDUnfold.cxx:146
 TSVDUnfold.cxx:147
 TSVDUnfold.cxx:148
 TSVDUnfold.cxx:149
 TSVDUnfold.cxx:150
 TSVDUnfold.cxx:151
 TSVDUnfold.cxx:152
 TSVDUnfold.cxx:153
 TSVDUnfold.cxx:154
 TSVDUnfold.cxx:155
 TSVDUnfold.cxx:156
 TSVDUnfold.cxx:157
 TSVDUnfold.cxx:158
 TSVDUnfold.cxx:159
 TSVDUnfold.cxx:160
 TSVDUnfold.cxx:161
 TSVDUnfold.cxx:162
 TSVDUnfold.cxx:163
 TSVDUnfold.cxx:164
 TSVDUnfold.cxx:165
 TSVDUnfold.cxx:166
 TSVDUnfold.cxx:167
 TSVDUnfold.cxx:168
 TSVDUnfold.cxx:169
 TSVDUnfold.cxx:170
 TSVDUnfold.cxx:171
 TSVDUnfold.cxx:172
 TSVDUnfold.cxx:173
 TSVDUnfold.cxx:174
 TSVDUnfold.cxx:175
 TSVDUnfold.cxx:176
 TSVDUnfold.cxx:177
 TSVDUnfold.cxx:178
 TSVDUnfold.cxx:179
 TSVDUnfold.cxx:180
 TSVDUnfold.cxx:181
 TSVDUnfold.cxx:182
 TSVDUnfold.cxx:183
 TSVDUnfold.cxx:184
 TSVDUnfold.cxx:185
 TSVDUnfold.cxx:186
 TSVDUnfold.cxx:187
 TSVDUnfold.cxx:188
 TSVDUnfold.cxx:189
 TSVDUnfold.cxx:190
 TSVDUnfold.cxx:191
 TSVDUnfold.cxx:192
 TSVDUnfold.cxx:193
 TSVDUnfold.cxx:194
 TSVDUnfold.cxx:195
 TSVDUnfold.cxx:196
 TSVDUnfold.cxx:197
 TSVDUnfold.cxx:198
 TSVDUnfold.cxx:199
 TSVDUnfold.cxx:200
 TSVDUnfold.cxx:201
 TSVDUnfold.cxx:202
 TSVDUnfold.cxx:203
 TSVDUnfold.cxx:204
 TSVDUnfold.cxx:205
 TSVDUnfold.cxx:206
 TSVDUnfold.cxx:207
 TSVDUnfold.cxx:208
 TSVDUnfold.cxx:209
 TSVDUnfold.cxx:210
 TSVDUnfold.cxx:211
 TSVDUnfold.cxx:212
 TSVDUnfold.cxx:213
 TSVDUnfold.cxx:214
 TSVDUnfold.cxx:215
 TSVDUnfold.cxx:216
 TSVDUnfold.cxx:217
 TSVDUnfold.cxx:218
 TSVDUnfold.cxx:219
 TSVDUnfold.cxx:220
 TSVDUnfold.cxx:221
 TSVDUnfold.cxx:222
 TSVDUnfold.cxx:223
 TSVDUnfold.cxx:224
 TSVDUnfold.cxx:225
 TSVDUnfold.cxx:226
 TSVDUnfold.cxx:227
 TSVDUnfold.cxx:228
 TSVDUnfold.cxx:229
 TSVDUnfold.cxx:230
 TSVDUnfold.cxx:231
 TSVDUnfold.cxx:232
 TSVDUnfold.cxx:233
 TSVDUnfold.cxx:234
 TSVDUnfold.cxx:235
 TSVDUnfold.cxx:236
 TSVDUnfold.cxx:237
 TSVDUnfold.cxx:238
 TSVDUnfold.cxx:239
 TSVDUnfold.cxx:240
 TSVDUnfold.cxx:241
 TSVDUnfold.cxx:242
 TSVDUnfold.cxx:243
 TSVDUnfold.cxx:244
 TSVDUnfold.cxx:245
 TSVDUnfold.cxx:246
 TSVDUnfold.cxx:247
 TSVDUnfold.cxx:248
 TSVDUnfold.cxx:249
 TSVDUnfold.cxx:250
 TSVDUnfold.cxx:251
 TSVDUnfold.cxx:252
 TSVDUnfold.cxx:253
 TSVDUnfold.cxx:254
 TSVDUnfold.cxx:255
 TSVDUnfold.cxx:256
 TSVDUnfold.cxx:257
 TSVDUnfold.cxx:258
 TSVDUnfold.cxx:259
 TSVDUnfold.cxx:260
 TSVDUnfold.cxx:261
 TSVDUnfold.cxx:262
 TSVDUnfold.cxx:263
 TSVDUnfold.cxx:264
 TSVDUnfold.cxx:265
 TSVDUnfold.cxx:266
 TSVDUnfold.cxx:267
 TSVDUnfold.cxx:268
 TSVDUnfold.cxx:269
 TSVDUnfold.cxx:270
 TSVDUnfold.cxx:271
 TSVDUnfold.cxx:272
 TSVDUnfold.cxx:273
 TSVDUnfold.cxx:274
 TSVDUnfold.cxx:275
 TSVDUnfold.cxx:276
 TSVDUnfold.cxx:277
 TSVDUnfold.cxx:278
 TSVDUnfold.cxx:279
 TSVDUnfold.cxx:280
 TSVDUnfold.cxx:281
 TSVDUnfold.cxx:282
 TSVDUnfold.cxx:283
 TSVDUnfold.cxx:284
 TSVDUnfold.cxx:285
 TSVDUnfold.cxx:286
 TSVDUnfold.cxx:287
 TSVDUnfold.cxx:288
 TSVDUnfold.cxx:289
 TSVDUnfold.cxx:290
 TSVDUnfold.cxx:291
 TSVDUnfold.cxx:292
 TSVDUnfold.cxx:293
 TSVDUnfold.cxx:294
 TSVDUnfold.cxx:295
 TSVDUnfold.cxx:296
 TSVDUnfold.cxx:297
 TSVDUnfold.cxx:298
 TSVDUnfold.cxx:299
 TSVDUnfold.cxx:300
 TSVDUnfold.cxx:301
 TSVDUnfold.cxx:302
 TSVDUnfold.cxx:303
 TSVDUnfold.cxx:304
 TSVDUnfold.cxx:305
 TSVDUnfold.cxx:306
 TSVDUnfold.cxx:307
 TSVDUnfold.cxx:308
 TSVDUnfold.cxx:309
 TSVDUnfold.cxx:310
 TSVDUnfold.cxx:311
 TSVDUnfold.cxx:312
 TSVDUnfold.cxx:313
 TSVDUnfold.cxx:314
 TSVDUnfold.cxx:315
 TSVDUnfold.cxx:316
 TSVDUnfold.cxx:317
 TSVDUnfold.cxx:318
 TSVDUnfold.cxx:319
 TSVDUnfold.cxx:320
 TSVDUnfold.cxx:321
 TSVDUnfold.cxx:322
 TSVDUnfold.cxx:323
 TSVDUnfold.cxx:324
 TSVDUnfold.cxx:325
 TSVDUnfold.cxx:326
 TSVDUnfold.cxx:327
 TSVDUnfold.cxx:328
 TSVDUnfold.cxx:329
 TSVDUnfold.cxx:330
 TSVDUnfold.cxx:331
 TSVDUnfold.cxx:332
 TSVDUnfold.cxx:333
 TSVDUnfold.cxx:334
 TSVDUnfold.cxx:335
 TSVDUnfold.cxx:336
 TSVDUnfold.cxx:337
 TSVDUnfold.cxx:338
 TSVDUnfold.cxx:339
 TSVDUnfold.cxx:340
 TSVDUnfold.cxx:341
 TSVDUnfold.cxx:342
 TSVDUnfold.cxx:343
 TSVDUnfold.cxx:344
 TSVDUnfold.cxx:345
 TSVDUnfold.cxx:346
 TSVDUnfold.cxx:347
 TSVDUnfold.cxx:348
 TSVDUnfold.cxx:349
 TSVDUnfold.cxx:350
 TSVDUnfold.cxx:351
 TSVDUnfold.cxx:352
 TSVDUnfold.cxx:353
 TSVDUnfold.cxx:354
 TSVDUnfold.cxx:355
 TSVDUnfold.cxx:356
 TSVDUnfold.cxx:357
 TSVDUnfold.cxx:358
 TSVDUnfold.cxx:359
 TSVDUnfold.cxx:360
 TSVDUnfold.cxx:361
 TSVDUnfold.cxx:362
 TSVDUnfold.cxx:363
 TSVDUnfold.cxx:364
 TSVDUnfold.cxx:365
 TSVDUnfold.cxx:366
 TSVDUnfold.cxx:367
 TSVDUnfold.cxx:368
 TSVDUnfold.cxx:369
 TSVDUnfold.cxx:370
 TSVDUnfold.cxx:371
 TSVDUnfold.cxx:372
 TSVDUnfold.cxx:373
 TSVDUnfold.cxx:374
 TSVDUnfold.cxx:375
 TSVDUnfold.cxx:376
 TSVDUnfold.cxx:377
 TSVDUnfold.cxx:378
 TSVDUnfold.cxx:379
 TSVDUnfold.cxx:380
 TSVDUnfold.cxx:381
 TSVDUnfold.cxx:382
 TSVDUnfold.cxx:383
 TSVDUnfold.cxx:384
 TSVDUnfold.cxx:385
 TSVDUnfold.cxx:386
 TSVDUnfold.cxx:387
 TSVDUnfold.cxx:388
 TSVDUnfold.cxx:389
 TSVDUnfold.cxx:390
 TSVDUnfold.cxx:391
 TSVDUnfold.cxx:392
 TSVDUnfold.cxx:393
 TSVDUnfold.cxx:394
 TSVDUnfold.cxx:395
 TSVDUnfold.cxx:396
 TSVDUnfold.cxx:397
 TSVDUnfold.cxx:398
 TSVDUnfold.cxx:399
 TSVDUnfold.cxx:400
 TSVDUnfold.cxx:401
 TSVDUnfold.cxx:402
 TSVDUnfold.cxx:403
 TSVDUnfold.cxx:404
 TSVDUnfold.cxx:405
 TSVDUnfold.cxx:406
 TSVDUnfold.cxx:407
 TSVDUnfold.cxx:408
 TSVDUnfold.cxx:409
 TSVDUnfold.cxx:410
 TSVDUnfold.cxx:411
 TSVDUnfold.cxx:412
 TSVDUnfold.cxx:413
 TSVDUnfold.cxx:414
 TSVDUnfold.cxx:415
 TSVDUnfold.cxx:416
 TSVDUnfold.cxx:417
 TSVDUnfold.cxx:418
 TSVDUnfold.cxx:419
 TSVDUnfold.cxx:420
 TSVDUnfold.cxx:421
 TSVDUnfold.cxx:422
 TSVDUnfold.cxx:423
 TSVDUnfold.cxx:424
 TSVDUnfold.cxx:425
 TSVDUnfold.cxx:426
 TSVDUnfold.cxx:427
 TSVDUnfold.cxx:428
 TSVDUnfold.cxx:429
 TSVDUnfold.cxx:430
 TSVDUnfold.cxx:431
 TSVDUnfold.cxx:432
 TSVDUnfold.cxx:433
 TSVDUnfold.cxx:434
 TSVDUnfold.cxx:435
 TSVDUnfold.cxx:436
 TSVDUnfold.cxx:437
 TSVDUnfold.cxx:438
 TSVDUnfold.cxx:439
 TSVDUnfold.cxx:440
 TSVDUnfold.cxx:441
 TSVDUnfold.cxx:442
 TSVDUnfold.cxx:443
 TSVDUnfold.cxx:444
 TSVDUnfold.cxx:445
 TSVDUnfold.cxx:446
 TSVDUnfold.cxx:447
 TSVDUnfold.cxx:448
 TSVDUnfold.cxx:449
 TSVDUnfold.cxx:450
 TSVDUnfold.cxx:451
 TSVDUnfold.cxx:452
 TSVDUnfold.cxx:453
 TSVDUnfold.cxx:454
 TSVDUnfold.cxx:455
 TSVDUnfold.cxx:456
 TSVDUnfold.cxx:457
 TSVDUnfold.cxx:458
 TSVDUnfold.cxx:459
 TSVDUnfold.cxx:460
 TSVDUnfold.cxx:461
 TSVDUnfold.cxx:462
 TSVDUnfold.cxx:463
 TSVDUnfold.cxx:464
 TSVDUnfold.cxx:465
 TSVDUnfold.cxx:466
 TSVDUnfold.cxx:467
 TSVDUnfold.cxx:468
 TSVDUnfold.cxx:469
 TSVDUnfold.cxx:470
 TSVDUnfold.cxx:471
 TSVDUnfold.cxx:472
 TSVDUnfold.cxx:473
 TSVDUnfold.cxx:474
 TSVDUnfold.cxx:475
 TSVDUnfold.cxx:476
 TSVDUnfold.cxx:477
 TSVDUnfold.cxx:478
 TSVDUnfold.cxx:479
 TSVDUnfold.cxx:480
 TSVDUnfold.cxx:481
 TSVDUnfold.cxx:482
 TSVDUnfold.cxx:483
 TSVDUnfold.cxx:484
 TSVDUnfold.cxx:485
 TSVDUnfold.cxx:486
 TSVDUnfold.cxx:487
 TSVDUnfold.cxx:488
 TSVDUnfold.cxx:489
 TSVDUnfold.cxx:490
 TSVDUnfold.cxx:491
 TSVDUnfold.cxx:492
 TSVDUnfold.cxx:493
 TSVDUnfold.cxx:494
 TSVDUnfold.cxx:495
 TSVDUnfold.cxx:496
 TSVDUnfold.cxx:497
 TSVDUnfold.cxx:498
 TSVDUnfold.cxx:499
 TSVDUnfold.cxx:500
 TSVDUnfold.cxx:501
 TSVDUnfold.cxx:502
 TSVDUnfold.cxx:503
 TSVDUnfold.cxx:504
 TSVDUnfold.cxx:505
 TSVDUnfold.cxx:506
 TSVDUnfold.cxx:507
 TSVDUnfold.cxx:508
 TSVDUnfold.cxx:509
 TSVDUnfold.cxx:510
 TSVDUnfold.cxx:511
 TSVDUnfold.cxx:512
 TSVDUnfold.cxx:513
 TSVDUnfold.cxx:514
 TSVDUnfold.cxx:515
 TSVDUnfold.cxx:516
 TSVDUnfold.cxx:517
 TSVDUnfold.cxx:518
 TSVDUnfold.cxx:519
 TSVDUnfold.cxx:520
 TSVDUnfold.cxx:521
 TSVDUnfold.cxx:522
 TSVDUnfold.cxx:523
 TSVDUnfold.cxx:524
 TSVDUnfold.cxx:525
 TSVDUnfold.cxx:526
 TSVDUnfold.cxx:527
 TSVDUnfold.cxx:528
 TSVDUnfold.cxx:529
 TSVDUnfold.cxx:530
 TSVDUnfold.cxx:531
 TSVDUnfold.cxx:532
 TSVDUnfold.cxx:533
 TSVDUnfold.cxx:534
 TSVDUnfold.cxx:535
 TSVDUnfold.cxx:536
 TSVDUnfold.cxx:537
 TSVDUnfold.cxx:538
 TSVDUnfold.cxx:539
 TSVDUnfold.cxx:540
 TSVDUnfold.cxx:541
 TSVDUnfold.cxx:542
 TSVDUnfold.cxx:543
 TSVDUnfold.cxx:544
 TSVDUnfold.cxx:545
 TSVDUnfold.cxx:546
 TSVDUnfold.cxx:547
 TSVDUnfold.cxx:548
 TSVDUnfold.cxx:549
 TSVDUnfold.cxx:550
 TSVDUnfold.cxx:551
 TSVDUnfold.cxx:552
 TSVDUnfold.cxx:553
 TSVDUnfold.cxx:554
 TSVDUnfold.cxx:555
 TSVDUnfold.cxx:556
 TSVDUnfold.cxx:557
 TSVDUnfold.cxx:558
 TSVDUnfold.cxx:559
 TSVDUnfold.cxx:560
 TSVDUnfold.cxx:561
 TSVDUnfold.cxx:562
 TSVDUnfold.cxx:563
 TSVDUnfold.cxx:564
 TSVDUnfold.cxx:565
 TSVDUnfold.cxx:566
 TSVDUnfold.cxx:567
 TSVDUnfold.cxx:568
 TSVDUnfold.cxx:569
 TSVDUnfold.cxx:570
 TSVDUnfold.cxx:571
 TSVDUnfold.cxx:572
 TSVDUnfold.cxx:573
 TSVDUnfold.cxx:574
 TSVDUnfold.cxx:575
 TSVDUnfold.cxx:576
 TSVDUnfold.cxx:577
 TSVDUnfold.cxx:578
 TSVDUnfold.cxx:579
 TSVDUnfold.cxx:580
 TSVDUnfold.cxx:581
 TSVDUnfold.cxx:582
 TSVDUnfold.cxx:583
 TSVDUnfold.cxx:584
 TSVDUnfold.cxx:585
 TSVDUnfold.cxx:586
 TSVDUnfold.cxx:587
 TSVDUnfold.cxx:588
 TSVDUnfold.cxx:589
 TSVDUnfold.cxx:590
 TSVDUnfold.cxx:591
 TSVDUnfold.cxx:592
 TSVDUnfold.cxx:593
 TSVDUnfold.cxx:594
 TSVDUnfold.cxx:595
 TSVDUnfold.cxx:596
 TSVDUnfold.cxx:597
 TSVDUnfold.cxx:598
 TSVDUnfold.cxx:599
 TSVDUnfold.cxx:600
 TSVDUnfold.cxx:601
 TSVDUnfold.cxx:602
 TSVDUnfold.cxx:603
 TSVDUnfold.cxx:604
 TSVDUnfold.cxx:605
 TSVDUnfold.cxx:606
 TSVDUnfold.cxx:607
 TSVDUnfold.cxx:608
 TSVDUnfold.cxx:609
 TSVDUnfold.cxx:610
 TSVDUnfold.cxx:611
 TSVDUnfold.cxx:612
 TSVDUnfold.cxx:613
 TSVDUnfold.cxx:614
 TSVDUnfold.cxx:615
 TSVDUnfold.cxx:616
 TSVDUnfold.cxx:617
 TSVDUnfold.cxx:618
 TSVDUnfold.cxx:619
 TSVDUnfold.cxx:620
 TSVDUnfold.cxx:621
 TSVDUnfold.cxx:622
 TSVDUnfold.cxx:623
 TSVDUnfold.cxx:624
 TSVDUnfold.cxx:625
 TSVDUnfold.cxx:626
 TSVDUnfold.cxx:627
 TSVDUnfold.cxx:628
 TSVDUnfold.cxx:629
 TSVDUnfold.cxx:630
 TSVDUnfold.cxx:631
 TSVDUnfold.cxx:632
 TSVDUnfold.cxx:633
 TSVDUnfold.cxx:634
 TSVDUnfold.cxx:635
 TSVDUnfold.cxx:636
 TSVDUnfold.cxx:637
 TSVDUnfold.cxx:638
 TSVDUnfold.cxx:639
 TSVDUnfold.cxx:640
 TSVDUnfold.cxx:641
 TSVDUnfold.cxx:642
 TSVDUnfold.cxx:643
 TSVDUnfold.cxx:644
 TSVDUnfold.cxx:645
 TSVDUnfold.cxx:646
 TSVDUnfold.cxx:647
 TSVDUnfold.cxx:648
 TSVDUnfold.cxx:649
 TSVDUnfold.cxx:650
 TSVDUnfold.cxx:651
 TSVDUnfold.cxx:652
 TSVDUnfold.cxx:653
 TSVDUnfold.cxx:654
 TSVDUnfold.cxx:655
 TSVDUnfold.cxx:656
 TSVDUnfold.cxx:657
 TSVDUnfold.cxx:658
 TSVDUnfold.cxx:659
 TSVDUnfold.cxx:660
 TSVDUnfold.cxx:661
 TSVDUnfold.cxx:662
 TSVDUnfold.cxx:663
 TSVDUnfold.cxx:664
 TSVDUnfold.cxx:665
 TSVDUnfold.cxx:666
 TSVDUnfold.cxx:667
 TSVDUnfold.cxx:668
 TSVDUnfold.cxx:669
 TSVDUnfold.cxx:670
 TSVDUnfold.cxx:671
 TSVDUnfold.cxx:672
 TSVDUnfold.cxx:673
 TSVDUnfold.cxx:674
 TSVDUnfold.cxx:675
 TSVDUnfold.cxx:676
 TSVDUnfold.cxx:677
 TSVDUnfold.cxx:678
 TSVDUnfold.cxx:679
 TSVDUnfold.cxx:680
 TSVDUnfold.cxx:681
 TSVDUnfold.cxx:682
 TSVDUnfold.cxx:683
 TSVDUnfold.cxx:684
 TSVDUnfold.cxx:685
 TSVDUnfold.cxx:686
 TSVDUnfold.cxx:687
 TSVDUnfold.cxx:688
 TSVDUnfold.cxx:689
 TSVDUnfold.cxx:690
 TSVDUnfold.cxx:691
 TSVDUnfold.cxx:692
 TSVDUnfold.cxx:693
 TSVDUnfold.cxx:694