// @(#)root/mathcore:$Id$
// Authors: Bartolomeu Rabacal    05/2010
/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006 , LCG ROOT MathLib Team                         *
 *                                                                    *
 *                                                                    *
 **********************************************************************/
// Header file for GoFTest

#ifndef ROOT_Math_GoFTest
#define ROOT_Math_GoFTest

#include <memory>

#ifndef ROOT_Math_WrappedFunction
#include "Math/WrappedFunction.h"
#endif
#ifndef ROOT_TMath
#include "TMath.h"
#endif

/*
  Goodness of Fit Statistical Tests Toolkit -- Anderson-Darling and Kolmogorov-Smirnov 1- and 2-Samples Tests
*/

namespace ROOT {

   namespace Fit { 
      class BinData; 
   }
namespace Math {

class GoFTest {
public:

   enum EDistribution { // H0 distributions for using only with 1-sample tests
      kUndefined,       // Default value for non templated 1-sample test. Set with SetDistribution
      kUserDefined,     // For internal use only within the class's template constructor
      kGaussian,
      kLogNormal,
      kExponential
   };

   enum EUserDistribution { // User input distribution option
      kCDF,
      kPDF                  // Default value
   };

   enum ETestType { // Goodness of Fit test types for using with the class's unary funtions as a shorthand for the in-built methods
      kAD,   // Anderson-Darling Test. Default value
      kAD2s, // Anderson-Darling 2-Samples Test
      kKS,   // Kolmogorov-Smirnov Test
      kKS2s  // Kolmogorov-Smirnov 2-Samples Test
   };

   /* Constructor for using only with 2-samples tests */
   GoFTest(UInt_t sample1Size, const Double_t* sample1, UInt_t sample2Size, const Double_t* sample2);

   /* Constructor for using only with 1-sample tests with a specified distribution */
   GoFTest(UInt_t sampleSize, const Double_t* sample, EDistribution dist = kUndefined);

   /* Templated constructor for using only with 1-sample tests with a user specified distribution */
   template<class Dist>
   GoFTest(UInt_t sampleSize, const Double_t* sample, Dist& dist, EUserDistribution userDist = kPDF,
           Double_t xmin = 1, Double_t xmax = 0)
   {
      Instantiate(sample, sampleSize);
      SetUserDistribution<Dist>(dist, userDist, xmin, xmax);
   }

   /* Specialization using IGenFunction interface */
   GoFTest(UInt_t sampleSize, const Double_t* sample, const IGenFunction& dist, EUserDistribution userDist = kPDF,
           Double_t xmin = 1, Double_t xmax = 0)
   {
      Instantiate(sample, sampleSize);
      SetUserDistribution(dist, userDist, xmin, xmax);
   }

   /* Sets the user input distribution function for 1-sample tests. */
   template<class Dist>
   void SetUserDistribution(Dist& dist, EUserDistribution userDist = kPDF, Double_t xmin = 1, Double_t xmax = 0) {
      WrappedFunction<Dist&> wdist(dist);
      SetDistributionFunction(wdist, userDist, xmin, xmax);
   }

   /* Template specialization to set the user input distribution for 1-sample tests */
   void SetUserDistribution(const IGenFunction& dist, GoFTest::EUserDistribution userDist = kPDF, Double_t xmin = 1, Double_t xmax = 0) {
      SetDistributionFunction(dist, userDist, xmin, xmax);
   }

   /* Sets the user input distribution as a probability density function for 1-sample tests */
   template<class Dist>
   void SetUserPDF(Dist& pdf, Double_t xmin = 1, Double_t xmax = 0) {
      SetUserDistribution<Dist>(pdf, kPDF, xmin, xmax);
   }

   /* Template specialization to set the user input distribution as a probability density function for 1-sample tests */
   void SetUserPDF(const IGenFunction& pdf, Double_t xmin = 1, Double_t xmax = 0) {
      SetUserDistribution(pdf, kPDF, xmin, xmax);
   }

