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