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  std::cerr << "Inverrting f(x = " << x << ") = " << func_value << std::endl;
15  if(std::isnan(func_value))
16  throw Core::Error::Runtime("NaN function value encountered.");
17  return (func_value - func_object->__target);
18 }
19 
20 double gsl_df(double x, void *params)
21 {
22  const Core::FunctionDerivatives *deriv =
23  reinterpret_cast<InverseFunction*>(params)->__to_invert.deriv(x);
24  double result = deriv->order(1);
25  delete deriv;
26  if(std::isnan(result))
27  throw Core::Error::Runtime("NaN derivative encountered.");
28  return result;
29 }
30 
31 void gsl_fdf(double x, void *params, double *f, double *df)
32 {
33  InverseFunction *func_object = reinterpret_cast<InverseFunction*>(params);
34  const Core::FunctionDerivatives *deriv = func_object->__to_invert.deriv(x);
35  *f = deriv->order(0) - func_object->__target;
36  *df = deriv->order(1);
37  delete deriv;
38  if(std::isnan(deriv->order(0)) || std::isnan(deriv->order(1)))
39  throw Core::Error::Runtime("NaN encountered.");
40 }
41 
42 InverseFunction::InverseFunction(const OneArgumentDiffFunction &to_invert,
43  double search_min,
44  double search_max,
45  double tolerance) :
46  __to_invert(to_invert),
47  __tolerance(tolerance),
48  __solver(gsl_root_fsolver_alloc(gsl_root_fsolver_brent)),
49  __search_min(search_min),
50  __search_max(search_max)
51 {
52  __solver_fdf.f = gsl_f;
53  __solver_fdf.df = gsl_df;
54  __solver_fdf.fdf = gsl_fdf;
55  __solver_fdf.params = reinterpret_cast<void*>(this);
56 
57  __solver_f.function = gsl_f;
58  __solver_f.params = reinterpret_cast<void*>(this);
59 
60  if(__solver == NULL)
62  "Failed to allocate GSL solver in inverse function."
63  );
64 
65 }
66 
67 double InverseFunction::operator()(double x) const
68 {
69  if(std::abs(__to_invert(__search_max) - x) < __tolerance)
70  return __search_max;
71  else if(std::abs(__to_invert(__search_min) - x) < __tolerance)
72  return __search_min;
73 
74  __target = x;
75  if(
76  gsl_root_fsolver_set(__solver,
77  const_cast<gsl_function*>(&__solver_f),
79  __search_max)
80  )
82  "Failed to initialize solver for inverse function."
83  );
84  double evaluation_error = Core::Inf,
85  result = Core::NaN;
86  while(evaluation_error > __tolerance) {
87  try {
88  if(gsl_root_fsolver_iterate(__solver))
89  throw Core::Error::Runtime("Error iterating function inversion.");
90  result = gsl_root_fsolver_root(__solver);
91  evaluation_error = std::abs(__to_invert(result) - x);
92  } catch(Core::Error::Runtime) {
93  return Core::NaN;
94  }
95  }
96  assert(!std::isnan(result));
97  return result;
98 }
99 
101 {
102  double value = operator()(x);
104  double first_deriv = 1.0 / deriv->order(1);
105  double second_deriv = deriv->order(2) * std::pow(first_deriv, 3);
106  delete deriv;
107  return new Core::CubicSplineDerivatives(value, first_deriv, second_deriv);
108 }
109 
110 InverseFunction::~InverseFunction()
111 {
112  gsl_root_fsolver_free(__solver);
113 }
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.