#include <G4INCLRootFinder.hh>
Static Public Member Functions | |
static G4bool | solve (RootFunctor const *const f, const G4double x0) |
Numerically solve a one-dimensional equation. | |
static std::pair< G4double, G4double > const & | getSolution () |
Get the solution of the last call to solve(). | |
Protected Member Functions | |
RootFinder () | |
~RootFinder () |
Definition at line 64 of file G4INCLRootFinder.hh.
G4INCL::RootFinder::RootFinder | ( | ) | [inline, protected] |
G4INCL::RootFinder::~RootFinder | ( | ) | [inline, protected] |
Get the solution of the last call to solve().
Definition at line 83 of file G4INCLRootFinder.hh.
Referenced by G4INCL::InteractionAvatar::enforceEnergyConservation().
G4bool G4INCL::RootFinder::solve | ( | RootFunctor const *const | f, | |
const G4double | x0 | |||
) | [static] |
Numerically solve a one-dimensional equation.
Numerically solves the equation f(x)==0. This implementation uses the false-position method.
If a root is found, it can be retrieved using the getSolution() method,
f | pointer to a RootFunctor | |
x0 | initial value of the function argument |
Definition at line 58 of file G4INCLRootFinder.cc.
References G4INCL::RootFunctor::cleanUp(), G4INCL::Math::sign(), and WARN.
Referenced by G4INCL::InteractionAvatar::enforceEnergyConservation().
00058 { 00059 // If we already have the solution, do nothing 00060 const G4double y0 = (*f)(x0); 00061 if( std::abs(y0) < toleranceY ) { 00062 solution = std::make_pair(x0,y0); 00063 return true; 00064 } 00065 00066 // Bracket the root and set the initial values 00067 std::pair<G4double,G4double> bracket = bracketRoot(f,x0); 00068 G4double x1 = bracket.first; 00069 G4double x2 = bracket.second; 00070 // If x1>x2, it means that we could not bracket the root. Return false. 00071 if(x1>x2) { 00072 // Maybe zero is a good solution? 00073 G4double y_at_zero = (*f)(0.); 00074 if(std::abs(y_at_zero)<=toleranceY) { 00075 f->cleanUp(true); 00076 solution = std::make_pair(0.,y_at_zero); 00077 return true; 00078 } else { 00079 WARN("Root-finding algorithm could not bracket the root." << std::endl); 00080 f->cleanUp(false); 00081 return false; 00082 } 00083 } 00084 00085 G4double y1 = (*f)(x1); 00086 G4double y2 = (*f)(x2); 00087 G4double x = x1; 00088 G4double y = y1; 00089 00090 /* ******************************** 00091 * Start of the false-position loop 00092 * ********************************/ 00093 00094 // Keep track of the last updated interval end (-1=left, 1=right) 00095 G4int lastUpdated = 0; 00096 00097 for(G4int iterations=0; std::abs(y) > toleranceY; iterations++) { 00098 00099 if(iterations > maxIterations) { 00100 WARN("Root-finding algorithm did not converge." << std::endl); 00101 f->cleanUp(false); 00102 return false; 00103 } 00104 00105 // Estimate the root position by linear interpolation 00106 x = (y1*x2-y2*x1)/(y1-y2); 00107 00108 // Update the value of the function 00109 y = (*f)(x); 00110 00111 // Update the bracketing interval 00112 if(Math::sign(y) == Math::sign(y1)) { 00113 x1=x; 00114 y1=y; 00115 if(lastUpdated==-1) y2 *= 0.5; 00116 lastUpdated = -1; 00117 } else { 00118 x2=x; 00119 y2=y; 00120 if(lastUpdated==1) y1 *= 0.5; 00121 lastUpdated = 1; 00122 } 00123 } 00124 00125 /* ****************************** 00126 * End of the false-position loop 00127 * ******************************/ 00128 00129 solution = std::make_pair(x,y); 00130 f->cleanUp(true); 00131 return true; 00132 }