Logo ROOT  
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\file RooImproperIntegrator1D.cxx
19\class RooImproperIntegrator1D
20\ingroup Roofitcore
21
22Special numeric integrator that can handle integrals over open domains.
23To this end the range is cut in up three pieces: [-inf,-1],[-1,+1] and [+1,inf]
24and the outer two pieces, if required are calculated using a 1/x transform
25**/
26
28#include "RooIntegrator1D.h"
29#include "RooInvTransform.h"
30#include "RooNumber.h"
31#include "RooNumIntFactory.h"
32#include "RooArgSet.h"
33#include "RooMsgService.h"
34
35#include "Riostream.h"
36#include <math.h>
37#include "TClass.h"
38
39
40
41using namespace std;
42
44;
45
46// Register this class with RooNumIntConfig
47
48////////////////////////////////////////////////////////////////////////////////
49/// Register RooImproperIntegrator1D, its parameters and capabilities with RooNumIntFactory
50
52{
55}
56
57
58
59////////////////////////////////////////////////////////////////////////////////
60/// Default constructor
61
63 _case(ClosedBothEnds), _xmin(-10), _xmax(10), _useIntegrandLimits(kTRUE),
64 _origFunc(0), _function(0), _integrator1(0), _integrator2(0), _integrator3(0)
65{
66}
67
68
69////////////////////////////////////////////////////////////////////////////////
70/// Constructor with function binding. The integration range is taken from the
71/// definition in the function binding
72
75 _useIntegrandLimits(kTRUE),
76 _origFunc((RooAbsFunc*)&function),
77 _function(0),
78 _integrator1(0),
79 _integrator2(0),
80 _integrator3(0)
81{
83}
84
85
86
87////////////////////////////////////////////////////////////////////////////////
88/// Constructor with function binding and configuration object. The integration range is taken
89/// from the definition in the function binding
90
93 _useIntegrandLimits(kTRUE),
94 _origFunc((RooAbsFunc*)&function),
95 _function(0),
96 _config(config),
97 _integrator1(0),
98 _integrator2(0),
99 _integrator3(0)
100{
102}
103
104
105
106////////////////////////////////////////////////////////////////////////////////
107/// Constructor with function binding, definition of integration range and configuration object
108
111 _xmin(xmin),
112 _xmax(xmax),
113 _useIntegrandLimits(kFALSE),
114 _origFunc((RooAbsFunc*)&function),
115 _function(0),
116 _config(config),
117 _integrator1(0),
118 _integrator2(0),
119 _integrator3(0)
120{
122}
123
124
125
126////////////////////////////////////////////////////////////////////////////////
127/// Return clone of integrator with given function and configuration. Needed by RooNumIntFactory.
128
130{
131 return new RooImproperIntegrator1D(function,config) ;
132}
133
134
135
136////////////////////////////////////////////////////////////////////////////////
137/// Initialize the integrator, construct and initialize subintegrators
138
140{
141 if(!isValid()) {
142 oocoutE((TObject*)0,Integration) << "RooImproperIntegrator: cannot integrate invalid function" << endl;
143 return;
144 }
145 // Create a new function object that uses the change of vars: x -> 1/x
146 if (function) {
148 } else {
150 if (_integrator1) {
151 delete _integrator1 ;
152 _integrator1 = 0 ;
153 }
154 if (_integrator2) {
155 delete _integrator2 ;
156 _integrator2 = 0 ;
157 }
158 if (_integrator3) {
159 delete _integrator3 ;
160 _integrator3 = 0 ;
161 }
162 }
163
164 // partition the integration range into subranges that can each be
165 // handled by RooIntegrator1D
166 switch(_case= limitsCase()) {
167 case ClosedBothEnds:
168 // both limits are finite: use the plain trapezoid integrator
170 break;
171 case OpenBothEnds:
172 // both limits are infinite: integrate over (-1,+1) using
173 // the plain trapezoid integrator...
175 // ...and integrate the infinite tails using the midpoint integrator
178 break;
180 // xmax >= 0 so integrate from (-inf,-1) and (-1,xmax)
183 break;
184 case OpenBelow:
185 // xmax < 0 so integrate from (-inf,xmax)
187 break;
189 // xmin <= 0 so integrate from (xmin,+1) and (+1,+inf)
192 break;
193 case OpenAbove:
194 // xmin > 0 so integrate from (xmin,+inf)
196 break;
197 case Invalid:
198 default:
199 _valid= kFALSE;
200 }
201}
202
203
204////////////////////////////////////////////////////////////////////////////////
205/// Destructor
206
208{
209 if(0 != _integrator1) delete _integrator1;
210 if(0 != _integrator2) delete _integrator2;
211 if(0 != _integrator3) delete _integrator3;
212 if(0 != _function) delete _function;
213}
214
215
216////////////////////////////////////////////////////////////////////////////////
217/// Change our integration limits. Return kTRUE if the new limits are
218/// ok, or otherwise kFALSE. Always returns kFALSE and does nothing
219/// if this object was constructed to always use our integrand's limits.
220
222{
224 oocoutE((TObject*)0,Integration) << "RooIntegrator1D::setLimits: cannot override integrand's limits" << endl;
225 return kFALSE;
226 }
227
228 _xmin= *xmin;
229 _xmax= *xmax;
230 return checkLimits();
231}
232
233
234////////////////////////////////////////////////////////////////////////////////
235/// Check if the limits are valid. For this integrator all limit configurations
236/// are valid, but if the limits change between two calculate() calls it
237/// may be necessary to reconfigure (e.g. if an open ended range becomes
238/// a closed range
239
241{
242 // Has either limit changed?
244 if(_xmin == integrand()->getMinLimit(0) &&
245 _xmax == integrand()->getMaxLimit(0)) return kTRUE;
246 }
247
248 // The limits have changed: can we use the same strategy?
249 if(limitsCase() != _case) {
250 // Reinitialize embedded integrators, will automatically propagate new limits
251 const_cast<RooImproperIntegrator1D*>(this)->initialize() ;
252 return kTRUE ;
253 }
254
255 // Reuse our existing integrators by updating their limits
256 switch(_case) {
257 case ClosedBothEnds:
259 break;
260 case OpenBothEnds:
261 // nothing has changed
262 break;
265 break;
266 case OpenBelow:
268 break;
271 break;
272 case OpenAbove:
274 break;
275 case Invalid:
276 default:
277 return kFALSE;
278 }
279 return kTRUE;
280}
281
282
283////////////////////////////////////////////////////////////////////////////////
284/// Classify the type of limits we have: OpenBothEnds,ClosedBothEnds,OpenBelow or OpenAbove.
285
287{
288 // Analyze the specified limits to determine which case applies.
289 if(0 == integrand() || !integrand()->isValid()) return Invalid;
290
294 }
295
298 if(!inf1 && !inf2) {
299 // both limits are finite
300 return ClosedBothEnds;
301 }
302 else if(inf1 && inf2) {
303 // both limits are infinite
304 return OpenBothEnds;
305 }
306 else if(inf1) { // inf2==false
307 if(_xmax >= 0) {
308 return OpenBelowSpansZero;
309 }
310 else {
311 return OpenBelow;
312 }
313 }
314 else { // inf1==false && inf2==true
315 if(_xmin <= 0) {
316 return OpenAboveSpansZero;
317 }
318 else {
319 return OpenAbove;
320 }
321 }
322 // return Invalid; OSF-CC: Statement unreachable
323}
324
325
326////////////////////////////////////////////////////////////////////////////////
327/// Calculate the integral at the given parameter values of the function binding
328
330{
331 Double_t result(0);
332 if(0 != _integrator1) result+= _integrator1->integral(yvec);
333 if(0 != _integrator2) result+= _integrator2->integral(yvec);
334 if(0 != _integrator3) result+= _integrator3->integral(yvec);
335 return result;
336}
#define oocoutE(o, a)
Definition: RooMsgService.h:48
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
float xmin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
const char * proto
Definition: civetweb.c:17493
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition: RooAbsFunc.h:27
virtual Double_t getMinLimit(UInt_t dimension) const =0
virtual Double_t getMaxLimit(UInt_t dimension) const =0
RooAbsIntegrator is the abstract interface for integrators of real-valued functions that implement th...
Bool_t _valid
Is integrator in valid state?
const RooAbsFunc * integrand() const
Return integrand function binding.
Bool_t isValid() const
Is integrator in valid state.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
Special numeric integrator that can handle integrals over open domains.
LimitsCase limitsCase() const
Classify the type of limits we have: OpenBothEnds,ClosedBothEnds,OpenBelow or OpenAbove.
Bool_t checkLimits() const override
Check if the limits are valid.
RooIntegrator1D * _integrator3
Piece integrators.
RooInvTransform * _function
Binding with inverse of function.
RooImproperIntegrator1D()
Default constructor.
LimitsCase _case
Configuration of limits.
RooAbsFunc * _origFunc
Original function binding.
void initialize(const RooAbsFunc *function=0)
Initialize the integrator, construct and initialize subintegrators.
Bool_t setLimits(Double_t *xmin, Double_t *xmax) override
Change our integration limits.
RooAbsIntegrator * clone(const RooAbsFunc &function, const RooNumIntConfig &config) const override
Return clone of integrator with given function and configuration. Needed by RooNumIntFactory.
Bool_t _useIntegrandLimits
Use limits in function binding?
Double_t _xmax
Value of limits.
Double_t integral(const Double_t *yvec=0) override
Calculate the integral at the given parameter values of the function binding.
RooNumIntConfig _config
Configuration object.
static void registerIntegrator(RooNumIntFactory &fact)
Register RooImproperIntegrator1D, its parameters and capabilities with RooNumIntFactory.
~RooImproperIntegrator1D() override
Destructor.
RooIntegrator1D implements an adaptive one-dimensional numerical integration algorithm.
static TClass * Class()
Bool_t setLimits(Double_t *xmin, Double_t *xmax) override
Change our integration limits.
Double_t integral(const Double_t *yvec=0) override
Calculate numeric integral at given set of function binding parameters.
Lightweight function binding that returns the inverse of an input function binding.
RooNumIntConfig holds the configuration parameters of the various numeric integrators used by RooReal...
RooNumIntFactory is a factory to instantiate numeric integrators from a given function binding and a ...
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...
static Int_t isInfinite(Double_t x)
Return true if x is infinite by RooNumBer internal specification.
Definition: RooNumber.cxx:57
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:167
@ Integration
Definition: RooGlobalFunc.h:63