RooAdaptiveIntegratorND.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAdaptiveIntegratorND.cxx 36209 2010-10-08 21:37:36Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooAdaptiveIntegratorND implements an adaptive one-dimensional 
00021 // numerical integration algorithm.
00022 // END_HTML
00023 //
00024 
00025 
00026 #include "RooFit.h"
00027 #include "Riostream.h"
00028 
00029 #include "TClass.h"
00030 #include "RooAdaptiveIntegratorND.h"
00031 #include "RooArgSet.h"
00032 #include "RooRealVar.h"
00033 #include "RooNumber.h"
00034 #include "RooMsgService.h"
00035 #include "RooNumIntFactory.h"
00036 #include "RooMultiGenFunction.h"
00037 #include "Math/AdaptiveIntegratorMultiDim.h"
00038 
00039 #include <assert.h>
00040 #include <iomanip>
00041 
00042 
00043 
00044 ClassImp(RooAdaptiveIntegratorND)
00045 ;
00046 
00047 // Register this class with RooNumIntConfig
00048 
00049 //_____________________________________________________________________________
00050 void RooAdaptiveIntegratorND::registerIntegrator(RooNumIntFactory& fact)
00051 {
00052   // Register RooAdaptiveIntegratorND, its parameters, dependencies and capabilities with RooNumIntFactory
00053 
00054   RooRealVar maxEval2D("maxEval2D","Max number of function evaluations for 2-dim integrals",100000) ;
00055   RooRealVar maxEval3D("maxEval3D","Max number of function evaluations for 3-dim integrals",1000000) ;
00056   RooRealVar maxEvalND("maxEvalND","Max number of function evaluations for >3-dim integrals",10000000) ;
00057   RooRealVar maxWarn("maxWarn","Max number of warnings on precision not reached that is printed",5) ;
00058 
00059   fact.storeProtoIntegrator(new RooAdaptiveIntegratorND(),RooArgSet(maxEval2D,maxEval3D,maxEvalND,maxWarn)) ;
00060 }
00061  
00062 
00063 
00064 //_____________________________________________________________________________
00065 RooAdaptiveIntegratorND::RooAdaptiveIntegratorND()
00066 {
00067   // Default ctor
00068   _xmin = 0 ;
00069   _xmax = 0 ;
00070   _epsRel = 1e-7 ;
00071   _epsAbs = 1e-7 ;
00072   _nmax = 10000 ;
00073   _func = 0 ;
00074   _integrator = 0 ;
00075   _nError = 0 ;
00076   _nWarn = 0 ;
00077   _useIntegrandLimits = kTRUE ;
00078   _intName = "(none)" ;
00079 }
00080 
00081 
00082 
00083 //_____________________________________________________________________________
00084 RooAdaptiveIntegratorND::RooAdaptiveIntegratorND(const RooAbsFunc& function, const RooNumIntConfig& config) :
00085   RooAbsIntegrator(function)
00086 {
00087   // Constructor of integral on given function binding and with given configuration. The
00088   // integration limits are taken from the definition in the function binding
00089   //_func = function.
00090 
00091 
00092   _func = new RooMultiGenFunction(function) ;  
00093   _nWarn = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxWarn")) ;
00094   switch (_func->NDim()) {
00095   case 1: throw string(Form("RooAdaptiveIntegratorND::ctor ERROR dimension of function must be at least 2")) ;
00096   case 2: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval2D")) ; break ; 
00097   case 3: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval3D")) ; break ;
00098   default: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEvalND")) ; break ;
00099   }
00100   _integrator = new ROOT::Math::AdaptiveIntegratorMultiDim(config.epsAbs(),config.epsRel(),_nmax) ;
00101   _integrator->SetFunction(*_func) ;
00102   _useIntegrandLimits=kTRUE ;
00103 
00104   _xmin = 0 ;
00105   _xmax = 0 ;
00106   _nError = 0 ;
00107   _nWarn = 0 ;
00108   _epsRel = 1e-7 ;
00109   _epsAbs = 1e-7 ;
00110   checkLimits() ;
00111   _intName = function.getName() ;
00112 } 
00113 
00114 
00115 
00116 //_____________________________________________________________________________
00117 RooAbsIntegrator* RooAdaptiveIntegratorND::clone(const RooAbsFunc& function, const RooNumIntConfig& config) const
00118 {
00119   // Virtual constructor with given function and configuration. Needed by RooNumIntFactory
00120 
00121   RooAbsIntegrator* ret = new RooAdaptiveIntegratorND(function,config) ;
00122   
00123   return ret ;
00124 }
00125 
00126 
00127 
00128 
00129 //_____________________________________________________________________________
00130 RooAdaptiveIntegratorND::~RooAdaptiveIntegratorND()
00131 {
00132   // Destructor
00133   delete[] _xmin ;
00134   delete[] _xmax ;
00135   delete _integrator ;
00136   delete _func ;
00137   if (_nError>_nWarn) {
00138     coutW(NumIntegration) << "RooAdaptiveIntegratorND::dtor(" << _intName 
00139                           << ") WARNING: Number of suppressed warningings about integral evaluations where target precision was not reached is " << _nError-_nWarn << endl ;
00140   }
00141 
00142 }
00143 
00144 
00145 
00146 //_____________________________________________________________________________
00147 Bool_t RooAdaptiveIntegratorND::checkLimits() const 
00148 {
00149   // Check that our integration range is finite and otherwise return kFALSE.
00150   // Update the limits from the integrand if requested.
00151   
00152   if (!_xmin) {
00153     _xmin = new Double_t[_func->NDim()] ;
00154     _xmax = new Double_t[_func->NDim()] ;
00155   }
00156   
00157   if (_useIntegrandLimits) {
00158     for (UInt_t i=0 ; i<_func->NDim() ; i++) {
00159       _xmin[i]= integrand()->getMinLimit(i);
00160       _xmax[i]= integrand()->getMaxLimit(i);
00161     }
00162   }
00163 
00164   return kTRUE ;
00165 }
00166 
00167 
00168 //_____________________________________________________________________________
00169 Bool_t RooAdaptiveIntegratorND::setLimits(Double_t *xmin, Double_t *xmax) 
00170 {
00171   // Change our integration limits. Return kTRUE if the new limits are
00172   // ok, or otherwise kFALSE. Always returns kFALSE and does nothing
00173   // if this object was constructed to always use our integrand's limits.
00174 
00175   if(_useIntegrandLimits) {
00176     oocoutE((TObject*)0,Integration) << "RooAdaptiveIntegratorND::setLimits: cannot override integrand's limits" << endl;
00177     return kFALSE;
00178   }
00179   for (UInt_t i=0 ; i<_func->NDim() ; i++) {
00180     _xmin[i]= xmin[i];
00181     _xmax[i]= xmax[i];
00182   }
00183 
00184   return checkLimits();
00185 }
00186 
00187 
00188 
00189 
00190 //_____________________________________________________________________________
00191 Double_t RooAdaptiveIntegratorND::integral(const Double_t* /*yvec*/) 
00192 {
00193   // Evaluate integral at given function binding parameter values
00194   Double_t ret = _integrator->Integral(_xmin,_xmax) ;  
00195   if (_integrator->Status()==1) {
00196     _nError++ ;
00197     if (_nError<=_nWarn) {
00198       coutW(NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName() << ") WARNING: target rel. precision not reached due to nEval limit of "
00199                             << _nmax << ", estimated rel. precision is " << Form("%3.1e",_integrator->RelError()) << endl ;
00200     } 
00201     if (_nError==_nWarn) {
00202       coutW(NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName() 
00203                             << ") Further warnings on target precision are suppressed conform specification in integrator specification" << endl ;
00204     }    
00205   }  
00206   return ret ;
00207 }
00208 

Generated on Tue Jul 5 15:05:56 2011 for ROOT_528-00b_version by  doxygen 1.5.1