   /* Sets the user input distribution as a cumulative distribution function for 1-sample tests
      The CDF must return zero
    */
   template<class Dist>
   void SetUserCDF(Dist& cdf, Double_t xmin = 1, Double_t xmax = 0) {
      SetUserDistribution<Dist>(cdf, kCDF, xmin, xmax);
   }

   /* Template specialization to set the user input distribution as a cumulative distribution function for 1-sample tests */
   void SetUserCDF(const IGenFunction& cdf, Double_t xmin = 1, Double_t xmax = 0)  {
      SetUserDistribution(cdf, kCDF, xmin, xmax);
   }


   /* Sets the distribution for the predefined distribution types  */
   void SetDistribution(EDistribution dist);


   virtual ~GoFTest();

/*
  The Anderson-Darling K-Sample Test algorithm is described and taken from
  http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/andeksam.htm
  and described and taken from
   (1) Scholz F.W., Stephens M.A. (1987), K-sample Anderson-Darling Tests, Journal of the American Statistical Association, 82, 918–924. (2-samples variant implemented)
*/ void AndersonDarling2SamplesTest(Double_t& pvalue, Double_t& testStat) const;
   Double_t AndersonDarling2SamplesTest(const Char_t* option = "p") const; // Returns default p-value; option "t" returns the test statistic value "A2"

/*
  The Anderson-Darling 1-Sample Test algorithm for a specific distribution is described at
  http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/andedarl.htm
  and described and taken from (2)
  Marsaglia J.C.W., Marsaglia G. (2004), Evaluating the Anderson-Darling Distribution, Journal of Statistical Software, Volume 09, Issue i02.
  and described and taken from (3)
  Lewis P.A.W. (1961), The Annals of Mathematical Statistics, Distribution of the Anderson-Darling Statistic, Volume 32, Number 4, 1118-1124.
*/ void AndersonDarlingTest(Double_t& pvalue, Double_t& testStat) const;
   Double_t AndersonDarlingTest(const Char_t* option = "p") const; // Returns default p-value; option "t" returns the test statistic value "A2"

/*
  The Kolmogorov-Smirnov 2-Samples Test algorithm is described at
  http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/ks2samp.htm
  and described and taken from
  http://root.cern.ch/root/html/TMath.html#TMath:KolmogorovTest
*/ void KolmogorovSmirnov2SamplesTest(Double_t& pvalue, Double_t& testStat) const;
   Double_t KolmogorovSmirnov2SamplesTest(const Char_t* option = "p") const; // Returns default p-value; option "t" returns the test statistic value "Dn"

/*
  The Kolmogorov-Smirnov 1-Sample Test algorithm for a specific distribution is described at
  http://www.itl.nist.gov/div898/software/dataplot/refman1/auxillar/kstest.htm
  and described and taken from (4)
  Press W. H., Teukolsky S.A., Vetterling W.T., Flannery B.P. (2007), Numerical Recipes - The Art of Scientific Computing (Third Edition), Cambridge Univerdity Press
*/ void KolmogorovSmirnovTest(Double_t& pvalue, Double_t& testStat) const;
   Double_t KolmogorovSmirnovTest(const Char_t* option = "p") const; // Returns default p-value; option "t" returns the test statistic value "Dn"

   // The class's unary functions
   void operator()(ETestType test, Double_t& pvalue, Double_t& testStat) const;

   // Returns default Anderson Darling 1-Sample Test and default p-value; option "t" returns the test statistic value
   // specific to the test type
   Double_t operator()(ETestType test = kAD, const Char_t* option = "p") const; 
 
   // Computation of the K-Sample Anderson-Darling Test's p-value as described in (1) 
   // given a normalized test statistic. The first variant described in the paper is used 
   static Double_t PValueADKSamples(UInt_t nsamples, Double_t A2 ); 

