The BioCro C++ Library
root_onedim_test.h
Go to the documentation of this file.
1#ifndef ROOT_ONEDIM_TEST_H
2#define ROOT_ONEDIM_TEST_H
3#include <functional> // for std::function
4#include <map> // std::map
5#include <cmath> // std::sin
6
7#include "../framework/module.h"
8#include "../framework/state_map.h"
9
10#include "../math/roots/onedim/secant.h"
11#include "../math/roots/onedim/bisection.h"
12#include "../math/roots/onedim/regula_falsi.h"
13#include "../math/roots/onedim/ridder.h"
14#include "../math/roots/onedim/illinois.h"
15#include "../math/roots/onedim/pegasus.h"
16#include "../math/roots/onedim/newton.h"
17#include "../math/roots/onedim/halley.h"
18#include "../math/roots/onedim/steffensen.h"
19#include "../math/roots/onedim/fixed_point.h"
20#include "../math/roots/onedim/dekker.h"
21#include "../math/roots/onedim/dekker_newton.h"
22#include "../math/roots/onedim/anderson_bjorck.h"
23
24namespace standardBML
25{
26
51 double epsilon;
52 double answer;
53 double y;
54
55 root_test_function(double ep, double ans) : epsilon{ep}, answer{ans}
56 {
57 y = ans - ep * std::sin(ans);
58 }
59
60 double operator()(double x)
61 {
62 return x - epsilon * std::sin(x) - y;
63 }
64
65 double derivative(double x)
66 {
67 return 1 - epsilon * std::cos(x);
68 }
69
70 double second_derivative(double x)
71 {
72 return epsilon * std::sin(x);
73 }
74};
75
77 double epsilon;
78 double answer;
79
80 fixed_point_test_function(double ep, double a) : epsilon{ep}, answer{a} {}
81
82 double operator()(double x)
83 {
84 return answer + epsilon * std::sin(x - answer);
85 }
86};
87
126class root_onedim_test : public direct_module
127{
128 struct result {
129 double* root_op;
130 double* residual_op;
131 double* iteration_op;
132 double* flag_op;
133
134 result(
135 state_map* output_quantities,
136 std::string&& name)
137 : root_op{get_op(output_quantities, name + "_root")},
138 residual_op{get_op(output_quantities, name + "_residual")},
139 iteration_op{get_op(output_quantities, name + "_iteration")},
140 flag_op{get_op(output_quantities, name + "_flag")}
141 {
142 }
143 };
144
145 public:
147 state_map const& input_quantities, state_map* output_quantities)
148 : direct_module{},
149
150 // Get pointers to input quantities
151 ecc{get_input(input_quantities, "ecc")},
152 answer{get_input(input_quantities, "answer")},
153 max_iterations{get_input(input_quantities, "max_iterations")},
154 abs_tol{get_input(input_quantities, "abs_tol")},
155 rel_tol{get_input(input_quantities, "rel_tol")},
156 lower_bracket{get_input(input_quantities, "lower_bracket")},
157 upper_bracket{get_input(input_quantities, "upper_bracket")},
158 single_guess{get_input(input_quantities, "single_guess")},
159
160 // Get pointers to output quantities
161 secant_result{output_quantities, "secant"},
162 fixed_point_result{output_quantities, "fixed_point"},
163 newton_result{output_quantities, "newton"},
164 halley_result{output_quantities, "halley"},
165 steffensen_result{output_quantities, "steffensen"},
166 bisection_result{output_quantities, "bisection"},
167 regula_falsi_result{output_quantities, "regula_falsi"},
168 ridder_result{output_quantities, "ridder"},
169 illinois_result{output_quantities, "illinois"},
170 pegasus_result{output_quantities, "pegasus"},
171 anderson_bjorck_result{output_quantities, "anderson_bjorck"},
172 dekker_result{output_quantities, "dekker"},
173 dekker_newton_result{output_quantities, "dekker_newton"}
174
175 {
176 }
177 static string_vector get_inputs();
178 static string_vector get_outputs();
179 static std::string get_name() { return "root_onedim_test"; }
180
181 private:
182 // Pointers to input quantities
183 const double& ecc;
184 const double& answer;
185 const double& max_iterations;
186 const double& abs_tol;
187 const double& rel_tol;
188 const double& lower_bracket;
189 const double& upper_bracket;
190 const double& single_guess;
191
192 // Pointers to output quantities
193 result secant_result;
194 result fixed_point_result;
195 result newton_result;
196 result halley_result;
197 result steffensen_result;
198 result bisection_result;
199 result regula_falsi_result;
200 result ridder_result;
201 result illinois_result;
202 result pegasus_result;
203 result anderson_bjorck_result;
204 result dekker_result;
205 result dekker_newton_result;
206
207 // Main operation
208 void do_operation() const;
209
210 static string_vector make_qname(std::string& name)
211 {
212 return {
213 name + "_root",
214 name + "_residual",
215 name + "_iteration",
216 name + "_flag"};
217 }
218
219 void inline update_result(
220 const result& r, root_finding::result_t& result) const
221 {
222 update(r.root_op, result.root);
223 update(r.residual_op, result.residual);
224 update(r.iteration_op, result.iteration);
225 update(r.flag_op, static_cast<int>(result.flag));
226 }
227};
228
230{
231 return {
232 "ecc",
233 "answer",
234 "max_iterations",
235 "abs_tol",
236 "rel_tol",
237 "lower_bracket",
238 "upper_bracket",
239 "single_guess"};
240}
241
243{
244 string_vector out;
245 const string_vector methods = {
246 "secant", "fixed_point", "newton", "halley", "steffensen",
247 "bisection", "regula_falsi", "ridder",
248 "illinois", "pegasus", "anderson_bjorck", "dekker",
249 "dekker_newton"};
250 for (auto name : methods) {
251 string_vector sv = make_qname(name);
252 out.insert(out.end(), sv.begin(), sv.end());
253 }
254
255 return out;
256}
257
258void root_onedim_test::do_operation() const
259{
260 // Collect inputs and make calculations
261 using namespace root_finding;
262 result_t result;
263 root_test_function test{ecc, answer};
264
265 fixed_point_test_function fix_pt_test{ecc, answer};
266 size_t iter = static_cast<size_t>(max_iterations);
267
268 result = secant(iter, abs_tol, rel_tol)
269 .solve(test, lower_bracket, upper_bracket);
270 update_result(secant_result, result);
271
272 result = fixed_point(iter, abs_tol, rel_tol)
273 .solve(fix_pt_test, single_guess);
274 update_result(fixed_point_result, result);
275
276 result = newton(iter, abs_tol, rel_tol)
277 .solve(test, single_guess);
278 update_result(newton_result, result);
279
280 result = halley(iter, abs_tol, rel_tol)
281 .solve(test, single_guess);
282 update_result(halley_result, result);
283
284 result = steffensen(iter, abs_tol, rel_tol)
285 .solve(test, single_guess);
286 update_result(steffensen_result, result);
287
288 result = bisection(iter, abs_tol, rel_tol)
289 .solve(test, lower_bracket, upper_bracket);
290 update_result(bisection_result, result);
291
292 result = regula_falsi(iter, abs_tol, rel_tol)
293 .solve(test, lower_bracket, upper_bracket);
294 update_result(regula_falsi_result, result);
295
296 result = ridder(iter, abs_tol, rel_tol)
297 .solve(test, lower_bracket, upper_bracket);
298 update_result(ridder_result, result);
299
300 result = illinois(iter, abs_tol, rel_tol)
301 .solve(test, lower_bracket, upper_bracket);
302 update_result(illinois_result, result);
303
304 result = pegasus(iter, abs_tol, rel_tol)
305 .solve(test, lower_bracket, upper_bracket);
306 update_result(pegasus_result, result);
307
308 result = anderson_bjorck(iter, abs_tol, rel_tol)
309 .solve(test, lower_bracket, upper_bracket);
310 update_result(anderson_bjorck_result, result);
311
312 result = dekker(iter, abs_tol, rel_tol)
313 .solve(test, lower_bracket, upper_bracket);
314 update_result(dekker_result, result);
315
316 result = dekker_newton(iter, abs_tol, rel_tol)
317 .solve(test, lower_bracket, upper_bracket);
318 update_result(dekker_newton_result, result);
319}
320
321} // namespace standardBML
322#endif
Function object for Kepler's equation. Kepler's equation relates the mean anomaly to the eccentric a...
root_onedim_test(state_map const &input_quantities, state_map *output_quantities)
static string_vector get_outputs()
static string_vector get_inputs()
static std::string get_name()
This is the standard BioCro module library; it includes the essential modules used in typical BioCro ...
Definition: aba_decay.h:8
fixed_point_test_function(double ep, double a)
Function object for Kepler's equation. Kepler's equation relates the mean anomaly to the eccentric a...
root_test_function(double ep, double ans)