bisection.cpp
1 #include <cmath>
2 #include "bisection.hpp"
3 #include "universal_error.hpp"
4 
5 namespace
6 {
7  bool is_effectively_zero(double x)
8  {
9  return fabs(x)<1e-14;
10  }
11 }
12 
13 double find_upper_bracket(Func1Var const& f,
14  double xl)
15 {
16  const int max_iter = 10;
17  int iter = 0;
18 
19  double fl = f.eval(xl);
20  double xr = xl;
21  // TODO: change to fr = fl
22  double fr = f.eval(xr);
23  while(fl*fr>=0){
24  xr = 2*xr;
25  fr = f.eval(xr);
26  if(iter>max_iter)
27  throw UniversalError("Error in bisection::find_upper_bracket. Max number of iterations exceeded");
28  else
29  ++iter;
30  }
31  return 2*xr;
32 }
33 
34 double bisection(Func1Var const& f,
35  double xl,
36  double xr,
37  double tol)
38 {
39  const int max_iter = 100;
40 
41  int iter = 0;
42 
43  double fl = f.eval(xl);
44  if(is_effectively_zero(fl))
45  return xl;
46 
47  double fr = f.eval(xr);
48  if(is_effectively_zero(fr))
49  return xr;
50 
51  if(fl*fr>0){
52  UniversalError eo("Error in bisection: root is not bracketed");
53  eo.AddEntry("xl",xl);
54  eo.AddEntry("xr",xr);
55  eo.AddEntry("fl",fl);
56  eo.AddEntry("fr",fr);
57  throw eo;
58  }
59 
60  while(fabs(xl-xr)>tol){
61  double xm = 0.5*(xl+xr);
62  double fm = f.eval(xm);
63  if(is_effectively_zero(fm))
64  return xm;
65  if(fm*fl>0)
66  xl = xm;
67  else if(fm*fr>0)
68  xr = xm;
69  else
70  throw UniversalError("Something bad happened. Probably a NaN");
71 
72  if(iter>max_iter)
73  throw UniversalError("Error in Bisection: Maximum number of iterations exceeded");
74  else
75  ++iter;
76  }
77 
78  return 0.5*(xl+xr);
79 }
Container for error reports.
double find_upper_bracket(Func1Var const &f, double xl)
Finds an upper limit to an equation.
Definition: bisection.cpp:13
virtual double eval(double x) const =0
Evaluates the function.
double bisection(Func1Var const &f, double xl, double xr, double tol=1e-6)
Solves a monotonous transcendental equation using the bisection method.
Definition: bisection.cpp:34
Scalar function of a single variable.
Definition: func_1_var.hpp:9
Solution of transcendental equations with a single variable using the bisection method.
void AddEntry(std::string const &field, double value)
Adds an entry to the list.
A class for storing error and debug information.