ROOT logo
// @(#)root/roostats:$Id: SamplingDistribution.cxx 31276 2009-11-18 15:06:42Z moneta $

/*************************************************************************
 * Project: RooStats                                                     *
 * Package: RooFit/RooStats                                              *
 * Authors:                                                              *
 *   Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke       *
 *************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//____________________________________________________________________
/*
SamplingDistribution : 

This class simply holds a sampling distribution of some test statistic.  
The distribution can either be an emperical distribution (eg. the samples themselves) or
a weighted set of points (eg. for the FFT method).
The class supports merging.
*/

#include "RooStats/SamplingDistribution.h"
#include "RooNumber.h"
#include "math.h"
#include <algorithm>
#include <iostream>
using namespace std ;

/// ClassImp for building the THtml documentation of the class 
ClassImp(RooStats::SamplingDistribution)

using namespace RooStats;

//_______________________________________________________
SamplingDistribution::SamplingDistribution( const char *name, const char *title,
					    std::vector<Double_t>& samplingDist, const TString varName) :
  TNamed(name,title)
{
  // SamplingDistribution constructor
  fSamplingDist = samplingDist;
  // need to check STL stuff here.  Will this = operator work as wanted, or do we need:
  //  std::copy(samplingDist.begin(), samplingDist.end(), fSamplingDist.begin());

  // WVE must fill sampleWeights vector here otherwise append behavior potentially undefined
  fSampleWeights.resize(fSamplingDist.size(),1.0) ;  

  fVarName = varName;
}

//_______________________________________________________
SamplingDistribution::SamplingDistribution( const char *name, const char *title,
					    std::vector<Double_t>& samplingDist, std::vector<Double_t>& sampleWeights, const TString varName) :
  TNamed(name,title)
{
  // SamplingDistribution constructor
  fSamplingDist = samplingDist;
  fSampleWeights = sampleWeights;
  // need to check STL stuff here.  Will this = operator work as wanted, or do we need:
  //  std::copy(samplingDist.begin(), samplingDist.end(), fSamplingDist.begin());

  fVarName = varName;
}

//_______________________________________________________
SamplingDistribution::SamplingDistribution( const char *name, const char *title, const TString varName) :
  TNamed(name,title)
{
   // SamplingDistribution constructor (with name and title)
  fVarName = varName;
}

//_______________________________________________________
SamplingDistribution::SamplingDistribution( ) :
  TNamed("SamplingDistribution_DefaultName","SamplingDistribution")
{
   // SamplingDistribution default constructor
}

//_______________________________________________________
SamplingDistribution::~SamplingDistribution()
{
   // SamplingDistribution destructor

   fSamplingDist.clear();
   fSampleWeights.clear();
}


//_______________________________________________________
void SamplingDistribution::Add(SamplingDistribution* other)
{
   // merge SamplingDistributions

  std::vector<double> newSamplingDist = other->fSamplingDist;
  std::vector<double> newSampleWeights = other->fSampleWeights;
  // need to check STL stuff here.  Will this = operator work as wanted, or do we need:
  //  std::copy(samplingDist.begin(), samplingDist.end(), fSamplingDist.begin());
  // need to look into STL, do it the easy way for now

  // reserve memory
  fSamplingDist.reserve(fSamplingDist.size()+newSamplingDist.size());
  fSampleWeights.reserve(fSampleWeights.size()+newSampleWeights.size());

  // push back elements
  for(unsigned int i=0; i<newSamplingDist.size(); ++i){
    fSamplingDist.push_back(newSamplingDist[i]);
    fSampleWeights.push_back(newSampleWeights[i]);
  }

}

//_______________________________________________________
Double_t SamplingDistribution::InverseCDF(Double_t pvalue)
{
   // returns the inverse of the cumulative distribution function

  Double_t dummy=0;
  return InverseCDF(pvalue,0,dummy);
}


