1 /* 2 [auto_generated] 3 boost/numeric/odeint/iterator/detail/n_step_iterator_impl.hpp 4 5 [begin_description] 6 tba. 7 [end_description] 8 9 Copyright 2009-2013 Karsten Ahnert 10 Copyright 2009-2013 Mario Mulansky 11 12 Distributed under the Boost Software License, Version 1.0. 13 (See accompanying file LICENSE_1_0.txt or 14 copy at http://www.boost.org/LICENSE_1_0.txt) 15 */ 16 17 18 #ifndef BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_N_STEP_ITERATOR_IMPL_HPP_DEFINED 19 #define BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_N_STEP_ITERATOR_IMPL_HPP_DEFINED 20 21 #include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp> 22 #include <boost/numeric/odeint/util/unit_helper.hpp> 23 24 25 26 namespace boost { 27 namespace numeric { 28 namespace odeint { 29 30 31 template< class Iterator , class Stepper , class System , class State , typename Tag , class StepperTag > 32 class n_step_iterator_impl; 33 34 35 /* 36 * Specilization for steppers and error steppers 37 */ 38 /** 39 * \brief ODE Iterator performing exactly n steps with constant step size. The value type of this iterator is the state type of the stepper. 40 * 41 * Implements an ODE iterator solving the ODE with constant step size. Uses steppers fulfilling the Stepper concept. 42 * n_step_iterator is a model of single-pass iterator. 43 * 44 * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time. 45 * 46 * \tparam Stepper The stepper type which should be used during the iteration. 47 * \tparam System The type of the system function (ODE) which should be solved. 48 */ 49 template< class Iterator , class Stepper , class System , class State , typename Tag > 50 class n_step_iterator_impl< Iterator , Stepper , System , State , Tag , stepper_tag > 51 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > 52 { 53 private: 54 55 typedef Stepper stepper_type; 56 typedef System system_type; 57 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type; 58 typedef State state_type; 59 typedef typename traits::time_type< stepper_type >::type time_type; 60 typedef typename traits::value_type< stepper_type >::type ode_value_type; 61 #ifndef DOXYGEN_SKIP 62 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type; 63 #endif 64 65 public: 66 67 /** 68 * \brief Constructs a n_step_iterator. This constructor should be used to construct the begin iterator. 69 * 70 * \param stepper The stepper to use during the iteration. 71 * \param sys The system function (ODE) to solve. 72 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration. 73 * \param t The initial time. 74 * \param dt The initial time step. 75 * \param num_of_steps the number of steps to be executed. 76 */ n_step_iterator_impl(stepper_type stepper,system_type sys,state_type & s,time_type t,time_type dt,size_t num_of_steps)77 n_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s , 78 time_type t , time_type dt , size_t num_of_steps ) 79 : base_type( stepper , sys , t , dt ) , m_t_start( t ) , m_state( &s ) , 80 m_steps(num_of_steps) , m_step( 0 ) 81 { } 82 83 /** 84 * \brief Constructs a const_step_iterator. This constructor should be used to construct the end iterator. 85 * 86 * \param stepper The stepper to use during the iteration. 87 * \param sys The system function (ODE) to solve. 88 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration. 89 */ n_step_iterator_impl(stepper_type stepper,system_type sys,state_type & s)90 n_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s ) 91 : base_type( stepper , sys ) , m_state( &s ) { } 92 93 protected: 94 95 friend class boost::iterator_core_access; 96 increment()97 void increment() 98 { 99 if( this->m_step < this->m_steps ) 100 { 101 unwrapped_stepper_type &stepper = this->m_stepper; 102 stepper.do_step( this->m_system , *this->m_state , this->m_t , this->m_dt ); 103 // use integer to compute current time to reduce roundoff errors 104 this->m_step++; 105 this->m_t = this->m_t_start + static_cast< typename unit_value_type<time_type>::type >(this->m_step)*this->m_dt; 106 } else { 107 this->m_at_end = true; 108 109 } 110 } 111 112 public: get_state() const113 const state_type& get_state() const 114 { 115 return *m_state; 116 } 117 118 119 private: 120 time_type m_t_start; 121 time_type m_t_end; 122 state_type* m_state; 123 size_t m_steps; 124 size_t m_step; 125 126 }; 127 128 129 130 131 /* 132 * Specilization for dense output stepper 133 */ 134 /** 135 * \brief ODE Iterator with step-size control and dense output. 136 * 137 * Implements an ODE iterator solving the ODE with constant steps. Uses dense-output steppers. 138 * n_step_iterator is a model of single-pass iterator. 139 * 140 * The value type of this iterator is the state type of the stepper. Hence one can only access the state and not the current time. 141 * 142 * \tparam Stepper The stepper type which should be used during the iteration. 143 * \tparam System The type of the system function (ODE) which should be solved. 144 */ 145 template< class Iterator , class Stepper , class System , class State , typename Tag > 146 class n_step_iterator_impl< Iterator , Stepper , System , State , Tag , dense_output_stepper_tag > 147 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > 148 { 149 private: 150 151 typedef Stepper stepper_type; 152 typedef System system_type; 153 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type; 154 typedef State state_type; 155 typedef typename traits::time_type< stepper_type >::type time_type; 156 typedef typename traits::value_type< stepper_type >::type ode_value_type; 157 #ifndef DOXYGEN_SKIP 158 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type; 159 #endif 160 161 public: 162 163 /** 164 * \brief Constructs a const_step_iterator. This constructor should be used to construct the begin iterator. 165 * 166 * \param stepper The stepper to use during the iteration. 167 * \param sys The system function (ODE) to solve. 168 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration. 169 * \param t The initial time. 170 * \param dt The initial time step. 171 * \param num_of_steps the number of steps to be executed. 172 */ n_step_iterator_impl(stepper_type stepper,system_type sys,state_type & s,time_type t,time_type dt,size_t num_of_steps)173 n_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s , 174 time_type t , time_type dt , size_t num_of_steps ) 175 : base_type( stepper , sys , t , dt ) , m_t_start( t ) , m_state( &s ) , 176 m_steps( num_of_steps ) , m_step( 0 ) 177 { 178 unwrapped_stepper_type &st = this->m_stepper; 179 st.initialize( * ( this->m_state ) , this->m_t , this->m_dt ); 180 } 181 182 /** 183 * \brief Constructs a const_step_iterator. This constructor should be used to construct the end iterator. 184 * 185 * \param stepper The stepper to use during the iteration. 186 * \param sys The system function (ODE) to solve. 187 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration. 188 */ n_step_iterator_impl(stepper_type stepper,system_type sys,state_type & s)189 n_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s ) 190 : base_type( stepper , sys ) , m_state( &s ) 191 { 192 } 193 194 195 196 protected: 197 198 friend class boost::iterator_core_access; 199 increment(void)200 void increment( void ) 201 { 202 if( this->m_step < this->m_steps ) 203 { 204 unwrapped_stepper_type &stepper = this->m_stepper; 205 // use integer to compute current time to reduce roundoff errors 206 this->m_step++; 207 this->m_t = this->m_t_start + static_cast< typename unit_value_type<time_type>::type >(this->m_step)*this->m_dt; 208 while( detail::less_with_sign( stepper.current_time() , this->m_t , 209 stepper.current_time_step() ) ) 210 { 211 stepper.do_step( this->m_system ); 212 } 213 stepper.calc_state( this->m_t , *( this->m_state ) ); 214 } else { 215 this->m_at_end = true; 216 } 217 } 218 219 public: get_state() const220 const state_type& get_state() const 221 { 222 return *m_state; 223 } 224 225 226 private: 227 time_type m_t_start; 228 time_type m_t_end; 229 state_type* m_state; 230 size_t m_steps; 231 size_t m_step; 232 }; 233 234 } // namespace odeint 235 } // namespace numeric 236 } // namespace boost 237 238 239 #endif // BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_N_STEP_ITERATOR_IMPL_HPP_DEFINED 240