ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
multiroot_function.hpp
Go to the documentation of this file.
1/*
2 * $Id: multiroot_function.hpp 235 2012-08-08 19:46:06Z 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_MULTIROOT_FUNCTION_HPP
21#define CCGSL_MULTIROOT_FUNCTION_HPP
22
23#include<gsl/gsl_multiroots.h>
24// For std::swap
25#if __cplusplus <= 199711L
26#include<algorithm>
27#else
28#include<utility>
29#endif
30
31namespace gsl {
32 namespace multiroot {
33 class function;
34 template<typename T>
53 class function : public gsl_multiroot_function {
54 public:
62 struct Concept {
70 virtual int f( gsl::vector const& x, gsl::vector& f ) = 0;
74 virtual size_t size() 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 };
182 // /**
183 // * Used internally to point to function objects.
184 // */
185 // template<typename T>
186 // struct gsl_F : public base_F {
187 // public:
188 // /**
189 // * The constructor requires an object that implements Concept.
190 // * @param A function object that implements Concept.
191 // */
192 // gsl_F( T& t ) : t( t ){}
193 // public:
194 // /**
195 // * A static function that gsl::function_f can use.
196 // * @param x The arguments of the functions.
197 // * @param params Always a pointer to an object of type gsl_F.
198 // * @param f The values of the functions.
199 // * @return The function result.
200 // */
201 // static int fn( gsl_vector const* x, void* params, gsl::vector* f ){
202 // return reinterpret_cast<F<T>*>( params )->t.f( x, f ); }
203 // private:
204 // /**
205 // * Reference to function object from which this was constructed.
206 // */
207 // T& t;
208 // };
209 // /**
210 // * Subclass that allows us to use arbitrary functions.
211 // */
212 // class gsl_Fn : public base_F {
213 // public:
214 // /**
215 // * The constructor requires a function.
216 // * @param f A function.
217 // * @param n The number of functions and arguments.
218 // */
219 // gsl_Fn( int (*const f)(gsl_vector const*,gsl_vector*), size_t n ) : f( f ), n( n ){}
220 // /**
221 // * @return A function for gsl_multiroot_function.
222 // */
223 // function_t function(){ return &fn; }
224 // private:
225 // /**
226 // * The original function.
227 // */
228 // int (*const f)(gsl_vector const*,gsl_vector*);
229 // public:
230 // /**
231 // * The number of functions and arguments.
232 // */
233 // size_t const n;
234 // /**
235 // * A static function that gsl::function_scl can use.
236 // * @param x The function argument.
237 // * @param params Always a pointer to an object of type gsl_Fn
238 // * @return The function result.
239 // */
240 // static int fn( gsl_vector const* x, void* params, gsl_vector* f ){
241 // return reinterpret_cast<gsl_Fn*>( params )->f( x, f ); }
242 // };
243#endif
247 base_F* func;
251 size_t* count;
252 public:
257 func = 0;
258 f = 0;
259 n = 0;
260 params = 0;
261 count = 0; // initially nullptr will do
262 }
263 template<typename T>
264 friend void function_constructor( function&, T& );
271 explicit function( gsl_multiroot_function& v ){
272 // explicitly set function = 0 to indicate nothing to be deleted.
273 func = 0;
274 // copy
275 f = v.f;
276 n = v.n;
277 params = v.params;
278 // just plausibly we could fail to allocate count: no further action needed.
279 count = new size_t;
280 *count = 1; // initially there is just one reference to function
281 }
286 template<typename T>
287 function( T& t ){ function_constructor<T>( *this, t ); }
293 function( int (* const f)(gsl::vector const&, gsl::vector&), size_t n ){
294 func = 0;
295 count = 0;
296 func = new function::Fn( f, n );
297 this->f = Fn::fn;
298 this->n = n;
299 params = func;
300 // just plausibly we could fail to allocate count: no further action needed.
301 count = new size_t;
302 *count = 1; // initially there is just one reference to function
303 }
304
305 // Copy and move constructors
306 // copy constructor
312 function( function const& v ) : func( v.func ), count( v.count ){
313 f = v.f;
314 n = v.n;
315 params = v.params;
316 if( count != 0 ) ++*count; // function is now shared.
317 }
318 // assignment operator
324 // first, possibly delete anything pointed to by this
325 if( count == 0 or --*count == 0 ){
326 delete func;
327 delete count;
328 }
329 // Then copy
330 func = v.func;
331 f = v.f;
332 n = v.n;
333 params = v.params;
334 // count = v.count;
335 if( count != 0 ) ++*count; // function is now shared.
336 return *this;
337 }
338#ifdef __GXX_EXPERIMENTAL_CXX0X__
343 function( function&& v ) : func( v.func ), count( nullptr ){
344 std::swap( f, v.f );
345 std::swap( n, v.n );
346 std::swap( params, v.params );
347 std::swap( count, v.count );
348 v.func = nullptr;
349 }
356 std::swap( func, v.func );
357 std::swap( f, v.f );
358 std::swap( n, v.n );
359 std::swap( params, v.params );
360 std::swap( count, v.count );
361 return *this;
362 }
363#endif
368 // first, possibly delete anything pointed to by f
369 if( count == 0 or --*count == 0 ){
370 delete func;
371 delete count;
372 }
373 }
374 };
375#ifndef DOXYGEN_SKIP
383 template<typename T>
384 inline void function_constructor( function& f, T& t ){
385 f.func = 0;
386 f.count = 0;
387 // try constructing from T
388 f.func = new function::F<T>( t );
389 f.f = &function::F<T>::fn;
390 f.n = t.size();
391 f.params = f.func;
392 // just plausibly we could fail to allocate count: no further action needed.
393 f.count = new size_t;
394 *f.count = 1; // initially there is just one reference to function
395 }
401 template<>
402 inline void function_constructor( function& f, function& v ){
403 f.func = v.func; f.count = v.count; f.f = v.f; f.n = v.n;
404 f.params = v.params; if( f.count != 0 ) ++*f.count;
405 /* function is now shared. */ }
411 template<>
412 inline void function_constructor( function& f, gsl_multiroot_function& v ){
413 f.f = v.f; f.n = v.n; f.params = v.params; }
414#endif
415
421 template<typename T>
422 inline function make_function( T& t ){
423 function fn( t );
424 return fn;
425 }
426 }
427}
428
429#endif
Class that extends gsl_multiroot_function so that it can be constructed from arbitrary function objec...
function & operator=(function &&v)
Move operator.
function(function &&v)
Move constructor.
function(gsl_multiroot_function &v)
Could construct from a gsl_multiroot_function.
friend void function_constructor(function &, T &)
base_F * func
This gives something for params to point to.
~function()
The destructor unshares any shared resource.
function & operator=(function const &v)
The assignment operator.
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(T &t)
Construct from an object that implements gsl::multiroot::function::Concept.
function(function const &v)
The copy constructor.
size_t * count
The shared reference count: used for copying this.
function()
The default constructor is only really useful for assigning to.
This class handles vector objects as shared handles.
Definition: vector.hpp:74
void function_constructor(function &, T &)
function make_function(T &t)
Make a gsl::multiroot::function from a function object that implements gsl::multiroot::function::Conc...
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 f(gsl::vector const &x, gsl::vector &f)=0
The function.
virtual size_t size() const =0
This function should return the number of elements of x and f in f().