3 boost/numeric/odeint/iterator/detail/const_step_iterator_impl.hpp
9 Copyright 2013 Karsten Ahnert
10 Copyright 2013 Mario Mulansky
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)
18 #ifndef BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_CONST_STEP_ITERATOR_IMPL_HPP_DEFINED
19 #define BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_CONST_STEP_ITERATOR_IMPL_HPP_DEFINED
21 #include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>
22 #include <boost/numeric/odeint/util/unit_helper.hpp>
31 template< class Iterator , class Stepper , class System , class State , typename Tag , class StepperTag >
32 class const_step_iterator_impl;
36 * Specilization for steppers and error steppers
38 template< class Iterator , class Stepper , class System , class State , typename Tag >
39 class const_step_iterator_impl< Iterator , Stepper , System , State , Tag , stepper_tag >
40 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
44 typedef Stepper stepper_type;
45 typedef System system_type;
46 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
47 typedef State state_type;
48 typedef typename traits::time_type< stepper_type >::type time_type;
49 typedef typename traits::value_type< stepper_type >::type ode_value_type;
51 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
57 * \brief Constructs a const_step_iterator. This constructor should be used to construct the begin iterator.
59 * \param stepper The stepper to use during the iteration.
60 * \param sys The system function (ODE) to solve.
61 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration.
62 * \param t The initial time.
63 * \param t_end The end time, at which the iteration should stop.
64 * \param dt The initial time step.
66 const_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s , time_type t , time_type t_end , time_type dt )
67 : base_type( stepper , sys , t , dt ) , m_t_start( t ) , m_t_end( t_end ) , m_state( &s ) , m_step( 0 )
69 if( detail::less_with_sign( this->m_t_end , this->m_t , this->m_dt ) )
70 this->m_at_end = true;
74 * \brief Constructs a const_step_iterator. This constructor should be used to construct the end iterator.
76 * \param stepper The stepper to use during the iteration.
77 * \param sys The system function (ODE) to solve.
78 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration.
80 const_step_iterator_impl( stepper_type stepper , system_type sys , state_type& /* s */ )
81 : base_type( stepper , sys ) { }
85 friend class boost::iterator_core_access;
89 if( detail::less_eq_with_sign( static_cast<time_type>(this->m_t+this->m_dt) ,
90 this->m_t_end , this->m_dt ) )
92 unwrapped_stepper_type &stepper = this->m_stepper;
93 stepper.do_step( this->m_system , *this->m_state , this->m_t , this->m_dt );
94 // use integer to compute current time to reduce roundoff errors
96 this->m_t = this->m_t_start + static_cast< typename unit_value_type<time_type>::type >(this->m_step)*this->m_dt;
98 this->m_at_end = true;
103 const state_type& get_state() const
119 * Specilization for dense output stepper
122 * \brief ODE Iterator with constant step size. The value type of this iterator is the state type of the stepper.
124 * Implements an ODE iterator solving the ODE with constant steps. Uses dense-output steppers.
125 * const_step_iterator is a model of single-pass iterator.
127 * 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.
129 * \tparam Stepper The stepper type which should be used during the iteration.
130 * \tparam System The type of the system function (ODE) which should be solved.
132 template< class Iterator , class Stepper , class System , class State , typename Tag >
133 class const_step_iterator_impl< Iterator , Stepper , System , State , Tag , dense_output_stepper_tag >
134 : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
138 typedef Stepper stepper_type;
139 typedef System system_type;
140 typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
141 typedef State state_type;
142 typedef typename traits::time_type< stepper_type >::type time_type;
143 typedef typename traits::value_type< stepper_type >::type ode_value_type;
145 typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
151 * \brief Constructs a const_step_iterator. This constructor should be used to construct the begin iterator.
153 * \param stepper The stepper to use during the iteration.
154 * \param sys The system function (ODE) to solve.
155 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration.
156 * \param t The initial time.
157 * \param t_end The end time, at which the iteration should stop.
158 * \param dt The initial time step.
160 const_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s , time_type t , time_type t_end , time_type dt )
161 : base_type( stepper , sys , t , dt ) , m_t_start( t ) , m_t_end( t_end ) , m_state( &s ) , m_step( 0 )
163 if( detail::less_eq_with_sign( this->m_t , this->m_t_end , this->m_dt ) )
165 unwrapped_stepper_type &st = this->m_stepper;
166 st.initialize( * ( this->m_state ) , this->m_t , this->m_dt );
168 this->m_at_end = true;
173 * \brief Constructs a const_step_iterator. This constructor should be used to construct the end iterator.
175 * \param stepper The stepper to use during the iteration.
176 * \param sys The system function (ODE) to solve.
177 * \param s The initial state. const_step_iterator stores a reference of s and changes its value during the iteration.
179 const_step_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
180 : base_type( stepper , sys ) , m_state( &s )
188 friend class boost::iterator_core_access;
190 void increment( void )
192 if( detail::less_eq_with_sign( static_cast<time_type>(this->m_t+this->m_dt) ,
193 this->m_t_end , this->m_dt ) )
195 unwrapped_stepper_type &stepper = this->m_stepper;
196 // use integer to compute current time to reduce roundoff errors
198 this->m_t = this->m_t_start + static_cast< typename unit_value_type<time_type>::type >(this->m_step)*this->m_dt;
199 while( detail::less_with_sign( stepper.current_time() , this->m_t ,
200 stepper.current_time_step() ) )
202 stepper.do_step( this->m_system );
204 stepper.calc_state( this->m_t , *( this->m_state ) );
206 this->m_at_end = true;
211 const state_type& get_state() const
223 } // namespace odeint
224 } // namespace numeric
228 #endif // BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_CONST_STEP_ITERATOR_IMPL_HPP_DEFINED