Root Finder  1.0
Using various numerical methods
Loading...
Searching...
No Matches
utils.cpp File Reference
#include "utils.h"
#include "methods.h"
#include "functions.h"
#include "plotting.h"
#include <iostream>
#include <cmath>
#include <iomanip>
#include <sstream>
#include <vector>
#include <map>
#include <string>
#include <functional>
#include <limits>
+ Include dependency graph for utils.cpp:

Go to the source code of this file.

Functions

void run_method (const std::string &method_name, std::function< long double(long double, long double, long double, int, std::vector< std::string > &, int)> method_func, long double a, long double b, long double tol, int max_iter, int decimal_places)
 
void run_problem_steps ()
 
void compare_all_methods ()
 
void get_user_input (long double &a, long double &b, long double &x0, std::string &method_name, long double &tol)
 
int calculate_decimal_places (long double tol)
 
void run_method_user_selection (const std::string &method_name, std::function< long double(long double, long double, long double, int, std::vector< std::string > &, int)> method_func, long double a, long double b, long double tol, int max_iter)
 

Variables

std::map< std::string, std::vector< RootInfo > > summary
 

Function Documentation

◆ calculate_decimal_places()

int calculate_decimal_places ( long double tol)

Definition at line 297 of file utils.cpp.

298{
299 if (tol <= 0)
300 return 0;
301 return static_cast<int>(ceil(-log10(tol))) + 1;
302}

◆ compare_all_methods()

void compare_all_methods ( )

Definition at line 141 of file utils.cpp.

