ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
multifit_function.hpp
Go to the documentation of this file.
1/*
2 * $Id: multifit_function.hpp 233 2012-08-08 19:44:28Z 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_MULTIFIT_FUNCTION_HPP
21#define CCGSL_MULTIFIT_FUNCTION_HPP
22
23#include<gsl/gsl_multifit_nlin.h>
24#include"vector.hpp"
25// For std::swap
26#if __cplusplus <= 199711L
27#include<algorithm>
28#endif
29
30namespace gsl {
31 namespace multifit {
49 class function : public gsl_multifit_function {
50 public:
58 struct Concept {
66 virtual double f( gsl::vector const& x, gsl::vector& f ) = 0;
70 virtual size_t size() const = 0;
74 virtual size_t num_parameters() const = 0;
75 };
76#ifndef DOXYGEN_SKIP
77 private:
81 struct base_F {
85 typedef int (*function_t)(gsl_vector const*,void*,gsl_vector*);
86 };
90 template<typename T>
91 struct F : public base_F {
92 public:
97 F( T& t ) : t( t ){
98 xv.wrap_gsl_vector_without_ownership( 0 );
99 fv.wrap_gsl_vector_without_ownership( 0 );
100 }
101 public:
110 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
111 // share gsl_vector* and gsl::vector contents.
112 F<T>* ft = reinterpret_cast<F<T>*>( params );
113 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
114 ft->fv.ccgsl_pointer = fx;
115 return ft->t.f( ft->xv, ft->fv ); }
116 private:
120 T& t;
124 gsl::vector xv;
128 gsl::vector fv;
129 };
133 class Fn : public base_F {
134 public:
140 Fn( int (*const f)(gsl::vector const&,gsl::vector&), size_t n ) : f( f ), n( n ){
141 xv.wrap_gsl_vector_without_ownership( 0 );
142 fv.wrap_gsl_vector_without_ownership( 0 );
143 }
147 function_t function(){ return &fn; }
148 private:
152 int (*const f)(gsl::vector const&,gsl::vector&);
153 public:
157 size_t const n;
166 static int fn( gsl_vector const* x, void* params, gsl_vector* fx ){
167 // share gsl_vector* and gsl::vector contents.
168 Fn* ft = reinterpret_cast<Fn*>( params );
169 ft->xv.ccgsl_pointer = const_cast<gsl_vector*>( x );
170 ft->fv.ccgsl_pointer = fx;
171 return ft->f( ft->xv, ft->fv ); }
172 private:
176 gsl::vector xv;
180 gsl::vector fv;
181 };
185 base_F* func;
189 size_t* count;
190#endif
191 public:
196 func = 0;
197 f = 0;
198 n = 0;
199 p = 0;
200 params = 0;
201 count = 0; // initially nullptr will do
202 }
203 template<typename T>
205 template<typename T>
206 friend void function_constructor( function&, T& );
213 explicit function( gsl_multifit_function& v ){
214 // explicitly set function = 0 to indicate nothing to be deleted.
215 func = 0;
216 // copy
217 f = v.f;
218 n = v.n;
219 p = v.p;
220 params = v.params;
221 // just plausibly we could fail to allocate count: no further action needed.
222 count = new size_t;
223 *count = 1; // initially there is just one reference to function
224 }
229 template<typename T>
230 function( T& t ){ function_constructor<T>( *this, t ); }
236 function( int (* const f)(gsl::vector const&, gsl::vector&), size_t n ){
237 func = 0;
238 count = 0;
239 func = new function::Fn( f, n );
240 this->f = Fn::fn;
241 this->n = n;
242 this->p = p;
243 params = func;
244 // just plausibly we could fail to allocate count: no further action needed.
245 count = new size_t;
246 *count = 1; // initially there is just one reference to function
247 }
248
249 // Copy and move constructors
250 // copy constructor
256 function( function const& v ) : func( v.func ), count( v.count ){
257 f = v.f;
258 n = v.n;
259 p = v.p;
260 params = v.params;
261 if( count != 0 ) ++*count; // function is now shared.
262 }
263 // assignment operator
269 // first, possibly delete anything pointed to by this
270 if( count == 0 or --*count == 0 ){
271 delete func;
272 delete count;
273 }
274 // Then copy
275 func = v.func;
276 f = v.f;
277 n = v.n;
278 p = v.p;
279 params = v.params;
280 // count = v.count;
281 if( count != 0 ) ++*count; // function is now shared.
282 return *this;
283 }
284#ifdef __GXX_EXPERIMENTAL_CXX0X__
289 function( function&& v ) : func( v.func ), count( nullptr ){
290 std::swap( f, v.f );
291 std::swap( n, v.n );
292 std::swap( p, v.p );
293 std::swap( params, v.params );
294 std::swap( count, v.count );
295 v.func = nullptr;
296 }
303 std::swap( func, v.func );
304 std::swap( f, v.f );
305 std::swap( n, v.n );
306 std::swap( p, v.p );
307 std::swap( params, v.params );
308 std::swap( count, v.count );
309 return *this;
310 }
311#endif
316 // first, possibly delete anything pointed to by f
317 if( count == 0 or --*count == 0 ){
318 delete func;
319 delete count;
320 }
321 }
322 };
323#ifndef DOXYGEN_SKIP
331 template<typename T>
332 inline void function_constructor( function& f, T& t ){
333 f.func = 0;
334 f.count = 0;
335 // try constructing from T
336 f.func = new function::F<T>( t );
337 f.f = &function::F<T>::fn;
338 f.n = t.size();
339 f.p = t.num_parameters();
340 f.params = f.func;
341 // just plausibly we could fail to allocate count: no further action needed.
342 f.count = new size_t;
343 *f.count = 1; // initially there is just one reference to function
344 }
350 template<>
351 inline void function_constructor( function& f, function& v ){
352 f.func = v.func; f.count = v.count; f.f = v.f; f.n = v.n; f.p = v.p;
353 f.params = v.params; if( f.count != 0 ) ++*f.count;
354 /* function is now shared. */ }
360 template<>
361 inline void function_constructor( function& f, gsl_multifit_function& v ){
362 f.f = v.f; f.n = v.n; f.p = v.p; f.params = v.params; }
363#endif
369 template<typename T>
370 inline function make_function( T& t ){
371 function fn( t );
372#ifdef __GXX_EXPERIMENTAL_CXX0X__
373 return std::move( fn );
374#else
375 return fn;
376#endif
377 }
378 }
379}
380
381#endif
Class that extends gsl_multifit_function so that it can be constructed from arbitrary function object...
void function_constructor(function &, T &)
function(int(*const f)(gsl::vector const &, gsl::vector &), size_t n)
Construct from a function with no parameters (but with n function values and arguments).
~function()
The destructor unshares any shared resource.
function(gsl_multifit_function &v)
Could construct from a gsl_multifit_function.
function()
The default constructor is only really useful for assigning to.
friend void function_constructor(function &, T &)
function & operator=(function &&v)
Move operator.
function & operator=(function const &v)
The assignment operator.
function(function const &v)
The copy constructor.
function(T &t)
Construct from an object that implements gsl::multifit::function::Concept.
function(function &&v)
Move constructor.
This class handles vector objects as shared handles.
Definition: vector.hpp:74
void function_constructor(function_fdf &f, T &t)
function make_function(T &t)
Make a gsl::multifit::function from a function object that implements gsl::multifit::function::Concep...
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
This is an empty abstract base class.
virtual double f(gsl::vector const &x, gsl::vector &f)=0
The function.
virtual size_t num_parameters() const =0
This function should return the number of components of x (independent variables).
virtual size_t size() const =0
This function should return the number of elements of x and f in f().