Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/numeric/odeint/iterator/impl/times_iterator_impl.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  [auto_generated]
0003   boost/numeric/odeint/iterator/detail/times_iterator_impl.hpp
0004 
0005   [begin_description]
0006   tba.
0007   [end_description]
0008 
0009   Copyright 2009-2013 Karsten Ahnert
0010   Copyright 2009-2013 Mario Mulansky
0011 
0012   Distributed under the Boost Software License, Version 1.0.
0013   (See accompanying file LICENSE_1_0.txt or
0014   copy at http://www.boost.org/LICENSE_1_0.txt)
0015 */
0016 
0017 
0018 #ifndef BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED
0019 #define BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED
0020 
0021 #include <boost/throw_exception.hpp>
0022 
0023 #include <boost/numeric/odeint/util/unit_helper.hpp>
0024 #include <boost/numeric/odeint/util/copy.hpp>
0025 #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
0026 #include <boost/numeric/odeint/iterator/detail/ode_iterator_base.hpp>
0027 
0028 
0029 namespace boost {
0030 namespace numeric {
0031 namespace odeint {
0032 
0033 
0034     template< class Iterator , class Stepper , class System , class State , class TimeIterator ,
0035               typename Tag , typename StepperTag >
0036     class times_iterator_impl;
0037 
0038     /*
0039      * Specilization for basic steppers
0040      */
0041     /**
0042      * \brief ODE Iterator with constant step size.
0043      *
0044      * Implements an ODE iterator with observer calls at predefined times.
0045      * Uses controlled steppers. times_iterator is a model of single-pass iterator.
0046      *
0047      * 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.
0048      *
0049      * \tparam Stepper The stepper type which should be used during the iteration.
0050      * \tparam System The type of the system function (ODE) which should be solved.
0051      */
0052     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0053     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , stepper_tag >
0054         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0055     {
0056     private:
0057 
0058 
0059         typedef Stepper stepper_type;
0060         typedef System system_type;
0061         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0062         typedef State state_type;
0063         typedef TimeIterator time_iterator_type;
0064         typedef typename traits::time_type< stepper_type >::type time_type;
0065         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0066         #ifndef DOXYGEN_SKIP
0067         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0068         #endif
0069 
0070     public:
0071 
0072         /**
0073          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0074          *
0075          * \param stepper The stepper to use during the iteration.
0076          * \param sys The system function (ODE) to solve.
0077          * \param s The initial state. adaptive_iterator stores a reference of s and changes its value during the iteration.
0078          * \param t_start Iterator to the begin of a sequence of time values.
0079          * \param t_end Iterator to the begin of a sequence of time values.
0080          * \param dt The (initial) time step.
0081          */
0082         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0083                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0084             : base_type( stepper , sys , *t_start , dt ) ,
0085               m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0086         {
0087             if( t_start == t_end )
0088                 this->m_at_end = true;
0089         }
0090 
0091         /**
0092          * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
0093          *
0094          * \param stepper The stepper to use during the iteration.
0095          * \param sys The system function (ODE) to solve.
0096          * \param s The initial state. adaptive_iterator store a reference of s and changes its value during the iteration.
0097          */
0098         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0099             : base_type( stepper , sys ) , m_state( &s ) { }
0100 
0101     protected:
0102 
0103         friend class boost::iterator_core_access;
0104 
0105         void increment()
0106         {
0107             unwrapped_stepper_type &stepper = this->m_stepper;
0108             if( ++m_t_start != m_t_end )
0109             {
0110                 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0111                 {
0112                     const time_type current_dt = detail::min_abs( this->m_dt , static_cast<time_type>(*m_t_start) - this->m_t );
0113                     stepper.do_step( this->m_system , *( this->m_state ) , this->m_t , current_dt );
0114                     this->m_t += current_dt;
0115                 }
0116 
0117             } else {
0118                 this->m_at_end = true;
0119             }
0120          }
0121 
0122     public:
0123         const state_type& get_state() const
0124         {
0125             return *m_state;
0126         }
0127 
0128     private:
0129         time_iterator_type m_t_start;
0130         time_iterator_type m_t_end;
0131         state_type* m_state;
0132     };
0133 
0134 
0135 
0136     /*
0137      * Specilization for controlled steppers
0138      */
0139     /**
0140      * \brief ODE Iterator with adaptive step size control. The value type of this iterator is the state type of the stepper.
0141      *
0142      * Implements an ODE iterator with observer calls at predefined times.
0143      * Uses controlled steppers. times_iterator is a model of single-pass iterator.
0144      *
0145      * 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.
0146      *
0147      * \tparam Stepper The stepper type which should be used during the iteration.
0148      * \tparam System The type of the system function (ODE) which should be solved.
0149      */
0150     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0151     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , controlled_stepper_tag >
0152         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0153     {
0154     private:
0155 
0156 
0157         typedef Stepper stepper_type;
0158         typedef System system_type;
0159         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0160         typedef State state_type;
0161         typedef TimeIterator time_iterator_type;
0162         typedef typename traits::time_type< stepper_type >::type time_type;
0163         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0164         #ifndef DOXYGEN_SKIP
0165         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0166         #endif
0167 
0168     public:
0169 
0170         /**
0171          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0172          *
0173          * \param stepper The stepper to use during the iteration.
0174          * \param sys The system function (ODE) to solve.
0175          * \param s The initial state. adaptive_iterator stores a reference of s and changes its value during the iteration.
0176          * \param t_start Iterator to the begin of a sequence of time values.
0177          * \param t_end Iterator to the begin of a sequence of time values.
0178          * \param dt The (initial) time step.
0179          */
0180         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0181                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0182             : base_type( stepper , sys , *t_start , dt ) ,
0183               m_t_start( t_start ) , m_t_end( t_end ) , m_state( &s )
0184         {
0185             if( t_start == t_end )
0186                 this->m_at_end = true;
0187         }
0188 
0189         /**
0190          * \brief Constructs an adaptive_iterator. This constructor should be used to construct the end iterator.
0191          *
0192          * \param stepper The stepper to use during the iteration.
0193          * \param sys The system function (ODE) to solve.
0194          * \param s The initial state. adaptive_iterator store a reference of s and changes its value during the iteration.
0195          */
0196         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0197             : base_type( stepper , sys ) , m_state( &s ) { }
0198 
0199     protected:
0200 
0201         friend class boost::iterator_core_access;
0202 
0203         void increment()
0204         {
0205             if( ++m_t_start != m_t_end )
0206             {
0207                 while( detail::less_with_sign( this->m_t , static_cast<time_type>(*m_t_start) , this->m_dt ) )
0208                 {
0209                     if( detail::less_with_sign( static_cast<time_type>(*m_t_start) - this->m_t , this->m_dt , this->m_dt ) )
0210                     {
0211                         // we want to end exactly at the time point
0212                         time_type current_dt = static_cast<time_type>(*m_t_start) - this->m_t;
0213                         step_loop( current_dt );
0214                     } else {
0215                         step_loop( this->m_dt );
0216                     }
0217                 }
0218 
0219             } else {
0220                 this->m_at_end = true;
0221             }
0222         }
0223 
0224     private:
0225         void step_loop( time_type &dt )
0226         {
0227             unwrapped_stepper_type &stepper = this->m_stepper;
0228             const size_t max_attempts = 1000;
0229             size_t trials = 0;
0230             controlled_step_result res = success;
0231             do
0232             {
0233                 res = stepper.try_step( this->m_system , *( this->m_state ) , this->m_t , dt );
0234                 ++trials;
0235             }
0236             while( ( res == fail ) && ( trials < max_attempts ) );
0237             if( trials == max_attempts )
0238             {
0239                 BOOST_THROW_EXCEPTION( std::overflow_error( "Adaptive iterator : Maximal number of iterations reached. A step size could not be found." ) );
0240             }
0241         }
0242 
0243     public:
0244         const state_type& get_state() const
0245         {
0246             return *m_state;
0247         }
0248 
0249 
0250     private:
0251         time_iterator_type m_t_start;
0252         time_iterator_type m_t_end;
0253         state_type* m_state;
0254     };
0255 
0256 
0257     /*
0258      * Specilization for dense outputer steppers
0259      */
0260     /**
0261      * \brief ODE Iterator with step size control and dense output.
0262      * Implements an ODE iterator with adaptive step size control. Uses dense-output steppers.
0263      * times_iterator is a model of single-pass iterator.
0264      *
0265      * \tparam Stepper The stepper type which should be used during the iteration.
0266      * \tparam System The type of the system function (ODE) which should be solved.
0267      */
0268     template< class Iterator , class Stepper , class System , class State , class TimeIterator , typename Tag >
0269     class times_iterator_impl< Iterator , Stepper , System , State , TimeIterator , Tag , dense_output_stepper_tag >
0270         : public detail::ode_iterator_base< Iterator , Stepper , System , State , Tag >
0271     {
0272     private:
0273 
0274 
0275         typedef Stepper stepper_type;
0276         typedef System system_type;
0277         typedef typename boost::numeric::odeint::unwrap_reference< stepper_type >::type unwrapped_stepper_type;
0278         typedef State state_type;
0279         typedef TimeIterator time_iterator_type;
0280         typedef typename traits::time_type< stepper_type >::type time_type;
0281         typedef typename traits::value_type< stepper_type >::type ode_value_type;
0282         #ifndef DOXYGEN_SKIP
0283         typedef detail::ode_iterator_base< Iterator , Stepper , System , State , Tag > base_type;
0284         #endif
0285 
0286 
0287    public:
0288 
0289 
0290         /**
0291          * \brief Constructs a times_iterator. This constructor should be used to construct the begin iterator.
0292          *
0293          * \param stepper The stepper to use during the iteration.
0294          * \param sys The system function (ODE) to solve.
0295          * \param s The initial state.
0296          * \param t_start Iterator to the begin of a sequence of time values.
0297          * \param t_end Iterator to the begin of a sequence of time values.
0298          * \param dt The (initial) time step.
0299          */
0300         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s ,
0301                              time_iterator_type t_start , time_iterator_type t_end , time_type dt )
0302             : base_type( stepper , sys , *t_start , dt ) ,
0303               m_t_start( t_start ) , m_t_end( t_end ) , m_final_time( *(t_end-1) ) ,
0304               m_state( &s )
0305         {
0306             if( t_start != t_end )
0307             {
0308                 unwrapped_stepper_type &st = this->m_stepper;
0309                 st.initialize( *( this->m_state ) , this->m_t , this->m_dt );
0310             } else {
0311                 this->m_at_end = true;
0312             }
0313         }
0314 
0315         /**
0316          * \brief Constructs a times_iterator. This constructor should be used to construct the end iterator.
0317          *
0318          * \param stepper The stepper to use during the iteration.
0319          * \param sys The system function (ODE) to solve.
0320          * \param s The initial state.
0321          */
0322         times_iterator_impl( stepper_type stepper , system_type sys , state_type &s )
0323             : base_type( stepper , sys ) , m_state( &s ) { }
0324 
0325     protected:
0326 
0327         friend class boost::iterator_core_access;
0328 
0329         void increment()
0330         {
0331             unwrapped_stepper_type &st = this->m_stepper;
0332             if( ++m_t_start != m_t_end )
0333             {
0334                 this->m_t = static_cast<time_type>(*m_t_start);
0335                 while( detail::less_with_sign( st.current_time() , this->m_t , this->m_dt ) )
0336                 {
0337                     // make sure we don't go beyond the last point
0338                     if( detail::less_with_sign( m_final_time-st.current_time() , st.current_time_step() , st.current_time_step() ) )
0339                     {
0340                         st.initialize( st.current_state() , st.current_time() , m_final_time-st.current_time() );
0341                     }
0342                     st.do_step( this->m_system );
0343                 }
0344                 st.calc_state( this->m_t , *( this->m_state ) );
0345             } else {
0346                 this->m_at_end = true;
0347             }
0348         }
0349 
0350     public:
0351         const state_type& get_state() const
0352         {
0353             return *m_state;
0354         }
0355 
0356 
0357     private:
0358         time_iterator_type m_t_start;
0359         time_iterator_type m_t_end;
0360         time_type m_final_time;
0361         state_type* m_state;
0362     };
0363 
0364 } // namespace odeint
0365 } // namespace numeric
0366 } // namespace boost
0367 
0368 
0369 #endif // BOOST_NUMERIC_ODEINT_ITERATOR_DETAIL_TIMES_ITERATOR_IMPL_HPP_DEFINED