142{
143 // Define intervals for three roots
144 std::vector<std::pair<long double, long double>> intervals = {
145 {-3.0L, -2.0L}, // Negative root
146 {0.0L, 1.0L}, // First positive root
147 {1.0L, 3.0L} // Second positive root
148 };
149
150 // Define tolerances and maximum iterations
151 long double tol = 1e-14L; // 14 decimal places
152 int max_iter = 1000;
153
154 // List of methods to compare
155 std::vector<std::pair<std::string, std::function<long double(long double, long double, long double, int, std::vector<std::string> &, int)>>> methods = {
156 {"Bisection Method", [](long double a, long double b, long double tol, int max_iter, std::vector<std::string> &iterations, int decimal_places) -> long double
157 {
158 return bisection(a, b, tol, max_iter, iterations, decimal_places);
159 }},
160 {"Newton-Raphson Method", [](long double a, long double b, long double tol, int max_iter, std::vector<std::string> &iterations, int decimal_places) -> long double
161 {
162 // For Newton-Raphson, use the midpoint as the initial guess
163 long double initial_guess = (a + b) / 2.0L;
164 return newton_raphson(initial_guess, tol, max_iter, iterations, decimal_places);
165 }},
166 {"Hybrid Method", [](long double a, long double b, long double tol, int max_iter, std::vector<std::string> &iterations, int decimal_places) -> long double
167 {
168 return hybrid_method(a, b, tol, max_iter, iterations, decimal_places);
169 }},
170 {"Brent's Method", [](long double a, long double b, long double tol, int max_iter, std::vector<std::string> &iterations, int decimal_places) -> long double
171 {
172 return brent_method(a, b, tol, max_iter, iterations, decimal_places);
173 }},
174 {"Ridder's Method", [](long double a, long double b, long double tol, int max_iter, std::vector<std::string> &iterations, int decimal_places) -> long double
175 {
176 return ridder_method(a, b, tol, max_iter, iterations, decimal_places);
177 }}};
178
179 // Store comparison results
180 std::map<std::string, std::vector<RootInfo>> comparison_results;
181
182 // Run each method for each interval
183 for (const auto &method : methods)
184 {
185 for (const auto &interval : intervals)
186 {
187 std::vector<std::string> iterations;
188 long double root = method.second(interval.first, interval.second, tol, max_iter, iterations, 15); // 1e-14 -> 15 decimal places
189 RootInfo info{root, static_cast<int>(iterations.size()), 15};
190 comparison_results[method.first].emplace_back(info);
191 }
192 }
193
194 // Display comparison table
195 std::cout << "\n--- Comparison of All Methods (Precision: 1e-14) ---\n\n";
196
197 // Table header
198 std::cout << std::left << std::setw(25) << "Method"
199 << std::setw(30) << "Root 1 (-3,-2)"
200 << std::setw(15) << "Iterations"
201 << std::setw(30) << "Root 2 (0,1)"
202 << std::setw(15) << "Iterations"
203 << std::setw(30) << "Root 3 (1,3)"
204 << std::setw(15) << "Iterations" << "\n";
205
206 // Separator
207 std::cout << std::string(130, '-') << "\n";
208
209 // Table rows
210 for (const auto &method : methods)
211 {
212 std::cout << std::left << std::setw(25) << method.first;
213 for (size_t i = 0; i < intervals.size(); ++i)
214 {
215 if (comparison_results[method.first][i].root != comparison_results[method.first][i].root)
216 {
217 // Check for NAN
218 std::cout << std::left << std::setw(30) << "N/A"
219 << std::left << std::setw(15) << "N/A";
220 }
221 else
222 {
223 std::cout << std::left << std::setw(30) << std::fixed << std::setprecision(15) << comparison_results[method.first][i].root
224 << std::left << std::setw(15) << comparison_results[method.first][i].iterations;
225 }
226 }
227 std::cout << "\n";
228 }
229
230 std::cout << "\nNote: Precision is set to 1e-14, output displays 15 decimal places.\n\n";
231}
long double bisection(long double a, long double b, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
Definition methods.cpp:17
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 methods.cpp:76
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 methods.cpp:226
long double newton_raphson(long double x0, long double tol, int max_iter, std::vector< std::string > &iterations, int decimal_places)
Definition methods.cpp:51
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 methods.cpp:139

◆ get_user_input()

void get_user_input ( long double & a,
long double & b,
long double & x0,
std::string & method_name,
long double & tol )

Definition at line 234 of file utils.cpp.

235{
236 // List of available methods
237 std::vector<std::string> available_methods = {"Bisection Method", "Hybrid Method", "Brent Method", "Ridder Method", "Newton-Raphson Method", "Problem Steps Mode", "Compare All Methods"};
238
239 // Display available methods
240 std::cout << "\nAvailable methods:\n";
241 for (size_t i = 0; i < available_methods.size(); ++i)
242 {
243 std::cout << i + 1 << ". " << available_methods[i] << "\n";
244 }
245
246 // Prompt user to select a method
247 int method_choice;
248 std::cout << "Select a method (1-" << available_methods.size() << "): ";
249 std::cin >> method_choice;
250 while (method_choice < 1 || method_choice > static_cast<int>(available_methods.size()))
251 {
252 std::cout << "Invalid choice. Please select a method (1-" << available_methods.size() << "): ";
253 std::cin >> method_choice;
254 }
255 method_name = available_methods[method_choice - 1];
256
257 if (method_name == "Newton-Raphson Method")
258 {
259 // Prompt user to input initial guess x0
260 std::cout << "Enter initial guess x0: ";
261 std::cin >> x0;
262 }
263 else if (method_name != "Problem Steps Mode" && method_name != "Compare All Methods")
264 {
265 // Prompt user to input interval [a, b]
266 std::cout << "Enter interval [a, b]:\n";
267 std::cout << "a = ";
268 std::cin >> a;
269 std::cout << "b = ";
270 std::cin >> b;
271 while (a >= b)
272 {
273 std::cout << "Invalid interval. 'a' should be less than 'b'. Please re-enter:\n";
274 std::cout << "a = ";
275 std::cin >> a;
276 std::cout << "b = ";
277 std::cin >> b;
278 }
279 }
280
281 if (method_name != "Problem Steps Mode" && method_name != "Compare All Methods")
282 {
283 // Prompt user to input desired precision
284 std::cout << "Enter desired precision (e.g., 1e-14, up to 1e-16): ";
285 std::cin >> tol;
286 const long double min_tol = 1e-16L;
287 const long double max_tol = 1e-4L;
288 while (tol < min_tol || tol > max_tol)
289 {
290 std::cout << "Precision out of bounds (" << min_tol << " to " << max_tol << "). Please re-enter: ";
291 std::cin >> tol;
292 }
293 }
294}

◆ run_method()

void run_method ( const std::string & method_name,
std::function< long double(long double, long double, long double, int, std::vector< std::string > &, int)> method_func,
long double a,
long double b,
long double tol,
int max_iter,
int decimal_places )

Definition at line 27 of file utils.cpp.

31{
32 std::vector<std::string> iterations;
33 long double root = method_func(a, b, tol, max_iter, iterations, decimal_places);
34
35 RootInfo info{root, static_cast<int>(iterations.size()), decimal_places};
36 summary[method_name].emplace_back(info);
37
38 // Display results
39 std::cout << "\nMethod: " << method_name << "\n";
40 if (method_name == "Newton-Raphson Method")
41 {
42 std::cout << "Initial guess: x0 = " << std::fixed << std::setprecision(decimal_places) << a << "\n";
43 }
44 else
45 {
46 std::cout << "Interval: [" << std::fixed << std::setprecision(2) << a << ", " << b << "]\n";
47 }
48 std::cout << "Root: " << std::fixed << std::setprecision(decimal_places) << root << "\n";
49 std::cout << "Iterations:\n";
50 for (const auto &iter : iterations)
51 {
52 std::cout << iter << "\n";
53 }
54 std::cout << "Iterations Count: " << iterations.size() << "\n";
55}
std::map< std::string, std::vector< RootInfo > > summary
Definition utils.cpp:24

◆ run_method_user_selection()

void run_method_user_selection ( const std::string & method_name,
std::function< long double(long double, long double, long double, int, std::vector< std::string > &, int)> method_func,
long double a,
long double b,
long double tol,
int max_iter )

Definition at line 305 of file utils.cpp.

308{
309 int decimal_places = calculate_decimal_places(tol);
310 run_method(method_name, method_func, a, b, tol, max_iter, decimal_places);
311}
void run_method(const std::string &method_name, std::function< long double(long double, long double, long double, int, std::vector< std::string > &, int)> method_func, long double a, long double b, long double tol, int max_iter, int decimal_places)
Definition utils.cpp:27
int calculate_decimal_places(long double tol)
Definition utils.cpp:297

◆ run_problem_steps()

void run_problem_steps ( )

Definition at line 58 of file utils.cpp.

59{
60 // Define intervals for three roots
61 std::vector<std::pair<long double, long double>> intervals = {
62 {-3.0L, -2.0L}, // Negative root
63 {0.0L, 1.0L}, // First positive root
64 {1.0L, 3.0L} // Second positive root
65 };
66
67 // Vector to store roots found in part (i)
68 std::vector<long double> found_roots;
69
70 // Define tolerances and maximum iterations
71 long double tol_bisection = 1e-4L; // 4 decimal places
72 long double tol_newton = 1e-14L; // 14 decimal places
73 long double tol_hybrid = 1e-14L; // 14 decimal places
74 int max_iter = 1000;
75
76 std::cout << "\n--- Problem Steps Execution ---\n";
77
78 // Part (i): Bisection Method to find three roots to 4 decimal places
79 std::cout << "\nPart (i): Bisection Method to find roots to 4 decimal places\n";
80 for (const auto &interval : intervals)
81 {
82 std::vector<std::string> iterations;
83 long double root = bisection(interval.first, interval.second, tol_bisection, max_iter, iterations, 4);
84 RootInfo info{root, static_cast<int>(iterations.size()), 4};
85 summary["Bisection Method"].emplace_back(info);
86
87 // Store the found root
88 found_roots.emplace_back(root);
89
90 std::cout << "Root in [" << std::fixed << std::setprecision(2) << interval.first << ", " << interval.second << "]: "
91 << std::fixed << std::setprecision(4) << root << "\n";
92 std::cout << "Iterations: " << iterations.size() << "\n";
93 }
94
95 // Part (ii): Newton-Raphson Method to refine the three roots to 14 decimal places
96 std::cout << "\nPart (ii): Newton-Raphson Method to refine roots to 14 decimal places\n";
97 for (auto &x0 : found_roots)
98 {
99 std::vector<std::string> iterations;
100 long double root = newton_raphson(x0, tol_newton, max_iter, iterations, 14);
101 RootInfo info{root, static_cast<int>(iterations.size()), 14};
102 summary["Newton-Raphson Method"].emplace_back(info);
103
104 std::cout << "Refined root starting from " << std::fixed << std::setprecision(4) << x0 << ": "
105 << std::fixed << std::setprecision(14) << root << "\n";
106 std::cout << "Iterations: " << iterations.size() << "\n";
107 }
108
109 // Part (iii): Hybrid Method to find three roots to 14 decimal places
110 std::cout << "\nPart (iii): Hybrid Method to find roots to 14 decimal places\n";
111 for (const auto &interval : intervals)
112 {
113 std::vector<std::string> iterations;
114 long double root = hybrid_method(interval.first, interval.second, tol_hybrid, max_iter, iterations, 14);
115 RootInfo info{root, static_cast<int>(iterations.size()), 14};
116 summary["Hybrid Method"].emplace_back(info);
117
118 std::cout << "Root in [" << std::fixed << std::setprecision(2) << interval.first << ", " << interval.second << "] (Hybrid): "
119 << std::fixed << std::setprecision(14) << root << "\n";
120 std::cout << "Iterations: " << iterations.size() << "\n";
121 }
122
123 // Output summary of results for problem steps
124 std::cout << "\n--- Summary of Problem Steps Results ---\n";
125 for (const auto &method : summary)
126 {
127 std::cout << "\nMethod: " << method.first << "\n";
128 int idx = 1;
129 for (const auto &info : method.second)
130 {
131 std::cout << " Root " << idx++ << ": " << std::fixed << std::setprecision(info.decimal_places) << info.root
132 << " | Iterations: " << info.iterations << "\n";
133 }
134 }
135
136 // Clear summary for next run
137 summary.clear();
138}

Variable Documentation

◆ summary

std::map<std::string, std::vector<RootInfo> > summary

Definition at line 24 of file utils.cpp.