   // Compute The 2-Sample Anderson Darling test for binned data
   static void  AndersonDarling2SamplesTest(const ROOT::Fit::BinData & data1, const ROOT::Fit::BinData & data2, Double_t& pvalue, Double_t& testStat);

private:

   GoFTest();                       // Disallowed default constructor
   GoFTest(GoFTest& gof);           // Disallowed copy constructor
   GoFTest operator=(GoFTest& gof); // Disallowed assign operator

   std::auto_ptr<IGenFunction> fCDF;


   EDistribution fDist;

   Double_t fMean;
   Double_t fSigma;

   std::vector<Double_t> fCombinedSamples;

   std::vector<std::vector<Double_t> > fSamples;

   Bool_t fTestSampleFromH0;

   void SetCDF();
   void SetDistributionFunction(const IGenFunction& cdf, Bool_t isPDF, Double_t xmin, Double_t xmax);

   void Instantiate(const Double_t* sample, UInt_t sampleSize);


   Double_t LogNormalCDF(Double_t x) const;
   Double_t GaussianCDF(Double_t x) const;
   Double_t ExponentialCDF(Double_t x) const;

   static Double_t GetSigmaN(const std::vector<UInt_t> & ns, UInt_t N); // Computation of sigma_N as described in (1)

   static Double_t InterpolatePValues(int nsamples,Double_t A2); // Linear interpolation used in GoFTest::PValueAD2Samples


   Double_t PValueAD1Sample(Double_t A2) const; // Computation of the 1-Sample Anderson-Darling Test's p-value

   void LogSample(); // Applies the logarithm to the sample when the specified distribution to test is LogNormal

   void SetSamples(std::vector<const Double_t*> samples, const std::vector<UInt_t> samplesSizes);