//_______________________________________________________
Double_t SamplingDistribution::InverseCDF(Double_t pvalue, 
					  Double_t sigmaVariation, 
					  Double_t& inverseWithVariation)
{
   // returns the inverse of the cumulative distribution function, with variations depending on number of samples

  // will need to deal with weights, but for now:
  std::sort(fSamplingDist.begin(), fSamplingDist.end());


  // Acceptance regions are meant to be inclusive of (1-\alpha) of the probability
  // so the returned values of the CDF should make this easy.
  // in particular:
  //   if finding the critical value for a lower bound
  //     when p_i < p < p_j, one should return the value associated with i
  //     if i=0, then one should return -infinity
  //   if finding the critical value for an upper bound
  //     when p_i < p < p_j, one should return the value associated with j
  //     if i = size-1, then one should return +infinity
  //   use pvalue < 0.5 to indicate a lower bound is requested
  
  // casting will round down, eg. give i
  int nominal = (unsigned int) (pvalue*fSamplingDist.size());


  if(nominal <= 0) {
    inverseWithVariation = -1.*RooNumber::infinity();
    return -1.*RooNumber::infinity();
  }
  else if(nominal >= (Int_t)fSamplingDist.size()-1 ) {
    inverseWithVariation = RooNumber::infinity();
    return RooNumber::infinity();
  }
  else if(pvalue < 0.5){
    int delta = (int)(sigmaVariation*sqrt(1.0*nominal)); // note sqrt(small fraction)
    int variation = nominal+delta;

    if(variation>=(Int_t)fSamplingDist.size()-1)
      inverseWithVariation = RooNumber::infinity();
    else if(variation<=0)
      inverseWithVariation = -1.*RooNumber::infinity();
    else 
      inverseWithVariation =  fSamplingDist[ variation ];

    return fSamplingDist[nominal];
  }
  else if(pvalue >= 0.5){
    int delta = (int)(sigmaVariation*sqrt(1.0*fSamplingDist.size()- nominal)); // note sqrt(small fraction)
    int variation = nominal+delta;


    if(variation>=(Int_t)fSamplingDist.size()-1)
      inverseWithVariation = RooNumber::infinity();

    else if(variation<=0)
      inverseWithVariation = -1.*RooNumber::infinity();
    else 
      inverseWithVariation =  fSamplingDist[ variation+1 ];


    /*
      std::cout << "dgb SamplingDistribution::InverseCDF. variation = " << variation
      << " size = " << fSamplingDist.size()
      << " value = " << inverseWithVariation << std::endl;
    */

    return fSamplingDist[nominal+1];
  }
  else{
    std::cout << "problem in SamplingDistribution::InverseCDF" << std::endl;
  }
  inverseWithVariation = RooNumber::infinity();
  return RooNumber::infinity();

}


//_______________________________________________________
Double_t SamplingDistribution::InverseCDFInterpolate(Double_t pvalue)
{
   // returns the inverse of the cumulative distribution function

  // will need to deal with weights, but for now:
  std::sort(fSamplingDist.begin(), fSamplingDist.end());

  // casting will round down, eg. give i
  int nominal = (unsigned int) (pvalue*fSamplingDist.size());

  if(nominal <= 0) {
    return -1.*RooNumber::infinity();
  }
  if(nominal >= (Int_t)fSamplingDist.size()-1 ) {
    return RooNumber::infinity();
  }
  Double_t upperX = fSamplingDist[nominal+1];
  Double_t upperY = ((Double_t) (nominal+1))/fSamplingDist.size();
  Double_t lowerX =  fSamplingDist[nominal];
  Double_t lowerY = ((Double_t) nominal)/fSamplingDist.size();
  
  //  std::cout << upperX << " " << upperY << " " << lowerX << " " << lowerY << std::endl;

  return (upperX-lowerX)/(upperY-lowerY)*(pvalue-lowerY)+lowerX;

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