ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
function_fdf.hpp
Go to the documentation of this file.
1/*
2 * $Id: function_fdf.hpp 51 2012-01-07 13:55:48Z jdl3 $
3 * Copyright (C) 2010, 2011, 2012, 2020, 2021 John D Lamb
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef CCGSL_FUNCTION_FDF_HPP
21#define CCGSL_FUNCTION_FDF_HPP
22
23// For std::pair
24#include<utility>
25// For std::swap
26#if __cplusplus <= 199711L
27#include<algorithm>
28#endif
29#include"function_scl.hpp"
30
31namespace gsl {
32 class function_fdf;
33 template<typename T>
80 class function_fdf : public gsl_function_fdf {
81 public:
89 struct Concept {
95 virtual double f( double x ) = 0;
101 virtual double df( double x ) = 0;
107 virtual std::pair<double,double> fdf( double x ) = 0;
108 };
109#ifndef DOXYGEN_SKIP
110 private:
114 struct base_F {
118 typedef double (*function_t)(double,void*);
122 typedef void (*function_fdf_t)(double,void*,double*,double*);
123 };
127 template<typename T>
128 struct FDF : public base_F {
129 public:
134 FDF( T& t ) : t( t ){}
135 public:
142 static double fn( double x, void* params ){
143 return reinterpret_cast<FDF<T>*>( params )->t.f( x ); }
150 static double dfn( double x, void* params ){
151 return reinterpret_cast<FDF<T>*>( params )->t.df( x ); }
158 static void fdfn( double x, void* params, double* d, double* df ){
159 std::pair<double,double> pair = reinterpret_cast<FDF<T>*>( params )->t.fdf( x );
160 *d = pair.first; *df = pair.second; }
161 private:
165 T& t;
166 };
171 struct function_scl_adapter : public base_F, public Concept {
172 public:
173 function_scl_adapter( function_scl& function, function_scl& dfunction )
174 : scl_function( function ), scl_dfunction( dfunction ){}
180 double f( double x ){ return fn_eval( scl_function, x ); }
186 double df( double x ){ return fn_eval( scl_dfunction, x ); }
192 std::pair<double,double> fdf( double x ){
193 return std::make_pair( fn_eval( scl_function, x ), fn_eval( scl_dfunction, x ) ); }
194 public:
201 static double fn( double x, void* params ){
202 return reinterpret_cast<function_scl_adapter*>( params )->f( x ); }
209 static double dfn( double x, void* params ){
210 return reinterpret_cast<function_scl_adapter*>( params )->df( x ); }
217 static void fdfn( double x, void* params, double* d, double* df ){
218 std::pair<double,double> pair = reinterpret_cast<function_scl_adapter*>( params )->fdf( x );
219 *d = pair.first; *df = pair.second; }
220 private:
224 function_scl& scl_function;
228 function_scl& scl_dfunction;
229 };
230#endif
234 base_F* function;
238 size_t* count;
239 public:
244 function = 0;
245 f = 0;
246 df = 0;
247 fdf = 0;
248 params = 0;
249 count = 0; // initially nullptr will do
250 }
251 template<typename T>
258 explicit function_fdf( gsl_function_fdf& v ){
259 // explicitly set function = 0 to indicate nothing to be deleted.
260 function = 0;
261 // copy
262 f = v.f;
263 df = v.df;
264 fdf = v.fdf;
265 params = v.params;
266 // just plausibly we could fail to allocate count: no further action needed.
267 count = new size_t;
268 *count = 1; // initially there is just one reference to function
269 }
274 template<typename T>
276 function_fdf_constructor<T>( *this, t );
277 }
285 this->function = 0;
286 count = 0;
287 // try constructing from function_scl_adapter
288 this->function = new function_scl_adapter( function, dfunction );
289 f = &function_scl_adapter::fn;
290 df = &function_scl_adapter::dfn;
291 fdf = &function_scl_adapter::fdfn;
292 params = this->function;
293 // just plausibly we could fail to allocate count: no further action needed.
294 count = new size_t;
295 *count = 1; // initially there is just one reference to function
296 }
297
298 // Copy and move constructors
299 // copy constructor
306 f = v.f;
307 df = v.df;
308 fdf = v.fdf;
309 params = v.params;
310 if( count != 0 ) ++*count; // function_fdf is now shared.
311 }
312 // assignment operator
318 // first, possibly delete anything pointed to by this
319 if( count == 0 or --*count == 0 ){
320 delete function;
321 delete count;
322 }
323 // Then copy
324 function = v.function;
325 f = v.f;
326 df = v.df;
327 fdf = v.fdf;
328 params = v.params;
329 // count = v.count;
330 if( count != 0 ) ++*count; // function_fdf is now shared.
331 return *this;
332 }
333#ifdef __GXX_EXPERIMENTAL_CXX0X__
339 std::swap( f, v.f );
340 std::swap( df, v.df );
341 std::swap( fdf, v.fdf );
342 std::swap( params, v.params );
343 std::swap( count, v.count );
344 v.function = nullptr;
345 }
352 std::swap( function, v.function );
353 std::swap( f, v.f );
354 std::swap( df, v.df );
355 std::swap( fdf, v.fdf );
356 std::swap( params, v.params );
357 std::swap( count, v.count );
358 return *this;
359 }
360#endif
365 // first, possibly delete anything pointed to by f
366 if( count == 0 or --*count == 0 ){
367 delete function;
368 delete count;
369 }
370 }
371 };
372#ifndef DOXYGEN_SKIP
378 template<typename T>
379 inline void function_fdf_constructor( function_fdf& fdf, T& t ){
380 fdf.function = 0;
381 fdf.count = 0;
382 // try constructing from T
383 fdf.function = new function_fdf::FDF<T>( t );
384 fdf.f = &function_fdf::FDF<T>::fn;
385 fdf.df = &function_fdf::FDF<T>::dfn;
386 fdf.fdf = &function_fdf::FDF<T>::fdfn;
387 fdf.params = fdf.function;
388 // just plausibly we could fail to allocate count: no further action needed.
389 fdf.count = new size_t;
390 *fdf.count = 1; // initially there is just one reference to function
391 }
395 template<>
396 inline void function_fdf_constructor( function_fdf& fdf, function_fdf& v ){
397 fdf.function = v.function; fdf.count = v.count; fdf.f = v.f; fdf.df = v.df;
398 fdf.fdf = v.fdf; fdf.params = v.params; if( fdf.count != 0 ) ++*fdf.count;
399 /* function_fdf is now shared. */ }
403 template<>
404 inline void function_fdf_constructor( function_fdf& fdf, gsl_function_fdf& v ){
405 fdf.f = v.f; fdf.df = v.df; fdf.fdf = v.fdf; fdf.params = v.params; }
406#endif
407
412 template<typename T>
414 function_fdf fn( t );
415 return fn;
416 }
417
424 inline double fn_fdf_eval_f( gsl_function_fdf const* const F, double const x ){
425 return (F->f)( x, F->params );
426 }
427
434 inline double fn_fdf_eval_f( gsl_function_fdf const& F, double const x ){
435 return (F.f)( x, F.params );
436 }
437
444 inline double fn_fdf_eval_df( gsl_function_fdf const* const F, double const x ){
445 return (F->df)( x, F->params );
446 }
447
454 inline double fn_fdf_eval_df( gsl_function_fdf const& F, double const x ){
455 return (F.df)( x, F.params );
456 }
457
465 inline void fn_fdf_eval_df( gsl_function_fdf const* const F, double const x,
466 double* f, double* df ){
467 return (F->fdf)( x, F->params, f, df );
468 }
469
477 inline void fn_fdf_eval_df( gsl_function_fdf const& F, double const x,
478 double& f, double& df ){
479 return (F.fdf)( x, F.params, &f, &df );
480 }
481}
482
483#endif
Class that extends gsl_function_fdf so that it can be constructed from arbitrary function objects.
function_fdf & operator=(function_fdf const &v)
The assignment operator.
function_fdf(function_fdf &&v)
Move constructor.
function_fdf(gsl_function_fdf &v)
Could construct from a gsl_function_fdf.
function_fdf()
The default constructor is only really useful for assigning to.
function_fdf & operator=(function_fdf &&v)
Move operator.
base_F * function
This gives something for params to point to.
size_t * count
The shared reference count: used for copying this.
function_fdf(function_fdf const &v)
The copy constructor.
~function_fdf()
The destructor unshares any shared resource.
friend void function_fdf_constructor(function_fdf &fdf, T &t)
function_fdf(function_scl &function, function_scl &dfunction)
Construct from function_scl objects for function and derivative.
function_fdf(T &t)
Construct from an object that implements gsl::function_fdf::Concept.
Class that extends gsl_function so that it can be constructed from arbitrary function objects.
int df(double const h, gsl_multifit_nlinear_fdtype const fdtype, vector const &x, vector const &wts, gsl::multifit::nlinear::function_fdf &fdf, vector const &f, matrix &J, vector &work)
C++ version of gsl_multifit_nlinear_df().
gsl_multilarge_nlinear_fdf fdf
Typedef for shorthand.
double F(double phi, double k, mode_t mode)
C++ version of gsl_sf_ellint_F().
Definition: sf_ellint.hpp:138
The gsl package creates an interface to the GNU Scientific Library for C++.
Definition: blas.hpp:34
function_fdf make_function_fdf(T &t)
Make a gsl::function_fdf from a function object that implements gsl::function_fdf::Concept.
void function_fdf_constructor(function_fdf &fdf, T &t)
double fn_eval(gsl_function const &F, double const x)
Evaluate a gsl::function (or gsl_function).
double fn_fdf_eval_f(gsl_function_fdf const *const F, double const x)
Evaluate a gsl::function_fdf (or gsl_function_fdf).
double fn_fdf_eval_df(gsl_function_fdf const *const F, double const x)
Evaluate a gsl::function_fdf (or gsl_function_fdf).
This is an empty abstract base class.
virtual std::pair< double, double > fdf(double x)=0
The function and derivative.
virtual double df(double x)=0
The derivative.
virtual double f(double x)=0
The function.