File indexing completed on 2025-07-11 08:18:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef BOOST_NUMERIC_ODEINT_EXTERNAL_GSL_GSL_WRAPPER_HPP_INCLUDED
0019 #define BOOST_NUMERIC_ODEINT_EXTERNAL_GSL_GSL_WRAPPER_HPP_INCLUDED
0020
0021 #include <new>
0022
0023 #include <gsl/gsl_vector.h>
0024
0025 #include <boost/range.hpp>
0026 #include <boost/iterator/iterator_facade.hpp>
0027
0028
0029 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0030 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0031 #include <boost/numeric/odeint/util/copy.hpp>
0032
0033 class const_gsl_vector_iterator;
0034
0035
0036
0037
0038 class gsl_vector_iterator : public boost::iterator_facade< gsl_vector_iterator , double , boost::random_access_traversal_tag >
0039 {
0040 public :
0041
0042 gsl_vector_iterator( void ): m_p(0) , m_stride( 0 ) { }
0043 explicit gsl_vector_iterator( gsl_vector *p ) : m_p( p->data ) , m_stride( p->stride ) { }
0044 friend gsl_vector_iterator end_iterator( gsl_vector * );
0045
0046 private :
0047
0048 friend class boost::iterator_core_access;
0049 friend class const_gsl_vector_iterator;
0050
0051 void increment( void ) { m_p += m_stride; }
0052 void decrement( void ) { m_p -= m_stride; }
0053 void advance( ptrdiff_t n ) { m_p += n*m_stride; }
0054 bool equal( const gsl_vector_iterator &other ) const { return this->m_p == other.m_p; }
0055 bool equal( const const_gsl_vector_iterator &other ) const;
0056 double& dereference( void ) const { return *m_p; }
0057
0058 double *m_p;
0059 size_t m_stride;
0060 };
0061
0062
0063
0064
0065
0066
0067 class const_gsl_vector_iterator : public boost::iterator_facade< const_gsl_vector_iterator , const double , boost::random_access_traversal_tag >
0068 {
0069 public :
0070
0071 const_gsl_vector_iterator( void ): m_p(0) , m_stride( 0 ) { }
0072 explicit const_gsl_vector_iterator( const gsl_vector *p ) : m_p( p->data ) , m_stride( p->stride ) { }
0073 const_gsl_vector_iterator( const gsl_vector_iterator &p ) : m_p( p.m_p ) , m_stride( p.m_stride ) { }
0074
0075 private :
0076
0077 friend class boost::iterator_core_access;
0078 friend class gsl_vector_iterator;
0079 friend const_gsl_vector_iterator end_iterator( const gsl_vector * );
0080
0081 void increment( void ) { m_p += m_stride; }
0082 void decrement( void ) { m_p -= m_stride; }
0083 void advance( ptrdiff_t n ) { m_p += n*m_stride; }
0084 bool equal( const const_gsl_vector_iterator &other ) const { return this->m_p == other.m_p; }
0085 bool equal( const gsl_vector_iterator &other ) const { return this->m_p == other.m_p; }
0086 const double& dereference( void ) const { return *m_p; }
0087
0088 const double *m_p;
0089 size_t m_stride;
0090 };
0091
0092
0093 bool gsl_vector_iterator::equal( const const_gsl_vector_iterator &other ) const { return this->m_p == other.m_p; }
0094
0095
0096 gsl_vector_iterator end_iterator( gsl_vector *x )
0097 {
0098 gsl_vector_iterator iter( x );
0099 iter.m_p += iter.m_stride * x->size;
0100 return iter;
0101 }
0102
0103 const_gsl_vector_iterator end_iterator( const gsl_vector *x )
0104 {
0105 const_gsl_vector_iterator iter( x );
0106 iter.m_p += iter.m_stride * x->size;
0107 return iter;
0108 }
0109
0110
0111
0112
0113 namespace boost
0114 {
0115 template<>
0116 struct range_mutable_iterator< gsl_vector* >
0117 {
0118 typedef gsl_vector_iterator type;
0119 };
0120
0121 template<>
0122 struct range_const_iterator< gsl_vector* >
0123 {
0124 typedef const_gsl_vector_iterator type;
0125 };
0126 }
0127
0128
0129
0130
0131
0132 inline gsl_vector_iterator range_begin( gsl_vector *x )
0133 {
0134 return gsl_vector_iterator( x );
0135 }
0136
0137
0138 inline const_gsl_vector_iterator range_begin( const gsl_vector *x )
0139 {
0140 return const_gsl_vector_iterator( x );
0141 }
0142
0143
0144 inline gsl_vector_iterator range_end( gsl_vector *x )
0145 {
0146 return end_iterator( x );
0147 }
0148
0149
0150 inline const_gsl_vector_iterator range_end( const gsl_vector *x )
0151 {
0152 return end_iterator( x );
0153 }
0154
0155
0156
0157
0158
0159
0160
0161 namespace boost {
0162 namespace numeric {
0163 namespace odeint {
0164
0165
0166 template<>
0167 struct is_resizeable< gsl_vector* >
0168 {
0169
0170 typedef std::integral_constant<bool, true> type;
0171 const static bool value = type::value;
0172 };
0173
0174 template <>
0175 struct same_size_impl< gsl_vector* , gsl_vector* >
0176 {
0177 static bool same_size( const gsl_vector* x , const gsl_vector* y )
0178 {
0179 return x->size == y->size;
0180 }
0181 };
0182
0183 template <>
0184 struct resize_impl< gsl_vector* , gsl_vector* >
0185 {
0186 static void resize( gsl_vector* &x , const gsl_vector* y )
0187 {
0188 gsl_vector_free( x );
0189 x = gsl_vector_alloc( y->size );
0190 }
0191 };
0192
0193 template<>
0194 struct state_wrapper< gsl_vector* >
0195 {
0196 typedef double value_type;
0197 typedef gsl_vector* state_type;
0198 typedef state_wrapper< gsl_vector* > state_wrapper_type;
0199
0200 state_type m_v;
0201
0202 state_wrapper( )
0203 {
0204 m_v = gsl_vector_alloc( 1 );
0205 }
0206
0207 state_wrapper( const state_wrapper_type &x )
0208 {
0209 resize( m_v , x.m_v );
0210 gsl_vector_memcpy( m_v , x.m_v );
0211 }
0212
0213
0214 ~state_wrapper()
0215 {
0216 gsl_vector_free( m_v );
0217 }
0218
0219 };
0220
0221 }
0222 }
0223 }
0224
0225
0226
0227
0228 #endif