Sequence of Bisect implementations
Bisect6.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 //
7 
8 #include <cmath>
9 #include <functional> // function; C++11
10 #include <iostream>
11 using namespace std;
12 
13 constexpr double EPS = 1e-6; // accuracy constant (global)
14 
15 double f(const double x) // declaration and
16 {
17  return sin(x) - 0.5 * x ; // definition of function f(x)
18 }
19 
20 double g(const double x) // declaration and
21 {
22  return -(x - 1.234567) * (x + 0.987654) ; // definition of function g(x)
23 }
24 
25 double h(const double x) // declaration and
26 {
27  return 3.0 - exp(x) ; // definition of function h(x)
28 }
29 
30 double t(const double x) // declaration and
31 {
32  return 1 - x * x ; // definition of function t(x)
33 }
34 
35 // The three versions of Bisect differ by its signature
36 // declaration of Bisect
37 double Bisect(const double a, const double b, const double eps);
38 // declaration of Bisect2
39 double Bisect(const double a, const double b);
40 // declaration of Bisect3
41 double Bisect(const std::function<double(double)>& func,
42  const double a, const double b, const double eps);
43 
44 int main()
45 {
46  cout << endl;
47  cout << " Determine point of zero in [a,b] by bisection " << endl;
48 
49  cout << " f(x) := sin(x) - x/2" << endl;
50  cout << " g(x) := (1.234567-x)*(x+0.987654)" << endl;
51  cout << " h(x) := 3.0 - exp(x)" << endl;
52  cout << " t(x) := 1-x*x" << endl;
53 
54  std::function<double(double)> ff; //function variable
55  char choice;
56  cout << endl << "Which function do you prefer ? ";
57  cin >> choice;
58 
59  switch (choice) {
60  case 'f':
61  ff = f;
62  break;
63  case 'g':
64  ff = g;
65  break;
66  case 't':
67  ff = t;
68  break;
69  default:
70  choice = 'h';
71  cout << " no correct choice. h(x) is used." << endl;
72  [[fallthrough]];
73  case 'h':
74  ff = h;
75  break;
76  }
77 
78  double a, b;
79  cout << " " << choice << "(a) > 0, a : ";
80  cin >> a;
81  cout << " " << choice << "(b) < 0, b : ";
82  cin >> b;
83  cout << endl;
84 
85  double fa = ff(a),
86  fb = ff(b),
87  x0;
88 
89  if (fa*fb<=0) { // one root in [a,b]
90  if ( abs(fa) < EPS || abs(fb) < EPS) { // solution is a or/and b
91  if ( abs(fa) < EPS ) { // solution is a
92  x0 = a;
93  cout << endl << " point of zero = " << x0 << endl;
94  }
95  if ( abs(fb) < EPS ) { // solution is b
96  x0 = b;
97  cout << endl << " point of zero = " << x0 << endl;
98  }
99  }
100  else { // root in open interval (a,b)
101  if ( fa < 0.0 ) { // f(a) < 0 && f(b) > 0
102  cout << "I have to swap a and b" << endl;
103  x0 = Bisect(ff, b, a, EPS); // Bisect(3) is called
104  }
105  else { // f(a) > 0 && f(b) < 0
106  x0 = Bisect(ff, a, b, EPS); // Bisect(3) is called
107  }
108  cout << endl << " point of zero = " << x0 << endl;
109  }
110  }
111  else { // no solution in [a,b]
112  cout << endl << "There is potentially no solution in [" << a << "," << b << "]" << endl;
113  }
114  cout << endl;
115 
116  return 0;
117 }
118 
119 // ---------------------------------------------------------------
120 // Recursive function Bisect
121 // ---------------------------------------------------------------
122 // definition of Bisect
123 
124 double Bisect(const double a, const double b, const double eps)
125 {
126  double x0, fc, c = (a + b) / 2;
127 
128  fc = sin(c) - 0.5 * c;
129  if ( std::abs(fc) < eps ) {
130  x0 = c; // end of recursion
131  }
132  else if ( fc > 0.0 ) {
133  x0 = Bisect(c, b, eps); // search in right intervall
134  }
135  else { // i.e., fc < 0.0
136  x0 = Bisect(a, c, eps); // search in left intervall
137  }
138 
139  return x0; // return the solution
140 }
141 
142 // ---------------------------------------------------------------
143 // Recursive function Bisect2
144 // ---------------------------------------------------------------
145 
146 double Bisect(const double a, const double b) // definition of Bisect2
147 {
148  double x0, fc, c = (a + b) / 2;
149 
150  fc = f(c);
151  if ( std::abs(fc) < EPS ) {
152  x0 = c; // end of recursion
153  }
154  else if ( fc > 0.0 ) {
155  x0 = Bisect(c, b); // search in right intervall
156  }
157  else { // i.e., fc < 0.0
158  x0 = Bisect(a, c); // search in left intervall
159  }
160 
161  return x0; // return with solution
162 }
163 
164 // ---------------------------------------------------------------
165 // Recursive function Bisect3
166 // ---------------------------------------------------------------
167 // definition of Bisect3
168 
169 double Bisect(const std::function<double(double)>& func,
170  const double a, const double b, const double eps)
171 {
172  double c = (a + b) / 2, fc = func(c), x0;
173 
174  if ( std::abs(fc) < eps ) {
175  x0 = c; // end of recursion
176  }
177  else if ( fc > 0.0 ) {
178  x0 = Bisect(func, c, b, eps); // search in right intervall
179  }
180  else { // i.e., fc < 0.0
181  x0 = Bisect(func, a, c, eps); // search in left intervall
182  }
183 
184  return x0; // return with solution
185 }
186 
187 
188 
189 
190 
191 
192 
193 
194 
constexpr double EPS
Definition: Bisect6.cpp:13
double f(const double x)
Definition: Bisect6.cpp:15
double Bisect(const double a, const double b, const double eps)
Definition: Bisect6.cpp:124
double g(const double x)
Definition: Bisect6.cpp:20
double t(const double x)
Definition: Bisect6.cpp:30
double h(const double x)
Definition: Bisect6.cpp:25
int main()
Definition: Bisect6.cpp:44
b
Definition: bisect.m:12
define interval a
Definition: bisect.m:11