Chris@16: /* Chris@16: [auto_generated] Chris@16: boost/numeric/odeint/stepper/adams_bashforth.hpp Chris@16: Chris@16: [begin_description] Chris@16: Implementaton of the Adam-Bashforth method a multistep method used for the predictor step in the Chris@16: Adams-Bashforth-Moulton method. Chris@16: [end_description] Chris@16: Chris@16: Copyright 2009-2011 Karsten Ahnert Chris@16: Copyright 2009-2011 Mario Mulansky Chris@16: Chris@16: Distributed under the Boost Software License, Version 1.0. Chris@16: (See accompanying file LICENSE_1_0.txt or Chris@16: copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: Chris@16: Chris@16: #ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED Chris@16: #define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: Chris@16: Chris@16: namespace boost { Chris@16: namespace numeric { Chris@16: namespace odeint { Chris@16: Chris@16: Chris@16: template< Chris@16: size_t Steps , Chris@16: class State , Chris@16: class Value = double , Chris@16: class Deriv = State , Chris@16: class Time = Value , Chris@16: class Algebra = range_algebra , Chris@16: class Operations = default_operations , Chris@16: class Resizer = initially_resizer , Chris@16: class InitializingStepper = runge_kutta4< State , Value , Deriv , Time , Algebra , Operations, Resizer > Chris@16: > Chris@16: class adams_bashforth : public algebra_stepper_base< Algebra , Operations > Chris@16: { Chris@16: Chris@16: #ifndef DOXYGEN_SKIP Chris@16: BOOST_STATIC_ASSERT(( Steps > 0 )); Chris@16: BOOST_STATIC_ASSERT(( Steps < 9 )); Chris@16: #endif Chris@16: Chris@16: public : Chris@16: Chris@16: typedef State state_type; Chris@16: typedef state_wrapper< state_type > wrapped_state_type; Chris@16: typedef Value value_type; Chris@16: typedef Deriv deriv_type; Chris@16: typedef state_wrapper< deriv_type > wrapped_deriv_type; Chris@16: typedef Time time_type; Chris@16: typedef Resizer resizer_type; Chris@16: typedef stepper_tag stepper_category; Chris@16: Chris@16: typedef InitializingStepper initializing_stepper_type; Chris@16: Chris@16: typedef typename algebra_stepper_base< Algebra , Operations >::algebra_type algebra_type; Chris@16: typedef typename algebra_stepper_base< Algebra , Operations >::operations_type operations_type; Chris@16: #ifndef DOXYGEN_SKIP Chris@16: typedef adams_bashforth< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer , InitializingStepper > stepper_type; Chris@16: #endif Chris@16: static const size_t steps = Steps; Chris@16: Chris@16: Chris@16: Chris@16: typedef unsigned short order_type; Chris@16: static const order_type order_value = steps; Chris@16: Chris@16: typedef detail::rotating_buffer< wrapped_deriv_type , steps > step_storage_type; Chris@16: Chris@16: Chris@16: Chris@16: order_type order( void ) const { return order_value; } Chris@16: Chris@16: adams_bashforth( const algebra_type &algebra = algebra_type() ) Chris@16: : m_step_storage() , m_resizer() , m_coefficients() , Chris@16: m_steps_initialized( 0 ) , m_initializing_stepper() , Chris@16: m_algebra( algebra ) Chris@16: { } Chris@16: Chris@16: adams_bashforth( const adams_bashforth &stepper ) Chris@16: : m_step_storage( stepper.m_step_storage ) , m_resizer( stepper.m_resizer ) , m_coefficients() , Chris@16: m_steps_initialized( stepper.m_steps_initialized ) , m_initializing_stepper( stepper.m_initializing_stepper ) , Chris@16: m_algebra( stepper.m_algebra ) Chris@16: { } Chris@16: Chris@16: adams_bashforth& operator=( const adams_bashforth &stepper ) Chris@16: { Chris@16: m_resizer = stepper.m_resizer; Chris@16: m_step_storage = stepper.m_step_storage; Chris@16: m_algebra = stepper.m_algebra; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: Chris@16: /* Chris@16: * Version 1 : do_step( system , x , t , dt ); Chris@16: * Chris@16: * solves the forwarding problem Chris@16: */ Chris@16: template< class System , class StateInOut > Chris@16: void do_step( System system , StateInOut &x , time_type t , time_type dt ) Chris@16: { Chris@16: do_step( system , x , t , x , dt ); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut. Chris@16: */ Chris@16: template< class System , class StateInOut > Chris@16: void do_step( System system , const StateInOut &x , time_type t , time_type dt ) Chris@16: { Chris@16: do_step( system , x , t , x , dt ); Chris@16: } Chris@16: Chris@16: Chris@16: Chris@16: /* Chris@16: * Version 2 : do_step( system , in , t , out , dt ); Chris@16: * Chris@16: * solves the forwarding problem Chris@16: */ Chris@16: Chris@16: template< class System , class StateIn , class StateOut > Chris@16: void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) Chris@16: { Chris@16: do_step_impl( system , in , t , out , dt ); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateOut. Chris@16: */ Chris@16: template< class System , class StateIn , class StateOut > Chris@16: void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt ) Chris@16: { Chris@16: do_step_impl( system , in , t , out , dt ); Chris@16: } Chris@16: Chris@16: Chris@16: template< class StateType > Chris@16: void adjust_size( const StateType &x ) Chris@16: { Chris@16: resize_impl( x ); Chris@16: } Chris@16: Chris@16: const step_storage_type& step_storage( void ) const Chris@16: { Chris@16: return m_step_storage; Chris@16: } Chris@16: Chris@16: step_storage_type& step_storage( void ) Chris@16: { Chris@16: return m_step_storage; Chris@16: } Chris@16: Chris@16: template< class ExplicitStepper , class System , class StateIn > Chris@16: void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt ) Chris@16: { Chris@16: typename odeint::unwrap_reference< ExplicitStepper >::type &stepper = explicit_stepper; Chris@16: typename odeint::unwrap_reference< System >::type &sys = system; Chris@16: Chris@16: m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl , detail::ref( *this ) , detail::_1 ) ); Chris@16: Chris@16: for( size_t i=0 ; i Chris@16: void initialize( System system , StateIn &x , time_type &t , time_type dt ) Chris@16: { Chris@16: initialize( detail::ref( m_initializing_stepper ) , system , x , t , dt ); Chris@16: } Chris@16: Chris@16: void reset( void ) Chris@16: { Chris@16: m_steps_initialized = 0; Chris@16: } Chris@16: Chris@16: bool is_initialized( void ) const Chris@16: { Chris@16: return m_steps_initialized >= steps; Chris@16: } Chris@16: Chris@16: const initializing_stepper_type& initializing_stepper( void ) const { return m_initializing_stepper; } Chris@16: Chris@16: initializing_stepper_type& initializing_stepper( void ) { return m_initializing_stepper; } Chris@16: Chris@16: private: Chris@16: Chris@16: template< class System , class StateIn , class StateOut > Chris@16: void do_step_impl( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) Chris@16: { Chris@16: typename odeint::unwrap_reference< System >::type &sys = system; Chris@16: if( m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl , detail::ref( *this ) , detail::_1 ) ) ) Chris@16: { Chris@16: m_steps_initialized = 0; Chris@16: } Chris@16: Chris@16: if( m_steps_initialized < steps - 1 ) Chris@16: { Chris@16: if( m_steps_initialized != 0 ) m_step_storage.rotate(); Chris@16: sys( in , m_step_storage[0].m_v , t ); Chris@16: m_initializing_stepper.do_step( system , in , m_step_storage[0].m_v , t , out , dt ); Chris@16: m_steps_initialized++; Chris@16: } Chris@16: else Chris@16: { Chris@16: m_step_storage.rotate(); Chris@16: sys( in , m_step_storage[0].m_v , t ); Chris@16: detail::adams_bashforth_call_algebra< steps , algebra_type , operations_type >()( m_algebra , in , out , m_step_storage , m_coefficients , dt ); Chris@16: } Chris@16: } Chris@16: Chris@16: Chris@16: template< class StateIn > Chris@16: bool resize_impl( const StateIn &x ) Chris@16: { Chris@16: bool resized( false ); Chris@16: for( size_t i=0 ; i::type() ); Chris@16: } Chris@16: return resized; Chris@16: } Chris@16: Chris@16: step_storage_type m_step_storage; Chris@16: resizer_type m_resizer; Chris@16: const detail::adams_bashforth_coefficients< value_type , steps > m_coefficients; Chris@16: size_t m_steps_initialized; Chris@16: initializing_stepper_type m_initializing_stepper; Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: Chris@16: protected: Chris@16: Chris@16: algebra_type m_algebra; Chris@16: }; Chris@16: Chris@16: Chris@16: /***** DOXYGEN *****/ Chris@16: Chris@16: /** Chris@16: * \class adams_bashforth Chris@16: * \brief The Adams-Bashforth multistep algorithm. Chris@16: * Chris@16: * The Adams-Bashforth method is a multi-step algorithm with configurable step Chris@16: * number. The step number is specified as template parameter Steps and it Chris@16: * then uses the result from the previous Steps steps. See also Chris@16: * en.wikipedia.org/wiki/Linear_multistep_method. Chris@16: * Currently, a maximum of Steps=8 is supported. Chris@16: * The method is explicit and fulfills the Stepper concept. Step size control Chris@16: * or continuous output are not provided. Chris@16: * Chris@16: * This class derives from algebra_base and inherits its interface via Chris@16: * CRTP (current recurring template pattern). For more details see Chris@16: * algebra_stepper_base. Chris@16: * Chris@16: * \tparam Steps The number of steps (maximal 8). Chris@16: * \tparam State The state type. Chris@16: * \tparam Value The value type. Chris@16: * \tparam Deriv The type representing the time derivative of the state. Chris@16: * \tparam Time The time representing the independent variable - the time. Chris@16: * \tparam Algebra The algebra type. Chris@16: * \tparam Operations The operations type. Chris@16: * \tparam Resizer The resizer policy type. Chris@16: * \tparam InitializingStepper The stepper for the first two steps. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn adams_bashforth::adams_bashforth( const algebra_type &algebra ) Chris@16: * \brief Constructs the adams_bashforth class. This constructor can be used as a default Chris@16: * constructor if the algebra has a default constructor. Chris@16: * \param algebra A copy of algebra is made and stored. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn order_type adams_bashforth::order( void ) const Chris@16: * \brief Returns the order of the algorithm, which is equal to the number of steps. Chris@16: * \return order of the method. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::do_step( System system , StateInOut &x , time_type t , time_type dt ) Chris@16: * \brief This method performs one step. It transforms the result in-place. Chris@16: * Chris@16: * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the Chris@16: * Simple System concept. Chris@16: * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. Chris@16: * \param t The value of the time, at which the step should be performed. Chris@16: * \param dt The step size. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt ) Chris@16: * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place. Chris@16: * Chris@16: * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the Chris@16: * Simple System concept. Chris@16: * \param in The state of the ODE which should be solved. in is not modified in this method Chris@16: * \param t The value of the time, at which the step should be performed. Chris@16: * \param out The result of the step is written in out. Chris@16: * \param dt The step size. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::adjust_size( const StateType &x ) Chris@16: * \brief Adjust the size of all temporaries in the stepper manually. Chris@16: * \param x A state from which the size of the temporaries to be resized is deduced. Chris@16: */ Chris@16: Chris@16: Chris@16: /** Chris@16: * \fn const step_storage_type& adams_bashforth::step_storage( void ) const Chris@16: * \brief Returns the storage of intermediate results. Chris@16: * \return The storage of intermediate results. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn step_storage_type& adams_bashforth::step_storage( void ) Chris@16: * \brief Returns the storage of intermediate results. Chris@16: * \return The storage of intermediate results. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt ) Chris@16: * \brief Initialized the stepper. Does Steps-1 steps with the explicit_stepper to fill the buffer. Chris@16: * \param explicit_stepper the stepper used to fill the buffer of previous step results Chris@16: * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the Chris@16: * Simple System concept. Chris@16: * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x. Chris@16: * \param t The value of the time, at which the step should be performed. Chris@16: * \param dt The step size. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::initialize( System system , StateIn &x , time_type &t , time_type dt ) Chris@16: * \brief Initialized the stepper. Does Steps-1 steps with an internal instance of InitializingStepper to fill the buffer. Chris@16: * \note The state x and time t are updated to the values after Steps-1 initial steps. Chris@16: * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the Chris@16: * Simple System concept. Chris@16: * \param x The initial state of the ODE which should be solved, updated in this method. Chris@16: * \param t The initial value of the time, updated in this method. Chris@16: * \param dt The step size. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn void adams_bashforth::reset( void ) Chris@16: * \brief Resets the internal buffer of the stepper. Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn bool adams_bashforth::is_initialized( void ) const Chris@16: * \brief Returns true if the stepper has been initialized. Chris@16: * \return bool true if stepper is initialized, false otherwise Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn const initializing_stepper_type& adams_bashforth::initializing_stepper( void ) const Chris@16: * \brief Returns the internal initializing stepper instance. Chris@16: * \return initializing_stepper Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn const initializing_stepper_type& adams_bashforth::initializing_stepper( void ) const Chris@16: * \brief Returns the internal initializing stepper instance. Chris@16: * \return initializing_stepper Chris@16: */ Chris@16: Chris@16: /** Chris@16: * \fn initializing_stepper_type& adams_bashforth::initializing_stepper( void ) Chris@16: * \brief Returns the internal initializing stepper instance. Chris@16: * \return initializing_stepper Chris@16: */ Chris@16: Chris@16: } // odeint Chris@16: } // numeric Chris@16: } // boost Chris@16: Chris@16: Chris@16: Chris@16: #endif // BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED