Sequence of Bisect implementations
Bisect7.cpp
Go to the documentation of this file.
1 // Bisect6.cpp
2 // Recursive function
3 // Example: Find the point of zero by bisection
4 
5 // Version 6: All three Bisection functions with the same name
6 // Version 7: now with array of functions
7 //
8 
9 #include <array>
10 #include <cmath>
11 #include <functional> // function; C++11
12 #include <iostream>
13 #include <map>
14 using namespace std;
15 
16 double f(const double x) // declaration and
17 {
18  return sin(x) - 0.5 * x ; // definition of function f(x)
19 }
20 
21 double g(const double x) // declaration and
22 {
23  return -(x - 1.234567) * (x + 0.987654) ; // definition of function g(x)
24 }
25 
26 double h(const double x) // declaration and
27 {
28  return 3.0 - exp(x) ; // definition of function h(x)
29 }
30 
31 double t(const double x) // declaration and
32 {
33  return 1 - x * x ; // definition of function t(x)
34 }
35 
36 // The three versions of Bisect differ by its signature
37 // declaration of Bisect
38 double Bisect(double a, double b, double eps);
39 // declaration of Bisect2
40 double Bisect(double a, double b);
41 // declaration of Bisect3
42 double Bisect(const std::function<double(double)> &func,
43  double a, double b, double eps);
44 
45 int main()
46 {
47  constexpr double EPS = 1e-6; // accuracy constant
48  array<string, 4> ssf{"f(x) := sin(x) - x/2",
49  "g(x) := (1.234567-x)*(x+0.987654)",
50  "h(x) := 3.0 - exp(x)",
51  "t(x) := 1-x*x" };
52 
53 // now with array of functions
54  array< std::function<double(double)>, 4> vff{f, g, h, t};
55 
56  // map char to index
57  map<char, int> mmf{{'f', 0}, {'g', 1}, {'h', 2}, {'t', 3}};
58 
59  // map char to function
60  map<char, std::function<double(double)> > mapff{{'f', f}, {'g', g}, {'h', h}, {'t', t}};
61 
62 
63  cout << endl;
64  cout << " Determine root in [a,b] by bisection " << endl;
65 
66  for (size_t k = 0; k < ssf.size(); ++k) {
67  //cout << "[" << k << "] ";
68  cout << ssf[k] << endl;
69  }
70 
71  char choice;
72  cout << endl << "Which function do you prefer ? ";
73  cin >> choice;
74 
75  std::function<double(double)> ff;
76  try {
77  // http://www.cplusplus.com/reference/map/map/at/
78  ff = mapff.at(choice); //function variable
79  }
80  catch (out_of_range& ) {
81  choice = 'h';
82  ff = mapff.at(choice);
83  cout << " incorrect choice. h(x) is used." << endl;
84  }
85 
86 
87  double a;
88  double b;
89  cout << " " << choice << "(a) > 0, a : ";
90  cin >> a;
91  cout << " " << choice << "(b) < 0, b : ";
92  cin >> b;
93  cout << endl;
94 
95  double const fa = ff(a);
96  double const fb = ff(b);
97  double x0;
98 
99  if (fa*fb<=0) { // one root in [a,b]
100  if ( abs(fa) < EPS || abs(fb) < EPS) { // solution is a or/and b
101  if ( abs(fa) < EPS ) { // solution is a
102  x0 = a;
103  cout << endl << " point of zero = " << x0 << endl;
104  }
105  if ( abs(fb) < EPS ) { // solution is b
106  x0 = b;
107  cout << endl << " point of zero = " << x0 << endl;
108  }
109  }
110  else { // root in open interval (a,b)
111  if ( fa < 0.0 ) { // f(a) < 0 && f(b) > 0
112  cout << "I have to swap a and b" << endl;
113  x0 = Bisect(ff, b, a, EPS); // Bisect(3) is called
114  }
115  else { // f(a) > 0 && f(b) < 0
116  x0 = Bisect(ff, a, b, EPS); // Bisect(3) is called
117  }
118  cout << endl << " point of zero = " << x0 << endl;
119  }
120  }
121  else { // no solution in [a,b]
122  cout << endl << "There is potentially no solution in [" << a << "," << b << "]" << endl;
123  }
124  cout << endl;
125 
126  return 0;
127 }
128 
129 // ---------------------------------------------------------------
130 // Recursive function Bisect3
131 // ---------------------------------------------------------------
132 // definition of Bisect3
133 
134 double Bisect(const std::function<double(double)> &func,
135  const double a, const double b, const double eps)
136 {
137  double const c = (a + b) / 2;
138  double const fc = func(c);
139  double x0;
140 
141  if ( std::abs(fc) < eps ) {
142  x0 = c; // end of recursion
143  }
144  else if ( fc > 0.0 ) {
145  x0 = Bisect(func, c, b, eps); // search in right intervall
146  }
147  else { // i.e., fc < 0.0
148  x0 = Bisect(func, a, c, eps); // search in left intervall
149  }
150 
151  return x0; // return with solution
152 }
153 
154 
155 
156 
157 
158 
159 
160 
161 
const double EPS
Definition: Bisect2.cpp:13
double Bisect(double a, double b, double eps)
Definition: Bisect6.cpp:124
double f(const double x)
Definition: Bisect7.cpp:16
double g(const double x)
Definition: Bisect7.cpp:21
double t(const double x)
Definition: Bisect7.cpp:31
double h(const double x)
Definition: Bisect7.cpp:26
int main()
Definition: Bisect7.cpp:45
b
Definition: bisect.m:12
define interval a
Definition: bisect.m:11