// @(#)root/tmva $Id$
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate Data analysis       *
 * Package: TMVA                                                                  *
 * Class  : TMVA::MethodHMatrix                                                   *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header file for description)                          *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Peter Speckmayer <Peter.Speckmayer@cern.ch> - CERN, Switzerland           *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

#include "TMVA/ClassifierFactory.h"
#include "TMVA/MethodHMatrix.h"
#include "TMVA/Tools.h"
#include "TMatrix.h"
#include "Riostream.h"
#include <algorithm>

REGISTER_METHOD(HMatrix)

ClassImp(TMVA::MethodHMatrix)

//_______________________________________________________________________
//Begin_Html
/*
  H-Matrix method, which is implemented as a simple comparison of
  chi-squared estimators for signal and background, taking into
  account the linear correlations between the input variables

  This MVA approach is used by the D&#216; collaboration (FNAL) for the
  purpose of electron identification (see, eg.,
  <a href="http://arxiv.org/abs/hep-ex/9507007">hep-ex/9507007</a>).
  As it is implemented in TMVA, it is usually equivalent or worse than
  the Fisher-Mahalanobis discriminant, and it has only been added for
  the purpose of completeness.
  Two &chi;<sup>2</sup> estimators are computed for an event, each one
  for signal and background, using the estimates for the means and
  covariance matrices obtained from the training sample:<br>
  <center>
  <img vspace=6 src="gif/tmva_chi2.gif" align="bottom" >
  </center>
  TMVA then uses as normalised analyser for event (<i>i</i>) the ratio:
  (<i>&chi;<sub>S</sub>(i)<sup>2</sup> &minus; &chi;<sub>B</sub><sup>2</sup>(i)</i>)
  (<i>&chi;<sub>S</sub><sup>2</sup>(i) + &chi;<sub>B</sub><sup>2</sup>(i)</i>).
*/
//End_Html
//_______________________________________________________________________


//_______________________________________________________________________
TMVA::MethodHMatrix::MethodHMatrix( const TString& jobName,
                                    const TString& methodTitle,
                                    DataSetInfo& theData,
                                    const TString& theOption,
                                    TDirectory* theTargetDir )
   : TMVA::MethodBase( jobName, Types::kHMatrix, methodTitle, theData, theOption, theTargetDir )
  ,fInvHMatrixS(0) 
  ,fInvHMatrixB(0) 
  ,fVecMeanS(0)    
  ,fVecMeanB(0)    
{
   // standard constructor for the H-Matrix method
}

