//-------------------------------------------------------------------------- // // // Copyright Information: See EvtGen/COPYRIGHT // // Environment: // This software is part of the EvtGen package developed jointly // for the BaBar and CLEO collaborations. If you use all or part // of it, please give an appropriate acknowledgement. // // Module: EvtBtoXsgammaRootFinder.cc // // Description: // Root finders for EvtBtoXsgammaKagan module. // // Modification history: // // Jane Tinslay March 21, 2001 Module created //------------------------------------------------------------------------ #include "EvtGenBase/EvtPatches.hh" #include "EvtGenModels/EvtBtoXsgammaRootFinder.hh" #include "EvtGenModels/EvtItgTwoCoeffFcn.hh" #include "EvtGenModels/EvtItgSimpsonIntegrator.hh" #include "EvtGenBase/EvtReport.hh" #include using std::endl; //------------- // C Headers -- //------------- extern "C" { } //----------------------------------------------------------------------- // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- //----------------------------------------------------------------------- #define EVTITGROOTFINDER_MAXIT 100 #define EVTITGROOTFINDER_RELATIVEPRECISION 1.0e-16 EvtBtoXsgammaRootFinder::EvtBtoXsgammaRootFinder() {} EvtBtoXsgammaRootFinder::~EvtBtoXsgammaRootFinder( ) {} double EvtBtoXsgammaRootFinder::GetRootSingleFunc(const EvtItgAbsFunction* theFunc, double functionValue, double lowerValue, double upperValue, double precision) { // Use the bisection to find the root. // Iterates until find root to the accuracy of precision double xLower = 0.0, xUpper = 0.0; double root=0; double f1 = theFunc->value(lowerValue) - functionValue; double f2 = theFunc->value(upperValue) - functionValue; if ( f1*f2 > 0.0 ) { report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: No root in specified range !"<value(rootGuess) - functionValue; for (int j = 0; j< EVTITGROOTFINDER_MAXIT; j++) { dxold = dx; dx = 0.5*(xUpper-xLower); rootGuess = xLower+dx; // If change in root is negligible, take it as solution. if (fabs(xLower - rootGuess) < precision) { root = rootGuess; return root; } f = theFunc->value(rootGuess) - functionValue; if (f < 0.0) { xLower = rootGuess; } else { xUpper = rootGuess; } } report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: Maximum number of iterations " <<"in EvtBtoXsgammaRootFinder::foundRoot exceeded!" <<" Returning false."<setCoeff(1,0,lowerValue); theFunc2->setCoeff(1,0,lowerValue); double f1 = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper); theFunc1->setCoeff(1,0,upperValue); theFunc2->setCoeff(1,0,upperValue); double f2 = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper); double xLower = 0.0, xUpper = 0.0; double root=0; if ( f1*f2 > 0.0 ) { report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: No root in specified range !"<setCoeff(1,0,rootGuess); theFunc2->setCoeff(1,0,rootGuess); double f = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper); for (int j = 0; j< EVTITGROOTFINDER_MAXIT; j++) { dxold = dx; dx = 0.5*(xUpper-xLower); rootGuess = xLower+dx; // If change in root is negligible, take it as solution. if (fabs(xLower - rootGuess) < precision) { root = rootGuess; return root; } theFunc1->setCoeff(1,0,rootGuess); theFunc2->setCoeff(1,0,rootGuess); f = func1Integ->evaluate(integLower,integUpper) - theFunc2->getCoeff(1,2)*func2Integ->evaluate(integLower,integUpper); if (f < 0.0) { xLower = rootGuess; } else { xUpper = rootGuess; } } report(WARNING,"EvtGen") << "EvtBtoXsgammaRootFinder: Maximum number of iterations " <<"in EvtBtoXsgammaRootFinder::foundRoot exceeded!" <<" Returning false."<