Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
InverseFunction.cpp
Go to the documentation of this file.
1 
8 #include "InverseFunction.h"
9 
10 double gsl_f(double x, void *params)
11 {
12  InverseFunction *func_object = reinterpret_cast<InverseFunction*>(params);
13  double func_value = func_object->__to_invert(x);
14  if(std::isnan(func_value))
15  throw Core::Error::Runtime("NaN function value encountered.");
16  return (func_value - func_object->__target);
17 }
18 
19 double gsl_df(double x, void *params)
20 {
21  const Core::FunctionDerivatives *deriv =
22  reinterpret_cast<InverseFunction*>(params)->__to_invert.deriv(x);
23  double result = deriv->order(1);
24  delete deriv;
25  if(std::isnan(result))
26  throw Core::Error::Runtime("NaN derivative encountered.");
27  return result;
28 }
29 
30 void gsl_fdf(double x, void *params, double *f, double *df)
31 {
32  InverseFunction *func_object = reinterpret_cast<InverseFunction*>(params);
33  const Core::FunctionDerivatives *deriv = func_object->__to_invert.deriv(x);
34  *f = deriv->order(0) - func_object->__target;
35  *df = deriv->order(1);
36  delete deriv;
37  if(std::isnan(deriv->order(0)) || std::isnan(deriv->order(1)))
38  throw Core::Error::Runtime("NaN encountered.");
39 }
40 
41 InverseFunction::InverseFunction(const OneArgumentDiffFunction &to_invert,
42  double search_min,
43  double search_max,
44  double tolerance) :
45  __to_invert(to_invert),
46  __tolerance(tolerance),
47  __solver(gsl_root_fsolver_alloc(gsl_root_fsolver_brent)),
48  __search_min(search_min),
49  __search_max(search_max)
50 {
51  __solver_fdf.f = gsl_f;
52  __solver_fdf.df = gsl_df;
53  __solver_fdf.fdf = gsl_fdf;
54  __solver_fdf.params = reinterpret_cast<void*>(this);
55 
56  __solver_f.function = gsl_f;
57  __solver_f.params = reinterpret_cast<void*>(this);
58 
59  if(__solver == NULL)
61  "Failed to allocate GSL solver in inverse function."
62  );
63 
64 }
65 
66 double InverseFunction::operator()(double x) const
67 {
68  if(std::abs(__to_invert(__search_max) - x) < __tolerance)
69  return __search_max;
70  else if(std::abs(__to_invert(__search_min) - x) < __tolerance)
71  return __search_min;
72 
73  __target = x;
74  if(
75  gsl_root_fsolver_set(__solver,
76  const_cast<gsl_function*>(&__solver_f),
78  __search_max)
79  )
81  "Failed to initialize solver for inverse function."
82  );
83  double evaluation_error = Core::Inf,
84  result = Core::NaN;
85  while(evaluation_error > __tolerance) {
86  try {
87  if(gsl_root_fsolver_iterate(__solver))
88  throw Core::Error::Runtime("Error iterating function inversion.");
89  result = gsl_root_fsolver_root(__solver);
90  evaluation_error = std::abs(__to_invert(result) - x);
91  } catch(Core::Error::Runtime) {
92  return Core::NaN;
93  }
94  }
95  assert(!std::isnan(result));
96  return result;
97 }
98 
100 {
101  double value = operator()(x);
103  double first_deriv = 1.0 / deriv->order(1);
104  double second_deriv = deriv->order(2) * std::pow(first_deriv, 3);
105  delete deriv;
106  return new Core::CubicSplineDerivatives(value, first_deriv, second_deriv);
107 }
108 
109 InverseFunction::~InverseFunction()
110 {
111  gsl_root_fsolver_free(__solver);
112 }
friend double gsl_df(double x, void *params)
GLS format derivative of function to invert.
const Core::OneArgumentDiffFunction & __to_invert
The function being inverted.
gsl_function __solver_f
The f argument used by the GSL solver.
Declarses a class for functions that are the inverse of some analytical function. ...
double operator()(double x) const
The value of the function at the given abscissa.
Any runtime error.
Definition: Error.h:61
virtual double order(unsigned deriv_order=1) const =0
Derivative of the given order of the function with respect to its argument.
friend void gsl_fdf(double x, void *params, double *f, double *df)
GLS format function and its derivative to invert.
A class representing arbitrary order derivatives of a function.
Definition: Functions.h:66
double __target
The value we are trying to match the function to.
InverseFunction(const OneArgumentDiffFunction &to_invert, double search_min, double search_max, double tolerance=1e-10)
Invert the given function.
double __search_min
The range which to search for a solution (must bracket a zero).
A class for the derivatives of a cubic spline (=0 for order>2).
Definition: Functions.h:77
The invrse of an existing function.
const Core::FunctionDerivatives * deriv(double x) const
Returns a pointer to the derivative of the function.
gsl_function_fdf __solver_fdf
The fdf argument used by the GSL solver.
friend double gsl_f(double x, void *params)
GLS format function to invert.
gsl_root_fsolver * __solver
The GSL derivative-based solver.
double __tolerance
The relative tolerance in the value returned by the function at the best guess for the solution...
virtual const FunctionDerivatives * deriv(double x) const =0
Returns a pointer to the derivative of the function.