EvtGen
2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Toggle main menu visibility
Loading...
Searching...
No Matches
src
EvtGenModels
EvtBtoXsgammaRootFinder.cpp
Go to the documentation of this file.
1
2
/***********************************************************************
3
* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4
* *
5
* This file is part of EvtGen. *
6
* *
7
* EvtGen is free software: you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation, either version 3 of the License, or *
10
* (at your option) any later version. *
11
* *
12
* EvtGen is distributed in the hope that it will be useful, *
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
* GNU General Public License for more details. *
16
* *
17
* You should have received a copy of the GNU General Public License *
18
* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19
***********************************************************************/
20
21
#include "
EvtGenModels/EvtBtoXsgammaRootFinder.hh
"
22
23
#include "
EvtGenBase/EvtReport.hh
"
24
25
#include "
EvtGenModels/EvtItgSimpsonIntegrator.hh
"
26
#include "
EvtGenModels/EvtItgTwoCoeffFcn.hh
"
27
28
#include <math.h>
29
using
std::endl;
30
31
//-------------
32
// C Headers --
33
//-------------
34
extern
"C"
{
35
}
36
37
//-----------------------------------------------------------------------
38
// Local Macros, Typedefs, Structures, Unions and Forward Declarations --
39
//-----------------------------------------------------------------------
40
41
#define EVTITGROOTFINDER_MAXIT 100
42
#define EVTITGROOTFINDER_RELATIVEPRECISION 1.0e-16
43
44
double
EvtBtoXsgammaRootFinder::GetRootSingleFunc
(
45
const
EvtItgAbsFunction
* theFunc,
double
functionValue,
double
lowerValue,
46
double
upperValue,
double
precision )
47
{
48
// Use the bisection to find the root.
49
// Iterates until find root to the accuracy of precision
50
51
double
xLower = 0.0, xUpper = 0.0;
52
double
root = 0;
53
54
double
f1 = theFunc->
value
( lowerValue ) - functionValue;
55
double
f2 = theFunc->
value
( upperValue ) - functionValue;
56
57
if
( f1 * f2 > 0.0 ) {
58
EvtGenReport
(
EVTGEN_WARNING
,
"EvtGen"
)
59
<<
"EvtBtoXsgammaRootFinder: No root in specified range !"
<< endl;
60
return
0;
61
}
62
63
// Already have root
64
if
( fabs( f1 ) < precision ) {
65
root = lowerValue;
66
return
root;
67
}
68
if
( fabs( f2 ) < precision ) {
69
root = upperValue;
70
return
root;
71
}
72
73
// Orient search so that f(xLower) < 0
74
if
( f1 < 0.0 ) {
75
xLower = lowerValue;
76
xUpper = upperValue;
77
}
else
{
78
xLower = upperValue;
79
xUpper = lowerValue;
80
}
81
82
double
rootGuess = 0.5 * ( lowerValue + upperValue );
83
double
dxold = fabs( upperValue - lowerValue );
84
double
dx = dxold;
85
86
double
f = theFunc->
value
( rootGuess ) - functionValue;
87
88
for
(
int
j = 0; j <
EVTITGROOTFINDER_MAXIT
; j++ ) {
89
dxold = dx;
90
dx = 0.5 * ( xUpper - xLower );
91
rootGuess = xLower + dx;
92
93
// If change in root is negligible, take it as solution.
94
if
( fabs( xLower - rootGuess ) < precision ) {
95
root = rootGuess;
96
return
root;
97
}
98
99
f = theFunc->
value
( rootGuess ) - functionValue;
100
101
if
( f < 0.0 ) {
102
xLower = rootGuess;
103
}
else
{
104
xUpper = rootGuess;
105
}
106
}
107
108
EvtGenReport
(
EVTGEN_WARNING
,
"EvtGen"
)
109
<<
"EvtBtoXsgammaRootFinder: Maximum number of iterations "
110
<<
"in EvtBtoXsgammaRootFinder::foundRoot exceeded!"
111
<<
" Returning false."
<< endl;
112
return
0;
113
}
114
115
double
EvtBtoXsgammaRootFinder::GetGaussIntegFcnRoot
(
116
EvtItgAbsFunction
* theFunc1,
EvtItgAbsFunction
* theFunc2,
117
double
integ1Precision,
double
integ2Precision,
int
maxLoop1,
int
maxLoop2,
118
double
integLower,
double
integUpper,
double
lowerValue,
double
upperValue,
119
double
precision )
120
{
121
// Use the bisection to find the root.
122
// Iterates until find root to the accuracy of precision
123
124
//Need to work with integrators
125
auto
func1Integ =
EvtItgSimpsonIntegrator
{ *theFunc1, integ1Precision,
126
maxLoop1 };
127
auto
func2Integ =
EvtItgSimpsonIntegrator
{ *theFunc2, integ2Precision,
128
maxLoop2 };
129
130
//coefficient 1 of the integrators is the root to be found
131
//need to set this to lower value to start off with
132
theFunc1->
setCoeff
( 1, 0, lowerValue );
133
theFunc2->
setCoeff
( 1, 0, lowerValue );
134
135
double
f1 = func1Integ.evaluate( integLower, integUpper ) -
136
theFunc2->
getCoeff
( 1, 2 ) *
137
func2Integ.evaluate( integLower, integUpper );
138
theFunc1->
setCoeff
( 1, 0, upperValue );
139
theFunc2->
setCoeff
( 1, 0, upperValue );
140
double
f2 = func1Integ.evaluate( integLower, integUpper ) -
141
theFunc2->
getCoeff
( 1, 2 ) *
142
func2Integ.evaluate( integLower, integUpper );
143
144
double
xLower = 0.0, xUpper = 0.0;
145
double
root = 0;
146
147
if
( f1 * f2 > 0.0 ) {
148
EvtGenReport
(
EVTGEN_WARNING
,
"EvtGen"
)
149
<<
"EvtBtoXsgammaRootFinder: No root in specified range !"
<< endl;
150
return
false
;
151
}
152
153
// Already have root
154
if
( fabs( f1 ) < precision ) {
155
root = lowerValue;
156
return
root;
157
}
158
if
( fabs( f2 ) < precision ) {
159
root = upperValue;
160
return
root;
161
}
162
163
// Orient search so that f(xLower) < 0
164
if
( f1 < 0.0 ) {
165
xLower = lowerValue;
166
xUpper = upperValue;
167
}
else
{
168
xLower = upperValue;
169
xUpper = lowerValue;
170
}
171
172
double
rootGuess = 0.5 * ( lowerValue + upperValue );
173
double
dxold = fabs( upperValue - lowerValue );
174
double
dx = dxold;
175
176
theFunc1->
setCoeff
( 1, 0, rootGuess );
177
theFunc2->
setCoeff
( 1, 0, rootGuess );
178
double
f = func1Integ.evaluate( integLower, integUpper ) -
179
theFunc2->
getCoeff
( 1, 2 ) *
180
func2Integ.evaluate( integLower, integUpper );
181
182
for
(
int
j = 0; j <
EVTITGROOTFINDER_MAXIT
; j++ ) {
183
dxold = dx;
184
dx = 0.5 * ( xUpper - xLower );
185
rootGuess = xLower + dx;
186
187
// If change in root is negligible, take it as solution.
188
if
( fabs( xLower - rootGuess ) < precision ) {
189
root = rootGuess;
190
return
root;
191
}
192
193
theFunc1->
setCoeff
( 1, 0, rootGuess );
194
theFunc2->
setCoeff
( 1, 0, rootGuess );
195
f = func1Integ.evaluate( integLower, integUpper ) -
196
theFunc2->
getCoeff
( 1, 2 ) *
197
func2Integ.evaluate( integLower, integUpper );
198
199
if
( f < 0.0 ) {
200
xLower = rootGuess;
201
}
else
{
202
xUpper = rootGuess;
203
}
204
}
205
206
EvtGenReport
(
EVTGEN_WARNING
,
"EvtGen"
)
207
<<
"EvtBtoXsgammaRootFinder: Maximum number of iterations "
208
<<
"in EvtBtoXsgammaRootFinder::foundRoot exceeded!"
209
<<
" Returning false."
<< endl;
210
return
0;
211
}
EVTITGROOTFINDER_MAXIT
#define EVTITGROOTFINDER_MAXIT
Definition
EvtBtoXsgammaRootFinder.cpp:41
EvtBtoXsgammaRootFinder.hh
EvtItgSimpsonIntegrator.hh
EvtItgTwoCoeffFcn.hh
EvtReport.hh
EvtGenReport
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition
EvtReport.cpp:32
EVTGEN_WARNING
@ EVTGEN_WARNING
Definition
EvtReport.hh:50
EvtBtoXsgammaRootFinder::GetGaussIntegFcnRoot
double GetGaussIntegFcnRoot(EvtItgAbsFunction *theFunc1, EvtItgAbsFunction *theFunc2, double integ1Precision, double integ2Precision, int maxLoop1, int maxLoop2, double integLower, double integUpper, double lowerValue, double upperValue, double precision)
Definition
EvtBtoXsgammaRootFinder.cpp:115
EvtBtoXsgammaRootFinder::GetRootSingleFunc
double GetRootSingleFunc(const EvtItgAbsFunction *theFunc, double functionValue, double lowerValue, double upperValue, double precision)
Definition
EvtBtoXsgammaRootFinder.cpp:44
EvtItgAbsFunction
Definition
EvtItgAbsFunction.hh:35
EvtItgAbsFunction::getCoeff
virtual double getCoeff(int, int)=0
EvtItgAbsFunction::setCoeff
virtual void setCoeff(int, int, double)=0
EvtItgAbsFunction::value
virtual double value(double x) const
Definition
EvtItgAbsFunction.cpp:38
EvtItgSimpsonIntegrator
Definition
EvtItgSimpsonIntegrator.hh:36
Generated by
1.17.0