20#ifndef CCGSL_ODEIV2_SYSTEM_HPP
21#define CCGSL_ODEIV2_SYSTEM_HPP
26#include<gsl/gsl_odeiv2.h>
66 class system :
public gsl_odeiv2_system {
85 int function(
double const t, T
const& y, T& dydt );
95 template<
typename T,
typename U>
96 int jacobian(
double const t, T
const&, U& dfdy, T& dfdt ){
102 virtual size_t size()
const = 0;
113 typedef int (*function_t)(
double const,
double const*,
double*,
void*);
117 typedef int (*jacobian_t)(
double const,
double const*,
double*,
double*,
void*);
125 virtual bool has_jacobian()
const = 0;
131 struct Function :
public base_F {
137 Function( T& t ) : t( t ){
138 size_t const size = t.size();
144 yv.wrap_gsl_vector_without_ownership( &vy );
150 dydtv.wrap_gsl_vector_without_ownership( &vdydt );
156 dfdyv.wrap_gsl_vector_without_ownership( &vdfdy );
163 dfdym.wrap_gsl_matrix_without_ownership( &mdfdy );
169 dfdtv.wrap_gsl_vector_without_ownership( &vdfdt );
180 static int function(
double const t,
double const* y,
double* dydt,
void* params ){
181 Function<T>* this_t =
reinterpret_cast<Function<T>*
>( params );
182 return this_t->function_detail( t, y, dydt );
192 static int jacobian(
double const t,
double const* y,
double* dfdy,
double* dfdt,
194 Function<T>* this_t =
reinterpret_cast<Function<T>*
>( params );
195 return this_t->jacobian_detail( t, y, dfdy, dfdt );
201 template<
bool N>
struct bool_to_type {};
207 template<
typename W,
int (V::*)(
double const,gsl::vector const&,gsl::vector&)>
struct S{};
208 template<
typename W>
static char test( S<W,&W::function>* );
209 template<
typename W,
int (V::*)(
double const,gsl::vector&,gsl::vector&)>
struct Su{};
210 template<
typename W>
static char test( Su<W,&W::function>* );
211 template<
typename W>
static int test( ... );
212 static const bool vector =
sizeof(test<V>( 0 )) ==
sizeof(
char);
217 enum { ptr_ptr = 0, ptr_vec = 1, ptr_mat = 2, vec_ptr = 4, vec_vec = 5, vec_mat = 6,
224 template<
typename W,
int (V::*)(
double const,
double const*,
double*,
double const*)>
226 template<
typename W>
static char test_ptr_ptr( PtrPtr<W,&W::jacobian>* );
227 template<
typename W,
int (V::*)(
double const,
double*,
double*,
double*)>
229 template<
typename W>
static char test_ptr_ptr( UPtrPtr<W,&W::jacobian>* );
230 template<
typename W>
static int test_ptr_ptr( ... );
231 template<
typename W,
int (V::*)(
double const,
double const*,gsl::vector&,
double*)>
233 template<
typename W>
static char test_ptr_vec( PtrVec<W,&W::jacobian>* );
234 template<
typename W,
int (V::*)(
double const,
double*,gsl::vector&,
double*)>
236 template<
typename W>
static char test_ptr_vec( UPtrVec<W,&W::jacobian>* );
237 template<
typename W>
static int test_ptr_vec( ... );
238 template<
typename W,
int (V::*)(
double const,
double const*,gsl::matrix&,
double*)>
240 template<
typename W>
static char test_ptr_mat( PtrMat<W,&W::jacobian>* );
241 template<
typename W,
int (V::*)(
double const,
double*,gsl::matrix&,
double*)>
243 template<
typename W>
static char test_ptr_mat( UPtrMat<W,&W::jacobian>* );
244 template<
typename W>
static int test_ptr_mat( ... );
245 template<
typename W,
int (V::*)(
double const,gsl::vector const&,
double*,gsl::vector&)>
247 template<
typename W>
static char test_vec_ptr( VecPtr<W,&W::jacobian>* );
248 template<
typename W,
int (V::*)(
double const,gsl::vector&,
double*,gsl::vector&)>
250 template<
typename W>
static char test_vec_ptr( UVecPtr<W,&W::jacobian>* );
251 template<
typename W>
static int test_vec_ptr( ... );
252 template<
typename W,
int (V::*)(
double const,gsl::vector const&,gsl::vector&,gsl::vector&)>
254 template<
typename W>
static char test_vec_vec( VecVec<W,&W::jacobian>* );
255 template<
typename W,
int (V::*)(
double const,gsl::vector&,gsl::vector&,gsl::vector&)>
257 template<
typename W>
static char test_vec_vec( UVecVec<W,&W::jacobian>* );
258 template<
typename W>
static int test_vec_vec( ... );
259 template<
typename W,
int (V::*)(
double const,gsl::vector const&,gsl::matrix,gsl::vector&)>
261 template<
typename W>
static char test_vec_mat( VecMat<W,&W::jacobian>* );
262 template<
typename W,
int (V::*)(
double const,gsl::vector&,gsl::matrix,gsl::vector&)>
264 template<
typename W>
static char test_vec_mat( UVecMat<W,&W::jacobian>* );
265 template<
typename W>
static int test_vec_mat( ... );
266 static const int type
267 =
sizeof(test_ptr_ptr<V>( 0 )) ==
sizeof(
char) ? ptr_ptr :
268 sizeof(test_ptr_vec<V>( 0 )) ==
sizeof(
char) ? ptr_vec :
269 sizeof(test_ptr_mat<V>( 0 )) ==
sizeof(
char) ? ptr_mat :
270 sizeof(test_vec_ptr<V>( 0 )) ==
sizeof(
char) ? vec_ptr :
271 sizeof(test_vec_vec<V>( 0 )) ==
sizeof(
char) ? vec_vec :
272 sizeof(test_vec_mat<V>( 0 )) ==
sizeof(
char) ? vec_mat :
282 template<
int N>
struct int_to_type {};
287 int function(
double const t,
double const* y,
double* dydt, U& u, bool_to_type<true> ){
288 vy.data =
const_cast<double*
>( y );
290 return u.function( t, yv, dydtv );
296 int function(
double const t,
double const* y,
double* dydt, U& u, bool_to_type<false> ){
297 return u.function( t, y, dydt );
302 int function_detail(
double const t,
double const* y,
double* dydt ){
303 return function( t, y, dydt, this->t, bool_to_type<Fvector<T>::vector>() );
309 int jacobian(
double const t,
double const* y,
double* dfdy,
double* dfdt,
310 U& u, int_to_type<undefined> ){
317 int jacobian(
double const t,
double const* y,
double* dfdy,
double* dfdt,
318 U& u, int_to_type<ptr_ptr> ){
319 return u.jacobian( t, y, dfdy, dfdt );
325 int jacobian(
double const t,
double const* y,
gsl::vector& dfdy,
double* dfdt,
326 U& u, int_to_type<ptr_vec> ){
328 return u.jacobian( t, y, dfdyv, dfdt );
334 int jacobian(
double const t,
double const* y,
gsl::vector& dfdy,
double* dfdt,
335 U& u, int_to_type<ptr_mat> ){
337 return u.jacobian( t, y, dfdym, dfdt );
344 U& u, int_to_type<vec_ptr> ){
347 return u.jacobian( t, yv, dfdy, dfdtv );
354 U& u, int_to_type<vec_vec> ){
358 return u.jacobian( t, yv, dfdyv, dfdtv );
366 U& u, int_to_type<vec_mat> ){
370 return u.jacobian( t, yv, dfdym, dfdtv );
375 int jacobian_detail(
double const t,
double const* y,
double* dfdy,
double* dfdt ){
455 function = v.function;
456 jacobian = v.jacobian;
457 dimension = v.dimension;
468 system( T& t ){ system_constructor<T>( *
this, t ); }
479 function = v.function;
480 jacobian = v.jacobian;
481 dimension = v.dimension;
498 function = v.function;
499 jacobian = v.jacobian;
500 dimension = v.dimension;
506#ifdef __GXX_EXPERIMENTAL_CXX0X__
512 std::swap( function, v.function );
513 std::swap( jacobian, v.jacobian );
514 std::swap( dimension, v.dimension );
515 std::swap( params, v.params );
516 std::swap(
count, v.count );
517 v.function =
nullptr;
526 std::swap( function, v.function );
527 std::swap( jacobian, v.jacobian );
528 std::swap( dimension, v.dimension );
529 std::swap( params, v.params );
530 std::swap(
count, v.count );
556 sys.f =
new system::Function<T>( t );
557 sys.function = &system::Function<T>::function;
558 if( sys.f->has_jacobian() )
561 sys.jacobian = &system::Function<T>::jacobian;
562 sys.dimension = t.size();
565 sys.count =
new size_t;
573 sys.f = v.f; sys.function = v.function; sys.jacobian = v.jacobian;
574 sys.dimension = v.dimension; sys.params = v.params;
575 if( sys.count != 0 ) ++*sys.count;
582 sys.function = v.function; sys.jacobian = v.jacobian;
583 sys.dimension = v.dimension; sys.params = v.params; }
This class handles matrix objects as shared handles.
Class that extends gsl_odeiv2_system so that it can be constructed from function objects.
system(T &t)
Construct from an object that implements gsl::odeiv2::system::Concept.
system(system const &v)
The copy constructor.
friend void system_constructor(system &sys, T &t)
system()
The default constructor is only really useful for assigning to.
system & operator=(system &&v)
Move operator.
base_F * f
This gives something for params to point to.
system(gsl_odeiv2_system &v)
Could construct from a gsl_odeiv2_system object.
system(system &&v)
Move constructor.
system & operator=(system const &v)
The assignment operator.
size_t * count
The shared reference count: used for copying this.
~system()
The destructor unshares any shared resource.
This class handles vector objects as shared handles.
double * data()
Give access to the data block.
size_t size(series const &cs)
C++ version of gsl_cheb_size().
int test(double const xtol, double const gtol, double const ftol, int *info, workspace const &w)
C++ version of gsl_multifit_nlinear_test().
gsl_multilarge_linear_type type
Typedef for shorthand.
void system_constructor(system &sys, T &t)
system make_system(T &t)
Make a gsl::odeiv2::system from a function object that implements gsl::odeiv2::system::concept.
The gsl package creates an interface to the GNU Scientific Library for C++.
This is an empty base class.
int function(double const t, T const &y, T &dydt)
The function that stores dydt given y and t.
virtual size_t size() const =0
The dimension of the function arguments.
int jacobian(double const t, T const &, U &dfdy, T &dfdt)
As function but also store Jacobian in dfdy.