C++ wrapper for GSL root finding algorithm with derivative

故事扮演 提交于 2019-12-01 20:41:34

You will need to do some modifications

Gsl fdf struct is the following

struct gsl_function_fdf_struct 
{
  double (* f) (double x, void * params);
  double (* df) (double x, void * params);
  void (* fdf) (double x, void * params, double * f, double * df);
  void * params;
};

typedef struct gsl_function_fdf_struct gsl_function_fdf ;

If you understood what the wrapper actually does, then you will see that generalization is quite straightforward

class gsl_function_fdf_pp : public gsl_function_fdf
{
   public:
   gsl_function_fdf_pp
   (
     std::function<double(double)> const& kf, 
     std::function<double(double)> const& kdf
   ) : _f(kf), _df(kdf)
   {
      f   = &gsl_function_fdf_pp::invoke;
      df  = &gsl_function_fdf_pp::invoke2;
      fdf = &gsl_function_fdf_pp::invoke3;
      params=this;
   }     
   private:
   std::function<double(double)> _f;
   std::function<double(double)> _df;

   static double invoke(double x, void *params) 
   {
     return static_cast<gsl_function_fdf_pp*>(params)->_f(x);
   }

   static double invoke2(double x, void *params) 
   {
     return static_cast<gsl_function_fdf_pp*>(params)->_df(x);
   }

   static void invoke3(double x, void * params, double* f, double* df)
   {
     (*f)  = static_cast<gsl_function_fdf_pp*>(params)->_f(x);
     (*df) = static_cast<gsl_function_fdf_pp*>(params)->_df(x);
   }
};

The template version.

template< typename F, typename U >  class gsl_function_fdf_pp : public gsl_function_fdf 
{
  public:
  gsl_function_fdf_pp(const F& kf, const U& kdf) : _f(kf), _df(kdf)
  {
    f   = &gsl_function_fdf_pp::invoke;
    df  = &gsl_function_fdf_pp::invoke2;
    fdf = &gsl_function_fdf_pp::invoke3;
    params=this;
  }
  private:
  const F& _f;
  const U& _df;

  static double invoke(double x, void *params) 
  {
    return static_cast<gsl_function_fdf_pp*>(params)->_f(x);
  }

  static double invoke2(double x, void *params) 
  {
    return static_cast<gsl_function_fdf_pp*>(params)->_df(x);
  }

  static void invoke3(double x, void * params, double* f, double* df)
  {
    (*f)  = static_cast<gsl_function_fdf_pp*>(params)->_f(x);
    (*df) = static_cast<gsl_function_fdf_pp*>(params)->_df(x);
  }
}; 

EDIT2: After fixing 2 small problems, this example works

int main()
{
  auto f  = [](double x)->double{ return x*x; };
  auto df = [](double x)->double{ return 2.0 * x; };

  gsl_function_fdf_pp<decltype(f),decltype(df)> Fp(f,df);

  return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!