ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
multiroot_function_fdf.hpp
Go to the documentation of this file.
1/*
2 * $Id: multiroot_function_fdf.hpp 171 2012-06-19 19:15:15Z 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_MULTIROOT_FUNCTION_FDF_HPP
21#define CCGSL_MULTIROOT_FUNCTION_FDF_HPP
22
23// For std::swap
24#if __cplusplus <= 199711L
25#include<algorithm>
26#else
27#include<utility>
28#endif
29
30namespace gsl {
31 namespace multiroot {
49 class function_fdf : public gsl_multiroot_function_fdf {
50 public:
58 struct Concept {
66 virtual int f( gsl::vector const& x, gsl::vector& f ) = 0;
75 virtual int df( gsl::vector const& x, gsl::matrix& J ) = 0;
85 virtual int fdf( gsl::vector const& x, gsl::vector& f, gsl::matrix& J ) = 0;
89 virtual size_t size() const = 0;
90 };
91#ifndef DOXYGEN_SKIP
92 private:
96 struct base_F {
100 typedef int (*function_t)(gsl_vector const*,void*,gsl_vector*);
104 typedef int (*dfunction_t)(gsl_vector const*,void*,gsl_matrix*);
108 typedef int (*fdfunction_t)(gsl_vector const*,void*,gsl_vector*,gsl_matrix*);
109 };
113 template<typename T>
114 struct F : public base_F {
115 public:
120 F( T& t ) : t( t ){
121 xv.wrap_gsl_vector_without_ownership( 0 );
122 fv.wrap_gsl_vector_without_ownership( 0 );
123 dfv.wrap_gsl_matrix_without_ownership( 0 );
124 }
125 public:
134 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
135 // share gsl_vector* and gsl::vector contents.
136 F<T>* ft = reinterpret_cast<F<T>*>( params );
137 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
138 ft->fv.ccgsl_pointer = fx;
139 return ft->t.f( ft->xv, ft->fv ); }
148 static int dfn( gsl_vector const* x, void* params, gsl_matrix* dfx ){
149 // share gsl_vector* and gsl::vector contents.
150 F<T>* ft = reinterpret_cast<F<T>*>( params );
151 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
152 ft->dfv.ccgsl_pointer = dfx;
153 return ft->t.df( ft->xv, ft->dfv ); }
163 static int fdfn( gsl_vector const* x, void* params, gsl_vector* fx, gsl_matrix* dfx ){
164 // share gsl_vector* and gsl::vector contents.
165 F<T>* ft = reinterpret_cast<F<T>*>( params );
166 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
167 ft->fv.ccgsl_pointer = fx;
168 ft->dfv.ccgsl_pointer = dfx;
169 return ft->t.fdf( ft->xv, ft->fv, ft->dfv ); }
170 private:
174 T& t;
178 gsl::vector xv;
182 gsl::vector fv;
186 gsl::matrix dfv;
187 };
191 class Fn : public base_F {
192 public:
198 Fn( int (*const f)(gsl::vector const&,gsl::vector&),
199 int (*const df)(gsl::vector const&,gsl::matrix&),
200 int (*const fdf)(gsl::vector const&,gsl::vector&,gsl::matrix&),
201 size_t n ) : f( f ), df( df ), fdf( fdf ), n( n ){}
205 function_t function(){ return &fn; }
209 dfunction_t dfunction(){ return &dfn; }
213 fdfunction_t fdfunction(){ return &fdfn; }
214 private:
218 int (*const f)(gsl::vector const&,gsl::vector&);
222 int (*const df)(gsl::vector const&,gsl::matrix&);
226 int (*const fdf)(gsl::vector const&,gsl::vector&,gsl::matrix&);
227 public:
231 size_t const n;
240 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
241 // share gsl_vector* and gsl::vector contents.
242 Fn* ft = reinterpret_cast<Fn*>( params );
243 ft->fv.ccgsl_pointer = fx;
244 return ft->f( ft->xv, ft->fv ); }
253 static int dfn( gsl_vector const* x, void* params, gsl_matrix* dfx ){
254 // share gsl_vector* and gsl::vector contents.
255 Fn* ft = reinterpret_cast<Fn*>( params );
256 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
257 ft->dfv.ccgsl_pointer = dfx;
258 return ft->df( ft->xv, ft->dfv ); }
268 static int fdfn( gsl_vector const* x, void* params, gsl_vector* fx, gsl_matrix* dfx ){
269 // share gsl_vector* and gsl::vector contents.
270 Fn* ft = reinterpret_cast<Fn*>( params );
271 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
272 ft->fv.ccgsl_pointer = fx;
273 ft->dfv.ccgsl_pointer = dfx;
274 return ft->fdf( ft->xv, ft->fv, ft->dfv ); }
275 private:
279 gsl::vector xv;
283 gsl::vector fv;
287 gsl::matrix dfv;
288 };
292 template<typename T>
293 struct gsl_F : public base_F {
294 public:
299 gsl_F( T& t ) : t( t ){}
300 public:
308 static int fn( gsl_vector const* x, void* params, gsl_vector* f ){
309 return reinterpret_cast<F<T>*>( params )->t.f( x, f ); }
318 static int dfn( gsl_vector const* x, void* params, gsl_matrix* df ){
319 return reinterpret_cast<F<T>*>( params )->t.df( x, df ); }
329 static int fdfn( gsl_vector const* x, void* params, gsl_vector* f, gsl_matrix* df ){
330 return reinterpret_cast<F<T>*>( params )->t.fdf( x, f, df ); }
331 private:
335 T& t;
336 };
340 class gsl_Fn : public base_F {
341 public:
349 gsl_Fn( int (*const f)(gsl_vector const*,gsl_vector*),
350 int (*const df)(gsl_vector const*,gsl_matrix*),
351 int (*const fdf)(gsl_vector const*,gsl_vector*,gsl_matrix*),
352 size_t n ) : f( f ), df( df ), fdf( fdf ), n( n ){}
356 function_t function(){ return &fn; }
360 dfunction_t dfunction(){ return &dfn; }
364 fdfunction_t fdfunction(){ return &fdfn; }
365 private:
369 int (*const f)(gsl_vector const*,gsl_vector*);
373 int (*const df)(gsl_vector const*,gsl_matrix*);
377 int (*const fdf)(gsl_vector const*,gsl_vector*,gsl_matrix*);
378 public:
382 size_t const n;
390 static int fn( gsl_vector const* x, void* params, gsl_vector* f ){
391 return reinterpret_cast<gsl_Fn*>( params )->f( x, f ); }
399 static int dfn( gsl_vector const* x, void* params, gsl_matrix* df ){
400 return reinterpret_cast<gsl_Fn*>( params )->df( x, df ); }
409 static int fdfn( gsl_vector const* x, void* params, gsl_vector* f, gsl_matrix* df ){
410 return reinterpret_cast<gsl_Fn*>( params )->fdf( x, f, df ); }
411 };
412#endif
416 base_F* func;
420 size_t* count;
421 public:
426 func = 0;
427 f = 0;
428 df = 0;
429 fdf = 0;
430 n = 0;
431 params = 0;
432 count = 0; // initially nullptr will do
433 }
434 template<typename T>
442 explicit function_fdf( gsl_multiroot_function_fdf& v ){
443 // explicitly set function = 0 to indicate nothing to be deleted.
444 func = 0;
445 // copy
446 f = v.f;
447 df = v.df;
448 fdf = v.fdf;
449 n = v.n;
450 params = v.params;
451 // just plausibly we could fail to allocate count: no further action needed.
452 count = new size_t;
453 *count = 1; // initially there is just one reference to function
454 }
459 template<typename T>
460 function_fdf( T& t ){ function_constructor<T>( *this, t ); }
468 function_fdf( int (* const f)(gsl::vector const&, gsl::vector&),
469 int (* const df)(gsl::vector const&, gsl::matrix&),
470 int (* const fdf)(gsl::vector const&, gsl::vector&, gsl::matrix&),
471 size_t n ){
472 func = 0;
473 count = 0;
474 func = new function_fdf::Fn( f, df, fdf, n );
475 this->f = Fn::fn;
476 this->df = Fn::dfn;
477 this->fdf = Fn::fdfn;
478 this->n = n;
479 params = func;
480 // just plausibly we could fail to allocate count: no further action needed.
481 count = new size_t;
482 *count = 1; // initially there is just one reference to function
483 }
484
485 // Copy and move constructors
486 // copy constructor
493 function_fdf( function_fdf const& v ) : func( v.func ), count( v.count ){
494 f = v.f;
495 df = v.df;
496 fdf = v.fdf;
497 n = v.n;
498 params = v.params;
499 if( count != 0 ) ++*count; // function is now shared.
500 }
501 // assignment operator
507 // first, possibly delete anything pointed to by this
508 if( count == 0 or --*count == 0 ){
509 delete func;
510 delete count;
511 }
512 // Then copy
513 func = v.func;
514 f = v.f;
515 df = v.df;
516 fdf = v.fdf;
517 n = v.n;
518 params = v.params;
519 // count = v.count;
520 if( count != 0 ) ++*count; // function is now shared.
521 return *this;
522 }
523#ifdef __GXX_EXPERIMENTAL_CXX0X__
528 function_fdf( function_fdf&& v ) : func( v.func ), count( nullptr ){
529 std::swap( f, v.f );
530 std::swap( df, v.df );
531 std::swap( fdf, v.fdf );
532 std::swap( n, v.n );
533 std::swap( params, v.params );
534 std::swap( count, v.count );
535 v.func = nullptr;
536 }
543 std::swap( func, v.func );
544 std::swap( f, v.f );
545 std::swap( df, v.df );
546 std::swap( fdf, v.fdf );
547 std::swap( n, v.n );
548 std::swap( params, v.params );
549 std::swap( count, v.count );
550 return *this;
551 }
552#endif
557 // first, possibly delete anything pointed to by f
558 if( count == 0 or --*count == 0 ){
559 delete func;
560 delete count;
561 }
562 }
563 };
564#ifndef DOXYGEN_SKIP
572 template<typename T>
573 inline void function_constructor( function_fdf& f, T& t ){
574 f.func = 0;
575 f.count = 0;
576 // try constructing from T
577 f.func = new function_fdf::F<T>( t );
578 f.f = &function_fdf::F<T>::fn;
579 f.df = &function_fdf::F<T>::dfn;
580 f.fdf = &function_fdf::F<T>::fdfn;
581 f.n = t.size();
582 f.params = f.func;
583 // just plausibly we could fail to allocate count: no further action needed.
584 f.count = new size_t;
585 *f.count = 1; // initially there is just one reference to function
586 }
592 template<>
593 inline void function_constructor( function_fdf& f, function_fdf& v ){
594 f.func = v.func; f.count = v.count; f.f = v.f; f.df = v.df; f.fdf = v.fdf; f.n = v.n;
595 f.params = v.params; if( f.count != 0 ) ++*f.count;
596 /* function is now shared. */ }
602 template<>
603 inline void function_constructor( function_fdf& f, gsl_multiroot_function_fdf& v ){
604 f.f = v.f; f.df = v.df; f.fdf = v.fdf; f.n = v.n; f.params = v.params; }
605#endif
606
612 template<typename T>
614 function_fdf fn( t );
615#ifdef __GXX_EXPERIMENTAL_CXX0X__
616 return std::move( fn );
617#else
618 return fn;
619#endif
620 }
621 }
622}
623
624#endif
Class that extends gsl_function_fdf so that it can be constructed from arbitrary function objects.
size_t * count
The shared reference count: used for copying this.
This class handles matrix objects as shared handles.
Definition: matrix.hpp:72
Class that extends gsl_multiroot_function_fdf so that it can be constructed from arbitrary function o...
~function_fdf()
The destructor unshares any shared resource.
function_fdf & operator=(function_fdf &&v)
Move operator.
function_fdf(function_fdf &&v)
Move constructor.
function_fdf(function_fdf const &v)
The copy constructor.
function_fdf(T &t)
Construct from an object that implements gsl::multiroot::function_fdf::Concept.
function_fdf & operator=(function_fdf const &v)
The assignment operator.
size_t * count
The shared reference count: used for copying this.
friend void function_constructor(function_fdf &, T &)
function_fdf(gsl_multiroot_function_fdf &v)
Could construct from a gsl_multiroot_function_fdf.
function_fdf()
The default constructor is only really useful for assigning to.
base_F * func
This gives something for params to point to.
function_fdf(int(*const f)(gsl::vector const &, gsl::vector &), int(*const df)(gsl::vector const &, gsl::matrix &), int(*const fdf)(gsl::vector const &, gsl::vector &, gsl::matrix &), size_t n)
Construct from a function with no parameters (but with n function values and arguments).
This class handles vector objects as shared handles.
Definition: vector.hpp:74
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.
void function_constructor(function &, T &)
function_fdf make_function_fdf(T &t)
Make a gsl::multiroot::function_fdf from a function object that implements gsl::multiroot::function_f...
size_t n(workspace const &w)
C++ version of gsl_rstat_n().
Definition: rstat.hpp:299
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
This is an empty abstract base class.
virtual int fdf(gsl::vector const &x, gsl::vector &f, gsl::matrix &J)=0
The function (returned as a vector) and derivatives (as Jacobian matrix)
virtual int f(gsl::vector const &x, gsl::vector &f)=0
The function.
virtual int df(gsl::vector const &x, gsl::matrix &J)=0
The derivatives (as Jacobian matrix)
virtual size_t size() const =0
This function should return the number of elements of x and f in f().