Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooDerivative.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 RooDerivative.cxx
19\class RooDerivative
20\ingroup Roofitcore
21
22Represents the first, second, or third order derivative
23of any RooAbsReal as calculated (numerically) by the MathCore Richardson
24derivator class.
25**/
26
27#include "Riostream.h"
28#include <cmath>
29
30#include "RooDerivative.h"
31#include "RooAbsReal.h"
32#include "RooAbsPdf.h"
33#include "RooErrorHandler.h"
34#include "RooArgSet.h"
35#include "RooMsgService.h"
36#include "RooRealVar.h"
37#include "RooFunctor.h"
38
41
42
43
44
45////////////////////////////////////////////////////////////////////////////////
46/// Default constructor
47
49
50////////////////////////////////////////////////////////////////////////////////
51
52RooDerivative::RooDerivative(const char* name, const char* title, RooAbsReal& func, RooRealVar& x, Int_t orderIn, double epsIn) :
53 RooAbsReal(name, title),
54 _order(orderIn),
55 _eps(epsIn),
56 _nset("nset","nset",this,false,false),
57 _func("function","function",this,func),
58 _x("x","x",this,x)
59{
60 if (_order<0 || _order>3 ) {
61 throw std::runtime_error(Form("RooDerivative::ctor(%s) ERROR, derivation order must be 1,2 or 3",name)) ;
62 }
63}
64
65////////////////////////////////////////////////////////////////////////////////
66
67RooDerivative::RooDerivative(const char *name, const char *title, RooAbsReal &func, RooRealVar &x,
68 const RooArgSet &nset, Int_t orderIn, double epsIn)
69 : RooDerivative(name, title, func, x, orderIn, epsIn)
70{
71 _nset.add(nset);
72}
73
74////////////////////////////////////////////////////////////////////////////////
75
78 _order(other._order),
79 _eps(other._eps),
80 _nset("nset",this,other._nset),
81 _func("function",this,other._func),
82 _x("x",this,other._x)
83{
84}
85
87
88////////////////////////////////////////////////////////////////////////////////
89/// Calculate value
90
92{
93 if (!_ftor) {
94 _ftor = std::unique_ptr<RooFunctor>{_func.arg().functor(_x.arg(), RooArgSet(), _nset)};
96 _rd = std::make_unique<ROOT::Math::RichardsonDerivator>(wf, _eps, true);
97 }
98
99 // Figure out if we are close to the variable boundaries
100 double val = _x;
101 auto &xVar = static_cast<RooRealVar &>(*_x);
102 double valMin = xVar.getMin();
103 double valMax = xVar.getMax();
104 bool isCloseLo = val - valMin < _eps;
105 bool isCloseHi = valMax - val < _eps;
106
107 // If we hit the boundary left and right, there is obviously a mistake when setting epsilon
108 if (isCloseLo && isCloseHi) {
109 std::stringstream errMsg;
110 errMsg << "error in numerical derivator: 2 * epsilon is larger than the variable range!";
111 coutE(Eval) << errMsg.str() << std::endl;
112 throw std::runtime_error(errMsg.str());
113 }
114
115 // If we are close to the variable boundary on either side
116 if (isCloseLo || isCloseHi) {
117 // For first-order derivatives we are good: the RichardsonDerivator can
118 // also calculate the derivative using only forward or backward
119 // variations:
120 if (_order == 1) {
121 return isCloseLo ? _rd->DerivativeForward(val) : _rd->DerivativeBackward(val);
122 }
123 // If the function is constant within floating point precision anyway,
124 // we don't have a problem.
125 const double eps = std::numeric_limits<double>::epsilon();
126 const double yval1 = _ftor->eval(val);
127 const double yval2 = isCloseLo ? _ftor->eval(val + _eps) : _ftor->eval(val - _eps);
128 if (std::abs(yval2 - yval1) <= eps) {
129 return 0.0;
130 }
131
132 // Give up
133 std::stringstream errMsg;
134 errMsg << "error in numerical derivator: variable value is to close to limits to compute finite differences";
135 coutE(Eval) << errMsg.str() << std::endl;
136 throw std::runtime_error(errMsg.str());
137 }
138
139 switch (_order) {
140 case 1: return _rd->Derivative1(val);
141 case 2: return _rd->Derivative2(val);
142 case 3: return _rd->Derivative3(val);
143 }
144 return 0;
145}
146
147////////////////////////////////////////////////////////////////////////////////
148/// Zap functor and derivator ;
149
#define coutE(a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
Template class to wrap any C++ callable object which takes one argument i.e.
Abstract container object that can hold multiple RooAbsArg objects.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
Represents the first, second, or third order derivative of any RooAbsReal as calculated (numerically)...
double eps() const
std::unique_ptr< ROOT::Math::RichardsonDerivator > _rd
! Derivator
~RooDerivative() override
RooDerivative()
Default constructor.
double _eps
Precision.
std::unique_ptr< RooFunctor > _ftor
! Functor binding of RooAbsReal
RooSetProxy _nset
Normalization set (optional)
bool redirectServersHook(const RooAbsCollection &, bool, bool, bool) override
Zap functor and derivator ;.
Int_t _order
Derivation order.
double evaluate() const override
Calculate value.
RooRealProxy _func
Input function.
RooRealProxy _x
Observable.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
const T & arg() const
Return reference to object held in proxy.
Double_t x[n]
Definition legend1.C:17