//_______________________________________________________________________
TMVA::MethodHMatrix::MethodHMatrix( DataSetInfo& theData,
                                    const TString& theWeightFile,
                                    TDirectory* theTargetDir )
   : TMVA::MethodBase( Types::kHMatrix, theData, theWeightFile, theTargetDir )
  ,fInvHMatrixS(0) 
  ,fInvHMatrixB(0) 
  ,fVecMeanS(0)    
  ,fVecMeanB(0)    
{
   // constructor from weight file
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::Init( void )
{
   // default initialization called by all constructors

   //SetNormalised( kFALSE ); obsolete!

   fInvHMatrixS = new TMatrixD( GetNvar(), GetNvar() );
   fInvHMatrixB = new TMatrixD( GetNvar(), GetNvar() );
   fVecMeanS    = new TVectorD( GetNvar() );
   fVecMeanB    = new TVectorD( GetNvar() );

   // the minimum requirement to declare an event signal-like
   SetSignalReferenceCut( 0.0 );
}

//_______________________________________________________________________
TMVA::MethodHMatrix::~MethodHMatrix( void )
{
   // destructor
   if (NULL != fInvHMatrixS) delete fInvHMatrixS;
   if (NULL != fInvHMatrixB) delete fInvHMatrixB;
   if (NULL != fVecMeanS   ) delete fVecMeanS;
   if (NULL != fVecMeanB   ) delete fVecMeanB;
}

//_______________________________________________________________________
Bool_t TMVA::MethodHMatrix::HasAnalysisType( Types::EAnalysisType type, UInt_t numberClasses, UInt_t /*numberTargets*/ )
{
   // FDA can handle classification with 2 classes and regression with one regression-target
   if( type == Types::kClassification && numberClasses == 2 ) return kTRUE;
   return kFALSE;
}


//_______________________________________________________________________
void TMVA::MethodHMatrix::DeclareOptions()
{
   // MethodHMatrix options: none (apart from those implemented in MethodBase)
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::ProcessOptions()
{
   // process user options
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::Train( void )
{
   // computes H-matrices for signal and background samples

   // covariance matrices for signal and background
   ComputeCovariance( kTRUE,  fInvHMatrixS );
   ComputeCovariance( kFALSE, fInvHMatrixB );

   // sanity checks
   if (TMath::Abs(fInvHMatrixS->Determinant()) < 10E-24) {
      Log() << kWARNING << "<Train> H-matrix  S is almost singular with deterinant= "
            << TMath::Abs(fInvHMatrixS->Determinant())
            << " did you use the variables that are linear combinations or highly correlated ???"
            << Endl;
   }
   if (TMath::Abs(fInvHMatrixB->Determinant()) < 10E-24) {
      Log() << kWARNING << "<Train> H-matrix  B is almost singular with deterinant= "
            << TMath::Abs(fInvHMatrixB->Determinant())
            << " did you use the variables that are linear combinations or highly correlated ???"
            << Endl;
   }

    if (TMath::Abs(fInvHMatrixS->Determinant()) < 10E-120) {
       Log() << kFATAL << "<Train> H-matrix  S is singular with deterinant= "
             << TMath::Abs(fInvHMatrixS->Determinant())
             << " did you use the variables that are linear combinations ???"
             << Endl;
    }
    if (TMath::Abs(fInvHMatrixB->Determinant()) < 10E-120) {
       Log() << kFATAL << "<Train> H-matrix  B is singular with deterinant= "
             << TMath::Abs(fInvHMatrixB->Determinant())
             << " did you use the variables that are linear combinations ???"
             << Endl;
    }

   // invert matrix
   fInvHMatrixS->Invert();
   fInvHMatrixB->Invert();
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::ComputeCovariance( Bool_t isSignal, TMatrixD* mat )
{
   // compute covariance matrix

   Data()->SetCurrentType(Types::kTraining);

   const UInt_t nvar = DataInfo().GetNVariables();
   UInt_t ivar, jvar;

   // init matrices
   TVectorD vec(nvar);        vec  *= 0;
   TMatrixD mat2(nvar, nvar); mat2 *= 0;

   // initialize internal sum-of-weights variables
   Double_t sumOfWeights = 0;
   Double_t *xval = new Double_t[nvar];

   // perform event loop
   for (Int_t i=0, iEnd=Data()->GetNEvents(); i<iEnd; ++i) {

      // retrieve the original (not transformed) event
      const Event* origEvt = Data()->GetEvent(i);
      Double_t weight = origEvt->GetWeight();

      // in case event with neg weights are to be ignored
      if (IgnoreEventsWithNegWeightsInTraining() && weight <= 0) continue;

      if (DataInfo().IsSignal(origEvt) != isSignal) continue;

      // transform the event
      GetTransformationHandler().SetTransformationReferenceClass( origEvt->GetClass() );
      const Event* ev = GetTransformationHandler().Transform( origEvt );
      
      // event is of good type
      sumOfWeights += weight;

      // mean values
      for (ivar=0; ivar<nvar; ivar++) xval[ivar] = ev->GetValue(ivar);

      // covariance matrix
      for (ivar=0; ivar<nvar; ivar++) {

         vec(ivar)        += xval[ivar]*weight;
         mat2(ivar, ivar) += (xval[ivar]*xval[ivar])*weight;

         for (jvar=ivar+1; jvar<nvar; jvar++) {
            mat2(ivar, jvar) += (xval[ivar]*xval[jvar])*weight;
            mat2(jvar, ivar) = mat2(ivar, jvar); // symmetric matrix
         }
      }
   }

   // variance-covariance
   for (ivar=0; ivar<nvar; ivar++) {

      if (isSignal) (*fVecMeanS)(ivar) = vec(ivar)/sumOfWeights;
      else          (*fVecMeanB)(ivar) = vec(ivar)/sumOfWeights;

      for (jvar=0; jvar<nvar; jvar++) {
         (*mat)(ivar, jvar) = mat2(ivar, jvar)/sumOfWeights - vec(ivar)*vec(jvar)/(sumOfWeights*sumOfWeights);
      }
   }

   delete [] xval;
}

//_______________________________________________________________________
Double_t TMVA::MethodHMatrix::GetMvaValue( Double_t* err, Double_t* errUpper )
{
   // returns the H-matrix signal estimator
   Double_t s = GetChi2( Types::kSignal     );
   Double_t b = GetChi2( Types::kBackground );
  
   if (s+b < 0) Log() << kFATAL << "big trouble: s+b: " << s+b << Endl;

   // cannot determine error
   NoErrorCalc(err, errUpper);

   return (b - s)/(s + b);
}

//_______________________________________________________________________
Double_t TMVA::MethodHMatrix::GetChi2( Types::ESBType type ) 
{
   // compute chi2-estimator for event according to type (signal/background)

   // get original (not transformed) event

   const Event* origEvt = fTmpEvent ? fTmpEvent:Data()->GetEvent();

   // loop over variables
   UInt_t ivar(0), jvar(0), nvar(GetNvar());
   std::vector<Double_t> val( nvar );

   // transform the event according to the given type (signal/background)
   if (type==Types::kSignal)
      GetTransformationHandler().SetTransformationReferenceClass( fSignalClass     );
   else
      GetTransformationHandler().SetTransformationReferenceClass( fBackgroundClass );

   const Event* ev = GetTransformationHandler().Transform( origEvt );

   for (ivar=0; ivar<nvar; ivar++) val[ivar] = ev->GetValue( ivar );

   Double_t chi2 = 0;
   for (ivar=0; ivar<nvar; ivar++) {
      for (jvar=0; jvar<nvar; jvar++) {
         if (type == Types::kSignal) 
            chi2 += ( (val[ivar] - (*fVecMeanS)(ivar))*(val[jvar] - (*fVecMeanS)(jvar))
                      * (*fInvHMatrixS)(ivar,jvar) );
         else
            chi2 += ( (val[ivar] - (*fVecMeanB)(ivar))*(val[jvar] - (*fVecMeanB)(jvar))
                      * (*fInvHMatrixB)(ivar,jvar) );
      }
   }

   // sanity check
   if (chi2 < 0) Log() << kFATAL << "<GetChi2> negative chi2: " << chi2 << Endl;

   return chi2;
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::AddWeightsXMLTo( void* parent ) const 
{
   // create XML description for HMatrix classification

   void* wght = gTools().AddChild(parent, "Weights");
   gTools().WriteTVectorDToXML( wght, "VecMeanS", fVecMeanS    ); 
   gTools().WriteTVectorDToXML( wght, "VecMeanB", fVecMeanB    );
   gTools().WriteTMatrixDToXML( wght, "InvHMatS", fInvHMatrixS ); 
   gTools().WriteTMatrixDToXML( wght, "InvHMatB", fInvHMatrixB );
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::ReadWeightsFromXML( void* wghtnode )
{
   // read weights from XML file

   void* descnode = gTools().GetChild(wghtnode);
   gTools().ReadTVectorDFromXML( descnode, "VecMeanS", fVecMeanS    );
   descnode = gTools().GetNextChild(descnode);
   gTools().ReadTVectorDFromXML( descnode, "VecMeanB", fVecMeanB    );
   descnode = gTools().GetNextChild(descnode);
   gTools().ReadTMatrixDFromXML( descnode, "InvHMatS", fInvHMatrixS ); 
   descnode = gTools().GetNextChild(descnode);
   gTools().ReadTMatrixDFromXML( descnode, "InvHMatB", fInvHMatrixB );
}

//_______________________________________________________________________
void  TMVA::MethodHMatrix::ReadWeightsFromStream( std::istream& istr )
{
   // read variable names and min/max
   // NOTE: the latter values are mandatory for the normalisation 
   // in the reader application !!!
   UInt_t ivar,jvar;
   TString var, dummy;
   istr >> dummy;
   //this->SetMethodName(dummy);

   // mean vectors
   for (ivar=0; ivar<GetNvar(); ivar++) 
      istr >> (*fVecMeanS)(ivar) >> (*fVecMeanB)(ivar);

   // inverse covariance matrices (signal)
   for (ivar=0; ivar<GetNvar(); ivar++) 
      for (jvar=0; jvar<GetNvar(); jvar++) 
         istr >> (*fInvHMatrixS)(ivar,jvar);

   // inverse covariance matrices (background)
   for (ivar=0; ivar<GetNvar(); ivar++) 
      for (jvar=0; jvar<GetNvar(); jvar++) 
         istr >> (*fInvHMatrixB)(ivar,jvar);
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::MakeClassSpecific( std::ostream& fout, const TString& className ) const
{
   // write Fisher-specific classifier response
   fout << "   // arrays of input evt vs. variable " << std::endl;
   fout << "   double fInvHMatrixS[" << GetNvar() << "][" << GetNvar() << "]; // inverse H-matrix (signal)" << std::endl;
   fout << "   double fInvHMatrixB[" << GetNvar() << "][" << GetNvar() << "]; // inverse H-matrix (background)" << std::endl;
   fout << "   double fVecMeanS[" << GetNvar() << "];    // vector of mean values (signal)" << std::endl;
   fout << "   double fVecMeanB[" << GetNvar() << "];    // vector of mean values (background)" << std::endl;
   fout << "   " << std::endl;
   fout << "   double GetChi2( const std::vector<double>& inputValues, int type ) const;" << std::endl;
   fout << "};" << std::endl;
   fout << "   " << std::endl;
   fout << "void " << className << "::Initialize() " << std::endl;
   fout << "{" << std::endl;
   fout << "   // init vectors with mean values" << std::endl;
   for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
      fout << "   fVecMeanS[" << ivar << "] = " << (*fVecMeanS)(ivar) << ";" << std::endl;
      fout << "   fVecMeanB[" << ivar << "] = " << (*fVecMeanB)(ivar) << ";" << std::endl;
   }
   fout << "   " << std::endl;
   fout << "   // init H-matrices" << std::endl;
   for (UInt_t ivar=0; ivar<GetNvar(); ivar++) {
      for (UInt_t jvar=0; jvar<GetNvar(); jvar++) {
         fout << "   fInvHMatrixS[" << ivar << "][" << jvar << "] = " 
              << (*fInvHMatrixS)(ivar,jvar) << ";" << std::endl;
         fout << "   fInvHMatrixB[" << ivar << "][" << jvar << "] = " 
              << (*fInvHMatrixB)(ivar,jvar) << ";" << std::endl;
      }
   }
   fout << "}" << std::endl;
   fout << "   " << std::endl;
   fout << "inline double " << className << "::GetMvaValue__( const std::vector<double>& inputValues ) const" << std::endl;
   fout << "{" << std::endl;
   fout << "   // returns the H-matrix signal estimator" << std::endl;
   fout << "   std::vector<double> inputValuesSig = inputValues;" << std::endl;
   fout << "   std::vector<double> inputValuesBgd = inputValues;" << std::endl;
   if (GetTransformationHandler().GetTransformationList().GetSize() != 0) {

      UInt_t signalClass    =DataInfo().GetClassInfo("Signal")->GetNumber();
      UInt_t backgroundClass=DataInfo().GetClassInfo("Background")->GetNumber();

      fout << "   Transform(inputValuesSig," << signalClass << ");" << std::endl;
      fout << "   Transform(inputValuesBgd," << backgroundClass << ");" << std::endl;
   }

//   fout << "   for(uint i=0; i<GetNvar(); ++i) std::cout << inputValuesSig.at(i) << \"  \" << inputValuesBgd.at(i) << std::endl; " << std::endl;

   fout << "   double s = GetChi2( inputValuesSig, " << Types::kSignal << " );" << std::endl;
   fout << "   double b = GetChi2( inputValuesBgd, " << Types::kBackground << " );" << std::endl;

//   fout << "   std::cout << s << \"  \" << b << std::endl; " << std::endl;

   fout << "   " << std::endl;
   fout << "   if (s+b <= 0) std::cout << \"Problem in class " << className << "::GetMvaValue__: s+b = \"" << std::endl;
   fout << "                           << s+b << \" <= 0 \"  << std::endl;" << std::endl;
   fout << "   " << std::endl;
   fout << "   return (b - s)/(s + b);" << std::endl;
   fout << "}" << std::endl;
   fout << "   " << std::endl;
   fout << "inline double " << className << "::GetChi2( const std::vector<double>& inputValues, int type ) const" << std::endl;
   fout << "{" << std::endl;
   fout << "   // compute chi2-estimator for event according to type (signal/background)" << std::endl;
   fout << "   " << std::endl;
   fout << "   size_t ivar,jvar;" << std::endl;
   fout << "   double chi2 = 0;" << std::endl;
   fout << "   for (ivar=0; ivar<GetNvar(); ivar++) {" << std::endl;
   fout << "      for (jvar=0; jvar<GetNvar(); jvar++) {" << std::endl;
   fout << "         if (type == " << Types::kSignal << ") " << std::endl;
   fout << "            chi2 += ( (inputValues[ivar] - fVecMeanS[ivar])*(inputValues[jvar] - fVecMeanS[jvar])" << std::endl;
   fout << "                      * fInvHMatrixS[ivar][jvar] );" << std::endl;
   fout << "         else" << std::endl;
   fout << "            chi2 += ( (inputValues[ivar] - fVecMeanB[ivar])*(inputValues[jvar] - fVecMeanB[jvar])" << std::endl;
   fout << "                      * fInvHMatrixB[ivar][jvar] );" << std::endl;
   fout << "      }" << std::endl;
   fout << "   }   // loop over variables   " << std::endl;
   fout << "   " << std::endl;
   fout << "   // sanity check" << std::endl;
   fout << "   if (chi2 < 0) std::cout << \"Problem in class " << className << "::GetChi2: chi2 = \"" << std::endl;
   fout << "                           << chi2 << \" < 0 \"  << std::endl;" << std::endl;
   fout << "   " << std::endl;
   fout << "   return chi2;" << std::endl;
   fout << "}" << std::endl;
   fout << "   " << std::endl;
   fout << "// Clean up" << std::endl;
   fout << "inline void " << className << "::Clear() " << std::endl;
   fout << "{" << std::endl;
   fout << "   // nothing to clear" << std::endl;
   fout << "}" << std::endl;
}

//_______________________________________________________________________
void TMVA::MethodHMatrix::GetHelpMessage() const
{
   // get help message text
   //
   // typical length of text line: 
   //         "|--------------------------------------------------------------|"
   Log() << Endl;
   Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
   Log() << Endl;
   Log() << "The H-Matrix classifier discriminates one class (signal) of a feature" << Endl;
   Log() << "vector from another (background). The correlated elements of the" << Endl;
   Log() << "vector are assumed to be Gaussian distributed, and the inverse of" << Endl;
   Log() << "the covariance matrix is the H-Matrix. A multivariate chi-squared" << Endl;
   Log() << "estimator is built that exploits differences in the mean values of" << Endl;
   Log() << "the vector elements between the two classes for the purpose of" << Endl;
   Log() << "discrimination." << Endl;
   Log() << Endl;
   Log() << gTools().Color("bold") << "--- Performance optimisation:" << gTools().Color("reset") << Endl;
   Log() << Endl;
   Log() << "The TMVA implementation of the H-Matrix classifier has been shown" << Endl;
   Log() << "to underperform in comparison with the corresponding Fisher discriminant," << Endl;
   Log() << "when using similar assumptions and complexity. Its use is therefore" << Endl;
   Log() << "depreciated. Only in cases where the background model is strongly" << Endl;
   Log() << "non-Gaussian, H-Matrix may perform better than Fisher. In such" << Endl;
   Log() << "occurrences the user is advised to employ non-linear classifiers. " << Endl;
   Log() << Endl;
   Log() << gTools().Color("bold") << "--- Performance tuning via configuration options:" << gTools().Color("reset") << Endl;
   Log() << Endl;
   Log() << "None" << Endl;
}
 MethodHMatrix.cxx:1
 MethodHMatrix.cxx:2
 MethodHMatrix.cxx:3
 MethodHMatrix.cxx:4
 MethodHMatrix.cxx:5
 MethodHMatrix.cxx:6
 MethodHMatrix.cxx:7
 MethodHMatrix.cxx:8
 MethodHMatrix.cxx:9
 MethodHMatrix.cxx:10
 MethodHMatrix.cxx:11
 MethodHMatrix.cxx:12
 MethodHMatrix.cxx:13
 MethodHMatrix.cxx:14
 MethodHMatrix.cxx:15
 MethodHMatrix.cxx:16
 MethodHMatrix.cxx:17
 MethodHMatrix.cxx:18
 MethodHMatrix.cxx:19
 MethodHMatrix.cxx:20
 MethodHMatrix.cxx:21
 MethodHMatrix.cxx:22
 MethodHMatrix.cxx:23
 MethodHMatrix.cxx:24
 MethodHMatrix.cxx:25
 MethodHMatrix.cxx:26
 MethodHMatrix.cxx:27
 MethodHMatrix.cxx:28
 MethodHMatrix.cxx:29
 MethodHMatrix.cxx:30
 MethodHMatrix.cxx:31
 MethodHMatrix.cxx:32
 MethodHMatrix.cxx:33
 MethodHMatrix.cxx:34
 MethodHMatrix.cxx:35
 MethodHMatrix.cxx:36
 MethodHMatrix.cxx:37
 MethodHMatrix.cxx:38
 MethodHMatrix.cxx:39
 MethodHMatrix.cxx:40
 MethodHMatrix.cxx:41
 MethodHMatrix.cxx:42
 MethodHMatrix.cxx:43
 MethodHMatrix.cxx:44
 MethodHMatrix.cxx:45
 MethodHMatrix.cxx:46
 MethodHMatrix.cxx:47
 MethodHMatrix.cxx:48
 MethodHMatrix.cxx:49
 MethodHMatrix.cxx:50
 MethodHMatrix.cxx:51
 MethodHMatrix.cxx:52
 MethodHMatrix.cxx:53
 MethodHMatrix.cxx:54
 MethodHMatrix.cxx:55
 MethodHMatrix.cxx:56
 MethodHMatrix.cxx:57
 MethodHMatrix.cxx:58
 MethodHMatrix.cxx:59
 MethodHMatrix.cxx:60
 MethodHMatrix.cxx:61
 MethodHMatrix.cxx:62
 MethodHMatrix.cxx:63
 MethodHMatrix.cxx:64
 MethodHMatrix.cxx:65
 MethodHMatrix.cxx:66
 MethodHMatrix.cxx:67
 MethodHMatrix.cxx:68
 MethodHMatrix.cxx:69
 MethodHMatrix.cxx:70
 MethodHMatrix.cxx:71
 MethodHMatrix.cxx:72
 MethodHMatrix.cxx:73
 MethodHMatrix.cxx:74
 MethodHMatrix.cxx:75
 MethodHMatrix.cxx:76
 MethodHMatrix.cxx:77
 MethodHMatrix.cxx:78
 MethodHMatrix.cxx:79
 MethodHMatrix.cxx:80
 MethodHMatrix.cxx:81
 MethodHMatrix.cxx:82
 MethodHMatrix.cxx:83
 MethodHMatrix.cxx:84
 MethodHMatrix.cxx:85
 MethodHMatrix.cxx:86
 MethodHMatrix.cxx:87
 MethodHMatrix.cxx:88
 MethodHMatrix.cxx:89
 MethodHMatrix.cxx:90
 MethodHMatrix.cxx:91
 MethodHMatrix.cxx:92
 MethodHMatrix.cxx:93
 MethodHMatrix.cxx:94
 MethodHMatrix.cxx:95
 MethodHMatrix.cxx:96
 MethodHMatrix.cxx:97
 MethodHMatrix.cxx:98
 MethodHMatrix.cxx:99
 MethodHMatrix.cxx:100
 MethodHMatrix.cxx:101
 MethodHMatrix.cxx:102
 MethodHMatrix.cxx:103
 MethodHMatrix.cxx:104
 MethodHMatrix.cxx:105
 MethodHMatrix.cxx:106
 MethodHMatrix.cxx:107
 MethodHMatrix.cxx:108
 MethodHMatrix.cxx:109
 MethodHMatrix.cxx:110
 MethodHMatrix.cxx:111
 MethodHMatrix.cxx:112
 MethodHMatrix.cxx:113
 MethodHMatrix.cxx:114
 MethodHMatrix.cxx:115
 MethodHMatrix.cxx:116
 MethodHMatrix.cxx:117
 MethodHMatrix.cxx:118
 MethodHMatrix.cxx:119
 MethodHMatrix.cxx:120
 MethodHMatrix.cxx:121
 MethodHMatrix.cxx:122
 MethodHMatrix.cxx:123
 MethodHMatrix.cxx:124
 MethodHMatrix.cxx:125
 MethodHMatrix.cxx:126
 MethodHMatrix.cxx:127
 MethodHMatrix.cxx:128
 MethodHMatrix.cxx:129
 MethodHMatrix.cxx:130
 MethodHMatrix.cxx:131
 MethodHMatrix.cxx:132
 MethodHMatrix.cxx:133
 MethodHMatrix.cxx:134
 MethodHMatrix.cxx:135
 MethodHMatrix.cxx:136
 MethodHMatrix.cxx:137
 MethodHMatrix.cxx:138
 MethodHMatrix.cxx:139
 MethodHMatrix.cxx:140
 MethodHMatrix.cxx:141
 MethodHMatrix.cxx:142
 MethodHMatrix.cxx:143
 MethodHMatrix.cxx:144
 MethodHMatrix.cxx:145
 MethodHMatrix.cxx:146
 MethodHMatrix.cxx:147
 MethodHMatrix.cxx:148
 MethodHMatrix.cxx:149
 MethodHMatrix.cxx:150
 MethodHMatrix.cxx:151
 MethodHMatrix.cxx:152
 MethodHMatrix.cxx:153
 MethodHMatrix.cxx:154
 MethodHMatrix.cxx:155
 MethodHMatrix.cxx:156
 MethodHMatrix.cxx:157
 MethodHMatrix.cxx:158
 MethodHMatrix.cxx:159
 MethodHMatrix.cxx:160
 MethodHMatrix.cxx:161
 MethodHMatrix.cxx:162
 MethodHMatrix.cxx:163
 MethodHMatrix.cxx:164
 MethodHMatrix.cxx:165
 MethodHMatrix.cxx:166
 MethodHMatrix.cxx:167
 MethodHMatrix.cxx:168
 MethodHMatrix.cxx:169
 MethodHMatrix.cxx:170
 MethodHMatrix.cxx:171
 MethodHMatrix.cxx:172
 MethodHMatrix.cxx:173
 MethodHMatrix.cxx:174
 MethodHMatrix.cxx:175
 MethodHMatrix.cxx:176
 MethodHMatrix.cxx:177
 MethodHMatrix.cxx:178
 MethodHMatrix.cxx:179
 MethodHMatrix.cxx:180
 MethodHMatrix.cxx:181
 MethodHMatrix.cxx:182
 MethodHMatrix.cxx:183
 MethodHMatrix.cxx:184
 MethodHMatrix.cxx:185
 MethodHMatrix.cxx:186
 MethodHMatrix.cxx:187
 MethodHMatrix.cxx:188
 MethodHMatrix.cxx:189
 MethodHMatrix.cxx:190
 MethodHMatrix.cxx:191
 MethodHMatrix.cxx:192
 MethodHMatrix.cxx:193
 MethodHMatrix.cxx:194
 MethodHMatrix.cxx:195
 MethodHMatrix.cxx:196
 MethodHMatrix.cxx:197
 MethodHMatrix.cxx:198
 MethodHMatrix.cxx:199
 MethodHMatrix.cxx:200
 MethodHMatrix.cxx:201
 MethodHMatrix.cxx:202
 MethodHMatrix.cxx:203
 MethodHMatrix.cxx:204
 MethodHMatrix.cxx:205
 MethodHMatrix.cxx:206
 MethodHMatrix.cxx:207
 MethodHMatrix.cxx:208
 MethodHMatrix.cxx:209
 MethodHMatrix.cxx:210
 MethodHMatrix.cxx:211
 MethodHMatrix.cxx:212
 MethodHMatrix.cxx:213
 MethodHMatrix.cxx:214
 MethodHMatrix.cxx:215
 MethodHMatrix.cxx:216
 MethodHMatrix.cxx:217
 MethodHMatrix.cxx:218
 MethodHMatrix.cxx:219
 MethodHMatrix.cxx:220
 MethodHMatrix.cxx:221
 MethodHMatrix.cxx:222
 MethodHMatrix.cxx:223
 MethodHMatrix.cxx:224
 MethodHMatrix.cxx:225
 MethodHMatrix.cxx:226
 MethodHMatrix.cxx:227
 MethodHMatrix.cxx:228
 MethodHMatrix.cxx:229
 MethodHMatrix.cxx:230
 MethodHMatrix.cxx:231
 MethodHMatrix.cxx:232
 MethodHMatrix.cxx:233
 MethodHMatrix.cxx:234
 MethodHMatrix.cxx:235
 MethodHMatrix.cxx:236
 MethodHMatrix.cxx:237
 MethodHMatrix.cxx:238
 MethodHMatrix.cxx:239
 MethodHMatrix.cxx:240
 MethodHMatrix.cxx:241
 MethodHMatrix.cxx:242
 MethodHMatrix.cxx:243
 MethodHMatrix.cxx:244
 MethodHMatrix.cxx:245
 MethodHMatrix.cxx:246
 MethodHMatrix.cxx:247
 MethodHMatrix.cxx:248
 MethodHMatrix.cxx:249
 MethodHMatrix.cxx:250
 MethodHMatrix.cxx:251
 MethodHMatrix.cxx:252
 MethodHMatrix.cxx:253
 MethodHMatrix.cxx:254
 MethodHMatrix.cxx:255
 MethodHMatrix.cxx:256
 MethodHMatrix.cxx:257
 MethodHMatrix.cxx:258
 MethodHMatrix.cxx:259
 MethodHMatrix.cxx:260
 MethodHMatrix.cxx:261
 MethodHMatrix.cxx:262
 MethodHMatrix.cxx:263
 MethodHMatrix.cxx:264
 MethodHMatrix.cxx:265
 MethodHMatrix.cxx:266
 MethodHMatrix.cxx:267
 MethodHMatrix.cxx:268
 MethodHMatrix.cxx:269
 MethodHMatrix.cxx:270
 MethodHMatrix.cxx:271
 MethodHMatrix.cxx:272
 MethodHMatrix.cxx:273
 MethodHMatrix.cxx:274
 MethodHMatrix.cxx:275
 MethodHMatrix.cxx:276
 MethodHMatrix.cxx:277
 MethodHMatrix.cxx:278
 MethodHMatrix.cxx:279
 MethodHMatrix.cxx:280
 MethodHMatrix.cxx:281
 MethodHMatrix.cxx:282
 MethodHMatrix.cxx:283
 MethodHMatrix.cxx:284
 MethodHMatrix.cxx:285
 MethodHMatrix.cxx:286
 MethodHMatrix.cxx:287
 MethodHMatrix.cxx:288
 MethodHMatrix.cxx:289
 MethodHMatrix.cxx:290
 MethodHMatrix.cxx:291
 MethodHMatrix.cxx:292
 MethodHMatrix.cxx:293
 MethodHMatrix.cxx:294
 MethodHMatrix.cxx:295
 MethodHMatrix.cxx:296
 MethodHMatrix.cxx:297
 MethodHMatrix.cxx:298
 MethodHMatrix.cxx:299
 MethodHMatrix.cxx:300
 MethodHMatrix.cxx:301
 MethodHMatrix.cxx:302
 MethodHMatrix.cxx:303
 MethodHMatrix.cxx:304
 MethodHMatrix.cxx:305
 MethodHMatrix.cxx:306
 MethodHMatrix.cxx:307
 MethodHMatrix.cxx:308
 MethodHMatrix.cxx:309
 MethodHMatrix.cxx:310
 MethodHMatrix.cxx:311
 MethodHMatrix.cxx:312
 MethodHMatrix.cxx:313
 MethodHMatrix.cxx:314
 MethodHMatrix.cxx:315
 MethodHMatrix.cxx:316
 MethodHMatrix.cxx:317
 MethodHMatrix.cxx:318
 MethodHMatrix.cxx:319
 MethodHMatrix.cxx:320
 MethodHMatrix.cxx:321
 MethodHMatrix.cxx:322
 MethodHMatrix.cxx:323
 MethodHMatrix.cxx:324
 MethodHMatrix.cxx:325
 MethodHMatrix.cxx:326
 MethodHMatrix.cxx:327
 MethodHMatrix.cxx:328
 MethodHMatrix.cxx:329
 MethodHMatrix.cxx:330
 MethodHMatrix.cxx:331
 MethodHMatrix.cxx:332
 MethodHMatrix.cxx:333
 MethodHMatrix.cxx:334
 MethodHMatrix.cxx:335
 MethodHMatrix.cxx:336
 MethodHMatrix.cxx:337
 MethodHMatrix.cxx:338
 MethodHMatrix.cxx:339
 MethodHMatrix.cxx:340
 MethodHMatrix.cxx:341
 MethodHMatrix.cxx:342
 MethodHMatrix.cxx:343
 MethodHMatrix.cxx:344
 MethodHMatrix.cxx:345
 MethodHMatrix.cxx:346
 MethodHMatrix.cxx:347
 MethodHMatrix.cxx:348
 MethodHMatrix.cxx:349
 MethodHMatrix.cxx:350
 MethodHMatrix.cxx:351
 MethodHMatrix.cxx:352
 MethodHMatrix.cxx:353
 MethodHMatrix.cxx:354
 MethodHMatrix.cxx:355
 MethodHMatrix.cxx:356
 MethodHMatrix.cxx:357
 MethodHMatrix.cxx:358
 MethodHMatrix.cxx:359
 MethodHMatrix.cxx:360
 MethodHMatrix.cxx:361
 MethodHMatrix.cxx:362
 MethodHMatrix.cxx:363
 MethodHMatrix.cxx:364
 MethodHMatrix.cxx:365
 MethodHMatrix.cxx:366
 MethodHMatrix.cxx:367
 MethodHMatrix.cxx:368
 MethodHMatrix.cxx:369
 MethodHMatrix.cxx:370
 MethodHMatrix.cxx:371
 MethodHMatrix.cxx:372
 MethodHMatrix.cxx:373
 MethodHMatrix.cxx:374
 MethodHMatrix.cxx:375
 MethodHMatrix.cxx:376
 MethodHMatrix.cxx:377
 MethodHMatrix.cxx:378
 MethodHMatrix.cxx:379
 MethodHMatrix.cxx:380
 MethodHMatrix.cxx:381
 MethodHMatrix.cxx:382
 MethodHMatrix.cxx:383
 MethodHMatrix.cxx:384
 MethodHMatrix.cxx:385
 MethodHMatrix.cxx:386
 MethodHMatrix.cxx:387
 MethodHMatrix.cxx:388
 MethodHMatrix.cxx:389
 MethodHMatrix.cxx:390
 MethodHMatrix.cxx:391
 MethodHMatrix.cxx:392
 MethodHMatrix.cxx:393
 MethodHMatrix.cxx:394
 MethodHMatrix.cxx:395
 MethodHMatrix.cxx:396
 MethodHMatrix.cxx:397
 MethodHMatrix.cxx:398
 MethodHMatrix.cxx:399
 MethodHMatrix.cxx:400
 MethodHMatrix.cxx:401
 MethodHMatrix.cxx:402
 MethodHMatrix.cxx:403
 MethodHMatrix.cxx:404
 MethodHMatrix.cxx:405
 MethodHMatrix.cxx:406
 MethodHMatrix.cxx:407
 MethodHMatrix.cxx:408
 MethodHMatrix.cxx:409
 MethodHMatrix.cxx:410
 MethodHMatrix.cxx:411
 MethodHMatrix.cxx:412
 MethodHMatrix.cxx:413
 MethodHMatrix.cxx:414
 MethodHMatrix.cxx:415
 MethodHMatrix.cxx:416
 MethodHMatrix.cxx:417
 MethodHMatrix.cxx:418
 MethodHMatrix.cxx:419
 MethodHMatrix.cxx:420
 MethodHMatrix.cxx:421
 MethodHMatrix.cxx:422
 MethodHMatrix.cxx:423
 MethodHMatrix.cxx:424
 MethodHMatrix.cxx:425
 MethodHMatrix.cxx:426
 MethodHMatrix.cxx:427
 MethodHMatrix.cxx:428
 MethodHMatrix.cxx:429
 MethodHMatrix.cxx:430
 MethodHMatrix.cxx:431
 MethodHMatrix.cxx:432
 MethodHMatrix.cxx:433
 MethodHMatrix.cxx:434
 MethodHMatrix.cxx:435
 MethodHMatrix.cxx:436
 MethodHMatrix.cxx:437
 MethodHMatrix.cxx:438
 MethodHMatrix.cxx:439
 MethodHMatrix.cxx:440
 MethodHMatrix.cxx:441
 MethodHMatrix.cxx:442
 MethodHMatrix.cxx:443
 MethodHMatrix.cxx:444
 MethodHMatrix.cxx:445
 MethodHMatrix.cxx:446
 MethodHMatrix.cxx:447
 MethodHMatrix.cxx:448
 MethodHMatrix.cxx:449
 MethodHMatrix.cxx:450
 MethodHMatrix.cxx:451
 MethodHMatrix.cxx:452
 MethodHMatrix.cxx:453
 MethodHMatrix.cxx:454
 MethodHMatrix.cxx:455
 MethodHMatrix.cxx:456
 MethodHMatrix.cxx:457
 MethodHMatrix.cxx:458
 MethodHMatrix.cxx:459
 MethodHMatrix.cxx:460
 MethodHMatrix.cxx:461
 MethodHMatrix.cxx:462
 MethodHMatrix.cxx:463
 MethodHMatrix.cxx:464
 MethodHMatrix.cxx:465
 MethodHMatrix.cxx:466
 MethodHMatrix.cxx:467
 MethodHMatrix.cxx:468
 MethodHMatrix.cxx:469
 MethodHMatrix.cxx:470
 MethodHMatrix.cxx:471
 MethodHMatrix.cxx:472
 MethodHMatrix.cxx:473
 MethodHMatrix.cxx:474
 MethodHMatrix.cxx:475
 MethodHMatrix.cxx:476
 MethodHMatrix.cxx:477
 MethodHMatrix.cxx:478
 MethodHMatrix.cxx:479
 MethodHMatrix.cxx:480