Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / numeric / odeint / iterator / impl / n_step_iterator_impl.hpp
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          */
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          */
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
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:
113         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          */
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          */
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
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:
220         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