   void SetParameters(); // Sets the estimated mean and standard-deviation from the samples
}; // end GoFTest class


} // ROOT namespace
} // Math namespace
#endif
 GoFTest.h:1
 GoFTest.h:2
 GoFTest.h:3
 GoFTest.h:4
 GoFTest.h:5
 GoFTest.h:6
 GoFTest.h:7
 GoFTest.h:8
 GoFTest.h:9
 GoFTest.h:10
 GoFTest.h:11
 GoFTest.h:12
 GoFTest.h:13
 GoFTest.h:14
 GoFTest.h:15
 GoFTest.h:16
 GoFTest.h:17
 GoFTest.h:18
 GoFTest.h:19
 GoFTest.h:20
 GoFTest.h:21
 GoFTest.h:22
 GoFTest.h:23
 GoFTest.h:24
 GoFTest.h:25
 GoFTest.h:26
 GoFTest.h:27
 GoFTest.h:28
 GoFTest.h:29
 GoFTest.h:30
 GoFTest.h:31
 GoFTest.h:32
 GoFTest.h:33
 GoFTest.h:34
 GoFTest.h:35
 GoFTest.h:36
 GoFTest.h:37
 GoFTest.h:38
 GoFTest.h:39
 GoFTest.h:40
 GoFTest.h:41
 GoFTest.h:42
 GoFTest.h:43
 GoFTest.h:44
 GoFTest.h:45
 GoFTest.h:46
 GoFTest.h:47
 GoFTest.h:48
 GoFTest.h:49
 GoFTest.h:50
 GoFTest.h:51
 GoFTest.h:52
 GoFTest.h:53
 GoFTest.h:54
 GoFTest.h:55
 GoFTest.h:56
 GoFTest.h:57
 GoFTest.h:58
 GoFTest.h:59
 GoFTest.h:60
 GoFTest.h:61
 GoFTest.h:62
 GoFTest.h:63
 GoFTest.h:64
 GoFTest.h:65
 GoFTest.h:66
 GoFTest.h:67
 GoFTest.h:68
 GoFTest.h:69
 GoFTest.h:70
 GoFTest.h:71
 GoFTest.h:72
 GoFTest.h:73
 GoFTest.h:74
 GoFTest.h:75
 GoFTest.h:76
 GoFTest.h:77
 GoFTest.h:78
 GoFTest.h:79
 GoFTest.h:80
 GoFTest.h:81
 GoFTest.h:82
 GoFTest.h:83
 GoFTest.h:84
 GoFTest.h:85
 GoFTest.h:86
 GoFTest.h:87
 GoFTest.h:88
 GoFTest.h:89
 GoFTest.h:90
 GoFTest.h:91
 GoFTest.h:92
 GoFTest.h:93
 GoFTest.h:94
 GoFTest.h:95
 GoFTest.h:96
 GoFTest.h:97
 GoFTest.h:98
 GoFTest.h:99
 GoFTest.h:100
 GoFTest.h:101
 GoFTest.h:102
 GoFTest.h:103
 GoFTest.h:104
 GoFTest.h:105
 GoFTest.h:106
 GoFTest.h:107
 GoFTest.h:108
 GoFTest.h:109
 GoFTest.h:110
 GoFTest.h:111
 GoFTest.h:112
 GoFTest.h:113
 GoFTest.h:114
 GoFTest.h:115
 GoFTest.h:116
 GoFTest.h:117
 GoFTest.h:118
 GoFTest.h:119
 GoFTest.h:120
 GoFTest.h:121
 GoFTest.h:122
 GoFTest.h:123
 GoFTest.h:124
 GoFTest.h:125
 GoFTest.h:126
 GoFTest.h:127
 GoFTest.h:128
 GoFTest.h:129
 GoFTest.h:130
 GoFTest.h:131
 GoFTest.h:132
 GoFTest.h:133
 GoFTest.h:134
 GoFTest.h:135
 GoFTest.h:136
 GoFTest.h:137
 GoFTest.h:138
 GoFTest.h:139
 GoFTest.h:140
 GoFTest.h:141
 GoFTest.h:142
 GoFTest.h:143
 GoFTest.h:144
 GoFTest.h:145
 GoFTest.h:146
 GoFTest.h:147
 GoFTest.h:148
 GoFTest.h:149
 GoFTest.h:150
 GoFTest.h:151
 GoFTest.h:152
 GoFTest.h:153
 GoFTest.h:154
 GoFTest.h:155
 GoFTest.h:156
 GoFTest.h:157
 GoFTest.h:158
 GoFTest.h:159
 GoFTest.h:160
 GoFTest.h:161
 GoFTest.h:162
 GoFTest.h:163
 GoFTest.h:164
 GoFTest.h:165
 GoFTest.h:166
 GoFTest.h:167
 GoFTest.h:168
 GoFTest.h:169
 GoFTest.h:170
 GoFTest.h:171
 GoFTest.h:172
 GoFTest.h:173
 GoFTest.h:174
 GoFTest.h:175
 GoFTest.h:176
 GoFTest.h:177
 GoFTest.h:178
 GoFTest.h:179
 GoFTest.h:180
 GoFTest.h:181
 GoFTest.h:182
 GoFTest.h:183
 GoFTest.h:184
 GoFTest.h:185
 GoFTest.h:186
 GoFTest.h:187
 GoFTest.h:188
 GoFTest.h:189
 GoFTest.h:190
 GoFTest.h:191
 GoFTest.h:192
 GoFTest.h:193
 GoFTest.h:194
 GoFTest.h:195
 GoFTest.h:196
 GoFTest.h:197
 GoFTest.h:198
 GoFTest.h:199
 GoFTest.h:200
 GoFTest.h:201
 GoFTest.h:202
 GoFTest.h:203
 GoFTest.h:204
 GoFTest.h:205
 GoFTest.h:206
 GoFTest.h:207
 GoFTest.h:208
 GoFTest.h:209
 GoFTest.h:210
 GoFTest.h:211
 GoFTest.h:212
 GoFTest.h:213
 GoFTest.h:214
 GoFTest.h:215
 GoFTest.h:216
 GoFTest.h:217
 GoFTest.h:218