ROOT  6.06/09
Reference Guide
RooImproperIntegrator1D.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 //////////////////////////////////////////////////////////////////////////////
18 //
19 // BEGIN_HTML
20 // Special numeric integrator that can handle integrals over open domains.
21 // To this end the range is cut in up three pieces: [-inf,-1],[-1,+1] and [+1,inf]
22 // and the outer two pieces, if required are calculated using a 1/x transform
23 // END_HTML
24 //
25 
26 
27 #include "RooFit.h"
28 
31 #include "RooIntegrator1D.h"
32 #include "RooInvTransform.h"
33 #include "RooNumber.h"
34 #include "RooNumIntFactory.h"
35 #include "RooArgSet.h"
36 #include "RooMsgService.h"
37 
38 #include "Riostream.h"
39 #include <math.h>
40 #include "TClass.h"
41 
42 
43 
44 using namespace std;
45 
47 ;
48 
49 // Register this class with RooNumIntConfig
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Register RooImproperIntegrator1D, its parameters and capabilities with RooNumIntFactory
53 
55 {
57  fact.storeProtoIntegrator(proto,RooArgSet(),RooIntegrator1D::Class()->GetName()) ;
58 }
59 
60 
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 /// Default constructor
64 
66  _case(ClosedBothEnds), _xmin(-10), _xmax(10), _useIntegrandLimits(kTRUE),
67  _origFunc(0), _function(0), _integrator1(0), _integrator2(0), _integrator3(0)
68 {
69 }
70 
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Constructor with function binding. The integration range is taken from the
74 /// definition in the function binding
75 
78  _useIntegrandLimits(kTRUE),
79  _origFunc((RooAbsFunc*)&function),
80  _function(0),
81  _integrator1(0),
82  _integrator2(0),
83  _integrator3(0)
84 {
85  initialize(&function) ;
86 }
87 
88 
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Constructor with function binding and configuration object. The integration range is taken
92 /// from the definition in the function binding
93 
96  _useIntegrandLimits(kTRUE),
97  _origFunc((RooAbsFunc*)&function),
98  _function(0),
99  _config(config),
100  _integrator1(0),
101  _integrator2(0),
102  _integrator3(0)
103 {
104  initialize(&function) ;
105 }
106 
107 
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Constructor with function binding, definition of integration range and configuration object
111 
114  _xmin(xmin),
115  _xmax(xmax),
116  _useIntegrandLimits(kFALSE),
117  _origFunc((RooAbsFunc*)&function),
118  _function(0),
119  _config(config),
120  _integrator1(0),
121  _integrator2(0),
122  _integrator3(0)
123 {
124  initialize(&function) ;
125 }
126 
127 
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Return clone of integrator with given function and configuration. Needed by RooNumIntFactory.
131 
133 {
134  return new RooImproperIntegrator1D(function,config) ;
135 }
136 
137 
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Initialize the integrator, construct and initialize subintegrators
141 
143 {
144  if(!isValid()) {
145  oocoutE((TObject*)0,Integration) << "RooImproperIntegrator: cannot integrate invalid function" << endl;
146  return;
147  }
148  // Create a new function object that uses the change of vars: x -> 1/x
149  if (function) {
150  _function= new RooInvTransform(*function);
151  } else {
152  function = _origFunc ;
153  if (_integrator1) {
154  delete _integrator1 ;
155  _integrator1 = 0 ;
156  }
157  if (_integrator2) {
158  delete _integrator2 ;
159  _integrator2 = 0 ;
160  }
161  if (_integrator3) {
162  delete _integrator3 ;
163  _integrator3 = 0 ;
164  }
165  }
166 
167  // partition the integration range into subranges that can each be
168  // handled by RooIntegrator1D
169  switch(_case= limitsCase()) {
170  case ClosedBothEnds:
171  // both limits are finite: use the plain trapezoid integrator
173  break;
174  case OpenBothEnds:
175  // both limits are infinite: integrate over (-1,+1) using
176  // the plain trapezoid integrator...
178  // ...and integrate the infinite tails using the midpoint integrator
181  break;
182  case OpenBelowSpansZero:
183  // xmax >= 0 so integrate from (-inf,-1) and (-1,xmax)
186  break;
187  case OpenBelow:
188  // xmax < 0 so integrate from (-inf,xmax)
190  break;
191  case OpenAboveSpansZero:
192  // xmin <= 0 so integrate from (xmin,+1) and (+1,+inf)
195  break;
196  case OpenAbove:
197  // xmin > 0 so integrate from (xmin,+inf)
199  break;
200  case Invalid:
201  default:
202  _valid= kFALSE;
203  }
204 }
205 
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// Destructor
209 
211 {
212  if(0 != _integrator1) delete _integrator1;
213  if(0 != _integrator2) delete _integrator2;
214  if(0 != _integrator3) delete _integrator3;
215  if(0 != _function) delete _function;
216 }
217 
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Change our integration limits. Return kTRUE if the new limits are
221 /// ok, or otherwise kFALSE. Always returns kFALSE and does nothing
222 /// if this object was constructed to always use our integrand's limits.
223 
225 {
226  if(_useIntegrandLimits) {
227  oocoutE((TObject*)0,Integration) << "RooIntegrator1D::setLimits: cannot override integrand's limits" << endl;
228  return kFALSE;
229  }
230 
231  _xmin= *xmin;
232  _xmax= *xmax;
233  return checkLimits();
234 }
235 
236 
237 ////////////////////////////////////////////////////////////////////////////////
238 /// Check if the limits are valid. For this integrator all limit configurations
239 /// are valid, but if the limits change between two calculate() calls it
240 /// may be necessary to reconfigure (e.g. if an open ended range becomes
241 /// a closed range
242 
244 {
245  // Has either limit changed?
246  if (_useIntegrandLimits) {
247  if(_xmin == integrand()->getMinLimit(0) &&
248  _xmax == integrand()->getMaxLimit(0)) return kTRUE;
249  }
250 
251  // The limits have changed: can we use the same strategy?
252  if(limitsCase() != _case) {
253  // Reinitialize embedded integrators, will automatically propagate new limits
254  const_cast<RooImproperIntegrator1D*>(this)->initialize() ;
255  return kTRUE ;
256  }
257 
258  // Reuse our existing integrators by updating their limits
259  switch(_case) {
260  case ClosedBothEnds:
262  break;
263  case OpenBothEnds:
264  // nothing has changed
265  break;
266  case OpenBelowSpansZero:
268  break;
269  case OpenBelow:
271  break;
272  case OpenAboveSpansZero:
274  break;
275  case OpenAbove:
277  break;
278  case Invalid:
279  default:
280  return kFALSE;
281  }
282  return kTRUE;
283 }
284 
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// Classify the type of limits we have: OpenBothEnds,ClosedBothEnds,OpenBelow or OpenAbove.
288 
290 {
291  // Analyze the specified limits to determine which case applies.
292  if(0 == integrand() || !integrand()->isValid()) return Invalid;
293 
294  if (_useIntegrandLimits) {
295  _xmin= integrand()->getMinLimit(0);
296  _xmax= integrand()->getMaxLimit(0);
297  }
298 
301  if(!inf1 && !inf2) {
302  // both limits are finite
303  return ClosedBothEnds;
304  }
305  else if(inf1 && inf2) {
306  // both limits are infinite
307  return OpenBothEnds;
308  }
309  else if(inf1) { // inf2==false
310  if(_xmax >= 0) {
311  return OpenBelowSpansZero;
312  }
313  else {
314  return OpenBelow;
315  }
316  }
317  else { // inf1==false && inf2==true
318  if(_xmin <= 0) {
319  return OpenAboveSpansZero;
320  }
321  else {
322  return OpenAbove;
323  }
324  }
325  // return Invalid; OSF-CC: Statement unreachable
326 }
327 
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// Calculate the integral at the given parameter values of the function binding
331 
333 {
334  Double_t result(0);
335  if(0 != _integrator1) result+= _integrator1->integral(yvec);
336  if(0 != _integrator2) result+= _integrator2->integral(yvec);
337  if(0 != _integrator3) result+= _integrator3->integral(yvec);
338  return result;
339 }
float xmin
Definition: THbookFile.cxx:93
virtual Bool_t checkLimits() const
Check if the limits are valid.
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
static Int_t isInfinite(Double_t x)
Return true if x is infinite by RooNumBer internal specification.
Definition: RooNumber.cxx:57
static void registerIntegrator(RooNumIntFactory &fact)
Register RooImproperIntegrator1D, its parameters and capabilities with RooNumIntFactory.
STL namespace.
void initialize(const RooAbsFunc *function=0)
Initialize the integrator, construct and initialize subintegrators.
void Class()
Definition: Class.C:29
#define oocoutE(o, a)
Definition: RooMsgService.h:48
ClassImp(RooImproperIntegrator1D)
Bool_t setLimits(Double_t *xmin, Double_t *xmax)
Change our integration limits.
void function(const char *name_, T fun, const char *docstring=0)
Definition: RExports.h:159
virtual Double_t integral(const Double_t *yvec=0)
Calculate numeric integral at given set of function binding parameters.
RooImproperIntegrator1D()
Default constructor.
virtual Double_t getMinLimit(UInt_t dimension) const =0
float xmax
Definition: THbookFile.cxx:93
Bool_t setLimits(Double_t *xmin, Double_t *xmax)
Change our integration limits.
virtual Double_t getMaxLimit(UInt_t dimension) const =0
double Double_t
Definition: RtypesCore.h:55
Mother of all ROOT objects.
Definition: TObject.h:58
LimitsCase limitsCase() const
Classify the type of limits we have: OpenBothEnds,ClosedBothEnds,OpenBelow or OpenAbove.
virtual Double_t integral(const Double_t *yvec=0)
Calculate the integral at the given parameter values of the function binding.
const RooAbsFunc * integrand() const
virtual RooAbsIntegrator * clone(const RooAbsFunc &function, const RooNumIntConfig &config) const
Return clone of integrator with given function and configuration. Needed by RooNumIntFactory.
double result[121]
Bool_t isValid() const
virtual ~RooImproperIntegrator1D()
Destructor.
const Bool_t kTRUE
Definition: Rtypes.h:91
Bool_t storeProtoIntegrator(RooAbsIntegrator *proto, const RooArgSet &defConfig, const char *depName="")
Method accepting registration of a prototype numeric integrator along with a RooArgSet of its default...