yat  0.21pre
RootFinderDerivative.h
1 #ifndef theplu_yat_utility_root_finder_derivative_
2 #define theplu_yat_utility_root_finder_derivative_
3 
4 // $Id: RootFinderDerivative.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 "Exception.h"
26 #include "univariable/f.h"
27 #include "univariable/df.h"
28 
29 #include <gsl/gsl_errno.h>
30 #include <gsl/gsl_roots.h>
31 
32 #include <limits>
33 #include <memory>
34 #include <sstream>
35 
36 namespace theplu {
37 namespace yat {
38 namespace utility {
39 
48  {
49  public:
52 
55 
59  unsigned int epochs(void) const;
60 
64  const char* name(void) const;
65 
68  class Stopper
69  {
70  public:
72  virtual bool operator()(const gsl_root_fdfsolver*)=0;
73  };
74 
77  class Delta : public Stopper
78  {
79  public:
84  Delta(double epsabs, double epsrel);
85 
90  bool operator()(const gsl_root_fdfsolver*);
91  private:
92  double epsabs_;
93  double epsrel_;
94  std::unique_ptr<double> prev_;
95  };
96 
99  template<class FUNC>
100  class Residual : public Stopper
101  {
102  public:
107  Residual(const FUNC& func, double epsabs)
108  : func_(func), epsabs_(epsabs)
109  {}
110 
115  bool operator()(const gsl_root_fdfsolver*);
116  private:
117  const FUNC& func_;
118  double epsabs_;
119  };
120 
129  template<class FUNC>
130  double operator()(FUNC& func, double guess, Stopper&& stopper);
131 
135  template<class FUNC>
136  double operator()(FUNC& func, double guess, Stopper&& stopper,
137  unsigned int max_epochs);
138 
139  protected:
145  RootFinderDerivative(const gsl_root_fdfsolver_type* t);
146  private:
147  const gsl_root_fdfsolver_type* type_;
148  struct GslFree
149  {
150  void operator()(gsl_root_fdfsolver*) const;
151  };
152  std::unique_ptr<gsl_root_fdfsolver, GslFree> solver_;
153  unsigned int epochs_;
154  };
155 
156 
157  // template implementation
158  template<class FUNC>
159  double
160  RootFinderDerivative::operator()(FUNC& func, double guess,
162  {
163  unsigned int max_epochs = std::numeric_limits<unsigned int>::max();
164  return (*this)(func, guess, std::move(stopper), max_epochs);
165  }
166 
167 
168  template<class FUNC>
169  double
170  RootFinderDerivative::operator()(FUNC& func, double guess,
172  unsigned int max_epochs)
173  {
174  gsl_function_fdf gsl_func;
175  gsl_func.f = univariable::f<FUNC>;
176  gsl_func.df = univariable::df<FUNC>;
177  gsl_func.fdf = univariable::fdf<FUNC>;
178  gsl_func.params = &func;
179  gsl_root_fdfsolver_set(solver_.get(), &gsl_func, guess);
180 
181  for (epochs_=0; epochs_<max_epochs && !stopper(solver_.get()); ++epochs_) {
182  int status = gsl_root_fdfsolver_iterate(solver_.get());
183  if (status) {
184  std::ostringstream ss;
185  ss << "RootFinderDerivative: at x = "
186  << gsl_root_fdfsolver_root(solver_.get());
187  throw GSL_error(ss.str(), status);
188 
189  }
190  }
191 
192  return gsl_root_fdfsolver_root(solver_.get());
193  }
194 
195 
196  template<class FUNC>
197  bool
199  {
200  double x = gsl_root_fdfsolver_root(s);
201  double f = func_(x);
202  return gsl_root_test_residual(f, epsabs_) == GSL_SUCCESS;
203  }
204 
205 }}}
206 #endif
Definition: RootFinderDerivative.h:77
Residual(const FUNC &func, double epsabs)
Definition: RootFinderDerivative.h:107
Definition: RootFinderDerivative.h:47
Definition: RootFinderDerivative.h:100
RootFinderDerivative & operator=(const RootFinderDerivative &)=delete
Assignment is not allowed.
Class for errors reported from underlying GSL calls.
Definition: Exception.h:102
The Department of Theoretical Physics namespace as we define it.
unsigned int epochs(void) const
Number of epochs (iterations) used in last minimisation.
double operator()(FUNC &func, double guess, Stopper &&stopper)
Definition: RootFinderDerivative.h:160
T max(const T &a, const T &b, const T &c)
Definition: stl_utility.h:699
RootFinderDerivative(const RootFinderDerivative &)=delete
Copy is not allowed.
virtual bool operator()(const gsl_root_fdfsolver *)=0
return true is search should stop
bool operator()(const gsl_root_fdfsolver *)
Definition: RootFinderDerivative.h:198
Definition: RootFinderDerivative.h:68
bool operator()(const gsl_root_fdfsolver *)

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