1 //--------------------------------------------------------------------------
4 // Copyright Information: See EvtGen/COPYRIGHT
7 // This software is part of the EvtGen package developed jointly
8 // for the BaBar and CLEO collaborations. If you use all or part
9 // of it, please give an appropriate acknowledgement.
11 // Module: EvtBtoXsgammaRootFinder.cc
14 // Root finders for EvtBtoXsgammaKagan module.
16 // Modification history:
18 // Jane Tinslay March 21, 2001 Module created
19 //------------------------------------------------------------------------
20 #include "EvtGenBase/EvtPatches.hh"
22 #include "EvtGenModels/EvtBtoXsgammaRootFinder.hh"
23 #include "EvtGenModels/EvtItgTwoCoeffFcn.hh"
24 #include "EvtGenModels/EvtItgSimpsonIntegrator.hh"
25 #include "EvtGenBase/EvtReport.hh"
35 //-----------------------------------------------------------------------
36 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
37 //-----------------------------------------------------------------------
39 #define EVTITGROOTFINDER_MAXIT 100
40 #define EVTITGROOTFINDER_RELATIVEPRECISION 1.0e-16
43 EvtBtoXsgammaRootFinder::EvtBtoXsgammaRootFinder() {}
45 EvtBtoXsgammaRootFinder::~EvtBtoXsgammaRootFinder( )
49 EvtBtoXsgammaRootFinder::GetRootSingleFunc(const EvtItgAbsFunction* theFunc, double functionValue, double lowerValue, double upperValue, double precision) {
51 // Use the bisection to find the root.
52 // Iterates until find root to the accuracy of precision
54 double xLower = 0.0, xUpper = 0.0;
57 double f1 = theFunc->value(lowerValue) - functionValue;
58 double f2 = theFunc->value(upperValue) - functionValue;
61 report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: No root in specified range !"<<endl;
66 if (fabs(f1) < precision) {
70 if (fabs(f2) < precision) {
75 // Orient search so that f(xLower) < 0
84 double rootGuess = 0.5*(lowerValue + upperValue);
85 double dxold = fabs(upperValue - lowerValue);
88 double f = theFunc->value(rootGuess) - functionValue;
90 for (int j = 0; j< EVTITGROOTFINDER_MAXIT; j++) {
93 dx = 0.5*(xUpper-xLower);
94 rootGuess = xLower+dx;
96 // If change in root is negligible, take it as solution.
97 if (fabs(xLower - rootGuess) < precision) {
102 f = theFunc->value(rootGuess) - functionValue;
112 report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: Maximum number of iterations "
113 <<"in EvtBtoXsgammaRootFinder::foundRoot exceeded!"
114 <<" Returning false."<<endl;
120 EvtBtoXsgammaRootFinder::GetGaussIntegFcnRoot(EvtItgAbsFunction *theFunc1, EvtItgAbsFunction *theFunc2, double integ1Precision, double integ2Precision, int maxLoop1, int maxLoop2, double integLower, double integUpper, double lowerValue, double upperValue, double precision) {
122 // Use the bisection to find the root.
123 // Iterates until find root to the accuracy of precision
125 //Need to work with integrators
126 EvtItgAbsIntegrator *func1Integ = new EvtItgSimpsonIntegrator(*theFunc1, integ1Precision, maxLoop1);
127 EvtItgAbsIntegrator *func2Integ = new EvtItgSimpsonIntegrator(*theFunc2, integ2Precision, maxLoop2);
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);
135 double f1 = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper);
136 theFunc1->setCoeff(1,0,upperValue);
137 theFunc2->setCoeff(1,0,upperValue);
138 double f2 = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper);
140 double xLower = 0.0, xUpper = 0.0;
144 report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: No root in specified range !"<<endl;
149 if (fabs(f1) < precision) {
153 if (fabs(f2) < precision) {
158 // Orient search so that f(xLower) < 0
167 double rootGuess = 0.5*(lowerValue + upperValue);
168 double dxold = fabs(upperValue - lowerValue);
171 theFunc1->setCoeff(1,0,rootGuess);
172 theFunc2->setCoeff(1,0,rootGuess);
173 double f = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper);
175 for (int j = 0; j< EVTITGROOTFINDER_MAXIT; j++) {
178 dx = 0.5*(xUpper-xLower);
179 rootGuess = xLower+dx;
181 // If change in root is negligible, take it as solution.
182 if (fabs(xLower - rootGuess) < precision) {
187 theFunc1->setCoeff(1,0,rootGuess);
188 theFunc2->setCoeff(1,0,rootGuess);
189 f = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper);
199 report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: Maximum number of iterations "
200 <<"in EvtBtoXsgammaRootFinder::foundRoot exceeded!"
201 <<" Returning false."<<endl;