Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4INCL::RootFinder Namespace Reference

Classes

class  Solution
 

Functions

Solution solve (RootFunctor const *const f, const G4double x0)
 Numerically solve a one-dimensional equation. More...
 

Function Documentation

Solution G4INCL::RootFinder::solve ( RootFunctor const *const  f,
const G4double  x0 
)

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,

Parameters
fpointer to a RootFunctor
x0initial value of the function argument
Returns
a Solution object describing the root, if it was found

Definition at line 118 of file G4INCLRootFinder.cc.

118  {
119  // If we already have the solution, do nothing
120  const G4double y0 = (*f)(x0);
121  if( std::abs(y0) < toleranceY ) {
122  return Solution(x0,y0);
123  }
124 
125  // Bracket the root and set the initial values
126  std::pair<G4double,G4double> bracket = bracketRoot(f,x0);
127  G4double x1 = bracket.first;
128  G4double x2 = bracket.second;
129  // If x1>x2, it means that we could not bracket the root. Return false.
130  if(x1>x2) {
131  // Maybe zero is a good solution?
132  G4double y_at_zero = (*f)(0.);
133  if(std::abs(y_at_zero)<=toleranceY) {
134  f->cleanUp(true);
135  return Solution(0.,y_at_zero);
136  } else {
137  INCL_DEBUG("Root-finding algorithm could not bracket the root." << '\n');
138  f->cleanUp(false);
139  return Solution();
140  }
141  }
142 
143  G4double y1 = (*f)(x1);
144  G4double y2 = (*f)(x2);
145  G4double x = x1;
146  G4double y = y1;
147 
148  /* ********************************
149  * Start of the false-position loop
150  * ********************************/
151 
152  // Keep track of the last updated interval end (-1=left, 1=right)
153  G4int lastUpdated = 0;
154 
155  for(G4int iterations=0; std::abs(y) > toleranceY; iterations++) {
156 
157  if(iterations > maxIterations) {
158  INCL_DEBUG("Root-finding algorithm did not converge." << '\n');
159  f->cleanUp(false);
160  return Solution();
161  }
162 
163  // Estimate the root position by linear interpolation
164  x = (y1*x2-y2*x1)/(y1-y2);
165 
166  // Update the value of the function
167  y = (*f)(x);
168 
169  // Update the bracketing interval
170  if(Math::sign(y) == Math::sign(y1)) {
171  x1=x;
172  y1=y;
173  if(lastUpdated==-1) y2 *= 0.5;
174  lastUpdated = -1;
175  } else {
176  x2=x;
177  y2=y;
178  if(lastUpdated==1) y1 *= 0.5;
179  lastUpdated = 1;
180  }
181  }
182 
183  /* ******************************
184  * End of the false-position loop
185  * ******************************/
186 
187  f->cleanUp(true);
188  return Solution(x,y);
189  }
int G4int
Definition: G4Types.hh:78
double G4double
Definition: G4Types.hh:76
#define INCL_DEBUG(x)
G4int sign(const T t)

Here is the call graph for this function:

Here is the caller graph for this function: