ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
multifit_function_fdf.hpp
Go to the documentation of this file.
1/*
2 * $Id: multifit_function_fdf.hpp 296 2013-01-02 12:17:04Z jdl3 $
3 * Copyright (C) 2010, 2011, 2012, 2016, 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_MULTIFIT_FUNCTION_FDF_HPP
21#define CCGSL_MULTIFIT_FUNCTION_FDF_HPP
22
23#include<gsl/gsl_multifit_nlin.h>
24#include"vector.hpp"
25#include"matrix.hpp"
26// For std::swap
27#if __cplusplus <= 199711L
28#include<algorithm>
29#else
30#include<utility>
31#endif
32
33#ifndef DOXYGEN_SKIP
34namespace gsl {
35 namespace multifit {
36 template<typename T> void function_constructor( function_fdf& f, T& t );
54 class function_fdf : public gsl_multifit_function_fdf {
55 public:
63 struct Concept {
71 virtual double f( gsl::vector const& x, gsl::vector& f ) = 0;
80 virtual double df( gsl::vector const& x, gsl::matrix& J ) = 0;
90 virtual double fdf( gsl::vector const& x, gsl::vector& f, gsl::matrix& J ) = 0;
94 virtual size_t size() const = 0;
98 virtual size_t num_parameters() const = 0;
99 };
100#ifndef DOXYGEN_SKIP
101 private:
105 struct base_F {
109 typedef int (*function_t)(gsl_vector const*,void*,gsl_vector*);
113 typedef int (*dfunction_t)(gsl_vector const*,void*,gsl_matrix*);
117 typedef int (*fdfunction_t)(gsl_vector const*,void*,gsl_vector*,gsl_matrix*);
118 };
122 template<typename T>
123 struct F : public base_F {
124 public:
129 F( T& t ) : t( t ){}
130 public:
139 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
140 // share gsl_vector* and gsl::vector contents.
141 F<T>* ft = reinterpret_cast<F<T>*>( params );
142 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
143 ft->fv.wrap_gsl_vector_without_ownership( fx );
144 return ft->t.f( ft->xv, ft->fv ); }
153 static int dfn( gsl_vector const* x, void* params, gsl_matrix* dfx ){
154 // share gsl_vector* and gsl::vector contents.
155 F<T>* ft = reinterpret_cast<F<T>*>( params );
156 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
157 ft->dfv.wrap_gsl_matrix_without_ownership( dfx );
158 return ft->t.df( ft->xv, ft->dfv ); }
168 static int fdfn( gsl_vector const* x, void* params, gsl_vector* fx, gsl_matrix* dfx ){
169 // share gsl_vector* and gsl::vector contents.
170 F<T>* ft = reinterpret_cast<F<T>*>( params );
171 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
172 ft->fv.wrap_gsl_vector_without_ownership( fx );
173 ft->dfv.wrap_gsl_matrix_without_ownership( dfx );
174 return ft->t.fdf( ft->xv, ft->fv, ft->dfv ); }
175 private:
179 T& t;
183 gsl::vector xv;
187 gsl::vector fv;
191 gsl::matrix dfv;
192 };
196 class Fn : public base_F {
197 public:
203 Fn( int (*const f)(gsl::vector const&,gsl::vector&),
204 int (*const df)(gsl::vector const&,gsl::matrix&),
205 int (*const fdf)(gsl::vector const&,gsl::vector&,gsl::matrix&),
206 size_t n ) : f( f ), df( df ), fdf( fdf ), n( n ){}
210 function_t function(){ return &fn; }
214 dfunction_t dfunction(){ return &dfn; }
218 fdfunction_t fdfunction(){ return &fdfn; }
219 private:
223 int (*const f)(gsl::vector const&,gsl::vector&);
227 int (*const df)(gsl::vector const&,gsl::matrix&);
231 int (*const fdf)(gsl::vector const&,gsl::vector&,gsl::matrix&);
232 public:
236 size_t const n;
245 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
246 // share gsl_vector* and gsl::vector contents.
247 Fn* ft = reinterpret_cast<Fn*>( params );
248 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
249 ft->fv.wrap_gsl_vector_without_ownership( fx );
250 return ft->f( ft->xv, ft->fv ); }
259 static int dfn( gsl_vector const* x, void* params, gsl_matrix* dfx ){
260 // share gsl_vector* and gsl::vector contents.
261 Fn* ft = reinterpret_cast<Fn*>( params );
262 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
263 ft->dfv.wrap_gsl_matrix_without_ownership( dfx );
264 return ft->df( ft->xv, ft->dfv ); }
274 static int fdfn( gsl_vector const* x, void* params, gsl_vector* fx, gsl_matrix* dfx ){
275 // share gsl_vector* and gsl::vector contents.
276 Fn* ft = reinterpret_cast<Fn*>( params );
277 ft->xv.wrap_gsl_vector_without_ownership( const_cast<gsl_vector*>( x ) );
278 ft->fv.wrap_gsl_vector_without_ownership( fx );
279 ft->dfv.wrap_gsl_matrix_without_ownership( dfx );
280 return ft->fdf( ft->xv, ft->fv, ft->dfv ); }
281 private:
285 gsl::vector xv;
289 gsl::vector fv;
293 gsl::matrix dfv;
294 };
295#endif
299 base_F* func;
303 size_t* count;
304 public:
308 function_fdf(){
309 func = 0;
310 f = 0;
311 df = 0;
312 fdf = 0;
313 n = 0;
314 p = 0;
315 params = 0;
316 count = 0; // initially nullptr will do
317 }
318 template<typename T>
319 friend void function_constructor( function_fdf&, T& );
326 explicit function_fdf( gsl_multifit_function_fdf& v ){
327 // explicitly set function = 0 to indicate nothing to be deleted.
328 func = 0;
329 // copy
330 f = v.f;
331 df = v.df;
332 fdf = v.fdf;
333 n = v.n;
334 p = v.p;
335 params = v.params;
336 // just plausibly we could fail to allocate count: no further action needed.
337 count = new size_t;
338 *count = 1; // initially there is just one reference to function
339 }
344 template<typename T>
345 function_fdf( T& t ){ function_constructor<T>( *this, t ); }
353 function_fdf( int (* const f)(gsl::vector const&, gsl::vector&),
354 int (* const df)(gsl::vector const&, gsl::matrix&),
355 int (* const fdf)(gsl::vector const&, gsl::vector&, gsl::matrix&),
356 size_t n ){
357 func = 0;
358 count = 0;
359 func = new function_fdf::Fn( f, df, fdf, n );
360 this->f = Fn::fn;
361 this->df = Fn::dfn;
362 this->fdf = Fn::fdfn;
363 this->n = n;
364 this->p = p;
365 params = func;
366 // just plausibly we could fail to allocate count: no further action needed.
367 count = new size_t;
368 *count = 1; // initially there is just one reference to function
369 }
370
371 // Copy and move constructors
372 // copy constructor
379 function_fdf( function_fdf const& v ) : func( v.func ), count( v.count ){
380 f = v.f;
381 df = v.df;
382 fdf = v.fdf;
383 n = v.n;
384 p = v.p;
385 params = v.params;
386 if( count != 0 ) ++*count; // function is now shared.
387 }
388 // assignment operator
393 function_fdf& operator=( function_fdf const& v ){
394 // first, possibly delete anything pointed to by this
395 if( count == 0 or --*count == 0 ){
396 delete func;
397 delete count;
398 }
399 // Then copy
400 func = v.func;
401 f = v.f;
402 df = v.df;
403 fdf = v.fdf;
404 n = v.n;
405 p = v.p;
406 params = v.params;
407 // count = v.count;
408 if( count != 0 ) ++*count; // function is now shared.
409 return *this;
410 }
411#ifdef __GXX_EXPERIMENTAL_CXX0X__
416 function_fdf( function_fdf&& v ) : func( v.func ), count( nullptr ){
417 std::swap( f, v.f );
418 std::swap( df, v.df );
419 std::swap( fdf, v.fdf );
420 std::swap( n, v.n );
421 std::swap( p, v.p );
422 std::swap( params, v.params );
423 std::swap( count, v.count );
424 v.func = nullptr;
425 }
431 function_fdf& operator=( function_fdf&& v ){
432 std::swap( func, v.func );
433 std::swap( f, v.f );
434 std::swap( df, v.df );
435 std::swap( fdf, v.fdf );
436 std::swap( n, v.n );
437 std::swap( p, v.p );
438 std::swap( params, v.params );
439 std::swap( count, v.count );
440 return *this;
441 }
442#endif
446 ~function_fdf(){
447 // first, possibly delete anything pointed to by f
448 if( count == 0 or --*count == 0 ){
449 delete func;
450 delete count;
451 }
452 }
453 };
454#ifndef DOXYGEN_SKIP
462 template<typename T>
463 inline void function_constructor( function_fdf& f, T& t ){
464 f.func = 0;
465 f.count = 0;
466 // try constructing from T
467 f.func = new function_fdf::F<T>( t );
468 f.f = &function_fdf::F<T>::fn;
469 f.df = &function_fdf::F<T>::dfn;
470 f.fdf = &function_fdf::F<T>::fdfn;
471 f.n = t.size();
472 f.p = t.num_parameters();
473 f.params = f.func;
474 // just plausibly we could fail to allocate count: no further action needed.
475 f.count = new size_t;
476 *f.count = 1; // initially there is just one reference to function
477 }
483 template<>
484 inline void function_constructor( function_fdf& f, function_fdf& v ){
485 f.func = v.func; f.count = v.count; f.f = v.f; f.df = v.df; f.fdf = v.fdf; f.n = v.n;
486 f.p = v.p; f.params = v.params; if( f.count != 0 ) ++*f.count;
487 /* function is now shared. */ }
493 template<>
494 inline void function_constructor( function_fdf& f, gsl_multifit_function_fdf& v ){
495 f.f = v.f; f.df = v.df; f.fdf = v.fdf; f.n = v.n; f.p = v.p; f.params = v.params; }
496#endif
497
503 template<typename T>
504 inline function_fdf make_function( T& t ){
505 function_fdf fn( t );
506#ifdef __GXX_EXPERIMENTAL_CXX0X__
507 return std::move( fn );
508#else
509 return fn;
510#endif
511 }
512 }
513}
514#endif
515
516#endif
This class handles matrix objects as shared handles.
Definition: matrix.hpp:72
This class handles vector objects as shared handles.
Definition: vector.hpp:74
size_t size(series const &cs)
C++ version of gsl_cheb_size().
Definition: chebyshev.hpp:287
void function_constructor(function_fdf &f, T &t)
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().
function make_function(T &t)
Make a gsl::multifit::function from a function object that implements gsl::multifit::function::Concep...
gsl_multilarge_nlinear_fdf fdf
Typedef for shorthand.
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
double func(int const n, double const x)
C++ version of gsl_sf_hermite_func().
Definition: sf_hermite.hpp:154
The gsl package creates an interface to the GNU Scientific Library for C++.
Definition: blas.hpp:34