yat  0.21pre
RootFinder.h
1 #ifndef theplu_yat_utility_root_finder_
2 #define theplu_yat_utility_root_finder_
3 
4 // $Id: RootFinder.h 4252 2022-11-18 02:54:04Z peter $
5 
6 /*
7  Copyright (C) 2022 Peter Johansson
8 
9  This file is part of the yat library, https://dev.thep.lu.se/yat
10 
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15 
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <https://www.gnu.org/licenses/>.
23 */
24 
25 #include "univariable/f.h"
26 #include "yat_assert.h"
27 
28 #include <gsl/gsl_errno.h>
29 #include <gsl/gsl_roots.h>
30 
31 #include <limits>
32 #include <memory>
33 
34 namespace theplu {
35 namespace yat {
36 namespace utility {
37 
45  class RootFinder
46  {
47  public:
49  RootFinder(const RootFinder&) = delete;
50 
52  RootFinder& operator=(const RootFinder&) = delete;
53 
57  unsigned int epochs(void) const;
58 
62  const char* name(void) const;
63 
66  class Stopper
67  {
68  public:
70  virtual bool operator()(const gsl_root_fsolver*)=0;
71  };
72 
75  class Interval : public Stopper
76  {
77  public:
82  Interval(double epsabs, double epsrel);
83 
90  bool operator()(const gsl_root_fsolver*);
91  private:
92  double epsabs_;
93  double epsrel_;
94  };
95 
98  class Delta : public Stopper
99  {
100  public:
105  Delta(double epsabs, double epsrel);
106 
111  bool operator()(const gsl_root_fsolver*);
112  private:
113  double epsabs_;
114  double epsrel_;
115  std::unique_ptr<double> prev_;
116  };
117 
120  template<class FUNC>
121  class Residual : public Stopper
122  {
123  public:
128  Residual(const FUNC& func, double epsabs)
129  : func_(func), epsabs_(epsabs)
130  {}
131 
136  bool operator()(const gsl_root_fsolver*);
137  private:
138  const FUNC& func_;
139  double epsabs_;
140  };
141 
147  template<class FUNC>
148  double operator()(FUNC& func, double lower, double upper,Stopper&& stopper);
149 
153  template<class FUNC>
154  double operator()(FUNC& func, double lower, double upper,
155  Stopper&& stopper, unsigned int max_epochs);
156 
157  protected:
163  RootFinder(const gsl_root_fsolver_type* t);
164  private:
165  const gsl_root_fsolver_type* type_;
166  struct GslFree
167  {
168  void operator()(gsl_root_fsolver*) const;
169  };
170  std::unique_ptr<gsl_root_fsolver, GslFree> solver_;
171  unsigned int epochs_;
172  };
173 
174 
175  // template implementation
176  template<class FUNC>
177  double RootFinder::operator()(FUNC& func, double lower, double upper,
178  RootFinder::Stopper&& stopper)
179  {
180  unsigned int max_epochs = std::numeric_limits<unsigned int>::max();
181  return (*this)(func, lower, upper, std::move(stopper), max_epochs);
182  }
183 
184 
185  template<class FUNC>
186  double
187  RootFinder::operator()(FUNC& func, double lower, double upper,
188  RootFinder::Stopper&& stopper,
189  unsigned int max_epochs)
190  {
191  gsl_function gsl_func;
192  gsl_func.function = univariable::f<FUNC>;
193  gsl_func.params = &func;
194  gsl_root_fsolver_set(solver_.get(), &gsl_func, lower, upper);
195 
196  for (epochs_=0; epochs_<max_epochs && !stopper(solver_.get()); ++epochs_) {
197  int status = gsl_root_fsolver_iterate(solver_.get());
198  if (status) {
199  std::ostringstream ss;
200  ss << "RootFinder: at x = "
201  << gsl_root_fsolver_root(solver_.get());
202  throw GSL_error(ss.str(), status);
203 
204  }
205  }
206 
207  return gsl_root_fsolver_root(solver_.get());
208  }
209 
210 
211  template<class FUNC>
212  bool RootFinder::Residual<FUNC>::operator()(const gsl_root_fsolver* s)
213  {
214  double x = gsl_root_fsolver_root(s);
215  double f = func_(x);
216  return gsl_root_test_residual(f, epsabs_) == GSL_SUCCESS;
217  }
218 
219 }}}
220 #endif
Delta(double epsabs, double epsrel)
virtual bool operator()(const gsl_root_fsolver *)=0
return true is search should stop
Interval(double epsabs, double epsrel)
Class for errors reported from underlying GSL calls.
Definition: Exception.h:102
The Department of Theoretical Physics namespace as we define it.
bool operator()(const gsl_root_fsolver *)
Definition: RootFinder.h:212
Definition: RootFinder.h:98
double operator()(FUNC &func, double lower, double upper, Stopper &&stopper)
Definition: RootFinder.h:177
Definition: RootFinder.h:121
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:699
const char * name(void) const
unsigned int epochs(void) const
Number of epochs (iterations) used in last minimisation.
Definition: RootFinder.h:45
RootFinder & operator=(const RootFinder &)=delete
Assignment is not allowed.
bool operator()(const gsl_root_fsolver *)
RootFinder(const RootFinder &)=delete
Copy is not allowed.
bool operator()(const gsl_root_fsolver *)
Residual(const FUNC &func, double epsabs)
Definition: RootFinder.h:128

Generated on Wed Jan 25 2023 03:34:29 for yat by  doxygen 1.8.14