Root Finder  1.0
Using various numerical methods
Loading...
Searching...
No Matches
methods.h File Reference
#include <vector>
#include <string>
#include "functions.h"
+ Include dependency graph for methods.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  RootInfo
 

Functions

long double bisection (long double a, long double b, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
 
long double newton_raphson (long double x0, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
 
long double hybrid_method (long double a, long double b, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
 
long double brent_method (long double a, long double b, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
 
long double ridder_method (long double a, long double b, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
 

Function Documentation

◆ bisection()

long double bisection ( long double a,
long double b,
long double tol,
int max_iter,
std::vector< std::string > & iterations,
int decimal_places )

Definition at line 17 of file methods.cpp.

18{
19 long double fa = f(a), fb = f(b);
20 if (fa * fb >= 0)
21 {
22 std::cerr << "Bisection method fails. f(a) and f(b) should have opposite signs.\n";
23 return NAN;
24 }
25
26 long double c = a;
27 for (int i = 0; i < max_iter; ++i)
28 {
29 c = (a + b) / 2.0L;
30 long double fc = f(c);
31 std::ostringstream oss;
32 oss << "Step " << i + 1 << ": [" << std::fixed << std::setprecision(decimal_places) << a << ", " << b << "]";
33 iterations.push_back(oss.str());
34 if ((b - a) / 2.0L < tol)
35 break;
36 if (fa * fc < 0)
37 {
38 b = c;
39 fb = fc;
40 }
41 else
42 {
43 a = c;
44 fa = fc;
45 }
46 }
47 return c;
48}
long double f(long double x)
Definition functions.cpp:13

◆ brent_method()

long double brent_method ( long double a,
long double b,
long double tol,
int max_iter,
std::vector< std::string > & iterations,
int decimal_places )

Definition at line 139 of file methods.cpp.

140{
141 long double fa = f(a), fb = f(b);
142 if (fa * fb >= 0)
143 {
144 std::cerr << "Brent's method fails. f(a) and f(b) should have opposite signs.\n";
145 return NAN;
146 }
147
148 if (fabs(fa) < fabs(fb))
149 {
150 std::swap(a, b);
151 std::swap(fa, fb);
152 }
153
154 long double c = a, fc = fa, s = b, fs = fb;
155 bool mflag = true;
156 long double d = 0.0;
157
158 for (int i = 0; i < max_iter; ++i)
159 {
160 if (fb != fc && fa != fc)
161 {
162 // Inverse quadratic interpolation
163 s = (a * fb * fc) / ((fa - fb) * (fa - fc)) +
164 (b * fa * fc) / ((fb - fa) * (fb - fc)) +
165 (c * fa * fb) / ((fc - fa) * (fc - fb));
166 }
167 else
168 {
169 // Secant method
170 s = b - fb * (b - a) / (fb - fa);
171 }
172
173 // Conditions to accept s
174 bool condition1 = (s < (3 * a + b) / 4.0L || s > b);
175 bool condition2 = (mflag && fabs(s - b) >= fabs(b - c) / 2.0L);
176 bool condition3 = (!mflag && fabs(s - b) >= fabs(c - d) / 2.0L);
177 bool condition4 = (mflag && fabs(b - c) < tol);
178 bool condition5 = (!mflag && fabs(c - d) < tol);
179
180 if (condition1 || condition2 || condition3 || condition4 || condition5)
181 {
182 // Bisection method
183 s = (a + b) / 2.0L;
184 mflag = true;
185 }
186 else
187 {
188 mflag = false;
189 }
190
191 long double fs_new = f(s);
192 std::ostringstream oss;
193 oss << "Step " << i + 1 << ": a = " << std::fixed << std::setprecision(decimal_places) << a
194 << ", b = " << b << ", s = " << s;
195 iterations.push_back(oss.str());
196
197 d = c;
198 c = b;
199 fc = fb;
200
201 if (fa * fs_new < 0)
202 {
203 b = s;
204 fb = fs_new;
205 }
206 else
207 {
208 a = s;
209 fa = fs_new;
210 }
211
212 if (fabs(fa) < fabs(fb))
213 {
214 std::swap(a, b);
215 std::swap(fa, fb);
216 }
217
218 if (fabs(b - a) < tol)
219 break;
220 }
221
222 return b;
223}

◆ hybrid_method()

long double hybrid_method ( long double a,
long double b,
long double tol,
int max_iter,
std::vector< std::string > & iterations,
int decimal_places )

Definition at line 76 of file methods.cpp.

77{
78 long double fa = f(a), fb = f(b);
79 if (fa * fb >= 0)
80 {
81 std::cerr << "Hybrid method fails. f(a) and f(b) should have opposite signs.\n";
82 return NAN;
83 }
84
85 long double c = a;
86 for (int i = 0; i < max_iter; ++i)
87 {
88 c = (a + b) / 2.0L;
89 long double fc = f(c);
90 std::ostringstream oss;
91 oss << "Step " << i + 1 << ": [" << std::fixed << std::setprecision(decimal_places) << a << ", " << b << "]";
92 iterations.push_back(oss.str());
93 if ((b - a) / 2.0L < tol)
94 break;
95
96 long double fpc = f_prime(c);
97 if (fpc != 0.0)
98 {
99 long double d = c - fc / fpc;
100 if (d > a && d < b)
101 {
102 long double fd = f(d);
103 std::ostringstream oss_newton;
104 oss_newton << "Newton Step: c = " << std::fixed << std::setprecision(decimal_places) << c
105 << ", d = " << d;
106 iterations.push_back(oss_newton.str());
107 if (fabs(d - c) < tol)
108 return d;
109 if (fa * fd < 0)
110 {
111 b = d;
112 fb = fd;
113 }
114 else
115 {
116 a = d;
117 fa = fd;
118 }
119 continue;
120 }
121 }
122
123 // Fallback to bisection
124 if (fa * fc < 0)
125 {
126 b = c;
127 fb = fc;
128 }
129 else
130 {
131 a = c;
132 fa = fc;
133 }
134 }
135 return c;
136}
long double f_prime(long double x)
Definition functions.cpp:19

◆ newton_raphson()

long double newton_raphson ( long double x0,
long double tol,
int max_iter,
std::vector< std::string > & iterations,
int decimal_places )

Definition at line 51 of file methods.cpp.

52{
53 long double x1;
54 for (int i = 0; i < max_iter; ++i)
55 {
56 long double fx0 = f(x0);
57 long double fpx0 = f_prime(x0);
58 if (fpx0 == 0.0)
59 {
60 std::cerr << "Newton-Raphson method fails. Derivative zero.\n";
61 return NAN;
62 }
63 x1 = x0 - fx0 / fpx0;
64 std::ostringstream oss;
65 oss << "Step " << i + 1 << ": x0 = " << std::fixed << std::setprecision(decimal_places) << x0
66 << ", x1 = " << x1;
67 iterations.push_back(oss.str());
68 if (fabs(x1 - x0) < tol)
69 break;
70 x0 = x1;
71 }
72 return x1;
73}

◆ ridder_method()

long double ridder_method ( long double a,
long double b,
long double tol,
int max_iter,
std::vector< std::string > & iterations,
int decimal_places )

Definition at line 226 of file methods.cpp.

227{
228 long double fa = f(a), fb = f(b);
229 if (fa * fb >= 0)
230 {
231 std::cerr << "Ridder's method fails. f(a) and f(b) should have opposite signs.\n";
232 return NAN;
233 }
234
235 for (int i = 0; i < max_iter; ++i)
236 {
237 long double c = 0.5L * (a + b);
238 long double fc = f(c);
239 long double s_sq = fc * fc - fa * fb;
240 if (s_sq < 0.0)
241 {
242 std::cerr << "Ridder's method fails. Square root of negative number.\n";
243 return NAN;
244 }
245 long double s = sqrt(s_sq);
246 if (s == 0.0)
247 return c;
248
249 long double sign = ((fa - fb) < 0) ? -1.0L : 1.0L;
250 long double x = c + (c - a) * fc / s * sign;
251 long double fx = f(x);
252 std::ostringstream oss;
253 oss << "Step " << i + 1 << ": [" << std::fixed << std::setprecision(decimal_places) << a << ", " << b << "]";
254 iterations.push_back(oss.str());
255
256 if (fabs(fx) < tol)
257 return x;
258
259 if (fc * fx < 0.0)
260 {
261 a = c;
262 fa = fc;
263 b = x;
264 fb = fx;
265 }
266 else if (fa * fx < 0.0)
267 {
268 b = x;
269 fb = fx;
270 }
271 else
272 {
273 a = x;
274 fa = fx;
275 }
276
277 if (fabs(b - a) < tol)
278 break;
279 }
280
281 return 0.5L * (a + b);
282}