TUnuranContDist.cxx

Go to the documentation of this file.
00001 // @(#)root/unuran:$Id: TUnuranContDist.cxx 35517 2010-09-21 09:43:15Z moneta $
00002 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Implementation file for class TUnuranContDist
00012 
00013 #include "TUnuranContDist.h"
00014 #include "Math/RichardsonDerivator.h"
00015 #include "Math/WrappedTF1.h"
00016 
00017 #include "Math/Integrator.h"
00018 
00019 #include "TF1.h"
00020 #include <cassert>
00021 #include <cmath>
00022 
00023 ClassImp(TUnuranContDist)
00024 
00025 TUnuranContDist::TUnuranContDist (const ROOT::Math::IGenFunction & pdf, const ROOT::Math::IGenFunction * deriv, bool isLogPdf, bool copyFunc  ) : 
00026    fPdf(&pdf),
00027    fDPdf(deriv),
00028    fCdf(0), 
00029    fXmin(1.), 
00030    fXmax(-1.), 
00031    fMode(0), 
00032    fArea(0),
00033    fIsLogPdf(isLogPdf),
00034    fHasDomain(0),
00035    fHasMode(0),
00036    fHasArea(0), 
00037    fOwnFunc(copyFunc)
00038 {
00039    // Constructor from generic function interfaces
00040    // manage the functions and clone them if flag copyFunc is true
00041    if (fOwnFunc) { 
00042       fPdf = fPdf->Clone(); 
00043       if (fDPdf) fDPdf->Clone(); 
00044    }
00045 } 
00046 
00047 
00048 TUnuranContDist::TUnuranContDist (TF1 * pdf, TF1 * deriv, bool isLogPdf  ) : 
00049    fPdf(  (pdf) ? new ROOT::Math::WrappedTF1 ( *pdf) : 0 ), 
00050    fDPdf( (deriv) ?  new ROOT::Math::WrappedTF1 ( *deriv) : 0 ),
00051    fCdf(0), 
00052    fXmin(1.), 
00053    fXmax(-1.), 
00054    fMode(0), 
00055    fArea(0),
00056    fIsLogPdf(isLogPdf),
00057    fHasDomain(0),
00058    fHasMode(0),
00059    fHasArea(0), 
00060    fOwnFunc(true)
00061 {
00062    // Constructor from a TF1 objects
00063    // function pointers are managed by class 
00064 } 
00065 
00066 
00067 TUnuranContDist::TUnuranContDist(const TUnuranContDist & rhs) : 
00068    TUnuranBaseDist(), 
00069    fPdf(0), 
00070    fDPdf(0),
00071    fCdf(0)
00072 {
00073    // Implementation of copy constructor 
00074    operator=(rhs);
00075 }
00076 
00077 TUnuranContDist & TUnuranContDist::operator = (const TUnuranContDist &rhs) 
00078 {
00079    // Implementation of assignment operator.
00080    if (this == &rhs) return *this;  // time saving self-test
00081    fXmin  = rhs.fXmin;  
00082    fXmax  = rhs.fXmax;  
00083    fMode  = rhs.fMode; 
00084    fArea  = rhs.fArea;
00085    fIsLogPdf  = rhs.fIsLogPdf;
00086    fHasDomain = rhs.fHasDomain;
00087    fHasMode   = rhs.fHasMode;
00088    fHasArea   = rhs.fHasArea;
00089    fOwnFunc   = rhs.fOwnFunc;
00090    if (!fOwnFunc) { 
00091       fPdf   = rhs.fPdf;
00092       fDPdf  = rhs.fDPdf;
00093       fCdf   = rhs.fCdf; 
00094    }
00095    else {
00096       if (fPdf) delete fPdf;
00097       if (fDPdf) delete fDPdf; 
00098       if (fCdf) delete fCdf; 
00099       fPdf  = (rhs.fPdf)  ? rhs.fPdf->Clone()  : 0;  
00100       fDPdf = (rhs.fDPdf) ? rhs.fDPdf->Clone() : 0;  
00101       fCdf  = (rhs.fCdf)  ? rhs.fCdf->Clone()  : 0;  
00102    }
00103 
00104    return *this;
00105 }
00106 
00107 TUnuranContDist::~TUnuranContDist() { 
00108    // destructor implementation
00109    if (fOwnFunc) { 
00110       if (fPdf) delete fPdf; 
00111       if (fDPdf) delete fDPdf; 
00112       if (fCdf) delete fCdf; 
00113    }
00114 }
00115 
00116 void TUnuranContDist::SetCdf(const ROOT::Math::IGenFunction & cdf) {  
00117    //  set cdf distribution using a generic function interface
00118    fCdf = (fOwnFunc) ? cdf.Clone() : &cdf; 
00119 }
00120 
00121 
00122 void TUnuranContDist::SetCdf(TF1 *  cdf) { 
00123    // set cumulative distribution function from a TF1
00124    if (!fOwnFunc) { 
00125       // need to manage all functions now
00126       assert (fPdf != 0); 
00127       fPdf = fPdf->Clone(); 
00128       if (fDPdf) fDPdf->Clone(); 
00129    }
00130    else 
00131       if (fOwnFunc && fCdf) delete fCdf;
00132 
00133    fCdf = (cdf) ? new ROOT::Math::WrappedTF1 ( *cdf) : 0;    
00134    fOwnFunc = true; 
00135 }
00136 
00137 double TUnuranContDist::Pdf ( double x) const { 
00138    // evaluate the pdf of the distribution    
00139    assert(fPdf != 0);
00140    //fX[0] = x; 
00141    return (*fPdf)(x); 
00142 }
00143 
00144 double TUnuranContDist::DPdf( double x) const { 
00145    // evaluate the derivative of the pdf
00146    // if derivative function is not given is evaluated numerically
00147    if (fDPdf != 0) { 
00148       //fX[0] = x; 
00149       return (*fDPdf)(x); 
00150    }
00151    // do numerical derivation using numerical derivation
00152    ROOT::Math::RichardsonDerivator rd;
00153    static double gEps = 0.001;
00154    double h = ( std::abs(x) > 0 ) ?  gEps * std::abs(x) : gEps; 
00155    assert (fPdf != 0);
00156    return rd.Derivative1( *fPdf, x, h);
00157 }
00158 
00159 double TUnuranContDist::Cdf(double x) const {   
00160    // evaluate the integral (cdf)  on the domain
00161    if (fCdf != 0) {  
00162      // fX[0] = x; 
00163       return (*fCdf)(x);
00164    }
00165    // do numerical integration
00166    ROOT::Math::Integrator ig; 
00167    if (fXmin > fXmax) return ig.Integral( *fPdf ); 
00168    else 
00169       return ig.Integral( *fPdf, fXmin, fXmax );
00170    
00171 }
00172 

Generated on Tue Jul 5 14:43:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1