DiFfRG
Loading...
Searching...
No Matches
root_finding.hh
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4
5namespace DiFfRG
6{
7 template <int dim> class AbstractRootFinder
8 {
9 protected:
10 using FUN = std::function<bool(const std::array<double, dim> &)>;
11
12 public:
13 AbstractRootFinder(const FUN &f, const double abs_tol = 1e-4, const int max_iter = 1000)
15 {
16 }
17
18 void set_abs_tol(const double abs_tol) { this->abs_tol = abs_tol; }
19
20 void set_max_iter(const uint max_iter) { this->max_iter = max_iter; }
21
22 uint get_iter() const { return iter; }
23
24 std::array<double, dim> search() { return this->search_impl(); }
25
26 protected:
28
29 double abs_tol;
32
33 virtual std::array<double, dim> search_impl() = 0;
34 };
35
36 // explicit specialization for 1D search
37 template <> class AbstractRootFinder<1>
38 {
39 protected:
40 using FUN = std::function<bool(const double)>;
41 using FUN_ARR = std::function<bool(const std::array<double, 1> &)>;
42
43 public:
44 AbstractRootFinder(const FUN &f, const double abs_tol = 1e-4, const int max_iter = 1000)
45 : f([f](const std::array<double, 1> &x) { return f(x[0]); }), abs_tol(abs_tol), max_iter(max_iter), iter(0)
46 {
47 }
48
49 AbstractRootFinder(const FUN_ARR &f, const double abs_tol = 1e-4, const int max_iter = 1000)
51 {
52 }
53
54 void set_abs_tol(const double abs_tol) { this->abs_tol = abs_tol; }
55
56 void set_max_iter(const uint max_iter) { this->max_iter = max_iter; }
57
58 uint get_iter() const { return iter; }
59
60 double search() { return this->search_impl()[0]; }
61
62 protected:
64
65 double abs_tol;
68
69 virtual std::array<double, 1> search_impl() = 0;
70 };
71
73 {
74 public:
75 BisectionRootFinder(const FUN &f, const double abs_tol = 1e-4, const int max_iter = 1000)
77 {
78 }
79
80 void set_x_min(const double x_min) { this->x_min = x_min; }
81 void set_x_max(const double x_max) { this->x_max = x_max; }
82
83 void set_bounds(const double x_min, const double x_max)
84 {
85 this->x_min = x_min;
86 this->x_max = x_max;
87 }
88
89 void set_next_x(const std::function<double(double, double)> &next_x) { this->next_x = next_x; }
90
91 protected:
92 std::array<double, 1> search_impl() override
93 {
94 double x_min = this->x_min;
95 double x_max = this->x_max;
96 double x_test = 0.;
97
98 bool success = false;
99
100 for (uint i = 0; i < this->max_iter; i++) {
101 x_test = next_x(x_min, x_max);
102 success = this->f({{x_test}});
103 if (success)
104 x_max = x_test;
105 else
106 x_min = x_test;
107
108 this->iter = i;
109 if (success && std::abs(x_max - x_min) < this->abs_tol) break;
110 }
111
112 if (!success) throw std::runtime_error("BisectionRootFinder: search did not converge");
113
114 return {{x_test}};
115 }
116
117 double x_min;
118 double x_max;
119
120 std::function<double(double, double)> next_x = [](const double x_min, const double x_max) {
121 return (x_min + x_max) / 2.;
122 };
123 };
124} // namespace DiFfRG
AbstractRootFinder(const FUN_ARR &f, const double abs_tol=1e-4, const int max_iter=1000)
Definition root_finding.hh:49
AbstractRootFinder(const FUN &f, const double abs_tol=1e-4, const int max_iter=1000)
Definition root_finding.hh:44
std::function< bool(const std::array< double, 1 > &)> FUN_ARR
Definition root_finding.hh:41
virtual std::array< double, 1 > search_impl()=0
uint iter
Definition root_finding.hh:67
FUN_ARR f
Definition root_finding.hh:63
std::function< bool(const double)> FUN
Definition root_finding.hh:40
void set_max_iter(const uint max_iter)
Definition root_finding.hh:56
void set_abs_tol(const double abs_tol)
Definition root_finding.hh:54
uint max_iter
Definition root_finding.hh:66
uint get_iter() const
Definition root_finding.hh:58
double abs_tol
Definition root_finding.hh:65
double search()
Definition root_finding.hh:60
Definition root_finding.hh:8
void set_abs_tol(const double abs_tol)
Definition root_finding.hh:18
FUN f
Definition root_finding.hh:27
virtual std::array< double, dim > search_impl()=0
void set_max_iter(const uint max_iter)
Definition root_finding.hh:20
std::function< bool(const std::array< double, dim > &)> FUN
Definition root_finding.hh:10
uint max_iter
Definition root_finding.hh:30
uint iter
Definition root_finding.hh:31
uint get_iter() const
Definition root_finding.hh:22
AbstractRootFinder(const FUN &f, const double abs_tol=1e-4, const int max_iter=1000)
Definition root_finding.hh:13
std::array< double, dim > search()
Definition root_finding.hh:24
double abs_tol
Definition root_finding.hh:29
Definition root_finding.hh:73
BisectionRootFinder(const FUN &f, const double abs_tol=1e-4, const int max_iter=1000)
Definition root_finding.hh:75
void set_x_max(const double x_max)
Definition root_finding.hh:81
void set_bounds(const double x_min, const double x_max)
Definition root_finding.hh:83
void set_x_min(const double x_min)
Definition root_finding.hh:80
std::function< double(double, double)> next_x
Definition root_finding.hh:120
void set_next_x(const std::function< double(double, double)> &next_x)
Definition root_finding.hh:89
double x_max
Definition root_finding.hh:118
std::array< double, 1 > search_impl() override
Definition root_finding.hh:92
double x_min
Definition root_finding.hh:117
Definition complex_math.hh:14
unsigned int uint
Definition utils.hh:22
Definition tuples.hh:117