00001 #include "TBenchmark.h"
00002 #include "Math/GoFTest.h"
00003 #include "Math/Functor.h"
00004 #include "TROOT.h"
00005 #include "TSystem.h"
00006 #include "TStopwatch.h"
00007
00008 #include "Math/GSLRndmEngines.h"
00009 #if not defined(__CINT__)
00010 #include "Math/Random.h"
00011 #endif
00012
00013 #include "TRandom3.h"
00014
00015 #include <iostream>
00016
00017 #include <cassert>
00018
00019
00020
00021 struct GoFTStress {
00022
00023 static enum EDebugLevelTypes {
00024 kNoDebug,
00025 kBasicDebug,
00026 kStandardDebug,
00027 } fgDebugLevel;
00028
00029 Int_t RunTests() {
00030 Int_t result = 0;
00031 result += UnitTest1();
00032 result += UnitTest2();
00033 result += UnitTest3();
00034 result += UnitTest4();
00035 result += UnitTest5();
00036 result += UnitTest6();
00037 result += UnitTest7();
00038 return result;
00039 }
00040
00041 void PrintBenchmark() {
00042 if (fgDebugLevel == kNoDebug) {
00043 return;
00044 }
00045
00046
00047 Bool_t UNIX = strcmp(gSystem->GetName(), "Unix") == 0;
00048 printf("******************************************************************\n");
00049 if (UNIX) {
00050 FILE *fp = gSystem->OpenPipe("uname -a", "r");
00051 Char_t line[60];
00052 fgets(line,60,fp); line[59] = 0;
00053 printf("* SYS: %s\n",line);
00054 gSystem->ClosePipe(fp);
00055 } else {
00056 const Char_t *os = gSystem->Getenv("OS");
00057 if (!os) {
00058 printf("* SYS: Windows 95\n");
00059 } else {
00060 printf("* SYS: %s %s \n",os,gSystem->Getenv("PROCESSOR_IDENTIFIER"));
00061 }
00062 }
00063
00064 printf("*****************************************************************************************\n");
00065 gBenchmark->Print("GoFTestStress");
00066 #ifdef __CINT__
00067 Double_t reftime = 0.02 ;
00068 #else
00069 Double_t reftime = 0.04;
00070 #endif
00071
00072 Double_t rootmarks = 800. * reftime / gBenchmark->GetCpuTime("GoFTestStress");
00073
00074 printf("*****************************************************************************************\n");
00075 printf("* ROOTMARKS = %6.1f * Root%-8s %d/%d\n", rootmarks, gROOT->GetVersion(),
00076 gROOT->GetVersionDate(),gROOT->GetVersionTime());
00077 printf("*****************************************************************************************\n");
00078 }
00079
00080 private:
00081
00082 Int_t UnitTest1() {
00083 std::cout << "UNIT TEST 1" << std::endl;
00084
00085 UInt_t nsmps = 2;
00086 const UInt_t smpSize1 = 71;
00087 const UInt_t smpSize2 = 135;
00088
00089
00090
00091
00092 const Double_t smp1[smpSize1] = {194, 15, 41, 29, 33, 181, 413, 14, 58, 37, 100, 65, 9, 169, 447, 18, 4, 36, 201, 118, 34, 31, 18, 18, 67, 57, 62, 7, 22, 34, 90, 10, 60, 186, 61, 49, 14, 24, 56, 20, 79, 84, 44, 59, 29, 118, 25, 156, 310, 76, 26, 44, 23, 62, 130, 208, 70, 101, 208, 74, 57, 48, 29, 502, 12, 70, 21, 29, 386, 59, 27};
00093
00094 const Double_t smp2[smpSize2] = {55, 320, 56, 104, 220, 239, 47, 246, 176, 182, 33, 23, 261, 87, 7, 120, 14, 62, 47, 225, 71, 246, 21, 42, 20, 5, 12, 120, 11, 3, 14, 71, 11, 14, 11, 16, 90, 1, 16, 52, 95, 97, 51, 11, 4, 141, 18, 142, 68, 77, 80, 1, 16, 106, 206, 82, 54, 31, 216, 46, 111, 39, 63, 18, 191, 18, 163, 24, 50, 44, 102, 72, 22, 39, 3, 15, 197, 188, 79, 88, 46, 5, 5, 36, 22, 139, 210, 97, 30, 23, 13, 14, 359, 9, 12, 270, 603, 3, 104, 2, 438, 50, 254, 5, 283, 35, 12, 487, 18, 100, 7, 98, 5, 85, 91, 43, 230, 3, 130, 102, 209, 14, 57, 54, 32, 67, 59, 134, 152, 27, 14, 230, 66, 61, 34};
00095
00096 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest( smpSize1, smp1, smpSize2, smp2 );
00097
00098 Double_t A2 = goft->AndersonDarling2SamplesTest("t");
00099
00100 Double_t pvalueAD = (*goft)(ROOT::Math::GoFTest::kAD2s);
00101
00102 Double_t expectedA2_akN = 1.58334 ;
00103
00104 Double_t sigmaN = 0.754539;
00105
00106 Double_t zScore = 0.773108;
00107
00108 Int_t result = PrintResultAD2Samples(nsmps, A2, expectedA2_akN, sigmaN, zScore, pvalueAD);
00109
00110
00111 Double_t Dn = (*goft)(ROOT::Math::GoFTest::kKS2s, "t");
00112 Double_t pvalueKS = goft->KolmogorovSmirnov2SamplesTest();
00113
00114 Double_t expectedDn = 0.139176;
00115
00116 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00117
00118 delete goft;
00119 return result;
00120 }
00121
00122 Int_t UnitTest2() {
00123 std::cout << "UNIT TEST 2" << std::endl;
00124
00125 const UInt_t nsmps = 2;
00126 const UInt_t smpSize = 16;
00127
00128
00129
00130
00131 const Double_t smp1[smpSize] = {38.7, 41.5, 43.8, 44.5, 45.5, 46.0, 47.7, 58.0, 39.2, 39.3, 39.7, 41.4, 41.8, 42.9, 43.3, 45.8};
00132 const Double_t smp2[smpSize] = {34.0, 35.0, 39.0, 40.0, 43.0, 43.0, 44.0, 45.0, 34.0, 34.8, 34.8, 35.4, 37.2, 37.8, 41.2, 42.8};
00133
00134 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest( smpSize, smp1, smpSize, smp2 );
00135
00136
00137 Double_t A2 = (*goft)(ROOT::Math::GoFTest::kAD2s, "t");
00138 Double_t pvalueAD = goft->AndersonDarling2SamplesTest();
00139
00140 Double_t expectedA2_akN = 4.5735;
00141
00142 Double_t sigmaN = 0.719388;
00143
00144 Double_t zScore = 4.96748;
00145
00146 Int_t result = PrintResultAD2Samples(nsmps, A2, expectedA2_akN, sigmaN, zScore, pvalueAD);
00147
00148 Double_t Dn = goft->KolmogorovSmirnov2SamplesTest("t");
00149
00150 Double_t pvalueKS = (*goft)(ROOT::Math::GoFTest::kKS2s);
00151
00152 Double_t expectedDn = 0.5;
00153
00154 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00155
00156 delete goft;
00157 return result;
00158 }
00159
00160 Int_t UnitTest3() {
00161 std::cout << "UNIT TEST 3" << std::endl;
00162
00163 UInt_t nEvents = 1000;
00164 UInt_t nsmps = 1;
00165
00166 ROOT::Math::Random<ROOT::Math::GSLRngMT> r;
00167
00168 Double_t* sample = new Double_t[nEvents];
00169
00170 for (UInt_t i = 0; i < nEvents; ++i) {
00171 Double_t data = r.LogNormal(5.0, 2.0);
00172 sample[i] = data;
00173 assert(sample[i] == data);
00174 }
00175
00176 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest(nEvents, sample, ROOT::Math::GoFTest::kLogNormal);
00177
00178 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug)
00179 std::cout << "LogNormal fitting" << std::endl;
00180
00181
00182 Double_t A2 = goft->operator()(ROOT::Math::GoFTest::kAD, "t");
00183 Double_t pvalueAD = goft->AndersonDarlingTest();
00184
00185 Double_t expectedA2 = 0.422771;
00186
00187 Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD);
00188
00189 Double_t Dn = goft->KolmogorovSmirnovTest("t");
00190
00191 Double_t pvalueKS = goft->operator()(ROOT::Math::GoFTest::kKS);
00192
00193 Double_t expectedDn = 0.0204916;
00194
00195 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00196
00197 delete goft;
00198 return result;
00199 }
00200
00201 Int_t UnitTest4() {
00202 std::cout << "UNIT TEST 4" << std::endl;
00203
00204 UInt_t nEvents = 1000;
00205 UInt_t nsmps = 1;
00206
00207 TRandom3 r;
00208
00209 Double_t* sample = new Double_t[nEvents];
00210
00211 for (UInt_t i = 0; i < nEvents; ++i) {
00212 Double_t data = r.Exp(1.54);
00213 sample[i] = data;
00214 assert(sample[i] == data);
00215 }
00216
00217 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest(nEvents, sample, ROOT::Math::GoFTest::kExponential);
00218
00219 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug)
00220 std::cout << "**Exponential fitting**" << std::endl;
00221
00222 Double_t A2 = goft->AndersonDarlingTest("t");
00223
00224 Double_t pvalueAD = goft->operator()();
00225
00226 Double_t expectedA2 = 0.521153;
00227
00228 Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD);
00229
00230
00231 Double_t Dn = goft->operator()(ROOT::Math::GoFTest::kKS, "t");
00232 Double_t pvalueKS = goft->KolmogorovSmirnovTest();
00233
00234 Double_t expectedDn = 0.0218148;
00235
00236 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00237
00238 delete goft;
00239 return result;
00240 }
00241
00242 Int_t UnitTest5() {
00243 std::cout << "UNIT TEST 5" << std::endl;
00244
00245 UInt_t nEvents = 1000;
00246 UInt_t nsmps = 1;
00247
00248 TRandom3 r;
00249
00250 Double_t* sample = new Double_t[nEvents];
00251
00252 for (UInt_t i = 0; i < nEvents; ++i) {
00253 Double_t data = r.Gaus(300, 50);
00254 sample[i] = data;
00255 assert(sample[i] == data);
00256 }
00257
00258 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest(nEvents, sample);
00259 goft->SetDistribution(ROOT::Math::GoFTest::kGaussian);
00260
00261 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug)
00262 std::cout << "**Gaussian fitting**" << std::endl;
00263
00264 Double_t A2 = goft->AndersonDarlingTest("t");
00265 Double_t pvalueAD = goft->AndersonDarlingTest();
00266
00267 Double_t expectedA2 = 0.441755;
00268
00269 Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD);
00270
00271 Double_t Dn = goft->KolmogorovSmirnovTest("t");
00272 Double_t pvalueKS = goft->KolmogorovSmirnovTest();
00273
00274 Double_t expectedDn = 0.0282508;
00275
00276 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00277
00278 delete goft;
00279 return result;
00280 }
00281
00282 Int_t UnitTest6() {
00283 std::cout << "UNIT TEST 6" << std::endl;
00284 UInt_t nEvents = 1000;
00285 UInt_t nsmps = 1;
00286
00287 TRandom3 r;
00288
00289 Double_t* sample = new Double_t[nEvents];
00290
00291 for (UInt_t i = 0; i < nEvents; ++i) {
00292 Double_t data = r.Landau();
00293 sample[i] = data;
00294 assert(sample[i] == data);
00295 }
00296
00297 ROOT::Math::Functor1D userCdf(&TMath::LandauI);
00298 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest(nEvents, sample, userCdf, ROOT::Math::GoFTest::kCDF);
00299
00300 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug)
00301 std::cout << "**Landau fitting**" << std::endl;
00302
00303 Double_t A2 = goft->AndersonDarlingTest("t");
00304 Double_t pvalueAD = goft->AndersonDarlingTest();
00305
00306 Double_t expectedA2 = 0.544658;
00307
00308 Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD);
00309
00310 Double_t Dn = goft->KolmogorovSmirnovTest("t");
00311 Double_t pvalueKS = goft->KolmogorovSmirnovTest();
00312
00313 Double_t expectedDn = 0.0203432;
00314
00315 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS);
00316
00317 delete goft;
00318 return result;
00319 }
00320
00321 Int_t UnitTest7() {
00322 std::cout << "UNIT TEST 7" << std::endl;
00323
00324 UInt_t nEvents = 1000;
00325 UInt_t nsmps = 1;
00326
00327 TRandom3 r;
00328
00329 Double_t* sample = new Double_t[nEvents];
00330
00331 for (UInt_t i = 0; i < nEvents; ++i) {
00332 Double_t data = r.Landau();
00333 sample[i] = data;
00334 }
00335
00336
00337 ROOT::Math::GoFTest* goft = new ROOT::Math::GoFTest(nEvents, sample);
00338
00339 ROOT::Math::Functor1D userPdf(&TMath::Landau);
00340
00341
00342 double xmin = 3*TMath::MinElement(nEvents, sample);
00343 double xmax = 3*TMath::MaxElement(nEvents, sample);
00344
00345 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug)
00346 std::cout << "**Landau fitting**" << " in [ " << xmin << " , " << xmax << " ]" << std::endl;
00347
00348 goft->SetUserDistribution(userPdf,ROOT::Math::GoFTest::kPDF, xmin, xmax);
00349
00350 Double_t A2 = goft->AndersonDarlingTest("t");
00351 Double_t pvalueAD = goft->AndersonDarlingTest();
00352
00353 Double_t expectedA2 = 0.544658;
00354
00355
00356 Int_t result = PrintResultAD1Sample(A2, expectedA2, pvalueAD,0.002);
00357
00358 Double_t Dn = goft->KolmogorovSmirnovTest("t");
00359 Double_t pvalueKS = goft->KolmogorovSmirnovTest();
00360
00361 Double_t expectedDn = 0.0203432;
00362
00363 result += PrintResultKS(nsmps, Dn, expectedDn, pvalueKS,0.001);
00364
00365 delete goft;
00366 return result;
00367 }
00368
00369 Int_t PrintResultAD2Samples(UInt_t nsmps, Double_t A2, Double_t expectedA2_akN, Double_t sigmaN, Double_t zScore, Double_t pvalue, Double_t limit = 0.0001) {
00370
00371 Double_t A2_akN = A2 * sigmaN + (nsmps - 1);
00372
00373 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug) {
00374 std::cout << "Anderson-Darling 2-Samples Test" << std::endl;
00375
00376 std::cout << "pvalue = " << pvalue << std::endl;
00377
00378 std::cout << "zScore = " << zScore << std::endl;
00379
00380 std::cout << "Expected A2 value = " << A2 << std::endl;
00381
00382 std::cout << "A2_akN = " << A2_akN << std::endl;
00383
00384 std::cout << "Expected A2_akN value = " << expectedA2_akN << std::endl;
00385 }
00386 if (TMath::Abs(A2_akN - expectedA2_akN) < limit * expectedA2_akN || TMath::Abs(A2 - zScore) < limit * zScore) {
00387 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00388 std::cout << "+++++++ TEST OK +++++++ \n" << std::endl;
00389 return EXIT_SUCCESS;
00390 } else {
00391 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00392 std::cout << "------- TEST FAIL ------- \n" << std::endl;
00393 return EXIT_FAILURE;
00394 }
00395 }
00396
00397 Int_t PrintResultAD1Sample(Double_t A2, Double_t expectedA2, Double_t pvalue, Double_t limit = 0.0001) {
00398
00399 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug) {
00400 std::cout << "Anderson-Darling 1-Sample Test" << std::endl;
00401
00402 std::cout << "pvalue = " << pvalue << std::endl;
00403
00404 std::cout << "A2 value = " << A2 << std::endl;
00405
00406 std::cout << "Expected A2 value = " << expectedA2 << std::endl;
00407 }
00408 if (TMath::Abs(A2 - expectedA2) < limit * expectedA2) {
00409 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00410 std::cout << "+++++++ TEST OK +++++++ \n" << std::endl;
00411 return EXIT_SUCCESS;
00412 } else {
00413 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00414 std::cout << "------- TEST FAIL ------- \n" << std::endl;
00415 return EXIT_FAILURE;
00416 }
00417 }
00418
00419 Int_t PrintResultKS(UInt_t nsmps, Double_t Dn, Double_t expectedDn, Double_t pvalue, Double_t limit = 0.0001) {
00420
00421 if (GoFTStress::fgDebugLevel == GoFTStress::kStandardDebug) {
00422 std::cout << "Kolmogorov-Smirnov "<< nsmps << "-Samples Test" << std::endl;
00423
00424 std::cout << "pvalue = " << pvalue << std::endl;
00425
00426 std::cout << "Dn value = " << Dn << std::endl;
00427
00428 std::cout << "Expected Dn value = " << expectedDn << std::endl;
00429 }
00430 if (TMath::Abs(Dn - expectedDn) < limit * expectedDn) {
00431 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00432 std::cout << "+++++++ TEST OK +++++++ \n" << std::endl;
00433 return EXIT_SUCCESS;
00434 } else {
00435 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug)
00436 std::cout << "------- TEST FAIL ------- \n" << std::endl;
00437 return EXIT_FAILURE;
00438 }
00439 }
00440 };
00441
00442 #ifdef __MAKECINT__
00443 #pragma link C++ class GoFTStress-;
00444 #endif
00445
00446 GoFTStress::EDebugLevelTypes GoFTStress::fgDebugLevel;
00447
00448 Int_t RunTests(Int_t argc, Char_t* argv[]) {
00449 Int_t result = 0;
00450 Bool_t validOption(kFALSE);
00451
00452 if (argc == 1) {
00453 GoFTStress::fgDebugLevel = GoFTStress::kBasicDebug;
00454 validOption = kTRUE;
00455 } else if (argc == 3 && strcmp(argv[1], "--o") == 0) {
00456 if (strcmp(argv[2], "0") == 0 || strcmp(argv[2], "no-debug") == 0) {
00457 GoFTStress::fgDebugLevel = GoFTStress::kNoDebug;
00458 validOption = kTRUE;
00459 } else if (strcmp(argv[2], "1") == 0 || strcmp(argv[2], "basic-debug") == 0) {
00460 GoFTStress::fgDebugLevel = GoFTStress::kBasicDebug;
00461 validOption = kTRUE;
00462 std::cout << "Debug level: basic." << std::endl;
00463 } else if (strcmp(argv[2], "2") == 0 || strcmp(argv[2], "standard-debug") == 0) {
00464 GoFTStress::fgDebugLevel = GoFTStress::kStandardDebug;
00465 validOption = kTRUE;
00466 std::cout << "Debug level: standard." << std::endl;
00467 } else if (strcmp(argv[2], "help") == 0) {
00468 std::cout << "Showing help: " << std::endl;
00469 }
00470 }
00471
00472 if (!validOption) {
00473 std::cout << "Please type just one of the following debug levels in either formats preceded by \"--o\":" << std::endl;
00474 std::cout << "a) no-debug(0) [no test results printing]" << std::endl;
00475 std::cout << "b) basic-debug(1) [prints either \"OK\" or \"FAIL\" test results]" << std::endl;
00476 std::cout << "c) standard-debug(2) [prints summarized test results]" << std::endl;
00477 return 0;
00478 }
00479
00480 if (GoFTStress::fgDebugLevel >= GoFTStress::kBasicDebug) {
00481 std::cout << "*****************************************************************************************" << std::endl;
00482 std::cout << "* Goodness of Fit Test STRESS suite *" <<std::endl;
00483 std::cout << "*****************************************************************************************" << std::endl;
00484 }
00485
00486 gBenchmark = new TBenchmark();
00487
00488 TStopwatch timer;
00489 timer.Start();
00490
00491 gBenchmark->Start("GoFTestStress");
00492
00493 GoFTStress* goftStressTest = new GoFTStress;
00494
00495 result = goftStressTest->RunTests();
00496
00497 gBenchmark->Stop("GoFTestStress");
00498
00499 goftStressTest->PrintBenchmark();
00500
00501 delete goftStressTest;
00502
00503 delete gBenchmark;
00504
00505 return result;
00506 }
00507
00508 Int_t stressGoFTest(Int_t argc = 1 , Char_t* argv[] = 0) {
00509 return RunTests(argc, argv);
00510 }
00511
00512 #if not defined(__CINT__) && not defined(__MAKECINT__)
00513 Int_t main(Int_t argc, Char_t* argv[]) {
00514 return RunTests(argc, argv);
00515 }
00516 #endif