Squashed 'third_party/boostorg/odeint/' content from commit 6ff2719
Change-Id: If4892e29c1a5e6cf3a7aa51486a2725c251b0c7d
git-subtree-dir: third_party/boostorg/odeint
git-subtree-split: 6ff2719b6907b86596c3d43e88c1bcfdf29df560
diff --git a/include/boost/numeric/odeint/stepper/adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adams_bashforth.hpp
new file mode 100644
index 0000000..5ff1e83
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/adams_bashforth.hpp
@@ -0,0 +1,420 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/adams_bashforth.hpp
+
+ [begin_description]
+ Implementaton of the Adam-Bashforth method a multistep method used for the predictor step in the
+ Adams-Bashforth-Moulton method.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+ Copyright 2013 Pascal Germroth
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED
+
+#include <boost/static_assert.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
+#include <boost/numeric/odeint/stepper/extrapolation_stepper.hpp>
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+
+#include <boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp>
+#include <boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp>
+#include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp>
+
+#include <boost/mpl/arithmetic.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/equal_to.hpp>
+
+namespace mpl = boost::mpl;
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+ using mpl::int_;
+
+ /* if N >= 4, returns the smallest even number > N, otherwise returns 4 */
+ template < int N >
+ struct order_helper
+ : mpl::max< typename mpl::eval_if<
+ mpl::equal_to< mpl::modulus< int_< N >, int_< 2 > >,
+ int_< 0 > >,
+ int_< N >, int_< N + 1 > >::type,
+ int_< 4 > >::type
+ { };
+
+template<
+size_t Steps ,
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer ,
+class InitializingStepper = extrapolation_stepper< order_helper<Steps>::value,
+ State, Value, Deriv, Time,
+ Algebra, Operations, Resizer >
+>
+class adams_bashforth : public algebra_stepper_base< Algebra , Operations >
+{
+
+#ifndef DOXYGEN_SKIP
+ BOOST_STATIC_ASSERT(( Steps > 0 ));
+ BOOST_STATIC_ASSERT(( Steps < 9 ));
+#endif
+
+public :
+
+ typedef State state_type;
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef Time time_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+
+ typedef InitializingStepper initializing_stepper_type;
+
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+ typedef typename algebra_stepper_base_type::operations_type operations_type;
+#ifndef DOXYGEN_SKIP
+ typedef adams_bashforth< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer , InitializingStepper > stepper_type;
+#endif
+ static const size_t steps = Steps;
+
+
+
+ typedef unsigned short order_type;
+ static const order_type order_value = steps;
+
+ typedef detail::rotating_buffer< wrapped_deriv_type , steps > step_storage_type;
+
+
+
+ order_type order( void ) const { return order_value; }
+
+ adams_bashforth( const algebra_type &algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra ) ,
+ m_step_storage() , m_resizer() , m_coefficients() ,
+ m_steps_initialized( 0 ) , m_initializing_stepper()
+ { }
+
+
+
+ /*
+ * Version 1 : do_step( system , x , t , dt );
+ *
+ * solves the forwarding problem
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ do_step( system , x , t , x , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ {
+ do_step( system , x , t , x , dt );
+ }
+
+
+
+ /*
+ * Version 2 : do_step( system , in , t , out , dt );
+ *
+ * solves the forwarding problem
+ */
+
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ do_step_impl( system , in , t , out , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateOut.
+ */
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt )
+ {
+ do_step_impl( system , in , t , out , dt );
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ }
+
+ const step_storage_type& step_storage( void ) const
+ {
+ return m_step_storage;
+ }
+
+ step_storage_type& step_storage( void )
+ {
+ return m_step_storage;
+ }
+
+ template< class ExplicitStepper , class System , class StateIn >
+ void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
+ {
+ typename odeint::unwrap_reference< ExplicitStepper >::type &stepper = explicit_stepper;
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+
+ for( size_t i=0 ; i+1<steps ; ++i )
+ {
+ if( i != 0 ) m_step_storage.rotate();
+ sys( x , m_step_storage[0].m_v , t );
+ stepper.do_step_dxdt_impl( system, x, m_step_storage[0].m_v, t,
+ dt );
+ t += dt;
+ }
+ m_steps_initialized = steps;
+ }
+
+ template< class System , class StateIn >
+ void initialize( System system , StateIn &x , time_type &t , time_type dt )
+ {
+ initialize( detail::ref( m_initializing_stepper ) , system , x , t , dt );
+ }
+
+ void reset( void )
+ {
+ m_steps_initialized = 0;
+ }
+
+ bool is_initialized( void ) const
+ {
+ return m_steps_initialized >= ( steps - 1 );
+ }
+
+ const initializing_stepper_type& initializing_stepper( void ) const { return m_initializing_stepper; }
+
+ initializing_stepper_type& initializing_stepper( void ) { return m_initializing_stepper; }
+
+private:
+
+ template< class System , class StateIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ if( m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) ) )
+ {
+ m_steps_initialized = 0;
+ }
+
+ if( m_steps_initialized + 1 < steps )
+ {
+ if( m_steps_initialized != 0 ) m_step_storage.rotate();
+ sys( in , m_step_storage[0].m_v , t );
+ m_initializing_stepper.do_step_dxdt_impl(
+ system, in, m_step_storage[0].m_v, t, out, dt );
+ ++m_steps_initialized;
+ }
+ else
+ {
+ m_step_storage.rotate();
+ sys( in , m_step_storage[0].m_v , t );
+ detail::adams_bashforth_call_algebra< steps , algebra_type , operations_type >()( this->m_algebra , in , out , m_step_storage , m_coefficients , dt );
+ }
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ for( size_t i=0 ; i<steps ; ++i )
+ {
+ resized |= adjust_size_by_resizeability( m_step_storage[i] , x , typename is_resizeable<deriv_type>::type() );
+ }
+ return resized;
+ }
+
+ step_storage_type m_step_storage;
+ resizer_type m_resizer;
+ detail::adams_bashforth_coefficients< value_type , steps > m_coefficients;
+ size_t m_steps_initialized;
+ initializing_stepper_type m_initializing_stepper;
+
+};
+
+
+/***** DOXYGEN *****/
+
+/**
+ * \class adams_bashforth
+ * \brief The Adams-Bashforth multistep algorithm.
+ *
+ * The Adams-Bashforth method is a multi-step algorithm with configurable step
+ * number. The step number is specified as template parameter Steps and it
+ * then uses the result from the previous Steps steps. See also
+ * <a href="http://en.wikipedia.org/wiki/Linear_multistep_method">en.wikipedia.org/wiki/Linear_multistep_method</a>.
+ * Currently, a maximum of Steps=8 is supported.
+ * The method is explicit and fulfills the Stepper concept. Step size control
+ * or continuous output are not provided.
+ *
+ * This class derives from algebra_base and inherits its interface via
+ * CRTP (current recurring template pattern). For more details see
+ * algebra_stepper_base.
+ *
+ * \tparam Steps The number of steps (maximal 8).
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ * \tparam InitializingStepper The stepper for the first two steps.
+ */
+
+ /**
+ * \fn adams_bashforth::adams_bashforth( const algebra_type &algebra )
+ * \brief Constructs the adams_bashforth class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored.
+ */
+
+ /**
+ * \fn order_type adams_bashforth::order( void ) const
+ * \brief Returns the order of the algorithm, which is equal to the number of steps.
+ * \return order of the method.
+ */
+
+ /**
+ * \fn void adams_bashforth::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void adams_bashforth::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void adams_bashforth::adjust_size( const StateType &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+
+ /**
+ * \fn const step_storage_type& adams_bashforth::step_storage( void ) const
+ * \brief Returns the storage of intermediate results.
+ * \return The storage of intermediate results.
+ */
+
+ /**
+ * \fn step_storage_type& adams_bashforth::step_storage( void )
+ * \brief Returns the storage of intermediate results.
+ * \return The storage of intermediate results.
+ */
+
+ /**
+ * \fn void adams_bashforth::initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
+ * \brief Initialized the stepper. Does Steps-1 steps with the explicit_stepper to fill the buffer.
+ * \param explicit_stepper the stepper used to fill the buffer of previous step results
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void adams_bashforth::initialize( System system , StateIn &x , time_type &t , time_type dt )
+ * \brief Initialized the stepper. Does Steps-1 steps with an internal instance of InitializingStepper to fill the buffer.
+ * \note The state x and time t are updated to the values after Steps-1 initial steps.
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The initial state of the ODE which should be solved, updated in this method.
+ * \param t The initial value of the time, updated in this method.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void adams_bashforth::reset( void )
+ * \brief Resets the internal buffer of the stepper.
+ */
+
+ /**
+ * \fn bool adams_bashforth::is_initialized( void ) const
+ * \brief Returns true if the stepper has been initialized.
+ * \return bool true if stepper is initialized, false otherwise
+ */
+
+ /**
+ * \fn const initializing_stepper_type& adams_bashforth::initializing_stepper( void ) const
+ * \brief Returns the internal initializing stepper instance.
+ * \return initializing_stepper
+ */
+
+ /**
+ * \fn const initializing_stepper_type& adams_bashforth::initializing_stepper( void ) const
+ * \brief Returns the internal initializing stepper instance.
+ * \return initializing_stepper
+ */
+
+ /**
+ * \fn initializing_stepper_type& adams_bashforth::initializing_stepper( void )
+ * \brief Returns the internal initializing stepper instance.
+ * \return initializing_stepper
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp
new file mode 100644
index 0000000..f3edce1
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp
@@ -0,0 +1,314 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp
+
+ [begin_description]
+ Implementation of the Adams-Bashforth-Moulton method, a predictor-corrector multistep method.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/adams_bashforth.hpp>
+#include <boost/numeric/odeint/stepper/adams_moulton.hpp>
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template<
+size_t Steps ,
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer,
+class InitializingStepper = runge_kutta4< State , Value , Deriv , Time , Algebra , Operations, Resizer >
+>
+class adams_bashforth_moulton
+{
+
+#ifndef DOXYGEN_SKIP
+ BOOST_STATIC_ASSERT(( Steps > 0 ));
+ BOOST_STATIC_ASSERT(( Steps < 9 ));
+#endif
+
+public :
+
+ typedef State state_type;
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef Time time_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+ typedef InitializingStepper initializing_stepper_type;
+
+ static const size_t steps = Steps;
+#ifndef DOXYGEN_SKIP
+ typedef adams_bashforth< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type, initializing_stepper_type > adams_bashforth_type;
+ typedef adams_moulton< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type > adams_moulton_type;
+ typedef adams_bashforth_moulton< steps , state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type , initializing_stepper_type> stepper_type;
+#endif //DOXYGEN_SKIP
+ typedef unsigned short order_type;
+ static const order_type order_value = steps;
+
+ /** \brief Constructs the adams_bashforth class. */
+ adams_bashforth_moulton( void )
+ : m_adams_bashforth() , m_adams_moulton( m_adams_bashforth.algebra() )
+ , m_x() , m_resizer()
+ { }
+
+ adams_bashforth_moulton( const algebra_type &algebra )
+ : m_adams_bashforth( algebra ) , m_adams_moulton( m_adams_bashforth.algebra() )
+ , m_x() , m_resizer()
+ { }
+
+ order_type order( void ) const { return order_value; }
+
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_impl1( system , x , t , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_impl1( system , x , t , dt );
+ }
+
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt )
+ {
+ do_step_impl2( system , in , t , out , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateOut.
+ */
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ do_step_impl2( system , in ,t , out , dt );
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ m_adams_bashforth.adjust_size( x );
+ m_adams_moulton.adjust_size( x );
+ resize_impl( x );
+ }
+
+
+ template< class ExplicitStepper , class System , class StateIn >
+ void initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
+ {
+ m_adams_bashforth.initialize( explicit_stepper , system , x , t , dt );
+ }
+
+
+ template< class System , class StateIn >
+ void initialize( System system , StateIn &x , time_type &t , time_type dt )
+ {
+ m_adams_bashforth.initialize( system , x , t , dt );
+ }
+
+
+ void reset(void)
+ {
+ m_adams_bashforth.reset();
+ }
+
+
+
+private:
+
+ template< typename System , typename StateInOut >
+ void do_step_impl1( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ if( m_adams_bashforth.is_initialized() )
+ {
+ m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ m_adams_bashforth.do_step( system , x , t , m_x.m_v , dt );
+ m_adams_moulton.do_step( system , x , m_x.m_v , t+dt , x , dt , m_adams_bashforth.step_storage() );
+ }
+ else
+ {
+ m_adams_bashforth.do_step( system , x , t , dt );
+ }
+ }
+
+ template< typename System , typename StateIn , typename StateInOut >
+ void do_step_impl2( System system , StateIn const &in , time_type t , StateInOut & out , time_type dt )
+ {
+ if( m_adams_bashforth.is_initialized() )
+ {
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ m_adams_bashforth.do_step( system , in , t , m_x.m_v , dt );
+ m_adams_moulton.do_step( system , in , m_x.m_v , t+dt , out , dt , m_adams_bashforth.step_storage() );
+ }
+ else
+ {
+ m_adams_bashforth.do_step( system , in , t , out , dt );
+ }
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_x , x , typename is_resizeable< state_type >::type() );
+ }
+
+ adams_bashforth_type m_adams_bashforth;
+ adams_moulton_type m_adams_moulton;
+ wrapped_state_type m_x;
+ resizer_type m_resizer;
+};
+
+
+/********* DOXYGEN ********/
+
+/**
+ * \class adams_bashforth_moulton
+ * \brief The Adams-Bashforth-Moulton multistep algorithm.
+ *
+ * The Adams-Bashforth method is a multi-step predictor-corrector algorithm
+ * with configurable step number. The step number is specified as template
+ * parameter Steps and it then uses the result from the previous Steps steps.
+ * See also
+ * <a href="http://en.wikipedia.org/wiki/Linear_multistep_method">en.wikipedia.org/wiki/Linear_multistep_method</a>.
+ * Currently, a maximum of Steps=8 is supported.
+ * The method is explicit and fulfills the Stepper concept. Step size control
+ * or continuous output are not provided.
+ *
+ * This class derives from algebra_base and inherits its interface via
+ * CRTP (current recurring template pattern). For more details see
+ * algebra_stepper_base.
+ *
+ * \tparam Steps The number of steps (maximal 8).
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ * \tparam InitializingStepper The stepper for the first two steps.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::adams_bashforth_moulton( const algebra_type &algebra )
+ * \brief Constructs the adams_bashforth class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::order( void ) const
+ * \brief Returns the order of the algorithm, which is equal to the number of steps+1.
+ * \return order of the method.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn adams_bashforth_moulton::do_step( System system , const StateIn &in , time_type t , const StateOut &out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::adjust_size( const StateType &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::initialize( ExplicitStepper explicit_stepper , System system , StateIn &x , time_type &t , time_type dt )
+ * \brief Initialized the stepper. Does Steps-1 steps with the explicit_stepper to fill the buffer.
+ * \note The state x and time t are updated to the values after Steps-1 initial steps.
+ * \param explicit_stepper the stepper used to fill the buffer of previous step results
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The initial state of the ODE which should be solved, updated after in this method.
+ * \param t The initial time, updated in this method.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::initialize( System system , StateIn &x , time_type &t , time_type dt )
+ * \brief Initialized the stepper. Does Steps-1 steps using the standard initializing stepper
+ * of the underlying adams_bashforth stepper.
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn adams_bashforth_moulton::reset( void )
+ * \brief Resets the internal buffers of the stepper.
+ */
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adams_moulton.hpp
new file mode 100644
index 0000000..05b4277
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/adams_moulton.hpp
@@ -0,0 +1,201 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/adams_moulton.hpp
+
+ [begin_description]
+ Implementation of the Adams-Moulton method. This is method is not a real stepper, it is more a helper class
+ which computes the corrector step in the Adams-Bashforth-Moulton method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_MOULTON_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_MOULTON_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp>
+
+#include <boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp>
+#include <boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp>
+#include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp>
+
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+/*
+ * Static implicit Adams-Moulton multistep-solver without step size control and without dense output.
+ */
+template<
+size_t Steps ,
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+class adams_moulton
+{
+private:
+
+
+public :
+
+ typedef State state_type;
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef Time time_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+
+ typedef adams_moulton< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_type;
+
+ static const size_t steps = Steps;
+
+ typedef unsigned short order_type;
+ static const order_type order_value = steps + 1;
+
+ typedef detail::rotating_buffer< wrapped_deriv_type , steps > step_storage_type;
+
+ adams_moulton( )
+ : m_coefficients() , m_dxdt() , m_resizer() ,
+ m_algebra_instance() , m_algebra( m_algebra_instance )
+ { }
+
+ adams_moulton( algebra_type &algebra )
+ : m_coefficients() , m_dxdt() , m_resizer() ,
+ m_algebra_instance() , m_algebra( algebra )
+ { }
+
+ adams_moulton& operator=( const adams_moulton &stepper )
+ {
+ m_dxdt = stepper.m_dxdt;
+ m_resizer = stepper.m_resizer;
+ m_algebra = stepper.m_algebra;
+ return *this;
+ }
+
+ order_type order( void ) const { return order_value; }
+
+
+ /*
+ * Version 1 : do_step( system , x , t , dt , buf );
+ *
+ * solves the forwarding problem
+ */
+ template< class System , class StateInOut , class StateIn , class ABBuf >
+ void do_step( System system , StateInOut &x , StateIn const & pred , time_type t , time_type dt , const ABBuf &buf )
+ {
+ do_step( system , x , pred , t , x , dt , buf );
+ }
+
+ template< class System , class StateInOut , class StateIn , class ABBuf >
+ void do_step( System system , const StateInOut &x , StateIn const & pred , time_type t , time_type dt , const ABBuf &buf )
+ {
+ do_step( system , x , pred , t , x , dt , buf );
+ }
+
+
+
+ /*
+ * Version 2 : do_step( system , in , t , out , dt , buf );
+ *
+ * solves the forwarding problem
+ */
+ template< class System , class StateIn , class PredIn , class StateOut , class ABBuf >
+ void do_step( System system , const StateIn &in , const PredIn &pred , time_type t , StateOut &out , time_type dt , const ABBuf &buf )
+ {
+ do_step_impl( system , in , pred , t , out , dt , buf );
+ }
+
+ template< class System , class StateIn , class PredIn , class StateOut , class ABBuf >
+ void do_step( System system , const StateIn &in , const PredIn &pred , time_type t , const StateOut &out , time_type dt , const ABBuf &buf )
+ {
+ do_step_impl( system , in , pred , t , out , dt , buf );
+ }
+
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ }
+
+ algebra_type& algebra()
+ { return m_algebra; }
+
+ const algebra_type& algebra() const
+ { return m_algebra; }
+
+
+private:
+
+
+ template< class System , class StateIn , class PredIn , class StateOut , class ABBuf >
+ void do_step_impl( System system , const StateIn &in , const PredIn &pred , time_type t , StateOut &out , time_type dt , const ABBuf &buf )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+ sys( pred , m_dxdt.m_v , t );
+ detail::adams_moulton_call_algebra< steps , algebra_type , operations_type >()( m_algebra , in , out , m_dxdt.m_v , buf , m_coefficients , dt );
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+
+ const detail::adams_moulton_coefficients< value_type , steps > m_coefficients;
+ wrapped_deriv_type m_dxdt;
+ resizer_type m_resizer;
+
+protected:
+
+ algebra_type m_algebra_instance;
+ algebra_type &m_algebra;
+};
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ADAMS_MOULTON_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp b/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp
new file mode 100644
index 0000000..3b014f8
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp
@@ -0,0 +1,91 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp
+
+ [begin_description]
+ Base class for all steppers with an algebra and operations.
+ [end_description]
+
+ Copyright 2012-2013 Karsten Ahnert
+ Copyright 2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template< class Algebra , class Operations >
+class algebra_stepper_base
+{
+public:
+
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+
+ algebra_stepper_base( const algebra_type &algebra = algebra_type() )
+ : m_algebra( algebra ) { }
+
+ algebra_type& algebra()
+ {
+ return m_algebra;
+ }
+
+ const algebra_type& algebra() const
+ {
+ return m_algebra;
+ }
+
+protected:
+
+ algebra_type m_algebra;
+};
+
+
+/******* DOXYGEN *******/
+
+/**
+ * \class algebra_stepper_base
+ * \brief Base class for all steppers with algebra and operations.
+ *
+ * This class serves a base class for all steppers with algebra and operations. It holds the
+ * algebra and provides access to the algebra. The operations are not instantiated, since they are
+ * static classes inside the operations class.
+ *
+ * \tparam Algebra The type of the algebra. Must fulfill the Algebra Concept, at least partially to work
+ * with the stepper.
+ * \tparam Operations The type of the operations. Must fulfill the Operations Concept, at least partially
+ * to work with the stepper.
+ */
+
+ /**
+ * \fn algebra_stepper_base::algebra_stepper_base( const algebra_type &algebra = algebra_type() )
+ * \brief Constructs a algebra_stepper_base and creates the algebra. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra The algebra_stepper_base stores and uses a copy of algebra.
+ */
+
+ /**
+ * \fn algebra_type& algebra_stepper_base::algebra()
+ * \return A reference to the algebra which is held by this class.
+ */
+
+ /**
+ * \fn const algebra_type& algebra_stepper_base::algebra() const
+ * \return A const reference to the algebra which is held by this class.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_ALGEBRA_STEPPER_BASE_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp b/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp
new file mode 100644
index 0000000..08009dc
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp
@@ -0,0 +1,588 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp
+
+ [begin_description]
+ Base class for all explicit Runge Kutta stepper which are also error steppers.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2012 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_BASE_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_BASE_HPP_INCLUDED
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+/*
+ * base class for explicit stepper and error steppers
+ * models the stepper AND the error stepper concept
+ *
+ * this class provides the following do_step variants:
+ * do_step( sys , x , t , dt )
+ * do_step( sys , x , dxdt , t , dt )
+ * do_step( sys , in , t , out , dt )
+ * do_step( sys , in , dxdt , t , out , dt )
+ * do_step( sys , x , t , dt , xerr )
+ * do_step( sys , x , dxdt , t , dt , xerr )
+ * do_step( sys , in , t , out , dt , xerr )
+ * do_step( sys , in , dxdt , t , out , dt , xerr )
+ */
+template<
+class Stepper ,
+unsigned short Order ,
+unsigned short StepperOrder ,
+unsigned short ErrorOrder ,
+class State ,
+class Value ,
+class Deriv ,
+class Time ,
+class Algebra ,
+class Operations ,
+class Resizer
+>
+class explicit_error_stepper_base : public algebra_stepper_base< Algebra , Operations >
+{
+public:
+
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Resizer resizer_type;
+ typedef Stepper stepper_type;
+ typedef explicit_error_stepper_tag stepper_category;
+ #ifndef DOXYGEN_SKIP
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef explicit_error_stepper_base< Stepper , Order , StepperOrder , ErrorOrder ,
+ State , Value , Deriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type;
+ #endif
+
+ typedef unsigned short order_type;
+ static const order_type order_value = Order;
+ static const order_type stepper_order_value = StepperOrder;
+ static const order_type error_order_value = ErrorOrder;
+
+
+ explicit_error_stepper_base( const algebra_type &algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra )
+ { }
+
+ order_type order( void ) const
+ {
+ return order_value;
+ }
+
+ order_type stepper_order( void ) const
+ {
+ return stepper_order_value;
+ }
+
+ order_type error_order( void ) const
+ {
+ return error_order_value;
+ }
+
+
+
+ /*
+ * Version 1 : do_step( sys , x , t , dt )
+ *
+ * the two overloads are needed in order to solve the forwarding problem
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+
+
+ /*
+ * Version 2 : do_step( sys , x , dxdt , t , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateInOut , class DerivIn >
+ typename boost::disable_if< boost::is_same< DerivIn , time_type > , void >::type
+ do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt )
+ {
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dt );
+ }
+
+
+ /*
+ * named Version 2: do_step_dxdt_impl( sys , in , dxdt , t , dt )
+ *
+ * this version is needed when this stepper is used for initializing
+ * multistep stepper like adams-bashforth. Hence we provide an explicitely
+ * named version that is not disabled. Meant for internal use only.
+ */
+ template < class System, class StateInOut, class DerivIn >
+ void do_step_dxdt_impl( System system, StateInOut &x, const DerivIn &dxdt,
+ time_type t, time_type dt )
+ {
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dt );
+ }
+
+
+
+ /*
+ * Version 3 : do_step( sys , in , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateIn , class StateOut >
+ typename boost::disable_if< boost::is_same< StateIn , time_type > , void >::type
+ do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+ sys( in , m_dxdt.m_v ,t );
+ this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , dt );
+ }
+
+ /*
+ * Version 4 :do_step( sys , in , dxdt , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ typename boost::disable_if< boost::is_same< DerivIn , time_type > , void >::type
+ do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ {
+ this->stepper().do_step_impl( system , in , dxdt , t , out , dt );
+ }
+
+ /*
+ * named Version 4: do_step_dxdt_impl( sys , in , dxdt , t , out, dt )
+ *
+ * this version is needed when this stepper is used for initializing
+ * multistep stepper like adams-bashforth. Hence we provide an explicitely
+ * named version that is not disabled. Meant for internal use only.
+ */
+ template < class System, class StateIn, class DerivIn, class StateOut >
+ void do_step_dxdt_impl( System system, const StateIn &in,
+ const DerivIn &dxdt, time_type t, StateOut &out,
+ time_type dt )
+ {
+ this->stepper().do_step_impl( system , in , dxdt , t , out , dt );
+ }
+
+ /*
+ * Version 5 :do_step( sys , x , t , dt , xerr )
+ *
+ * the two overloads are needed in order to solve the forwarding problem
+ */
+ template< class System , class StateInOut , class Err >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ do_step_v5( system , x , t , dt , xerr );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut , class Err >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ do_step_v5( system , x , t , dt , xerr );
+ }
+
+
+ /*
+ * Version 6 :do_step( sys , x , dxdt , t , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateInOut , class DerivIn , class Err >
+ typename boost::disable_if< boost::is_same< DerivIn , time_type > , void >::type
+ do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt , Err &xerr )
+ {
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dt , xerr );
+ }
+
+
+ /*
+ * Version 7 : do_step( sys , in , t , out , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class StateOut , class Err >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+ sys( in , m_dxdt.m_v ,t );
+ this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , dt , xerr );
+ }
+
+
+ /*
+ * Version 8 : do_step( sys , in , dxdt , t , out , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut , class Err >
+ void do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
+ {
+ this->stepper().do_step_impl( system , in , dxdt , t , out , dt , xerr );
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ }
+
+
+
+private:
+
+ template< class System , class StateInOut >
+ void do_step_v1( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl<StateInOut> , detail::ref( *this ) , detail::_1 ) );
+ sys( x , m_dxdt.m_v , t );
+ this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , dt );
+ }
+
+ template< class System , class StateInOut , class Err >
+ void do_step_v5( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl<StateInOut> , detail::ref( *this ) , detail::_1 ) );
+ sys( x , m_dxdt.m_v ,t );
+ this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , dt , xerr );
+ }
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+ stepper_type& stepper( void )
+ {
+ return *static_cast< stepper_type* >( this );
+ }
+
+ const stepper_type& stepper( void ) const
+ {
+ return *static_cast< const stepper_type* >( this );
+ }
+
+
+ resizer_type m_resizer;
+
+protected:
+
+ wrapped_deriv_type m_dxdt;
+};
+
+
+
+
+/******** DOXYGEN *******/
+
+/**
+ * \class explicit_error_stepper_base
+ * \brief Base class for explicit steppers with error estimation. This class can used with
+ * controlled steppers for step size control.
+ *
+ * This class serves as the base class for all explicit steppers with algebra and operations. In contrast to
+ * explicit_stepper_base it also estimates the error and can be used in a controlled stepper to provide
+ * step size control.
+ *
+ * \note This stepper provides `do_step` methods with and without error estimation. It has therefore three orders,
+ * one for the order of a step if the error is not estimated. The other two orders are the orders of the step and
+ * the error step if the error estimation is performed.
+ *
+ * explicit_error_stepper_base is used as the interface in a CRTP (currently recurring template
+ * pattern). In order to work correctly the parent class needs to have a method
+ * `do_step_impl( system , in , dxdt_in , t , out , dt , xerr )`.
+ * explicit_error_stepper_base derives from algebra_stepper_base.
+ *
+ * explicit_error_stepper_base provides several overloaded `do_step` methods, see the list below. Only two of them
+ * are needed to fulfill the Error Stepper concept. The other ones are for convenience and for performance. Some
+ * of them simply update the state out-of-place, while other expect that the first derivative at `t` is passed to the
+ * stepper.
+ *
+ * - `do_step( sys , x , t , dt )` - The classical `do_step` method needed to fulfill the Error Stepper concept. The
+ * state is updated in-place. A type modelling a Boost.Range can be used for x.
+ * - `do_step( sys , x , dxdt , t , dt )` - This method updates the state in-place, but the derivative at the point `t`
+ * must be explicitly passed in `dxdt`.
+ * - `do_step( sys , in , t , out , dt )` - This method updates the state out-of-place, hence the result of the step
+ * is stored in `out`.
+ * - `do_step( sys , in , dxdt , t , out , dt )` - This method update the state out-of-place and expects that the
+ * derivative at the point `t` is explicitly passed in `dxdt`. It is a combination of the two `do_step` methods
+ * above.
+ * - `do_step( sys , x , t , dt , xerr )` - This `do_step` method is needed to fulfill the Error Stepper concept. The
+ * state is updated in-place and an error estimate is calculated. A type modelling a Boost.Range can be used for x.
+ * - `do_step( sys , x , dxdt , t , dt , xerr )` - This method updates the state in-place, but the derivative at the
+ * point `t` must be passed in `dxdt`. An error estimate is calculated.
+ * - `do_step( sys , in , t , out , dt , xerr )` - This method updates the state out-of-place and estimates the error
+ * during the step.
+ * - `do_step( sys , in , dxdt , t , out , dt , xerr )` - This methods updates the state out-of-place and estimates
+ * the error during the step. Furthermore, the derivative at `t` must be passed in `dxdt`.
+ *
+ * \note The system is always passed as value, which might result in poor performance if it contains data. In this
+ * case it can be used with `boost::ref` or `std::ref`, for example `stepper.do_step( boost::ref( sys ) , x , t , dt );`
+ *
+ * \note The time `t` is not advanced by the stepper. This has to done manually, or by the appropriate `integrate`
+ * routines or `iterator`s.
+ *
+ * \tparam Stepper The stepper on which this class should work. It is used via CRTP, hence explicit_stepper_base
+ * provides the interface for the Stepper.
+ * \tparam Order The order of a stepper if the stepper is used without error estimation.
+ * \tparam StepperOrder The order of a step if the stepper is used with error estimation. Usually Order and StepperOrder have
+ * the same value.
+ * \tparam ErrorOrder The order of the error step if the stepper is used with error estimation.
+ * \tparam State The state type for the stepper.
+ * \tparam Value The value type for the stepper. This should be a floating point type, like float,
+ * double, or a multiprecision type. It must not necessary be the value_type of the State. For example
+ * the State can be a `vector< complex< double > >` in this case the Value must be double.
+ * The default value is double.
+ * \tparam Deriv The type representing time derivatives of the state type. It is usually the same type as the
+ * state type, only if used with Boost.Units both types differ.
+ * \tparam Time The type representing the time. Usually the same type as the value type. When Boost.Units is
+ * used, this type has usually a unit.
+ * \tparam Algebra The algebra type which must fulfill the Algebra Concept.
+ * \tparam Operations The type for the operations which must fulfill the Operations Concept.
+ * \tparam Resizer The resizer policy class.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_base::explicit_error_stepper_base( const algebra_type &algebra = algebra_type() )
+ *
+ * \brief Constructs a explicit_error_stepper_base class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::order( void ) const
+ * \return Returns the order of the stepper if it used without error estimation.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::stepper_order( void ) const
+ * \return Returns the order of a step if the stepper is used without error estimation.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::error_order( void ) const
+ * \return Returns the order of an error step if the stepper is used without error estimation.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other method
+ * the derivative of x is also passed to this method. It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( x , dxdt , t );
+ * stepper.do_step( sys , x , dxdt , t , dt );
+ * \endcode
+ *
+ * The result is updated in place in x. This method is disabled if Time and Deriv are of the same type. In this
+ * case the method could not be distinguished from other `do_step` versions.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * This method is disabled if StateIn and Time are the same type. In this case the method can not be distinguished from
+ * other `do_step` variants.
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the derivative of x at t is passed to the stepper. It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( in , dxdt , t );
+ * stepper.do_step( sys , in , dxdt , t , out , dt );
+ * \endcode
+ *
+ * This method is disabled if DerivIn and Time are of same type.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper and estimates the error. The state of the ODE
+ * is updated in-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. x is updated by this method.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ * \param xerr The estimation of the error is stored in xerr.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other method
+ * the derivative of x is also passed to this method. It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( x , dxdt , t );
+ * stepper.do_step( sys , x , dxdt , t , dt , xerr );
+ * \endcode
+ *
+ * The result is updated in place in x. This method is disabled if Time and DerivIn are of the same type. In this
+ * case the method could not be distinguished from other `do_step` versions.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ * \param xerr The error estimate is stored in xerr.
+ */
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the error is estimated.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ * \param xerr The error estimate.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_base::do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the derivative of x at t is passed to the stepper and the error is estimated. It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( in , dxdt , t );
+ * stepper.do_step( sys , in , dxdt , t , out , dt );
+ * \endcode
+ *
+ * This method is disabled if DerivIn and Time are of same type.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ * \param xerr The error estimate.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_base::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_BASE_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp b/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp
new file mode 100644
index 0000000..b1d751a
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp
@@ -0,0 +1,677 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp
+
+ [begin_description]
+ Base class for all explicit first-same-as-last Runge Kutta steppers.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2012 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/copy.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+/*
+ * base class for explicit stepper and error steppers with the fsal property
+ * models the stepper AND the error stepper fsal concept
+ *
+ * this class provides the following do_step overloads
+ * do_step( sys , x , t , dt )
+ * do_step( sys , x , dxdt , t , dt )
+ * do_step( sys , in , t , out , dt )
+ * do_step( sys , in , dxdt_in , t , out , dxdt_out , dt )
+ * do_step( sys , x , t , dt , xerr )
+ * do_step( sys , x , dxdt , t , dt , xerr )
+ * do_step( sys , in , t , out , dt , xerr )
+ * do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr )
+ */
+template<
+class Stepper ,
+unsigned short Order ,
+unsigned short StepperOrder ,
+unsigned short ErrorOrder ,
+class State ,
+class Value ,
+class Deriv ,
+class Time ,
+class Algebra ,
+class Operations ,
+class Resizer
+>
+class explicit_error_stepper_fsal_base : public algebra_stepper_base< Algebra , Operations >
+{
+public:
+
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Resizer resizer_type;
+ typedef Stepper stepper_type;
+ typedef explicit_error_stepper_fsal_tag stepper_category;
+
+ #ifndef DOXYGEN_SKIP
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef explicit_error_stepper_fsal_base< Stepper , Order , StepperOrder , ErrorOrder ,
+ State , Value , Deriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type;
+ #endif
+
+
+ typedef unsigned short order_type;
+ static const order_type order_value = Order;
+ static const order_type stepper_order_value = StepperOrder;
+ static const order_type error_order_value = ErrorOrder;
+
+ explicit_error_stepper_fsal_base( const algebra_type &algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra ) , m_first_call( true )
+ { }
+
+ order_type order( void ) const
+ {
+ return order_value;
+ }
+
+ order_type stepper_order( void ) const
+ {
+ return stepper_order_value;
+ }
+
+ order_type error_order( void ) const
+ {
+ return error_order_value;
+ }
+
+
+ /*
+ * version 1 : do_step( sys , x , t , dt )
+ *
+ * the two overloads are needed in order to solve the forwarding problem
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+
+ /*
+ * version 2 : do_step( sys , x , dxdt , t , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateInOut , class DerivInOut >
+ typename boost::disable_if< boost::is_same< StateInOut , time_type > , void >::type
+ do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt )
+ {
+ m_first_call = true;
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt );
+ }
+
+
+ /*
+ * named Version 2: do_step_dxdt_impl( sys , in , dxdt , t , dt )
+ *
+ * this version is needed when this stepper is used for initializing
+ * multistep stepper like adams-bashforth. Hence we provide an explicitely
+ * named version that is not disabled. Meant for internal use only.
+ */
+ template< class System , class StateInOut , class DerivInOut >
+ void do_step_dxdt_impl( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt )
+ {
+ m_first_call = true;
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt );
+ }
+
+ /*
+ * version 3 : do_step( sys , in , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not
+ * be used.
+ *
+ * the disable is needed to avoid ambiguous overloads if
+ * state_type = time_type
+ */
+ template< class System , class StateIn , class StateOut >
+ typename boost::disable_if< boost::is_same< StateIn , time_type > , void >::type
+ do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ if( m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , in , t );
+ }
+ this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , m_dxdt.m_v , dt );
+ }
+
+
+ /*
+ * version 4 : do_step( sys , in , dxdt_in , t , out , dxdt_out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System, class StateIn, class DerivIn, class StateOut,
+ class DerivOut >
+ void do_step( System system, const StateIn &in, const DerivIn &dxdt_in,
+ time_type t, StateOut &out, DerivOut &dxdt_out, time_type dt )
+ {
+ m_first_call = true;
+ this->stepper().do_step_impl( system, in, dxdt_in, t, out, dxdt_out,
+ dt );
+ }
+
+
+
+
+
+ /*
+ * version 5 : do_step( sys , x , t , dt , xerr )
+ *
+ * the two overloads are needed in order to solve the forwarding problem
+ */
+ template< class System , class StateInOut , class Err >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ do_step_v5( system , x , t , dt , xerr );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut , class Err >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ do_step_v5( system , x , t , dt , xerr );
+ }
+
+
+ /*
+ * version 6 : do_step( sys , x , dxdt , t , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateInOut , class DerivInOut , class Err >
+ typename boost::disable_if< boost::is_same< StateInOut , time_type > , void >::type
+ do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt , Err &xerr )
+ {
+ m_first_call = true;
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dxdt , dt , xerr );
+ }
+
+
+
+
+ /*
+ * version 7 : do_step( sys , in , t , out , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class StateOut , class Err >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr )
+ {
+ if( m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , in , t );
+ }
+ this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , m_dxdt.m_v , dt , xerr );
+ }
+
+
+ /*
+ * version 8 : do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut , class Err >
+ void do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t ,
+ StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr )
+ {
+ m_first_call = true;
+ this->stepper().do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt , xerr );
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ }
+
+ void reset( void )
+ {
+ m_first_call = true;
+ }
+
+ template< class DerivIn >
+ void initialize( const DerivIn &deriv )
+ {
+ boost::numeric::odeint::copy( deriv , m_dxdt.m_v );
+ m_first_call = false;
+ }
+
+ template< class System , class StateIn >
+ void initialize( System system , const StateIn &x , time_type t )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ sys( x , m_dxdt.m_v , t );
+ m_first_call = false;
+ }
+
+ bool is_initialized( void ) const
+ {
+ return ! m_first_call;
+ }
+
+
+
+private:
+
+ template< class System , class StateInOut >
+ void do_step_v1( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ if( m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , x , t );
+ }
+ this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , m_dxdt.m_v , dt );
+ }
+
+ template< class System , class StateInOut , class Err >
+ void do_step_v5( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ {
+ if( m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , x , t );
+ }
+ this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , m_dxdt.m_v , dt , xerr );
+ }
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+
+ stepper_type& stepper( void )
+ {
+ return *static_cast< stepper_type* >( this );
+ }
+
+ const stepper_type& stepper( void ) const
+ {
+ return *static_cast< const stepper_type* >( this );
+ }
+
+
+ resizer_type m_resizer;
+ bool m_first_call;
+
+protected:
+
+
+ wrapped_deriv_type m_dxdt;
+};
+
+
+/******* DOXYGEN *******/
+
+/**
+ * \class explicit_error_stepper_fsal_base
+ * \brief Base class for explicit steppers with error estimation and stepper fulfilling the FSAL (first-same-as-last)
+ * property. This class can be used with controlled steppers for step size control.
+ *
+ * This class serves as the base class for all explicit steppers with algebra and operations and which fulfill the FSAL
+ * property. In contrast to explicit_stepper_base it also estimates the error and can be used in a controlled stepper
+ * to provide step size control.
+ *
+ * The FSAL property means that the derivative of the system at t+dt is already used in the current step going from
+ * t to t +dt. Therefore, some more do_steps method can be introduced and the controlled steppers can explicitly make use
+ * of this property.
+ *
+ * \note This stepper provides `do_step` methods with and without error estimation. It has therefore three orders,
+ * one for the order of a step if the error is not estimated. The other two orders are the orders of the step and
+ * the error step if the error estimation is performed.
+ *
+ * explicit_error_stepper_fsal_base is used as the interface in a CRTP (currently recurring template
+ * pattern). In order to work correctly the parent class needs to have a method
+ * `do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt , xerr )`.
+ * explicit_error_stepper_fsal_base derives from algebra_stepper_base.
+ *
+ * This class can have an intrinsic state depending on the explicit usage of the `do_step` method. This means that some
+ * `do_step` methods are expected to be called in order. For example the `do_step( sys , x , t , dt , xerr )` will keep track
+ * of the derivative of `x` which is the internal state. The first call of this method is recognized such that one
+ * does not explicitly initialize the internal state, so it is safe to use this method like
+ *
+ * \code
+ * stepper_type stepper;
+ * stepper.do_step( sys , x , t , dt , xerr );
+ * stepper.do_step( sys , x , t , dt , xerr );
+ * stepper.do_step( sys , x , t , dt , xerr );
+ * \endcode
+ *
+ * But it is unsafe to call this method with different system functions after each other. Do do so, one must initialize the
+ * internal state with the `initialize` method or reset the internal state with the `reset` method.
+ *
+ * explicit_error_stepper_fsal_base provides several overloaded `do_step` methods, see the list below. Only two of them are needed
+ * to fulfill the Error Stepper concept. The other ones are for convenience and for better performance. Some of them
+ * simply update the state out-of-place, while other expect that the first derivative at `t` is passed to the stepper.
+ *
+ * - `do_step( sys , x , t , dt )` - The classical `do_step` method needed to fulfill the Error Stepper concept. The
+ * state is updated in-place. A type modelling a Boost.Range can be used for x.
+ * - `do_step( sys , x , dxdt , t , dt )` - This method updates the state x and the derivative dxdt in-place. It is expected
+ * that dxdt has the value of the derivative of x at time t.
+ * - `do_step( sys , in , t , out , dt )` - This method updates the state out-of-place, hence the result of the step
+ * is stored in `out`.
+ * - `do_step( sys , in , dxdt_in , t , out , dxdt_out , dt )` - This method updates the state and the derivative
+ * out-of-place. It expects that the derivative at the point `t` is explicitly passed in `dxdt_in`.
+ * - `do_step( sys , x , t , dt , xerr )` - This `do_step` method is needed to fulfill the Error Stepper concept. The
+ * state is updated in-place and an error estimate is calculated. A type modelling a Boost.Range can be used for x.
+ * - `do_step( sys , x , dxdt , t , dt , xerr )` - This method updates the state and the derivative in-place. It is assumed
+ * that the dxdt has the value of the derivative of x at time t. An error estimate is calculated.
+ * - `do_step( sys , in , t , out , dt , xerr )` - This method updates the state out-of-place and estimates the error
+ * during the step.
+ * - `do_step( sys , in , dxdt_in , t , out , dxdt_out , dt , xerr )` - This methods updates the state and the derivative
+ * out-of-place and estimates the error during the step. It is assumed the dxdt_in is derivative of in at time t.
+ *
+ * \note The system is always passed as value, which might result in poor performance if it contains data. In this
+ * case it can be used with `boost::ref` or `std::ref`, for example `stepper.do_step( boost::ref( sys ) , x , t , dt );`
+ *
+ * \note The time `t` is not advanced by the stepper. This has to done manually, or by the appropriate `integrate`
+ * routines or `iterator`s.
+ *
+ * \tparam Stepper The stepper on which this class should work. It is used via CRTP, hence explicit_stepper_base
+ * provides the interface for the Stepper.
+ * \tparam Order The order of a stepper if the stepper is used without error estimation.
+ * \tparam StepperOrder The order of a step if the stepper is used with error estimation. Usually Order and StepperOrder have
+ * the same value.
+ * \tparam ErrorOrder The order of the error step if the stepper is used with error estimation.
+ * \tparam State The state type for the stepper.
+ * \tparam Value The value type for the stepper. This should be a floating point type, like float,
+ * double, or a multiprecision type. It must not necessary be the value_type of the State. For example
+ * the State can be a `vector< complex< double > >` in this case the Value must be double.
+ * The default value is double.
+ * \tparam Deriv The type representing time derivatives of the state type. It is usually the same type as the
+ * state type, only if used with Boost.Units both types differ.
+ * \tparam Time The type representing the time. Usually the same type as the value type. When Boost.Units is
+ * used, this type has usually a unit.
+ * \tparam Algebra The algebra type which must fulfill the Algebra Concept.
+ * \tparam Operations The type for the operations which must fulfill the Operations Concept.
+ * \tparam Resizer The resizer policy class.
+ */
+
+
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::explicit_error_stepper_fsal_base( const algebra_type &algebra )
+ * \brief Constructs a explicit_stepper_fsal_base class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::order( void ) const
+ * \return Returns the order of the stepper if it used without error estimation.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::stepper_order( void ) const
+ * \return Returns the order of a step if the stepper is used without error estimation.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::error_order( void ) const
+ * \return Returns the order of an error step if the stepper is used without error estimation.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * \note This method uses the internal state of the stepper.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other methods
+ * the derivative of x is also passed to this method. Therefore, dxdt must be evaluated initially:
+ *
+ * \code
+ * ode( x , dxdt , t );
+ * for( ... )
+ * {
+ * stepper.do_step( ode , x , dxdt , t , dt );
+ * t += dt;
+ * }
+ * \endcode
+ *
+ * \note This method does NOT use the initial state, since the first derivative is explicitly passed to this method.
+ *
+ * The result is updated in place in x as well as the derivative dxdt. This method is disabled if
+ * Time and StateInOut are of the same type. In this case the method could not be distinguished from other `do_step`
+ * versions.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param dxdt The derivative of x at t. After calling `do_step` dxdt is updated to the new value.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * This method is disabled if StateIn and Time are the same type. In this case the method can not be distinguished from
+ * other `do_step` variants.
+ *
+ * \note This method uses the internal state of the stepper.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the derivative of x at t is passed to the stepper and updated by the stepper to its new value at
+ * t+dt.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \note This method does NOT use the internal state of the stepper.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt_in The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dxdt_out The updated derivative of `out` at `t+dt`.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , time_type t , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper and estimates the error. The state of the ODE
+ * is updated in-place.
+ *
+ *
+ * \note This method uses the internal state of the stepper.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. x is updated by this method.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ * \param xerr The estimation of the error is stored in xerr.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , StateInOut &x , DerivInOut &dxdt , time_type t , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. Additionally to the other method
+ * the derivative of x is also passed to this method and updated by this method.
+ *
+ * \note This method does NOT use the internal state of the stepper.
+ *
+ * The result is updated in place in x. This method is disabled if Time and Deriv are of the same type. In this
+ * case the method could not be distinguished from other `do_step` versions. This method is disabled if StateInOut and
+ * Time are of the same type.
+ *
+ * \note This method does NOT use the internal state of the stepper.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param dxdt The derivative of x at t. After calling `do_step` this value is updated to the new value at `t+dt`.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ * \param xerr The error estimate is stored in xerr.
+ */
+
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the error is estimated.
+ *
+ * \note This method uses the internal state of the stepper.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ * \param xerr The error estimate.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::do_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr )
+ * \brief The method performs one step with the stepper passed by Stepper. The state of the ODE is updated out-of-place.
+ * Furthermore, the derivative of x at t is passed to the stepper and the error is estimated.
+ *
+ * \note This method does NOT use the internal state of the stepper.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt_in The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dxdt_out The new derivative at `t+dt` is written into this variable.
+ * \param dt The step size.
+ * \param xerr The error estimate.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::reset( void )
+ * \brief Resets the internal state of this stepper. After calling this method it is safe to use all
+ * `do_step` method without explicitly initializing the stepper.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::initialize( const DerivIn &deriv )
+ * \brief Initializes the internal state of the stepper.
+ * \param deriv The derivative of x. The next call of `do_step` expects that the derivative of `x` passed to `do_step`
+ * has the value of `deriv`.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::initialize( System system , const StateIn &x , time_type t )
+ * \brief Initializes the internal state of the stepper.
+ *
+ * This method is equivalent to
+ * \code
+ * Deriv dxdt;
+ * system( x , dxdt , t );
+ * stepper.initialize( dxdt );
+ * \endcode
+ *
+ * \param system The system function for the next calls of `do_step`.
+ * \param x The current state of the ODE.
+ * \param t The current time of the ODE.
+ */
+
+ /**
+ * \fn explicit_error_stepper_fsal_base::is_initialized( void ) const
+ * \brief Returns if the stepper is already initialized. If the stepper is not initialized, the first
+ * call of `do_step` will initialize the state of the stepper. If the stepper is already initialized
+ * the system function can not be safely exchanged between consecutive `do_step` calls.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_ERROR_STEPPER_FSAL_BASE_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp b/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp
new file mode 100644
index 0000000..d81c8c7
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp
@@ -0,0 +1,415 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp
+
+ [begin_description]
+ Base class for all explicit Runge Kutta steppers.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2012 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_STEPPER_BASE_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_STEPPER_BASE_HPP_INCLUDED
+
+
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+/*
+ * base class for explicit steppers
+ * models the stepper concept
+ *
+ * this class provides the following overloads
+ * do_step( sys , x , t , dt )
+ * do_step( sys , in , t , out , dt )
+ * do_step( sys , x , dxdt_in , t , dt )
+ * do_step( sys , in , dxdt_in , t , out , dt )
+ */
+
+template<
+class Stepper ,
+unsigned short Order ,
+class State ,
+class Value ,
+class Deriv ,
+class Time ,
+class Algebra ,
+class Operations ,
+class Resizer
+>
+class explicit_stepper_base : public algebra_stepper_base< Algebra , Operations >
+{
+public:
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_stepper_base< Stepper , Order , State , Value , Deriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type;
+ #endif // DOXYGEN_SKIP
+
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Resizer resizer_type;
+ typedef Stepper stepper_type;
+ typedef stepper_tag stepper_category;
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+ typedef typename algebra_stepper_base_type::operations_type operations_type;
+ typedef unsigned short order_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ #endif // DOXYGEN_SKIP
+
+
+ static const order_type order_value = Order;
+
+
+ explicit_stepper_base( const algebra_type &algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra )
+ { }
+
+ /**
+ * \return Returns the order of the stepper.
+ */
+ order_type order( void ) const
+ {
+ return order_value;
+ }
+
+
+ /*
+ * Version 1 : do_step( sys , x , t , dt )
+ *
+ * the two overloads are needed in order to solve the forwarding problem
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be called with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+ /*
+ * Version 2 : do_step( sys , x , dxdt , t , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ template< class System , class StateInOut , class DerivIn >
+ typename boost::disable_if< boost::is_same< DerivIn , time_type > , void >::type
+ do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt )
+ {
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dt );
+ }
+
+
+ /*
+ * named Version 2: do_step_dxdt_impl( sys , in , dxdt , t , dt )
+ *
+ * this version is needed when this stepper is used for initializing
+ * multistep stepper like adams-bashforth. Hence we provide an explicitely
+ * named version that is not disabled. Meant for internal use only.
+ */
+ template < class System, class StateInOut, class DerivIn >
+ void do_step_dxdt_impl( System system, StateInOut &x, const DerivIn &dxdt,
+ time_type t, time_type dt )
+ {
+ this->stepper().do_step_impl( system , x , dxdt , t , x , dt );
+ }
+
+
+ /*
+ * Version 3 : do_step( sys , in , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( in , detail::bind( &internal_stepper_base_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+ sys( in , m_dxdt.m_v ,t );
+ this->stepper().do_step_impl( system , in , m_dxdt.m_v , t , out , dt );
+ }
+
+
+ /*
+ * Version 4 : do_step( sys , in , dxdt , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ {
+ this->stepper().do_step_impl( system , in , dxdt , t , out , dt );
+ }
+
+
+ /*
+ * named Version 4: do_step_dxdt_impl( sys , in , dxdt , t , out, dt )
+ *
+ * this version is needed when this stepper is used for initializing
+ * multistep stepper like adams-bashforth. Hence we provide an explicitely
+ * named version. Meant for internal use only.
+ */
+ template < class System, class StateIn, class DerivIn, class StateOut >
+ void do_step_dxdt_impl( System system, const StateIn &in,
+ const DerivIn &dxdt, time_type t, StateOut &out,
+ time_type dt )
+ {
+ this->stepper().do_step_impl( system , in , dxdt , t , out , dt );
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ }
+
+private:
+
+ stepper_type& stepper( void )
+ {
+ return *static_cast< stepper_type* >( this );
+ }
+
+ const stepper_type& stepper( void ) const
+ {
+ return *static_cast< const stepper_type* >( this );
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+
+ template< class System , class StateInOut >
+ void do_step_v1( System system , StateInOut &x , time_type t , time_type dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_resizer.adjust_size( x , detail::bind( &internal_stepper_base_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ sys( x , m_dxdt.m_v ,t );
+ this->stepper().do_step_impl( system , x , m_dxdt.m_v , t , x , dt );
+ }
+
+
+ resizer_type m_resizer;
+
+protected:
+
+ wrapped_deriv_type m_dxdt;
+};
+
+
+/******* DOXYGEN *********/
+
+/**
+ * \class explicit_stepper_base
+ * \brief Base class for explicit steppers without step size control and without dense output.
+ *
+ * This class serves as the base class for all explicit steppers with algebra and operations.
+ * Step size control and error estimation as well as dense output are not provided. explicit_stepper_base
+ * is used as the interface in a CRTP (currently recurring template pattern). In order to work
+ * correctly the parent class needs to have a method `do_step_impl( system , in , dxdt_in , t , out , dt )`.
+ * This is method is used by explicit_stepper_base. explicit_stepper_base derives from
+ * algebra_stepper_base. An example how this class can be used is
+ *
+ * \code
+ * template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resizer >
+ * class custom_euler : public explicit_stepper_base< 1 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+ * {
+ * public:
+ *
+ * typedef explicit_stepper_base< 1 , State , Value , Deriv , Time , Algebra , Operations , Resizer > base_type;
+ *
+ * custom_euler( const Algebra &algebra = Algebra() ) { }
+ *
+ * template< class Sys , class StateIn , class DerivIn , class StateOut >
+ * void do_step_impl( Sys sys , const StateIn &in , const DerivIn &dxdt , Time t , StateOut &out , Time dt )
+ * {
+ * m_algebra.for_each3( out , in , dxdt , Operations::scale_sum2< Value , Time >( 1.0 , dt );
+ * }
+ *
+ * template< class State >
+ * void adjust_size( const State &x )
+ * {
+ * base_type::adjust_size( x );
+ * }
+ * };
+ * \endcode
+ *
+ * For the Stepper concept only the `do_step( sys , x , t , dt )` needs to be implemented. But this class
+ * provides additional `do_step` variants since the stepper is explicit. These methods can be used to increase
+ * the performance in some situation, for example if one needs to analyze `dxdt` during each step. In this case
+ * one can use
+ *
+ * \code
+ * sys( x , dxdt , t );
+ * stepper.do_step( sys , x , dxdt , t , dt ); // the value of dxdt is used here
+ * t += dt;
+ * \endcode
+ *
+ * In detail explicit_stepper_base provides the following `do_step` variants
+ * - `do_step( sys , x , t , dt )` - The classical `do_step` method needed to fulfill the Stepper concept. The state is updated in-place.
+ * A type modelling a Boost.Range can be used for x.
+ * - `do_step( sys , in , t , out , dt )` - This method updates the state out-of-place, hence the result of the step is stored in `out`.
+ * - `do_step( sys , x , dxdt , t , dt )` - This method updates the state in-place, but the derivative at the point `t` must be
+ * explicitly passed in `dxdt`. For an example see the code snippet above.
+ * - `do_step( sys , in , dxdt , t , out , dt )` - This method update the state out-of-place and expects that the derivative at the point
+ * `t` is explicitly passed in `dxdt`. It is a combination of the two `do_step` methods above.
+ *
+ * \note The system is always passed as value, which might result in poor performance if it contains data. In this case it can be used with `boost::ref`
+ * or `std::ref`, for example `stepper.do_step( boost::ref( sys ) , x , t , dt );`
+ *
+ * \note The time `t` is not advanced by the stepper. This has to done manually, or by the appropriate `integrate` routines or `iterator`s.
+ *
+ * \tparam Stepper The stepper on which this class should work. It is used via CRTP, hence explicit_stepper_base
+ * provides the interface for the Stepper.
+ * \tparam Order The order of the stepper.
+ * \tparam State The state type for the stepper.
+ * \tparam Value The value type for the stepper. This should be a floating point type, like float,
+ * double, or a multiprecision type. It must not necessary be the value_type of the State. For example
+ * the State can be a `vector< complex< double > >` in this case the Value must be double.
+ * The default value is double.
+ * \tparam Deriv The type representing time derivatives of the state type. It is usually the same type as the
+ * state type, only if used with Boost.Units both types differ.
+ * \tparam Time The type representing the time. Usually the same type as the value type. When Boost.Units is
+ * used, this type has usually a unit.
+ * \tparam Algebra The algebra type which must fulfill the Algebra Concept.
+ * \tparam Operations The type for the operations which must fulfill the Operations Concept.
+ * \tparam Resizer The resizer policy class.
+ */
+
+
+ /**
+ * \fn explicit_stepper_base::explicit_stepper_base( const algebra_type &algebra )
+ * \brief Constructs a explicit_stepper_base class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn explicit_stepper_base::order_type order( void ) const
+ * \return Returns the order of the stepper.
+ */
+
+ /**
+ * \fn explicit_stepper_base::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn explicit_stepper_base::do_step( System system , StateInOut &x , const DerivIn &dxdt , time_type t , time_type dt )
+
+ * \brief The method performs one step. Additionally to the other method
+ * the derivative of x is also passed to this method. It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( x , dxdt , t );
+ * stepper.do_step( sys , x , dxdt , t , dt );
+ * \endcode
+ *
+ * The result is updated in place in x. This method is disabled if Time and Deriv are of the same type. In this
+ * case the method could not be distinguished from other `do_step` versions.
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. After calling do_step the result is updated in x.
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void explicit_stepper_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step. The state of the ODE is updated out-of-place.
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void explicit_stepper_base::do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief The method performs one step. The state of the ODE is updated out-of-place.
+ * Furthermore, the derivative of x at t is passed to the stepper.
+ * It is supposed to be used in the following way:
+ *
+ * \code
+ * sys( in , dxdt , t );
+ * stepper.do_step( sys , in , dxdt , t , out , dt );
+ * \endcode
+ *
+ * \note This method does not solve the forwarding problem.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn void explicit_stepper_base::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_EXPLICIT_STEPPER_BASE_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp b/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp
new file mode 100644
index 0000000..eb09aef
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp
@@ -0,0 +1,431 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp
+
+ [begin_description]
+ Base class for symplectic Runge-Kutta-Nystrom steppers.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BASE_SYMPLECTIC_RKN_STEPPER_BASE_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BASE_SYMPLECTIC_RKN_STEPPER_BASE_HPP_INCLUDED
+
+#include <boost/array.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/util/copy.hpp>
+#include <boost/numeric/odeint/util/is_pair.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template<
+size_t NumOfStages ,
+unsigned short Order ,
+class Coor ,
+class Momentum ,
+class Value ,
+class CoorDeriv ,
+class MomentumDeriv ,
+class Time ,
+class Algebra ,
+class Operations ,
+class Resizer
+>
+class symplectic_nystroem_stepper_base : public algebra_stepper_base< Algebra , Operations >
+{
+
+public:
+
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+ typedef typename algebra_stepper_base_type::operations_type operations_type;
+
+ const static size_t num_of_stages = NumOfStages;
+ typedef Coor coor_type;
+ typedef Momentum momentum_type;
+ typedef std::pair< coor_type , momentum_type > state_type;
+ typedef CoorDeriv coor_deriv_type;
+ typedef state_wrapper< coor_deriv_type> wrapped_coor_deriv_type;
+ typedef MomentumDeriv momentum_deriv_type;
+ typedef state_wrapper< momentum_deriv_type > wrapped_momentum_deriv_type;
+ typedef std::pair< coor_deriv_type , momentum_deriv_type > deriv_type;
+ typedef Value value_type;
+ typedef Time time_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+
+ #ifndef DOXYGEN_SKIP
+ typedef symplectic_nystroem_stepper_base< NumOfStages , Order , Coor , Momentum , Value ,
+ CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer > internal_stepper_base_type;
+ #endif
+ typedef unsigned short order_type;
+
+ static const order_type order_value = Order;
+
+ typedef boost::array< value_type , num_of_stages > coef_type;
+
+ symplectic_nystroem_stepper_base( const coef_type &coef_a , const coef_type &coef_b , const algebra_type &algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra ) , m_coef_a( coef_a ) , m_coef_b( coef_b ) ,
+ m_dqdt_resizer() , m_dpdt_resizer() , m_dqdt() , m_dpdt()
+ { }
+
+
+ order_type order( void ) const
+ {
+ return order_value;
+ }
+
+ /*
+ * Version 1 : do_step( system , x , t , dt )
+ *
+ * This version does not solve the forwarding problem, boost.range can not be used.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut &state , time_type t , time_type dt )
+ {
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ do_step_impl( system , state , t , state , dt , typename is_pair< system_type >::type() );
+ }
+
+ /**
+ * \brief Same function as above. It differs only in a different const specifier in order
+ * to solve the forwarding problem, can be used with Boost.Range.
+ */
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut &state , time_type t , time_type dt )
+ {
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ do_step_impl( system , state , t , state , dt , typename is_pair< system_type >::type() );
+ }
+
+
+
+
+ /*
+ * Version 2 : do_step( system , q , p , t , dt );
+ *
+ * For Convenience
+ *
+ * The two overloads are needed in order to solve the forwarding problem.
+ */
+ template< class System , class CoorInOut , class MomentumInOut >
+ void do_step( System system , CoorInOut &q , MomentumInOut &p , time_type t , time_type dt )
+ {
+ do_step( system , std::make_pair( detail::ref( q ) , detail::ref( p ) ) , t , dt );
+ }
+
+ /**
+ * \brief Same function as do_step( system , q , p , t , dt ). It differs only in a different const specifier in order
+ * to solve the forwarding problem, can be called with Boost.Range.
+ */
+ template< class System , class CoorInOut , class MomentumInOut >
+ void do_step( System system , const CoorInOut &q , const MomentumInOut &p , time_type t , time_type dt )
+ {
+ do_step( system , std::make_pair( detail::ref( q ) , detail::ref( p ) ) , t , dt );
+ }
+
+
+
+
+
+ /*
+ * Version 3 : do_step( system , in , t , out , dt )
+ *
+ * The forwarding problem is not solved in this version
+ */
+ template< class System , class StateIn , class StateOut >
+ void do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ {
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ do_step_impl( system , in , t , out , dt , typename is_pair< system_type >::type() );
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_dqdt( x );
+ resize_dpdt( x );
+ }
+
+ /** \brief Returns the coefficients a. */
+ const coef_type& coef_a( void ) const { return m_coef_a; }
+
+ /** \brief Returns the coefficients b. */
+ const coef_type& coef_b( void ) const { return m_coef_b; }
+
+private:
+
+ // stepper for systems with function for dq/dt = f(p) and dp/dt = -f(q)
+ template< class System , class StateIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , time_type /* t */ , StateOut &out , time_type dt , boost::mpl::true_ )
+ {
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ typedef typename odeint::unwrap_reference< typename system_type::first_type >::type coor_deriv_func_type;
+ typedef typename odeint::unwrap_reference< typename system_type::second_type >::type momentum_deriv_func_type;
+ system_type &sys = system;
+ coor_deriv_func_type &coor_func = sys.first;
+ momentum_deriv_func_type &momentum_func = sys.second;
+
+ typedef typename odeint::unwrap_reference< StateIn >::type state_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
+ const state_in_type &state_in = in;
+ const coor_in_type &coor_in = state_in.first;
+ const momentum_in_type &momentum_in = state_in.second;
+
+ typedef typename odeint::unwrap_reference< StateOut >::type state_out_type;
+ typedef typename odeint::unwrap_reference< typename state_out_type::first_type >::type coor_out_type;
+ typedef typename odeint::unwrap_reference< typename state_out_type::second_type >::type momentum_out_type;
+ state_out_type &state_out = out;
+ coor_out_type &coor_out = state_out.first;
+ momentum_out_type &momentum_out = state_out.second;
+
+ m_dqdt_resizer.adjust_size( coor_in , detail::bind( &internal_stepper_base_type::template resize_dqdt< coor_in_type > , detail::ref( *this ) , detail::_1 ) );
+ m_dpdt_resizer.adjust_size( momentum_in , detail::bind( &internal_stepper_base_type::template resize_dpdt< momentum_in_type > , detail::ref( *this ) , detail::_1 ) );
+
+ // ToDo: check sizes?
+
+ for( size_t l=0 ; l<num_of_stages ; ++l )
+ {
+ if( l == 0 )
+ {
+ coor_func( momentum_in , m_dqdt.m_v );
+ this->m_algebra.for_each3( coor_out , coor_in , m_dqdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
+ momentum_func( coor_out , m_dpdt.m_v );
+ this->m_algebra.for_each3( momentum_out , momentum_in , m_dpdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
+ }
+ else
+ {
+ coor_func( momentum_out , m_dqdt.m_v );
+ this->m_algebra.for_each3( coor_out , coor_out , m_dqdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
+ momentum_func( coor_out , m_dpdt.m_v );
+ this->m_algebra.for_each3( momentum_out , momentum_out , m_dpdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
+ }
+ }
+ }
+
+
+ // stepper for systems with only function dp /dt = -f(q), dq/dt = p, time not required but still expected for compatibility reasons
+ template< class System , class StateIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , time_type /* t */ , StateOut &out , time_type dt , boost::mpl::false_ )
+ {
+ typedef typename odeint::unwrap_reference< System >::type momentum_deriv_func_type;
+ momentum_deriv_func_type &momentum_func = system;
+
+ typedef typename odeint::unwrap_reference< StateIn >::type state_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
+ const state_in_type &state_in = in;
+ const coor_in_type &coor_in = state_in.first;
+ const momentum_in_type &momentum_in = state_in.second;
+
+ typedef typename odeint::unwrap_reference< StateOut >::type state_out_type;
+ typedef typename odeint::unwrap_reference< typename state_out_type::first_type >::type coor_out_type;
+ typedef typename odeint::unwrap_reference< typename state_out_type::second_type >::type momentum_out_type;
+ state_out_type &state_out = out;
+ coor_out_type &coor_out = state_out.first;
+ momentum_out_type &momentum_out = state_out.second;
+
+
+ // m_dqdt not required when called with momentum_func only - don't resize
+ // m_dqdt_resizer.adjust_size( coor_in , detail::bind( &internal_stepper_base_type::template resize_dqdt< coor_in_type > , detail::ref( *this ) , detail::_1 ) );
+ m_dpdt_resizer.adjust_size( momentum_in , detail::bind( &internal_stepper_base_type::template resize_dpdt< momentum_in_type > , detail::ref( *this ) , detail::_1 ) );
+
+
+ // ToDo: check sizes?
+
+ // step 0
+ this->m_algebra.for_each3( coor_out , coor_in , momentum_in ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[0] * dt ) );
+ momentum_func( coor_out , m_dpdt.m_v );
+ this->m_algebra.for_each3( momentum_out , momentum_in , m_dpdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[0] * dt ) );
+
+ for( size_t l=1 ; l<num_of_stages ; ++l )
+ {
+ this->m_algebra.for_each3( coor_out , coor_out , momentum_out ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_a[l] * dt ) );
+ momentum_func( coor_out , m_dpdt.m_v );
+ this->m_algebra.for_each3( momentum_out , momentum_out , m_dpdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , m_coef_b[l] * dt ) );
+ }
+ }
+
+ template< class StateIn >
+ bool resize_dqdt( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dqdt , x , typename is_resizeable<coor_deriv_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_dpdt( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dpdt , x , typename is_resizeable<momentum_deriv_type>::type() );
+ }
+
+
+ const coef_type m_coef_a;
+ const coef_type m_coef_b;
+
+ resizer_type m_dqdt_resizer;
+ resizer_type m_dpdt_resizer;
+ wrapped_coor_deriv_type m_dqdt;
+ wrapped_momentum_deriv_type m_dpdt;
+
+};
+
+/********* DOXYGEN *********/
+
+/**
+ * \class symplectic_nystroem_stepper_base
+ * \brief Base class for all symplectic steppers of Nystroem type.
+ *
+ * This class is the base class for the symplectic Runge-Kutta-Nystroem steppers. Symplectic steppers are usually
+ * used to solve Hamiltonian systems and they conserve the phase space volume, see
+ * <a href="http://en.wikipedia.org/wiki/Symplectic_integrator">en.wikipedia.org/wiki/Symplectic_integrator</a>.
+ * Furthermore, the energy is conserved
+ * in average. In detail this class of steppers can be used to solve separable Hamiltonian systems which can be written
+ * in the form H(q,p) = H1(p) + H2(q). q is usually called the coordinate, while p is the momentum. The equations of motion
+ * are dq/dt = dH1/dp, dp/dt = -dH2/dq.
+ *
+ * ToDo : add formula for solver and explanation of the coefficients
+ *
+ * symplectic_nystroem_stepper_base uses odeints algebra and operation system. Step size and error estimation are not
+ * provided for this class of solvers. It derives from algebra_stepper_base. Several `do_step` variants are provided:
+ *
+ * - `do_step( sys , x , t , dt )` - The classical `do_step` method. The sys can be either a pair of function objects
+ * for the coordinate or the momentum part or one function object for the momentum part. `x` is a pair of coordinate
+ * and momentum. The state is updated in-place.
+ * - `do_step( sys , q , p , t , dt )` - This method is similar to the method above with the difference that the coordinate
+ * and the momentum are passed explicitly and not packed into a pair.
+ * - `do_step( sys , x_in , t , x_out , dt )` - This method transforms the state out-of-place. `x_in` and `x_out` are here pairs
+ * of coordinate and momentum.
+ *
+ * \tparam NumOfStages Number of stages.
+ * \tparam Order The order of the stepper.
+ * \tparam Coor The type representing the coordinates q.
+ * \tparam Momentum The type representing the coordinates p.
+ * \tparam Value The basic value type. Should be something like float, double or a high-precision type.
+ * \tparam CoorDeriv The type representing the time derivative of the coordinate dq/dt.
+ * \tparam MomemtnumDeriv The type representing the time derivative of the momentum dp/dt.
+ * \tparam Time The type representing the time t.
+ * \tparam Algebra The algebra.
+ * \tparam Operations The operations.
+ * \tparam Resizer The resizer policy.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::symplectic_nystroem_stepper_base( const coef_type &coef_a , const coef_type &coef_b , const algebra_type &algebra )
+ * \brief Constructs a symplectic_nystroem_stepper_base class. The parameters of the specific Nystroem method and the
+ * algebra have to be passed.
+ * \param coef_a The coefficients a.
+ * \param coef_b The coefficients b.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::order( void ) const
+ * \return Returns the order of the stepper.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::do_step( System system , const StateInOut &state , time_type t , time_type dt )
+ * \brief This method performs one step. The system can be either a pair of two function object
+ * describing the momentum part and the coordinate part or one function object describing only
+ * the momentum part. In this case the coordinate is assumed to be trivial dq/dt = p. The state
+ * is updated in-place.
+ *
+ * \note boost::ref or std::ref can be used for the system as well as for the state. So, it is correct
+ * to write `stepper.do_step( make_pair( std::ref( fq ) , std::ref( fp ) ) , make_pair( std::ref( q ) , std::ref( p ) ) , t , dt )`.
+ *
+ * \note This method solves the forwarding problem.
+ *
+ * \param system The system, can be represented as a pair of two function object or one function object. See above.
+ * \param state The state of the ODE. It is a pair of Coor and Momentum. The state is updated in-place, therefore, the
+ * new value of the state will be written into this variable.
+ * \param t The time of the ODE. It is not advanced by this method.
+ * \param dt The time step.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::do_step( System system , CoorInOut &q , MomentumInOut &p , time_type t , time_type dt )
+ * \brief This method performs one step. The system can be either a pair of two function object
+ * describing the momentum part and the coordinate part or one function object describing only
+ * the momentum part. In this case the coordinate is assumed to be trivial dq/dt = p. The state
+ * is updated in-place.
+ *
+ * \note boost::ref or std::ref can be used for the system. So, it is correct
+ * to write `stepper.do_step( make_pair( std::ref( fq ) , std::ref( fp ) ) , q , p , t , dt )`.
+ *
+ * \note This method solves the forwarding problem.
+ *
+ * \param system The system, can be represented as a pair of two function object or one function object. See above.
+ * \param q The coordinate of the ODE. It is updated in-place. Therefore, the new value of the coordinate will be written
+ * into this variable.
+ * \param p The momentum of the ODE. It is updated in-place. Therefore, the new value of the momentum will be written info
+ * this variable.
+ * \param t The time of the ODE. It is not advanced by this method.
+ * \param dt The time step.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::do_step( System system , const StateIn &in , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The system can be either a pair of two function object
+ * describing the momentum part and the coordinate part or one function object describing only
+ * the momentum part. In this case the coordinate is assumed to be trivial dq/dt = p. The state
+ * is updated out-of-place.
+ *
+ * \note boost::ref or std::ref can be used for the system. So, it is correct
+ * to write `stepper.do_step( make_pair( std::ref( fq ) , std::ref( fp ) ) , x_in , t , x_out , dt )`.
+ *
+ * \note This method NOT solve the forwarding problem.
+ *
+ * \param system The system, can be represented as a pair of two function object or one function object. See above.
+ * \param in The state of the ODE, which is a pair of coordinate and momentum. The state is updated out-of-place, therefore the
+ * new value is written into out
+ * \param t The time of the ODE. It is not advanced by this method.
+ * \param out The new state of the ODE.
+ * \param dt The time step.
+ */
+
+ /**
+ * \fn symplectic_nystroem_stepper_base::adjust_size( const StateType &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BASE_SYMPLECTIC_RKN_STEPPER_BASE_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp
new file mode 100644
index 0000000..02c3749
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp
@@ -0,0 +1,642 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/bulirsch_stoer.hpp
+
+ [begin_description]
+ Implementation of the Burlish-Stoer method. As described in
+ Ernst Hairer, Syvert Paul Norsett, Gerhard Wanner
+ Solving Ordinary Differential Equations I. Nonstiff Problems.
+ Springer Series in Comput. Mathematics, Vol. 8, Springer-Verlag 1987, Second revised edition 1993.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_HPP_INCLUDED
+
+
+#include <iostream>
+
+#include <algorithm>
+
+#include <boost/config.hpp> // for min/max guidelines
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/modified_midpoint.hpp>
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/unit_helper.hpp>
+#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template<
+ class State ,
+ class Value = double ,
+ class Deriv = State ,
+ class Time = Value ,
+ class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+ class Operations = typename operations_dispatcher< State >::operations_type ,
+ class Resizer = initially_resizer
+ >
+class bulirsch_stoer {
+
+public:
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+ typedef Resizer resizer_type;
+#ifndef DOXYGEN_SKIP
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef controlled_stepper_tag stepper_category;
+
+ typedef bulirsch_stoer< State , Value , Deriv , Time , Algebra , Operations , Resizer > controlled_error_bs_type;
+
+ typedef typename inverse_time< time_type >::type inv_time_type;
+
+ typedef std::vector< value_type > value_vector;
+ typedef std::vector< time_type > time_vector;
+ typedef std::vector< inv_time_type > inv_time_vector; //should be 1/time_type for boost.units
+ typedef std::vector< value_vector > value_matrix;
+ typedef std::vector< size_t > int_vector;
+ typedef std::vector< wrapped_state_type > state_table_type;
+#endif //DOXYGEN_SKIP
+ const static size_t m_k_max = 8;
+
+ bulirsch_stoer(
+ value_type eps_abs = 1E-6 , value_type eps_rel = 1E-6 ,
+ value_type factor_x = 1.0 , value_type factor_dxdt = 1.0 ,
+ time_type max_dt = static_cast<time_type>(0))
+ : m_error_checker( eps_abs , eps_rel , factor_x, factor_dxdt ) , m_midpoint() ,
+ m_last_step_rejected( false ) , m_first( true ) ,
+ m_max_dt(max_dt) ,
+ m_interval_sequence( m_k_max+1 ) ,
+ m_coeff( m_k_max+1 ) ,
+ m_cost( m_k_max+1 ) ,
+ m_facmin_table( m_k_max+1 ) ,
+ m_table( m_k_max ) ,
+ STEPFAC1( 0.65 ) , STEPFAC2( 0.94 ) , STEPFAC3( 0.02 ) , STEPFAC4( 4.0 ) , KFAC1( 0.8 ) , KFAC2( 0.9 )
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ /* initialize sequence of stage numbers and work */
+ for( unsigned short i = 0; i < m_k_max+1; i++ )
+ {
+ m_interval_sequence[i] = 2 * (i+1);
+ if( i == 0 )
+ m_cost[i] = m_interval_sequence[i];
+ else
+ m_cost[i] = m_cost[i-1] + m_interval_sequence[i];
+ m_coeff[i].resize(i);
+ m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast< value_type >(1) / static_cast< value_type >( 2*i+1 ) );
+ for( size_t k = 0 ; k < i ; ++k )
+ {
+ const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] );
+ m_coeff[i][k] = 1.0 / ( r*r - static_cast< value_type >( 1.0 ) ); // coefficients for extrapolation
+ }
+ }
+ reset();
+ }
+
+
+ /*
+ * Version 1 : try_step( sys , x , t , dt )
+ *
+ * The overloads are needed to solve the forwarding problem
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t, dt );
+ }
+
+ /**
+ * \brief Second version to solve the forwarding problem, can be used with Boost.Range as StateInOut.
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , const StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t, dt );
+ }
+
+ /*
+ * Version 2 : try_step( sys , x , dxdt , t , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateInOut , class DerivIn >
+ controlled_step_result try_step( System system , StateInOut &x , const DerivIn &dxdt , time_type &t , time_type &dt )
+ {
+ m_xnew_resizer.adjust_size( x , detail::bind( &controlled_error_bs_type::template resize_m_xnew< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , dt );
+ if( res == success )
+ {
+ boost::numeric::odeint::copy( m_xnew.m_v , x );
+ }
+ return res;
+ }
+
+ /*
+ * Version 3 : try_step( sys , in , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ template< class System , class StateIn , class StateOut >
+ typename boost::disable_if< boost::is_same< StateIn , time_type > , controlled_step_result >::type
+ try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_error_bs_type::template resize_m_dxdt< StateIn > , detail::ref( *this ) , detail::_1 ) );
+ sys( in , m_dxdt.m_v , t );
+ return try_step( system , in , m_dxdt.m_v , t , out , dt );
+ }
+
+
+ /*
+ * Full version : try_step( sys , in , dxdt_in , t , out , dt )
+ *
+ * contains the actual implementation
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , time_type &dt )
+ {
+ if( m_max_dt != static_cast<time_type>(0) && detail::less_with_sign(m_max_dt, dt, dt) )
+ {
+ // given step size is bigger then max_dt
+ // set limit and return fail
+ dt = m_max_dt;
+ return fail;
+ }
+
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+
+ static const value_type val1( 1.0 );
+
+ if( m_resizer.adjust_size( in , detail::bind( &controlled_error_bs_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) )
+ {
+ reset(); // system resized -> reset
+ }
+
+ if( dt != m_dt_last )
+ {
+ reset(); // step size changed from outside -> reset
+ }
+
+ bool reject( true );
+
+ time_vector h_opt( m_k_max+1 );
+ inv_time_vector work( m_k_max+1 );
+
+ time_type new_h = dt;
+
+ /* m_current_k_opt is the estimated current optimal stage number */
+ for( size_t k = 0 ; k <= m_current_k_opt+1 ; k++ )
+ {
+ /* the stage counts are stored in m_interval_sequence */
+ m_midpoint.set_steps( m_interval_sequence[k] );
+ if( k == 0 )
+ {
+ m_midpoint.do_step( system , in , dxdt , t , out , dt );
+ /* the first step, nothing more to do */
+ }
+ else
+ {
+ m_midpoint.do_step( system , in , dxdt , t , m_table[k-1].m_v , dt );
+ extrapolate( k , m_table , m_coeff , out );
+ // get error estimate
+ m_algebra.for_each3( m_err.m_v , out , m_table[0].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 , -val1 ) );
+ const value_type error = m_error_checker.error( m_algebra , in , dxdt , m_err.m_v , dt );
+ h_opt[k] = calc_h_opt( dt , error , k );
+ work[k] = static_cast<value_type>( m_cost[k] ) / h_opt[k];
+
+ if( (k == m_current_k_opt-1) || m_first )
+ { // convergence before k_opt ?
+ if( error < 1.0 )
+ {
+ //convergence
+ reject = false;
+ if( (work[k] < KFAC2*work[k-1]) || (m_current_k_opt <= 2) )
+ {
+ // leave order as is (except we were in first round)
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(k)+1 ) );
+ new_h = h_opt[k];
+ new_h *= static_cast<value_type>( m_cost[k+1] ) / static_cast<value_type>( m_cost[k] );
+ } else {
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(k) ) );
+ new_h = h_opt[k];
+ }
+ break;
+ }
+ else if( should_reject( error , k ) && !m_first )
+ {
+ reject = true;
+ new_h = h_opt[k];
+ break;
+ }
+ }
+ if( k == m_current_k_opt )
+ { // convergence at k_opt ?
+ if( error < 1.0 )
+ {
+ //convergence
+ reject = false;
+ if( (work[k-1] < KFAC2*work[k]) )
+ {
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(m_current_k_opt)-1 );
+ new_h = h_opt[m_current_k_opt];
+ }
+ else if( (work[k] < KFAC2*work[k-1]) && !m_last_step_rejected )
+ {
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max-1) , static_cast<int>(m_current_k_opt)+1 );
+ new_h = h_opt[k];
+ new_h *= static_cast<value_type>(m_cost[m_current_k_opt])/static_cast<value_type>(m_cost[k]);
+ } else
+ new_h = h_opt[m_current_k_opt];
+ break;
+ }
+ else if( should_reject( error , k ) )
+ {
+ reject = true;
+ new_h = h_opt[m_current_k_opt];
+ break;
+ }
+ }
+ if( k == m_current_k_opt+1 )
+ { // convergence at k_opt+1 ?
+ if( error < 1.0 )
+ { //convergence
+ reject = false;
+ if( work[k-2] < KFAC2*work[k-1] )
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(m_current_k_opt)-1 );
+ if( (work[k] < KFAC2*work[m_current_k_opt]) && !m_last_step_rejected )
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , static_cast<int>(k) );
+ new_h = h_opt[m_current_k_opt];
+ } else
+ {
+ reject = true;
+ new_h = h_opt[m_current_k_opt];
+ }
+ break;
+ }
+ }
+ }
+
+ if( !reject )
+ {
+ t += dt;
+ }
+
+ if( !m_last_step_rejected || boost::numeric::odeint::detail::less_with_sign(new_h, dt, dt) )
+ {
+ // limit step size
+ if( m_max_dt != static_cast<time_type>(0) )
+ {
+ new_h = detail::min_abs(m_max_dt, new_h);
+ }
+ m_dt_last = new_h;
+ dt = new_h;
+ }
+
+ m_last_step_rejected = reject;
+ m_first = false;
+
+ if( reject )
+ return fail;
+ else
+ return success;
+ }
+
+ /** \brief Resets the internal state of the stepper */
+ void reset()
+ {
+ m_first = true;
+ m_last_step_rejected = false;
+ // crude estimate of optimal order
+ m_current_k_opt = 4;
+ /* no calculation because log10 might not exist for value_type!
+ const value_type logfact( -log10( max BOOST_PREVENT_MACRO_SUBSTITUTION( eps_rel , static_cast< value_type >(1.0E-12) ) ) * 0.6 + 0.5 );
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>( 1 ) , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>( m_k_max-1 ) , logfact ));
+ */
+ }
+
+
+ /* Resizer methods */
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_m_dxdt( x );
+ resize_m_xnew( x );
+ resize_impl( x );
+ m_midpoint.adjust_size( x );
+ }
+
+
+private:
+
+ template< class StateIn >
+ bool resize_m_dxdt( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_xnew( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ for( size_t i = 0 ; i < m_k_max ; ++i )
+ resized |= adjust_size_by_resizeability( m_table[i] , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_err , x , typename is_resizeable<state_type>::type() );
+ return resized;
+ }
+
+
+ template< class System , class StateInOut >
+ controlled_step_result try_step_v1( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_dxdt_resizer.adjust_size( x , detail::bind( &controlled_error_bs_type::template resize_m_dxdt< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ sys( x , m_dxdt.m_v ,t );
+ return try_step( system , x , m_dxdt.m_v , t , dt );
+ }
+
+
+ template< class StateInOut >
+ void extrapolate( size_t k , state_table_type &table , const value_matrix &coeff , StateInOut &xest )
+ /* polynomial extrapolation, see http://www.nr.com/webnotes/nr3web21.pdf
+ uses the obtained intermediate results to extrapolate to dt->0
+ */
+ {
+ static const value_type val1 = static_cast< value_type >( 1.0 );
+ for( int j=k-1 ; j>0 ; --j )
+ {
+ m_algebra.for_each3( table[j-1].m_v , table[j].m_v , table[j-1].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k][j] , -coeff[k][j] ) );
+ }
+ m_algebra.for_each3( xest , table[0].m_v , xest ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k][0] , -coeff[k][0]) );
+ }
+
+ time_type calc_h_opt( time_type h , value_type error , size_t k ) const
+ /* calculates the optimal step size for a given error and stage number */
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+ value_type expo( 1.0/(2*k+1) );
+ value_type facmin = m_facmin_table[k];
+ value_type fac;
+ if (error == 0.0)
+ fac=1.0/facmin;
+ else
+ {
+ fac = STEPFAC2 / pow BOOST_PREVENT_MACRO_SUBSTITUTION( error / STEPFAC1 , expo );
+ fac = max BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>(facmin/STEPFAC4) , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>(1.0/facmin) , fac ) );
+ }
+ return h*fac;
+ }
+
+ controlled_step_result set_k_opt( size_t k , const inv_time_vector &work , const time_vector &h_opt , time_type &dt )
+ /* calculates the optimal stage number */
+ {
+ if( k == 1 )
+ {
+ m_current_k_opt = 2;
+ return success;
+ }
+ if( (work[k-1] < KFAC1*work[k]) || (k == m_k_max) )
+ { // order decrease
+ m_current_k_opt = k-1;
+ dt = h_opt[ m_current_k_opt ];
+ return success;
+ }
+ else if( (work[k] < KFAC2*work[k-1]) || m_last_step_rejected || (k == m_k_max-1) )
+ { // same order - also do this if last step got rejected
+ m_current_k_opt = k;
+ dt = h_opt[ m_current_k_opt ];
+ return success;
+ }
+ else
+ { // order increase - only if last step was not rejected
+ m_current_k_opt = k+1;
+ dt = h_opt[ m_current_k_opt-1 ] * m_cost[ m_current_k_opt ] / m_cost[ m_current_k_opt-1 ] ;
+ return success;
+ }
+ }
+
+ bool in_convergence_window( size_t k ) const
+ {
+ if( (k == m_current_k_opt-1) && !m_last_step_rejected )
+ return true; // decrease stepsize only if last step was not rejected
+ return ( (k == m_current_k_opt) || (k == m_current_k_opt+1) );
+ }
+
+ bool should_reject( value_type error , size_t k ) const
+ {
+ if( k == m_current_k_opt-1 )
+ {
+ const value_type d = m_interval_sequence[m_current_k_opt] * m_interval_sequence[m_current_k_opt+1] /
+ (m_interval_sequence[0]*m_interval_sequence[0]);
+ //step will fail, criterion 17.3.17 in NR
+ return ( error > d*d );
+ }
+ else if( k == m_current_k_opt )
+ {
+ const value_type d = m_interval_sequence[m_current_k_opt] / m_interval_sequence[0];
+ return ( error > d*d );
+ } else
+ return error > 1.0;
+ }
+
+ default_error_checker< value_type, algebra_type , operations_type > m_error_checker;
+ modified_midpoint< state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type > m_midpoint;
+
+ bool m_last_step_rejected;
+ bool m_first;
+
+ time_type m_dt_last;
+ time_type m_t_last;
+ time_type m_max_dt;
+
+ size_t m_current_k_opt;
+
+ algebra_type m_algebra;
+
+ resizer_type m_dxdt_resizer;
+ resizer_type m_xnew_resizer;
+ resizer_type m_resizer;
+
+ wrapped_state_type m_xnew;
+ wrapped_state_type m_err;
+ wrapped_deriv_type m_dxdt;
+
+ int_vector m_interval_sequence; // stores the successive interval counts
+ value_matrix m_coeff;
+ int_vector m_cost; // costs for interval count
+ value_vector m_facmin_table; // for precomputed facmin to save pow calls
+
+ state_table_type m_table; // sequence of states for extrapolation
+
+ value_type STEPFAC1 , STEPFAC2 , STEPFAC3 , STEPFAC4 , KFAC1 , KFAC2;
+};
+
+
+/******** DOXYGEN ********/
+/**
+ * \class bulirsch_stoer
+ * \brief The Bulirsch-Stoer algorithm.
+ *
+ * The Bulirsch-Stoer is a controlled stepper that adjusts both step size
+ * and order of the method. The algorithm uses the modified midpoint and
+ * a polynomial extrapolation compute the solution.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+ /**
+ * \fn bulirsch_stoer::bulirsch_stoer( value_type eps_abs , value_type eps_rel , value_type factor_x , value_type factor_dxdt )
+ * \brief Constructs the bulirsch_stoer class, including initialization of
+ * the error bounds.
+ *
+ * \param eps_abs Absolute tolerance level.
+ * \param eps_rel Relative tolerance level.
+ * \param factor_x Factor for the weight of the state.
+ * \param factor_dxdt Factor for the weight of the derivative.
+ */
+
+ /**
+ * \fn bulirsch_stoer::try_step( System system , StateInOut &x , time_type &t , time_type &dt )
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed. Also, the internal order of the stepper is adjusted if required.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE.
+ * It must fulfill the Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+
+ /**
+ * \fn bulirsch_stoer::try_step( System system , StateInOut &x , const DerivIn &dxdt , time_type &t , time_type &dt )
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed. Also, the internal order of the stepper is adjusted if required.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE.
+ * It must fulfill the Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+
+ /**
+ * \fn bulirsch_stoer::try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
+ * \brief Tries to perform one step.
+ *
+ * \note This method is disabled if state_type=time_type to avoid ambiguity.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed. Also, the internal order of the stepper is adjusted if required.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE.
+ * It must fulfill the Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+
+
+ /**
+ * \fn bulirsch_stoer::try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , time_type &dt )
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed. Also, the internal order of the stepper is adjusted if required.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE.
+ * It must fulfill the Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+
+
+ /**
+ * \fn bulirsch_stoer::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
new file mode 100644
index 0000000..6a1eed1
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
@@ -0,0 +1,838 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp
+
+ [begin_description]
+ Implementaiton of the Burlish-Stoer method with dense output
+ [end_description]
+
+ Copyright 2011-2015 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_DENSE_OUT_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_DENSE_OUT_HPP_INCLUDED
+
+
+#include <iostream>
+
+#include <algorithm>
+
+#include <boost/config.hpp> // for min/max guidelines
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/math/special_functions/binomial.hpp>
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/modified_midpoint.hpp>
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/unit_helper.hpp>
+
+#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
+
+#include <boost/type_traits.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template<
+ class State ,
+ class Value = double ,
+ class Deriv = State ,
+ class Time = Value ,
+ class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+ class Operations = typename operations_dispatcher< State >::operations_type ,
+ class Resizer = initially_resizer
+ >
+class bulirsch_stoer_dense_out {
+
+
+public:
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+ typedef Resizer resizer_type;
+ typedef dense_output_stepper_tag stepper_category;
+#ifndef DOXYGEN_SKIP
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+
+ typedef bulirsch_stoer_dense_out< State , Value , Deriv , Time , Algebra , Operations , Resizer > controlled_error_bs_type;
+
+ typedef typename inverse_time< time_type >::type inv_time_type;
+
+ typedef std::vector< value_type > value_vector;
+ typedef std::vector< time_type > time_vector;
+ typedef std::vector< inv_time_type > inv_time_vector; //should be 1/time_type for boost.units
+ typedef std::vector< value_vector > value_matrix;
+ typedef std::vector< size_t > int_vector;
+ typedef std::vector< wrapped_state_type > state_vector_type;
+ typedef std::vector< wrapped_deriv_type > deriv_vector_type;
+ typedef std::vector< deriv_vector_type > deriv_table_type;
+#endif //DOXYGEN_SKIP
+
+ const static size_t m_k_max = 8;
+
+
+
+ bulirsch_stoer_dense_out(
+ value_type eps_abs = 1E-6 , value_type eps_rel = 1E-6 ,
+ value_type factor_x = 1.0 , value_type factor_dxdt = 1.0 ,
+ time_type max_dt = static_cast<time_type>(0) ,
+ bool control_interpolation = false )
+ : m_error_checker( eps_abs , eps_rel , factor_x, factor_dxdt ) ,
+ m_max_dt(max_dt) ,
+ m_control_interpolation( control_interpolation) ,
+ m_last_step_rejected( false ) , m_first( true ) ,
+ m_current_state_x1( true ) ,
+ m_error( m_k_max ) ,
+ m_interval_sequence( m_k_max+1 ) ,
+ m_coeff( m_k_max+1 ) ,
+ m_cost( m_k_max+1 ) ,
+ m_facmin_table( m_k_max+1 ) ,
+ m_table( m_k_max ) ,
+ m_mp_states( m_k_max+1 ) ,
+ m_derivs( m_k_max+1 ) ,
+ m_diffs( 2*m_k_max+2 ) ,
+ STEPFAC1( 0.65 ) , STEPFAC2( 0.94 ) , STEPFAC3( 0.02 ) , STEPFAC4( 4.0 ) , KFAC1( 0.8 ) , KFAC2( 0.9 )
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+
+ for( unsigned short i = 0; i < m_k_max+1; i++ )
+ {
+ /* only this specific sequence allows for dense output */
+ m_interval_sequence[i] = 2 + 4*i; // 2 6 10 14 ...
+ m_derivs[i].resize( m_interval_sequence[i] );
+ if( i == 0 )
+ {
+ m_cost[i] = m_interval_sequence[i];
+ } else
+ {
+ m_cost[i] = m_cost[i-1] + m_interval_sequence[i];
+ }
+ m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast< value_type >(1) / static_cast< value_type >( 2*i+1 ) );
+ m_coeff[i].resize(i);
+ for( size_t k = 0 ; k < i ; ++k )
+ {
+ const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] );
+ m_coeff[i][k] = 1.0 / ( r*r - static_cast< value_type >( 1.0 ) ); // coefficients for extrapolation
+ }
+ // crude estimate of optimal order
+
+ m_current_k_opt = 4;
+ /* no calculation because log10 might not exist for value_type!
+ const value_type logfact( -log10( max BOOST_PREVENT_MACRO_SUBSTITUTION( eps_rel , static_cast< value_type >( 1.0E-12 ) ) ) * 0.6 + 0.5 );
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( 1 , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>( m_k_max-1 ) , static_cast<int>( logfact ) ));
+ */
+ }
+ int num = 1;
+ for( int i = 2*(m_k_max)+1 ; i >=0 ; i-- )
+ {
+ m_diffs[i].resize( num );
+ num += (i+1)%2;
+ }
+ }
+
+ template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
+ controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , DerivOut &dxdt_new , time_type &dt )
+ {
+ if( m_max_dt != static_cast<time_type>(0) && detail::less_with_sign(m_max_dt, dt, dt) )
+ {
+ // given step size is bigger then max_dt
+ // set limit and return fail
+ dt = m_max_dt;
+ return fail;
+ }
+
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+
+ static const value_type val1( 1.0 );
+
+ bool reject( true );
+
+ time_vector h_opt( m_k_max+1 );
+ inv_time_vector work( m_k_max+1 );
+
+ m_k_final = 0;
+ time_type new_h = dt;
+
+ //std::cout << "t=" << t <<", dt=" << dt << ", k_opt=" << m_current_k_opt << ", first: " << m_first << std::endl;
+
+ for( size_t k = 0 ; k <= m_current_k_opt+1 ; k++ )
+ {
+ m_midpoint.set_steps( m_interval_sequence[k] );
+ if( k == 0 )
+ {
+ m_midpoint.do_step( system , in , dxdt , t , out , dt , m_mp_states[k].m_v , m_derivs[k]);
+ }
+ else
+ {
+ m_midpoint.do_step( system , in , dxdt , t , m_table[k-1].m_v , dt , m_mp_states[k].m_v , m_derivs[k] );
+ extrapolate( k , m_table , m_coeff , out );
+ // get error estimate
+ m_algebra.for_each3( m_err.m_v , out , m_table[0].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 , -val1 ) );
+ const value_type error = m_error_checker.error( m_algebra , in , dxdt , m_err.m_v , dt );
+ h_opt[k] = calc_h_opt( dt , error , k );
+ work[k] = static_cast<value_type>( m_cost[k] ) / h_opt[k];
+
+ m_k_final = k;
+
+ if( (k == m_current_k_opt-1) || m_first )
+ { // convergence before k_opt ?
+ if( error < 1.0 )
+ {
+ //convergence
+ reject = false;
+ if( (work[k] < KFAC2*work[k-1]) || (m_current_k_opt <= 2) )
+ {
+ // leave order as is (except we were in first round)
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(k)+1 ) );
+ new_h = h_opt[k] * static_cast<value_type>( m_cost[k+1] ) / static_cast<value_type>( m_cost[k] );
+ } else {
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(k) ) );
+ new_h = h_opt[k];
+ }
+ break;
+ }
+ else if( should_reject( error , k ) && !m_first )
+ {
+ reject = true;
+ new_h = h_opt[k];
+ break;
+ }
+ }
+ if( k == m_current_k_opt )
+ { // convergence at k_opt ?
+ if( error < 1.0 )
+ {
+ //convergence
+ reject = false;
+ if( (work[k-1] < KFAC2*work[k]) )
+ {
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(m_current_k_opt)-1 );
+ new_h = h_opt[m_current_k_opt];
+ }
+ else if( (work[k] < KFAC2*work[k-1]) && !m_last_step_rejected )
+ {
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , static_cast<int>(m_current_k_opt)+1 );
+ new_h = h_opt[k]*static_cast<value_type>( m_cost[m_current_k_opt] ) / static_cast<value_type>( m_cost[k] );
+ } else
+ new_h = h_opt[m_current_k_opt];
+ break;
+ }
+ else if( should_reject( error , k ) )
+ {
+ reject = true;
+ new_h = h_opt[m_current_k_opt];
+ break;
+ }
+ }
+ if( k == m_current_k_opt+1 )
+ { // convergence at k_opt+1 ?
+ if( error < 1.0 )
+ { //convergence
+ reject = false;
+ if( work[k-2] < KFAC2*work[k-1] )
+ m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( 2 , static_cast<int>(m_current_k_opt)-1 );
+ if( (work[k] < KFAC2*work[m_current_k_opt]) && !m_last_step_rejected )
+ m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<int>(m_k_max)-1 , static_cast<int>(k) );
+ new_h = h_opt[m_current_k_opt];
+ } else
+ {
+ reject = true;
+ new_h = h_opt[m_current_k_opt];
+ }
+ break;
+ }
+ }
+ }
+
+ if( !reject )
+ {
+
+ //calculate dxdt for next step and dense output
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ sys( out , dxdt_new , t+dt );
+
+ //prepare dense output
+ value_type error = prepare_dense_output( m_k_final , in , dxdt , out , dxdt_new , dt );
+
+ if( error > static_cast<value_type>(10) ) // we are not as accurate for interpolation as for the steps
+ {
+ reject = true;
+ new_h = dt * pow BOOST_PREVENT_MACRO_SUBSTITUTION( error , static_cast<value_type>(-1)/(2*m_k_final+2) );
+ } else {
+ t += dt;
+ }
+ }
+ //set next stepsize
+ if( !m_last_step_rejected || (new_h < dt) )
+ {
+ // limit step size
+ if( m_max_dt != static_cast<time_type>(0) )
+ {
+ new_h = detail::min_abs(m_max_dt, new_h);
+ }
+ dt = new_h;
+ }
+
+ m_last_step_rejected = reject;
+ if( reject )
+ return fail;
+ else
+ return success;
+ }
+
+ template< class StateType >
+ void initialize( const StateType &x0 , const time_type &t0 , const time_type &dt0 )
+ {
+ m_resizer.adjust_size( x0 , detail::bind( &controlled_error_bs_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::copy( x0 , get_current_state() );
+ m_t = t0;
+ m_dt = dt0;
+ reset();
+ }
+
+
+ /* =======================================================
+ * the actual step method that should be called from outside (maybe make try_step private?)
+ */
+ template< class System >
+ std::pair< time_type , time_type > do_step( System system )
+ {
+ if( m_first )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ sys( get_current_state() , get_current_deriv() , m_t );
+ }
+
+ failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
+ controlled_step_result res = fail;
+ m_t_last = m_t;
+ while( res == fail )
+ {
+ res = try_step( system , get_current_state() , get_current_deriv() , m_t , get_old_state() , get_old_deriv() , m_dt );
+ m_first = false;
+ fail_checker(); // check for overflow of failed steps
+ }
+ toggle_current_state();
+ return std::make_pair( m_t_last , m_t );
+ }
+
+ /* performs the interpolation from a calculated step */
+ template< class StateOut >
+ void calc_state( time_type t , StateOut &x ) const
+ {
+ do_interpolation( t , x );
+ }
+
+ const state_type& current_state( void ) const
+ {
+ return get_current_state();
+ }
+
+ time_type current_time( void ) const
+ {
+ return m_t;
+ }
+
+ const state_type& previous_state( void ) const
+ {
+ return get_old_state();
+ }
+
+ time_type previous_time( void ) const
+ {
+ return m_t_last;
+ }
+
+ time_type current_time_step( void ) const
+ {
+ return m_dt;
+ }
+
+ /** \brief Resets the internal state of the stepper. */
+ void reset()
+ {
+ m_first = true;
+ m_last_step_rejected = false;
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ m_midpoint.adjust_size( x );
+ }
+
+
+private:
+
+ template< class StateInOut , class StateVector >
+ void extrapolate( size_t k , StateVector &table , const value_matrix &coeff , StateInOut &xest , size_t order_start_index = 0 )
+ //polynomial extrapolation, see http://www.nr.com/webnotes/nr3web21.pdf
+ {
+ static const value_type val1( 1.0 );
+ for( int j=k-1 ; j>0 ; --j )
+ {
+ m_algebra.for_each3( table[j-1].m_v , table[j].m_v , table[j-1].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k + order_start_index][j + order_start_index] ,
+ -coeff[k + order_start_index][j + order_start_index] ) );
+ }
+ m_algebra.for_each3( xest , table[0].m_v , xest ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k + order_start_index][0 + order_start_index] ,
+ -coeff[k + order_start_index][0 + order_start_index]) );
+ }
+
+
+ template< class StateVector >
+ void extrapolate_dense_out( size_t k , StateVector &table , const value_matrix &coeff , size_t order_start_index = 0 )
+ //polynomial extrapolation, see http://www.nr.com/webnotes/nr3web21.pdf
+ {
+ // result is written into table[0]
+ static const value_type val1( 1.0 );
+ for( int j=k ; j>1 ; --j )
+ {
+ m_algebra.for_each3( table[j-1].m_v , table[j].m_v , table[j-1].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k + order_start_index][j + order_start_index - 1] ,
+ -coeff[k + order_start_index][j + order_start_index - 1] ) );
+ }
+ m_algebra.for_each3( table[0].m_v , table[1].m_v , table[0].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( val1 + coeff[k + order_start_index][order_start_index] ,
+ -coeff[k + order_start_index][order_start_index]) );
+ }
+
+ time_type calc_h_opt( time_type h , value_type error , size_t k ) const
+ {
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+
+ value_type expo = static_cast<value_type>(1)/(m_interval_sequence[k-1]);
+ value_type facmin = m_facmin_table[k];
+ value_type fac;
+ if (error == 0.0)
+ fac = static_cast<value_type>(1)/facmin;
+ else
+ {
+ fac = STEPFAC2 / pow BOOST_PREVENT_MACRO_SUBSTITUTION( error / STEPFAC1 , expo );
+ fac = max BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>( facmin/STEPFAC4 ) , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast<value_type>(static_cast<value_type>(1)/facmin) , fac ) );
+ }
+ return h*fac;
+ }
+
+ bool in_convergence_window( size_t k ) const
+ {
+ if( (k == m_current_k_opt-1) && !m_last_step_rejected )
+ return true; // decrease order only if last step was not rejected
+ return ( (k == m_current_k_opt) || (k == m_current_k_opt+1) );
+ }
+
+ bool should_reject( value_type error , size_t k ) const
+ {
+ if( k == m_current_k_opt-1 )
+ {
+ const value_type d = m_interval_sequence[m_current_k_opt] * m_interval_sequence[m_current_k_opt+1] /
+ (m_interval_sequence[0]*m_interval_sequence[0]);
+ //step will fail, criterion 17.3.17 in NR
+ return ( error > d*d );
+ }
+ else if( k == m_current_k_opt )
+ {
+ const value_type d = m_interval_sequence[m_current_k_opt+1] / m_interval_sequence[0];
+ return ( error > d*d );
+ } else
+ return error > 1.0;
+ }
+
+ template< class StateIn1 , class DerivIn1 , class StateIn2 , class DerivIn2 >
+ value_type prepare_dense_output( int k , const StateIn1 &x_start , const DerivIn1 &dxdt_start ,
+ const StateIn2 & /* x_end */ , const DerivIn2 & /*dxdt_end */ , time_type dt )
+ /* k is the order to which the result was approximated */
+ {
+
+ /* compute the coefficients of the interpolation polynomial
+ * we parametrize the interval t .. t+dt by theta = -1 .. 1
+ * we use 2k+3 values at the interval center theta=0 to obtain the interpolation coefficients
+ * the values are x(t+dt/2) and the derivatives dx/dt , ... d^(2k+2) x / dt^(2k+2) at the midpoints
+ * the derivatives are approximated via finite differences
+ * all values are obtained from interpolation of the results from the increasing orders of the midpoint calls
+ */
+
+ // calculate finite difference approximations to derivatives at the midpoint
+ for( int j = 0 ; j<=k ; j++ )
+ {
+ /* not working with boost units... */
+ const value_type d = m_interval_sequence[j] / ( static_cast<value_type>(2) * dt );
+ value_type f = 1.0; //factor 1/2 here because our interpolation interval has length 2 !!!
+ for( int kappa = 0 ; kappa <= 2*j+1 ; ++kappa )
+ {
+ calculate_finite_difference( j , kappa , f , dxdt_start );
+ f *= d;
+ }
+
+ if( j > 0 )
+ extrapolate_dense_out( j , m_mp_states , m_coeff );
+ }
+
+ time_type d = dt/2;
+
+ // extrapolate finite differences
+ for( int kappa = 0 ; kappa<=2*k+1 ; kappa++ )
+ {
+ for( int j=1 ; j<=(k-kappa/2) ; ++j )
+ extrapolate_dense_out( j , m_diffs[kappa] , m_coeff , kappa/2 );
+
+ // extrapolation results are now stored in m_diffs[kappa][0]
+
+ // divide kappa-th derivative by kappa because we need these terms for dense output interpolation
+ m_algebra.for_each1( m_diffs[kappa][0].m_v , typename operations_type::template scale< time_type >( static_cast<time_type>(d) ) );
+
+ d *= dt/(2*(kappa+2));
+ }
+
+ // dense output coefficients a_0 is stored in m_mp_states[0], a_i for i = 1...2k are stored in m_diffs[i-1][0]
+
+ // the error is just the highest order coefficient of the interpolation polynomial
+ // this is because we use only the midpoint theta=0 as support for the interpolation (remember that theta = -1 .. 1)
+
+ value_type error = 0.0;
+ if( m_control_interpolation )
+ {
+ boost::numeric::odeint::copy( m_diffs[2*k+1][0].m_v , m_err.m_v );
+ error = m_error_checker.error( m_algebra , x_start , dxdt_start , m_err.m_v , dt );
+ }
+
+ return error;
+ }
+
+ template< class DerivIn >
+ void calculate_finite_difference( size_t j , size_t kappa , value_type fac , const DerivIn &dxdt )
+ {
+ const int m = m_interval_sequence[j]/2-1;
+ if( kappa == 0) // no calculation required for 0th derivative of f
+ {
+ m_algebra.for_each2( m_diffs[0][j].m_v , m_derivs[j][m].m_v ,
+ typename operations_type::template scale_sum1< value_type >( fac ) );
+ }
+ else
+ {
+ // calculate the index of m_diffs for this kappa-j-combination
+ const int j_diffs = j - kappa/2;
+
+ m_algebra.for_each2( m_diffs[kappa][j_diffs].m_v , m_derivs[j][m+kappa].m_v ,
+ typename operations_type::template scale_sum1< value_type >( fac ) );
+ value_type sign = -1.0;
+ int c = 1;
+ //computes the j-th order finite difference for the kappa-th derivative of f at t+dt/2 using function evaluations stored in m_derivs
+ for( int i = m+static_cast<int>(kappa)-2 ; i >= m-static_cast<int>(kappa) ; i -= 2 )
+ {
+ if( i >= 0 )
+ {
+ m_algebra.for_each3( m_diffs[kappa][j_diffs].m_v , m_diffs[kappa][j_diffs].m_v , m_derivs[j][i].m_v ,
+ typename operations_type::template scale_sum2< value_type , value_type >( 1.0 ,
+ sign * fac * boost::math::binomial_coefficient< value_type >( kappa , c ) ) );
+ }
+ else
+ {
+ m_algebra.for_each3( m_diffs[kappa][j_diffs].m_v , m_diffs[kappa][j_diffs].m_v , dxdt ,
+ typename operations_type::template scale_sum2< value_type , value_type >( 1.0 , sign * fac ) );
+ }
+ sign *= -1;
+ ++c;
+ }
+ }
+ }
+
+ template< class StateOut >
+ void do_interpolation( time_type t , StateOut &out ) const
+ {
+ // interpolation polynomial is defined for theta = -1 ... 1
+ // m_k_final is the number of order-iterations done for the last step - it governs the order of the interpolation polynomial
+ const value_type theta = 2 * get_unit_value( (t - m_t_last) / (m_t - m_t_last) ) - 1;
+ // we use only values at interval center, that is theta=0, for interpolation
+ // our interpolation polynomial is thus of order 2k+2, hence we have 2k+3 terms
+
+ boost::numeric::odeint::copy( m_mp_states[0].m_v , out );
+ // add remaining terms: x += a_1 theta + a2 theta^2 + ... + a_{2k} theta^{2k}
+ value_type theta_pow( theta );
+ for( size_t i=0 ; i<=2*m_k_final+1 ; ++i )
+ {
+ m_algebra.for_each3( out , out , m_diffs[i][0].m_v ,
+ typename operations_type::template scale_sum2< value_type >( static_cast<value_type>(1) , theta_pow ) );
+ theta_pow *= theta;
+ }
+ }
+
+ /* Resizer methods */
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdt1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdt2 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_err , x , typename is_resizeable<state_type>::type() );
+
+ for( size_t i = 0 ; i < m_k_max ; ++i )
+ resized |= adjust_size_by_resizeability( m_table[i] , x , typename is_resizeable<state_type>::type() );
+ for( size_t i = 0 ; i < m_k_max+1 ; ++i )
+ resized |= adjust_size_by_resizeability( m_mp_states[i] , x , typename is_resizeable<state_type>::type() );
+ for( size_t i = 0 ; i < m_k_max+1 ; ++i )
+ for( size_t j = 0 ; j < m_derivs[i].size() ; ++j )
+ resized |= adjust_size_by_resizeability( m_derivs[i][j] , x , typename is_resizeable<deriv_type>::type() );
+ for( size_t i = 0 ; i < 2*m_k_max+2 ; ++i )
+ for( size_t j = 0 ; j < m_diffs[i].size() ; ++j )
+ resized |= adjust_size_by_resizeability( m_diffs[i][j] , x , typename is_resizeable<deriv_type>::type() );
+
+ return resized;
+ }
+
+
+ state_type& get_current_state( void )
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ const state_type& get_current_state( void ) const
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ state_type& get_old_state( void )
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ const state_type& get_old_state( void ) const
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ deriv_type& get_current_deriv( void )
+ {
+ return m_current_state_x1 ? m_dxdt1.m_v : m_dxdt2.m_v ;
+ }
+
+ const deriv_type& get_current_deriv( void ) const
+ {
+ return m_current_state_x1 ? m_dxdt1.m_v : m_dxdt2.m_v ;
+ }
+
+ deriv_type& get_old_deriv( void )
+ {
+ return m_current_state_x1 ? m_dxdt2.m_v : m_dxdt1.m_v ;
+ }
+
+ const deriv_type& get_old_deriv( void ) const
+ {
+ return m_current_state_x1 ? m_dxdt2.m_v : m_dxdt1.m_v ;
+ }
+
+
+ void toggle_current_state( void )
+ {
+ m_current_state_x1 = ! m_current_state_x1;
+ }
+
+
+
+ default_error_checker< value_type, algebra_type , operations_type > m_error_checker;
+ modified_midpoint_dense_out< state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type > m_midpoint;
+
+ time_type m_max_dt;
+
+ bool m_control_interpolation;
+
+ bool m_last_step_rejected;
+ bool m_first;
+
+ time_type m_t;
+ time_type m_dt;
+ time_type m_dt_last;
+ time_type m_t_last;
+
+ size_t m_current_k_opt;
+ size_t m_k_final;
+
+ algebra_type m_algebra;
+
+ resizer_type m_resizer;
+
+ wrapped_state_type m_x1 , m_x2;
+ wrapped_deriv_type m_dxdt1 , m_dxdt2;
+ wrapped_state_type m_err;
+ bool m_current_state_x1;
+
+
+
+ value_vector m_error; // errors of repeated midpoint steps and extrapolations
+ int_vector m_interval_sequence; // stores the successive interval counts
+ value_matrix m_coeff;
+ int_vector m_cost; // costs for interval count
+ value_vector m_facmin_table; // for precomputed facmin to save pow calls
+
+ state_vector_type m_table; // sequence of states for extrapolation
+
+ //for dense output:
+ state_vector_type m_mp_states; // sequence of approximations of x at distance center
+ deriv_table_type m_derivs; // table of function values
+ deriv_table_type m_diffs; // table of function values
+
+ //wrapped_state_type m_a1 , m_a2 , m_a3 , m_a4;
+
+ value_type STEPFAC1 , STEPFAC2 , STEPFAC3 , STEPFAC4 , KFAC1 , KFAC2;
+};
+
+
+
+/********** DOXYGEN **********/
+
+/**
+ * \class bulirsch_stoer_dense_out
+ * \brief The Bulirsch-Stoer algorithm.
+ *
+ * The Bulirsch-Stoer is a controlled stepper that adjusts both step size
+ * and order of the method. The algorithm uses the modified midpoint and
+ * a polynomial extrapolation compute the solution. This class also provides
+ * dense output facility.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::bulirsch_stoer_dense_out( value_type eps_abs , value_type eps_rel , value_type factor_x , value_type factor_dxdt , bool control_interpolation )
+ * \brief Constructs the bulirsch_stoer class, including initialization of
+ * the error bounds.
+ *
+ * \param eps_abs Absolute tolerance level.
+ * \param eps_rel Relative tolerance level.
+ * \param factor_x Factor for the weight of the state.
+ * \param factor_dxdt Factor for the weight of the derivative.
+ * \param control_interpolation Set true to additionally control the error of
+ * the interpolation.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , DerivOut &dxdt_new , time_type &dt )
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed. Also, the internal order of the stepper is adjusted if required.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE.
+ * It must fulfill the Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::initialize( const StateType &x0 , const time_type &t0 , const time_type &dt0 )
+ * \brief Initializes the dense output stepper.
+ *
+ * \param x0 The initial state.
+ * \param t0 The initial time.
+ * \param dt0 The initial time step.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::do_step( System system )
+ * \brief Does one time step. This is the main method that should be used to
+ * integrate an ODE with this stepper.
+ * \note initialize has to be called before using this method to set the
+ * initial conditions x,t and the stepsize.
+ * \param system The system function to solve, hence the r.h.s. of the
+ * ordinary differential equation. It must fulfill the Simple System concept.
+ * \return Pair with start and end time of the integration step.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::calc_state( time_type t , StateOut &x ) const
+ * \brief Calculates the solution at an intermediate point within the last step
+ * \param t The time at which the solution should be calculated, has to be
+ * in the current time interval.
+ * \param x The output variable where the result is written into.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::current_state( void ) const
+ * \brief Returns the current state of the solution.
+ * \return The current state of the solution x(t).
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::current_time( void ) const
+ * \brief Returns the current time of the solution.
+ * \return The current time of the solution t.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::previous_state( void ) const
+ * \brief Returns the last state of the solution.
+ * \return The last state of the solution x(t-dt).
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::previous_time( void ) const
+ * \brief Returns the last time of the solution.
+ * \return The last time of the solution t-dt.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::current_time_step( void ) const
+ * \brief Returns the current step size.
+ * \return The current step size.
+ */
+
+ /**
+ * \fn bulirsch_stoer_dense_out::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_BULIRSCH_STOER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp
new file mode 100644
index 0000000..aac2b02
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp
@@ -0,0 +1,1014 @@
+/* [auto_generated]
+ boost/numeric/odeint/stepper/controlled_runge_kutta.hpp
+
+ [begin_description]
+ The default controlled stepper which can be used with all explicit Runge-Kutta error steppers.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2015 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
+
+
+
+#include <cmath>
+
+#include <boost/config.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+#include <boost/numeric/odeint/util/copy.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template
+<
+class Value ,
+class Algebra ,
+class Operations
+>
+class default_error_checker
+{
+public:
+
+ typedef Value value_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+
+ default_error_checker(
+ value_type eps_abs = static_cast< value_type >( 1.0e-6 ) ,
+ value_type eps_rel = static_cast< value_type >( 1.0e-6 ) ,
+ value_type a_x = static_cast< value_type >( 1 ) ,
+ value_type a_dxdt = static_cast< value_type >( 1 ))
+ : m_eps_abs( eps_abs ) , m_eps_rel( eps_rel ) , m_a_x( a_x ) , m_a_dxdt( a_dxdt )
+ { }
+
+
+ template< class State , class Deriv , class Err, class Time >
+ value_type error( const State &x_old , const Deriv &dxdt_old , Err &x_err , Time dt ) const
+ {
+ return error( algebra_type() , x_old , dxdt_old , x_err , dt );
+ }
+
+ template< class State , class Deriv , class Err, class Time >
+ value_type error( algebra_type &algebra , const State &x_old , const Deriv &dxdt_old , Err &x_err , Time dt ) const
+ {
+ using std::abs;
+ // this overwrites x_err !
+ algebra.for_each3( x_err , x_old , dxdt_old ,
+ typename operations_type::template rel_error< value_type >( m_eps_abs , m_eps_rel , m_a_x , m_a_dxdt * abs(get_unit_value( dt )) ) );
+
+ // value_type res = algebra.reduce( x_err ,
+ // typename operations_type::template maximum< value_type >() , static_cast< value_type >( 0 ) );
+ return algebra.norm_inf( x_err );
+ }
+
+private:
+
+ value_type m_eps_abs;
+ value_type m_eps_rel;
+ value_type m_a_x;
+ value_type m_a_dxdt;
+
+};
+
+
+template< typename Value, typename Time >
+class default_step_adjuster
+{
+public:
+ typedef Time time_type;
+ typedef Value value_type;
+
+ default_step_adjuster(const time_type max_dt=static_cast<time_type>(0))
+ : m_max_dt(max_dt)
+ {}
+
+
+ time_type decrease_step(time_type dt, const value_type error, const int error_order) const
+ {
+ // returns the decreased time step
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+
+ dt *= max
+ BOOST_PREVENT_MACRO_SUBSTITUTION(
+ static_cast<value_type>( static_cast<value_type>(9) / static_cast<value_type>(10) *
+ pow(error, static_cast<value_type>(-1) / (error_order - 1))),
+ static_cast<value_type>( static_cast<value_type>(1) / static_cast<value_type> (5)));
+ if(m_max_dt != static_cast<time_type >(0))
+ // limit to maximal stepsize even when decreasing
+ dt = detail::min_abs(dt, m_max_dt);
+ return dt;
+ }
+
+ time_type increase_step(time_type dt, value_type error, const int stepper_order) const
+ {
+ // returns the increased time step
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+
+ // adjust the size if dt is smaller than max_dt (providede max_dt is not zero)
+ if(error < 0.5)
+ {
+ // error should be > 0
+ error = max BOOST_PREVENT_MACRO_SUBSTITUTION (
+ static_cast<value_type>( pow( static_cast<value_type>(5.0) , -static_cast<value_type>(stepper_order) ) ) ,
+ error);
+ // time_type dt_old = dt; unused variable warning
+ //error too small - increase dt and keep the evolution and limit scaling factor to 5.0
+ dt *= static_cast<value_type>(9)/static_cast<value_type>(10) *
+ pow(error, static_cast<value_type>(-1) / stepper_order);
+ if(m_max_dt != static_cast<time_type >(0))
+ // limit to maximal stepsize
+ dt = detail::min_abs(dt, m_max_dt);
+ }
+ return dt;
+ }
+
+ bool check_step_size_limit(const time_type dt)
+ {
+ if(m_max_dt != static_cast<time_type >(0))
+ return detail::less_eq_with_sign(dt, m_max_dt, dt);
+ return true;
+ }
+
+ time_type get_max_dt() { return m_max_dt; }
+
+private:
+ time_type m_max_dt;
+};
+
+
+
+/*
+ * error stepper category dispatcher
+ */
+template<
+class ErrorStepper ,
+class ErrorChecker = default_error_checker< typename ErrorStepper::value_type ,
+ typename ErrorStepper::algebra_type ,
+ typename ErrorStepper::operations_type > ,
+class StepAdjuster = default_step_adjuster< typename ErrorStepper::value_type ,
+ typename ErrorStepper::time_type > ,
+class Resizer = typename ErrorStepper::resizer_type ,
+class ErrorStepperCategory = typename ErrorStepper::stepper_category
+>
+class controlled_runge_kutta ;
+
+
+
+/*
+ * explicit stepper version
+ *
+ * this class introduces the following try_step overloads
+ * try_step( sys , x , t , dt )
+ * try_step( sys , x , dxdt , t , dt )
+ * try_step( sys , in , t , out , dt )
+ * try_step( sys , in , dxdt , t , out , dt )
+ */
+/**
+ * \brief Implements step size control for Runge-Kutta steppers with error
+ * estimation.
+ *
+ * This class implements the step size control for standard Runge-Kutta
+ * steppers with error estimation.
+ *
+ * \tparam ErrorStepper The stepper type with error estimation, has to fulfill the ErrorStepper concept.
+ * \tparam ErrorChecker The error checker
+ * \tparam Resizer The resizer policy type.
+ */
+template<
+class ErrorStepper,
+class ErrorChecker,
+class StepAdjuster,
+class Resizer
+>
+class controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster, Resizer ,
+ explicit_error_stepper_tag >
+{
+
+public:
+
+ typedef ErrorStepper stepper_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::algebra_type algebra_type;
+ typedef typename stepper_type::operations_type operations_type;
+ typedef Resizer resizer_type;
+ typedef ErrorChecker error_checker_type;
+ typedef StepAdjuster step_adjuster_type;
+ typedef explicit_controlled_stepper_tag stepper_category;
+
+#ifndef DOXYGEN_SKIP
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+
+ typedef controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster ,
+ Resizer , explicit_error_stepper_tag > controlled_stepper_type;
+#endif //DOXYGEN_SKIP
+
+
+ /**
+ * \brief Constructs the controlled Runge-Kutta stepper.
+ * \param error_checker An instance of the error checker.
+ * \param stepper An instance of the underlying stepper.
+ */
+ controlled_runge_kutta(
+ const error_checker_type &error_checker = error_checker_type( ) ,
+ const step_adjuster_type &step_adjuster = step_adjuster_type() ,
+ const stepper_type &stepper = stepper_type( )
+ )
+ : m_stepper(stepper), m_error_checker(error_checker) , m_step_adjuster(step_adjuster)
+ { }
+
+
+
+ /*
+ * Version 1 : try_step( sys , x , t , dt )
+ *
+ * The overloads are needed to solve the forwarding problem
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t, dt );
+ }
+
+ /**
+ * \brief Tries to perform one step. Solves the forwarding problem and
+ * allows for using boost range as state_type.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful. Can be a boost range.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , const StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t, dt );
+ }
+
+
+
+ /*
+ * Version 2 : try_step( sys , x , dxdt , t , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut , class DerivIn >
+ controlled_step_result try_step( System system , StateInOut &x , const DerivIn &dxdt , time_type &t , time_type &dt )
+ {
+ m_xnew_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_xnew_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , dt );
+ if( res == success )
+ {
+ boost::numeric::odeint::copy( m_xnew.m_v , x );
+ }
+ return res;
+ }
+
+ /*
+ * Version 3 : try_step( sys , in , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ *
+ * the disable is needed to avoid ambiguous overloads if state_type = time_type
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * \note This method is disabled if state_type=time_type to avoid ambiguity.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateIn , class StateOut >
+ typename boost::disable_if< boost::is_same< StateIn , time_type > , controlled_step_result >::type
+ try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+ sys( in , m_dxdt.m_v , t );
+ return try_step( system , in , m_dxdt.m_v , t , out , dt );
+ }
+
+
+ /*
+ * Version 4 : try_step( sys , in , dxdt , t , out , dt )
+ *
+ * this version does not solve the forwarding problem, boost.range can not be used
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , time_type &dt )
+ {
+ if( !m_step_adjuster.check_step_size_limit(dt) )
+ {
+ // given dt was above step size limit - adjust and return fail;
+ dt = m_step_adjuster.get_max_dt();
+ return fail;
+ }
+
+ m_xerr_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_xerr_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ // do one step with error calculation
+ m_stepper.do_step( system , in , dxdt , t , out , dt , m_xerr.m_v );
+
+ value_type max_rel_err = m_error_checker.error( m_stepper.algebra() , in , dxdt , m_xerr.m_v , dt );
+
+ if( max_rel_err > 1.0 )
+ {
+ // error too big, decrease step size and reject this step
+ dt = m_step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order());
+ return fail;
+ } else
+ {
+ // otherwise, increase step size and accept
+ t += dt;
+ dt = m_step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order());
+ return success;
+ }
+ }
+
+ /**
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_m_xerr_impl( x );
+ resize_m_dxdt_impl( x );
+ resize_m_xnew_impl( x );
+ m_stepper.adjust_size( x );
+ }
+
+ /**
+ * \brief Returns the instance of the underlying stepper.
+ * \returns The instance of the underlying stepper.
+ */
+ stepper_type& stepper( void )
+ {
+ return m_stepper;
+ }
+
+ /**
+ * \brief Returns the instance of the underlying stepper.
+ * \returns The instance of the underlying stepper.
+ */
+ const stepper_type& stepper( void ) const
+ {
+ return m_stepper;
+ }
+
+private:
+
+
+ template< class System , class StateInOut >
+ controlled_step_result try_step_v1( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ m_dxdt_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ sys( x , m_dxdt.m_v ,t );
+ return try_step( system , x , m_dxdt.m_v , t , dt );
+ }
+
+ template< class StateIn >
+ bool resize_m_xerr_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xerr , x , typename is_resizeable<state_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_dxdt_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_xnew_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
+ }
+
+
+
+ stepper_type m_stepper;
+ error_checker_type m_error_checker;
+ step_adjuster_type m_step_adjuster;
+
+ resizer_type m_dxdt_resizer;
+ resizer_type m_xerr_resizer;
+ resizer_type m_xnew_resizer;
+
+ wrapped_deriv_type m_dxdt;
+ wrapped_state_type m_xerr;
+ wrapped_state_type m_xnew;
+};
+
+
+
+
+
+
+
+
+
+
+/*
+ * explicit stepper fsal version
+ *
+ * the class introduces the following try_step overloads
+ * try_step( sys , x , t , dt )
+ * try_step( sys , in , t , out , dt )
+ * try_step( sys , x , dxdt , t , dt )
+ * try_step( sys , in , dxdt_in , t , out , dxdt_out , dt )
+ */
+/**
+ * \brief Implements step size control for Runge-Kutta FSAL steppers with
+ * error estimation.
+ *
+ * This class implements the step size control for FSAL Runge-Kutta
+ * steppers with error estimation.
+ *
+ * \tparam ErrorStepper The stepper type with error estimation, has to fulfill the ErrorStepper concept.
+ * \tparam ErrorChecker The error checker
+ * \tparam Resizer The resizer policy type.
+ */
+template<
+class ErrorStepper ,
+class ErrorChecker ,
+class StepAdjuster ,
+class Resizer
+>
+class controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster , Resizer , explicit_error_stepper_fsal_tag >
+{
+
+public:
+
+ typedef ErrorStepper stepper_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::algebra_type algebra_type;
+ typedef typename stepper_type::operations_type operations_type;
+ typedef Resizer resizer_type;
+ typedef ErrorChecker error_checker_type;
+ typedef StepAdjuster step_adjuster_type;
+ typedef explicit_controlled_stepper_fsal_tag stepper_category;
+
+#ifndef DOXYGEN_SKIP
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+
+ typedef controlled_runge_kutta< ErrorStepper , ErrorChecker , StepAdjuster , Resizer , explicit_error_stepper_tag > controlled_stepper_type;
+#endif // DOXYGEN_SKIP
+
+ /**
+ * \brief Constructs the controlled Runge-Kutta stepper.
+ * \param error_checker An instance of the error checker.
+ * \param stepper An instance of the underlying stepper.
+ */
+ controlled_runge_kutta(
+ const error_checker_type &error_checker = error_checker_type() ,
+ const step_adjuster_type &step_adjuster = step_adjuster_type() ,
+ const stepper_type &stepper = stepper_type()
+ )
+ : m_stepper( stepper ) , m_error_checker( error_checker ) , m_step_adjuster(step_adjuster) ,
+ m_first_call( true )
+ { }
+
+ /*
+ * Version 1 : try_step( sys , x , t , dt )
+ *
+ * The two overloads are needed in order to solve the forwarding problem
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t , dt );
+ }
+
+
+ /**
+ * \brief Tries to perform one step. Solves the forwarding problem and
+ * allows for using boost range as state_type.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful. Can be a boost range.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut >
+ controlled_step_result try_step( System system , const StateInOut &x , time_type &t , time_type &dt )
+ {
+ return try_step_v1( system , x , t , dt );
+ }
+
+
+
+ /*
+ * Version 2 : try_step( sys , in , t , out , dt );
+ *
+ * This version does not solve the forwarding problem, boost::range can not be used.
+ *
+ * The disabler is needed to solve ambiguous overloads
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * \note This method is disabled if state_type=time_type to avoid ambiguity.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateIn , class StateOut >
+ typename boost::disable_if< boost::is_same< StateIn , time_type > , controlled_step_result >::type
+ try_step( System system , const StateIn &in , time_type &t , StateOut &out , time_type &dt )
+ {
+ if( m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateIn > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , in , t );
+ }
+ return try_step( system , in , m_dxdt.m_v , t , out , dt );
+ }
+
+
+ /*
+ * Version 3 : try_step( sys , x , dxdt , t , dt )
+ *
+ * This version does not solve the forwarding problem, boost::range can not be used.
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The state of the ODE which should be solved. Overwritten if
+ * the step is successful.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateInOut , class DerivInOut >
+ controlled_step_result try_step( System system , StateInOut &x , DerivInOut &dxdt , time_type &t , time_type &dt )
+ {
+ m_xnew_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_xnew_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ m_dxdt_new_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_new_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) );
+ controlled_step_result res = try_step( system , x , dxdt , t , m_xnew.m_v , m_dxdtnew.m_v , dt );
+ if( res == success )
+ {
+ boost::numeric::odeint::copy( m_xnew.m_v , x );
+ boost::numeric::odeint::copy( m_dxdtnew.m_v , dxdt );
+ }
+ return res;
+ }
+
+
+ /*
+ * Version 4 : try_step( sys , in , dxdt_in , t , out , dxdt_out , dt )
+ *
+ * This version does not solve the forwarding problem, boost::range can not be used.
+ */
+ /**
+ * \brief Tries to perform one step.
+ *
+ * This method tries to do one step with step size dt. If the error estimate
+ * is to large, the step is rejected and the method returns fail and the
+ * step size dt is reduced. If the error estimate is acceptably small, the
+ * step is performed, success is returned and dt might be increased to make
+ * the steps as large as possible. This method also updates t if a step is
+ * performed.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved.
+ * \param dxdt The derivative of state.
+ * \param t The value of the time. Updated if the step is successful.
+ * \param out Used to store the result of the step.
+ * \param dt The step size. Updated.
+ * \return success if the step was accepted, fail otherwise.
+ */
+ template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
+ controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type &t ,
+ StateOut &out , DerivOut &dxdt_out , time_type &dt )
+ {
+ if( !m_step_adjuster.check_step_size_limit(dt) )
+ {
+ // given dt was above step size limit - adjust and return fail;
+ dt = m_step_adjuster.get_max_dt();
+ return fail;
+ }
+
+ m_xerr_resizer.adjust_size( in , detail::bind( &controlled_runge_kutta::template resize_m_xerr_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ //fsal: m_stepper.get_dxdt( dxdt );
+ //fsal: m_stepper.do_step( sys , x , dxdt , t , dt , m_x_err );
+ m_stepper.do_step( system , in , dxdt_in , t , out , dxdt_out , dt , m_xerr.m_v );
+
+ // this potentially overwrites m_x_err! (standard_error_checker does, at least)
+ value_type max_rel_err = m_error_checker.error( m_stepper.algebra() , in , dxdt_in , m_xerr.m_v , dt );
+
+ if( max_rel_err > 1.0 )
+ {
+ // error too big, decrease step size and reject this step
+ dt = m_step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order());
+ return fail;
+ }
+ // otherwise, increase step size and accept
+ t += dt;
+ dt = m_step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order());
+ return success;
+ }
+
+
+ /**
+ * \brief Resets the internal state of the underlying FSAL stepper.
+ */
+ void reset( void )
+ {
+ m_first_call = true;
+ }
+
+ /**
+ * \brief Initializes the internal state storing an internal copy of the derivative.
+ *
+ * \param deriv The initial derivative of the ODE.
+ */
+ template< class DerivIn >
+ void initialize( const DerivIn &deriv )
+ {
+ boost::numeric::odeint::copy( deriv , m_dxdt.m_v );
+ m_first_call = false;
+ }
+
+ /**
+ * \brief Initializes the internal state storing an internal copy of the derivative.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param x The initial state of the ODE which should be solved.
+ * \param t The initial time.
+ */
+ template< class System , class StateIn >
+ void initialize( System system , const StateIn &x , time_type t )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ sys( x , m_dxdt.m_v , t );
+ m_first_call = false;
+ }
+
+ /**
+ * \brief Returns true if the stepper has been initialized, false otherwise.
+ *
+ * \return true, if the stepper has been initialized, false otherwise.
+ */
+ bool is_initialized( void ) const
+ {
+ return ! m_first_call;
+ }
+
+
+ /**
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_m_xerr_impl( x );
+ resize_m_dxdt_impl( x );
+ resize_m_dxdt_new_impl( x );
+ resize_m_xnew_impl( x );
+ }
+
+
+ /**
+ * \brief Returns the instance of the underlying stepper.
+ * \returns The instance of the underlying stepper.
+ */
+ stepper_type& stepper( void )
+ {
+ return m_stepper;
+ }
+
+ /**
+ * \brief Returns the instance of the underlying stepper.
+ * \returns The instance of the underlying stepper.
+ */
+ const stepper_type& stepper( void ) const
+ {
+ return m_stepper;
+ }
+
+
+
+private:
+
+
+ template< class StateIn >
+ bool resize_m_xerr_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xerr , x , typename is_resizeable<state_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_dxdt_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_dxdt_new_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdtnew , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_xnew_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
+ }
+
+
+ template< class System , class StateInOut >
+ controlled_step_result try_step_v1( System system , StateInOut &x , time_type &t , time_type &dt )
+ {
+ if( m_dxdt_resizer.adjust_size( x , detail::bind( &controlled_runge_kutta::template resize_m_dxdt_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ) || m_first_call )
+ {
+ initialize( system , x , t );
+ }
+ return try_step( system , x , m_dxdt.m_v , t , dt );
+ }
+
+
+ stepper_type m_stepper;
+ error_checker_type m_error_checker;
+ step_adjuster_type m_step_adjuster;
+
+ resizer_type m_dxdt_resizer;
+ resizer_type m_xerr_resizer;
+ resizer_type m_xnew_resizer;
+ resizer_type m_dxdt_new_resizer;
+
+ wrapped_deriv_type m_dxdt;
+ wrapped_state_type m_xerr;
+ wrapped_state_type m_xnew;
+ wrapped_deriv_type m_dxdtnew;
+ bool m_first_call;
+};
+
+
+/********** DOXYGEN **********/
+
+/**** DEFAULT ERROR CHECKER ****/
+
+/**
+ * \class default_error_checker
+ * \brief The default error checker to be used with Runge-Kutta error steppers
+ *
+ * This class provides the default mechanism to compare the error estimates
+ * reported by Runge-Kutta error steppers with user defined error bounds.
+ * It is used by the controlled_runge_kutta steppers.
+ *
+ * \tparam Value The value type.
+ * \tparam Time The time type.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ */
+
+ /**
+ * \fn default_error_checker( value_type eps_abs , value_type eps_rel , value_type a_x , value_type a_dxdt ,
+ * time_type max_dt)
+ * \brief Constructs the error checker.
+ *
+ * The error is calculated as follows: ????
+ *
+ * \param eps_abs Absolute tolerance level.
+ * \param eps_rel Relative tolerance level.
+ * \param a_x Factor for the weight of the state.
+ * \param a_dxdt Factor for the weight of the derivative.
+ * \param max_dt Maximum allowed step size.
+ */
+
+ /**
+ * \fn error( const State &x_old , const Deriv &dxdt_old , Err &x_err , time_type dt ) const
+ * \brief Calculates the error level.
+ *
+ * If the returned error level is greater than 1, the estimated error was
+ * larger than the permitted error bounds and the step should be repeated
+ * with a smaller step size.
+ *
+ * \param x_old State at the beginning of the step.
+ * \param dxdt_old Derivative at the beginning of the step.
+ * \param x_err Error estimate.
+ * \param dt Time step.
+ * \return error
+ */
+
+ /**
+ * \fn error( algebra_type &algebra , const State &x_old , const Deriv &dxdt_old , Err &x_err , time_type dt ) const
+ * \brief Calculates the error level using a given algebra.
+ *
+ * If the returned error level is greater than 1, the estimated error was
+ * larger than the permitted error bounds and the step should be repeated
+ * with a smaller step size.
+ *
+ * \param algebra The algebra used for calculation of the error.
+ * \param x_old State at the beginning of the step.
+ * \param dxdt_old Derivative at the beginning of the step.
+ * \param x_err Error estimate.
+ * \param dt Time step.
+ * \return error
+ */
+
+ /**
+ * \fn time_type decrease_step(const time_type dt, const value_type error, const int error_order)
+ * \brief Returns a decreased step size based on the given error and order
+ *
+ * Calculates a new smaller step size based on the given error and its order.
+ *
+ * \param dt The old step size.
+ * \param error The computed error estimate.
+ * \param error_order The error order of the stepper.
+ * \return dt_new The new, reduced step size.
+ */
+
+ /**
+ * \fn time_type increase_step(const time_type dt, const value_type error, const int error_order)
+ * \brief Returns an increased step size based on the given error and order.
+ *
+ * Calculates a new bigger step size based on the given error and its order. If max_dt != 0, the
+ * new step size is limited to max_dt.
+ *
+ * \param dt The old step size.
+ * \param error The computed error estimate.
+ * \param error_order The order of the stepper.
+ * \return dt_new The new, increased step size.
+ */
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/controlled_step_result.hpp b/include/boost/numeric/odeint/stepper/controlled_step_result.hpp
new file mode 100644
index 0000000..7f17726
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/controlled_step_result.hpp
@@ -0,0 +1,42 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/controlled_step_result.hpp
+
+ [begin_description]
+ Defines the result type for all controlled stepper.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_STEP_RESULT_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_STEP_RESULT_HPP_INCLUDED
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+/**
+ * \enum controlled_step_result
+ *
+ * \brief Enum representing the return values of the controlled steppers.
+ */
+typedef enum
+{
+ success , /**< The trial step was successful, hence the state and the time have been advanced. */
+ fail /**< The step was not successful and might possibly be repeated with a small step size. */
+} controlled_step_result;
+
+} // namespace odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_STEP_RESULT_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp
new file mode 100644
index 0000000..94abc5a
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp
@@ -0,0 +1,476 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp
+
+ [begin_description]
+ Implementation of the Dense-output stepper for all steppers. Note, that this class does
+ not computes the result but serves as an interface.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2015 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
+
+
+#include <utility>
+#include <stdexcept>
+
+#include <boost/throw_exception.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/util/copy.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template< class Stepper , class StepperCategory = typename Stepper::stepper_category >
+class dense_output_runge_kutta;
+
+
+/**
+ * \brief The class representing dense-output Runge-Kutta steppers.
+ * \note In this stepper, the initialize method has to be called before using
+ * the do_step method.
+ *
+ * The dense-output functionality allows to interpolate the solution between
+ * subsequent integration points using intermediate results obtained during the
+ * computation. This version works based on a normal stepper without step-size
+ * control.
+ *
+ *
+ * \tparam Stepper The stepper type of the underlying algorithm.
+ */
+template< class Stepper >
+class dense_output_runge_kutta< Stepper , stepper_tag >
+{
+
+public:
+
+ /*
+ * We do not need all typedefs.
+ */
+ typedef Stepper stepper_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::algebra_type algebra_type;
+ typedef typename stepper_type::operations_type operations_type;
+ typedef typename stepper_type::resizer_type resizer_type;
+ typedef dense_output_stepper_tag stepper_category;
+ typedef dense_output_runge_kutta< Stepper > dense_output_stepper_type;
+
+
+ /**
+ * \brief Constructs the dense_output_runge_kutta class. An instance of the
+ * underlying stepper can be provided.
+ * \param stepper An instance of the underlying stepper.
+ */
+ dense_output_runge_kutta( const stepper_type &stepper = stepper_type() )
+ : m_stepper( stepper ) , m_resizer() ,
+ m_x1() , m_x2() , m_current_state_x1( true ) ,
+ m_t() , m_t_old() , m_dt()
+ { }
+
+
+ /**
+ * \brief Initializes the stepper. Has to be called before do_step can be
+ * used to set the initial conditions and the step size.
+ * \param x0 The initial state of the ODE which should be solved.
+ * \param t0 The initial time, at which the step should be performed.
+ * \param dt0 The step size.
+ */
+ template< class StateType >
+ void initialize( const StateType &x0 , time_type t0 , time_type dt0 )
+ {
+ m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::copy( x0 , get_current_state() );
+ m_t = t0;
+ m_dt = dt0;
+ }
+
+ /**
+ * \brief Does one time step.
+ * \note initialize has to be called before using this method to set the
+ * initial conditions x,t and the stepsize.
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Simple System concept.
+ * \return Pair with start and end time of the integration step.
+ */
+ template< class System >
+ std::pair< time_type , time_type > do_step( System system )
+ {
+ m_stepper.do_step( system , get_current_state() , m_t , get_old_state() , m_dt );
+ m_t_old = m_t;
+ m_t += m_dt;
+ toggle_current_state();
+ return std::make_pair( m_t_old , m_dt );
+ }
+
+ /*
+ * The next two overloads are needed to solve the forwarding problem
+ */
+
+ /**
+ * \brief Calculates the solution at an intermediate point.
+ * \param t The time at which the solution should be calculated, has to be
+ * in the current time interval.
+ * \param x The output variable where the result is written into.
+ */
+ template< class StateOut >
+ void calc_state( time_type t , StateOut &x ) const
+ {
+ if( t == current_time() )
+ {
+ boost::numeric::odeint::copy( get_current_state() , x );
+ }
+ m_stepper.calc_state( x , t , get_old_state() , m_t_old , get_current_state() , m_t );
+ }
+
+ /**
+ * \brief Calculates the solution at an intermediate point. Solves the forwarding problem
+ * \param t The time at which the solution should be calculated, has to be
+ * in the current time interval.
+ * \param x The output variable where the result is written into, can be a boost range.
+ */
+ template< class StateOut >
+ void calc_state( time_type t , const StateOut &x ) const
+ {
+ m_stepper.calc_state( x , t , get_old_state() , m_t_old , get_current_state() , m_t );
+ }
+
+ /**
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ m_stepper.stepper().resize( x );
+ }
+
+ /**
+ * \brief Returns the current state of the solution.
+ * \return The current state of the solution x(t).
+ */
+ const state_type& current_state( void ) const
+ {
+ return get_current_state();
+ }
+
+ /**
+ * \brief Returns the current time of the solution.
+ * \return The current time of the solution t.
+ */
+ time_type current_time( void ) const
+ {
+ return m_t;
+ }
+
+ /**
+ * \brief Returns the last state of the solution.
+ * \return The last state of the solution x(t-dt).
+ */
+ const state_type& previous_state( void ) const
+ {
+ return get_old_state();
+ }
+
+ /**
+ * \brief Returns the last time of the solution.
+ * \return The last time of the solution t-dt.
+ */
+ time_type previous_time( void ) const
+ {
+ return m_t_old;
+ }
+
+ /**
+ * \brief Returns the current time step.
+ * \return dt.
+ */
+ time_type current_time_step( void ) const
+ {
+ return m_dt;
+ }
+
+
+private:
+
+ state_type& get_current_state( void )
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ const state_type& get_current_state( void ) const
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ state_type& get_old_state( void )
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ const state_type& get_old_state( void ) const
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ void toggle_current_state( void )
+ {
+ m_current_state_x1 = ! m_current_state_x1;
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() );
+ return resized;
+ }
+
+
+ stepper_type m_stepper;
+ resizer_type m_resizer;
+ wrapped_state_type m_x1 , m_x2;
+ bool m_current_state_x1; // if true, the current state is m_x1
+ time_type m_t , m_t_old , m_dt;
+
+};
+
+
+
+
+
+/**
+ * \brief The class representing dense-output Runge-Kutta steppers with FSAL property.
+ *
+ * The interface is the same as for dense_output_runge_kutta< Stepper , stepper_tag >.
+ * This class provides dense output functionality based on methods with step size controlled
+ *
+ *
+ * \tparam Stepper The stepper type of the underlying algorithm.
+ */
+template< class Stepper >
+class dense_output_runge_kutta< Stepper , explicit_controlled_stepper_fsal_tag >
+{
+public:
+
+ /*
+ * We do not need all typedefs.
+ */
+ typedef Stepper controlled_stepper_type;
+
+ typedef typename controlled_stepper_type::stepper_type stepper_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::algebra_type algebra_type;
+ typedef typename stepper_type::operations_type operations_type;
+ typedef typename stepper_type::resizer_type resizer_type;
+ typedef dense_output_stepper_tag stepper_category;
+ typedef dense_output_runge_kutta< Stepper > dense_output_stepper_type;
+
+
+ dense_output_runge_kutta( const controlled_stepper_type &stepper = controlled_stepper_type() )
+ : m_stepper( stepper ) , m_resizer() ,
+ m_current_state_x1( true ) ,
+ m_x1() , m_x2() , m_dxdt1() , m_dxdt2() ,
+ m_t() , m_t_old() , m_dt() ,
+ m_is_deriv_initialized( false )
+ { }
+
+
+ template< class StateType >
+ void initialize( const StateType &x0 , time_type t0 , time_type dt0 )
+ {
+ m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize< StateType > , detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::copy( x0 , get_current_state() );
+ m_t = t0;
+ m_dt = dt0;
+ m_is_deriv_initialized = false;
+ }
+
+ template< class System >
+ std::pair< time_type , time_type > do_step( System system )
+ {
+ if( !m_is_deriv_initialized )
+ {
+ typename odeint::unwrap_reference< System >::type &sys = system;
+ sys( get_current_state() , get_current_deriv() , m_t );
+ m_is_deriv_initialized = true;
+ }
+
+ failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
+ controlled_step_result res = fail;
+ m_t_old = m_t;
+ do
+ {
+ res = m_stepper.try_step( system , get_current_state() , get_current_deriv() , m_t ,
+ get_old_state() , get_old_deriv() , m_dt );
+ fail_checker(); // check for overflow of failed steps
+ }
+ while( res == fail );
+ toggle_current_state();
+ return std::make_pair( m_t_old , m_t );
+ }
+
+
+ /*
+ * The two overloads are needed in order to solve the forwarding problem.
+ */
+ template< class StateOut >
+ void calc_state( time_type t , StateOut &x ) const
+ {
+ m_stepper.stepper().calc_state( t , x , get_old_state() , get_old_deriv() , m_t_old ,
+ get_current_state() , get_current_deriv() , m_t );
+ }
+
+ template< class StateOut >
+ void calc_state( time_type t , const StateOut &x ) const
+ {
+ m_stepper.stepper().calc_state( t , x , get_old_state() , get_old_deriv() , m_t_old ,
+ get_current_state() , get_current_deriv() , m_t );
+ }
+
+
+ template< class StateIn >
+ bool resize( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdt1 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdt2 , x , typename is_resizeable<deriv_type>::type() );
+ return resized;
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize( x );
+ m_stepper.stepper().resize( x );
+ }
+
+ const state_type& current_state( void ) const
+ {
+ return get_current_state();
+ }
+
+ time_type current_time( void ) const
+ {
+ return m_t;
+ }
+
+ const state_type& previous_state( void ) const
+ {
+ return get_old_state();
+ }
+
+ time_type previous_time( void ) const
+ {
+ return m_t_old;
+ }
+
+ time_type current_time_step( void ) const
+ {
+ return m_dt;
+ }
+
+
+private:
+
+ state_type& get_current_state( void )
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ const state_type& get_current_state( void ) const
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ state_type& get_old_state( void )
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ const state_type& get_old_state( void ) const
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ deriv_type& get_current_deriv( void )
+ {
+ return m_current_state_x1 ? m_dxdt1.m_v : m_dxdt2.m_v ;
+ }
+
+ const deriv_type& get_current_deriv( void ) const
+ {
+ return m_current_state_x1 ? m_dxdt1.m_v : m_dxdt2.m_v ;
+ }
+
+ deriv_type& get_old_deriv( void )
+ {
+ return m_current_state_x1 ? m_dxdt2.m_v : m_dxdt1.m_v ;
+ }
+
+ const deriv_type& get_old_deriv( void ) const
+ {
+ return m_current_state_x1 ? m_dxdt2.m_v : m_dxdt1.m_v ;
+ }
+
+
+ void toggle_current_state( void )
+ {
+ m_current_state_x1 = ! m_current_state_x1;
+ }
+
+
+ controlled_stepper_type m_stepper;
+ resizer_type m_resizer;
+ bool m_current_state_x1;
+ wrapped_state_type m_x1 , m_x2;
+ wrapped_deriv_type m_dxdt1 , m_dxdt2;
+ time_type m_t , m_t_old , m_dt;
+ bool m_is_deriv_initialized;
+
+};
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp b/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp
new file mode 100644
index 0000000..cc279ab
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp
@@ -0,0 +1,151 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/adams_bashforth_call_algebra.hpp
+
+ [begin_description]
+ Algebra caller for the Adams Bashforth stepper.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_CALL_ALGEBRA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_CALL_ALGEBRA_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< size_t Step , class Algebra , class Operations >
+struct adams_bashforth_call_algebra;
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 1 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each3( out , in , steps[0].m_v , typename Operations::template scale_sum2< value_type , Time >( 1.0 , dt * coef[0] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 2 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each4( out , in , steps[0].m_v , steps[1].m_v ,
+ typename Operations::template scale_sum3< value_type , Time , Time >( 1.0 , dt * coef[0] , dt * coef[1] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 3 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each5( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v ,
+ typename Operations::template scale_sum4< value_type , Time , Time , Time >( 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 4 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each6( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v ,
+ typename Operations::template scale_sum5< value_type , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 5 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each7( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v ,
+ typename Operations::template scale_sum6< value_type , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 6 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each8( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v , steps[5].m_v ,
+ typename Operations::template scale_sum7< value_type , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 7 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ //BOOST_ASSERT( false ); // not implemented
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each9( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v , steps[5].m_v , steps[6].m_v ,
+ typename Operations::template scale_sum8< value_type , Time , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] , dt * coef[6] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_bashforth_call_algebra< 8 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ //BOOST_ASSERT( false ); // not implemented
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each10( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v , steps[5].m_v , steps[6].m_v , steps[7].m_v ,
+ typename Operations::template scale_sum9< value_type , Time , Time , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] , dt * coef[6] , dt * coef[7] ) );
+ }
+};
+
+
+
+
+} // detail
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_CALL_ALGEBRA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp
new file mode 100644
index 0000000..26a9f9a
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp
@@ -0,0 +1,168 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/adams_bashforth_coefficients.hpp
+
+ [begin_description]
+ Definition of the coefficients for the Adams-Bashforth method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_COEFFICIENTS_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_COEFFICIENTS_HPP_INCLUDED
+
+#include <boost/array.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< class Value , size_t Steps >
+class adams_bashforth_coefficients ;
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 1 > : public boost::array< Value , 1 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 1 >()
+ {
+ (*this)[0] = static_cast< Value >( 1 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 2 > : public boost::array< Value , 2 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 2 >()
+ {
+ (*this)[0] = static_cast< Value >( 3 ) / static_cast< Value >( 2 );
+ (*this)[1] = -static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 3 > : public boost::array< Value , 3 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 3 >()
+ {
+ (*this)[0] = static_cast< Value >( 23 ) / static_cast< Value >( 12 );
+ (*this)[1] = -static_cast< Value >( 4 ) / static_cast< Value >( 3 );
+ (*this)[2] = static_cast< Value >( 5 ) / static_cast< Value >( 12 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 4 > : public boost::array< Value , 4 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 4 >()
+ {
+ (*this)[0] = static_cast< Value >( 55 ) / static_cast< Value >( 24 );
+ (*this)[1] = -static_cast< Value >( 59 ) / static_cast< Value >( 24 );
+ (*this)[2] = static_cast< Value >( 37 ) / static_cast< Value >( 24 );
+ (*this)[3] = -static_cast< Value >( 3 ) / static_cast< Value >( 8 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 5 > : public boost::array< Value , 5 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 5 >()
+ {
+ (*this)[0] = static_cast< Value >( 1901 ) / static_cast< Value >( 720 );
+ (*this)[1] = -static_cast< Value >( 1387 ) / static_cast< Value >( 360 );
+ (*this)[2] = static_cast< Value >( 109 ) / static_cast< Value >( 30 );
+ (*this)[3] = -static_cast< Value >( 637 ) / static_cast< Value >( 360 );
+ (*this)[4] = static_cast< Value >( 251 ) / static_cast< Value >( 720 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 6 > : public boost::array< Value , 6 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 6 >()
+ {
+ (*this)[0] = static_cast< Value >( 4277 ) / static_cast< Value >( 1440 );
+ (*this)[1] = -static_cast< Value >( 2641 ) / static_cast< Value >( 480 );
+ (*this)[2] = static_cast< Value >( 4991 ) / static_cast< Value >( 720 );
+ (*this)[3] = -static_cast< Value >( 3649 ) / static_cast< Value >( 720 );
+ (*this)[4] = static_cast< Value >( 959 ) / static_cast< Value >( 480 );
+ (*this)[5] = -static_cast< Value >( 95 ) / static_cast< Value >( 288 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 7 > : public boost::array< Value , 7 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 7 >()
+ {
+ (*this)[0] = static_cast< Value >( 198721 ) / static_cast< Value >( 60480 );
+ (*this)[1] = -static_cast< Value >( 18637 ) / static_cast< Value >( 2520 );
+ (*this)[2] = static_cast< Value >( 235183 ) / static_cast< Value >( 20160 );
+ (*this)[3] = -static_cast< Value >( 10754 ) / static_cast< Value >( 945 );
+ (*this)[4] = static_cast< Value >( 135713 ) / static_cast< Value >( 20160 );
+ (*this)[5] = -static_cast< Value >( 5603 ) / static_cast< Value >( 2520 );
+ (*this)[6] = static_cast< Value >( 19087 ) / static_cast< Value >( 60480 );
+ }
+};
+
+
+template< class Value >
+class adams_bashforth_coefficients< Value , 8 > : public boost::array< Value , 8 >
+{
+public:
+ adams_bashforth_coefficients( void )
+ : boost::array< Value , 8 >()
+ {
+ (*this)[0] = static_cast< Value >( 16083 ) / static_cast< Value >( 4480 );
+ (*this)[1] = -static_cast< Value >( 1152169 ) / static_cast< Value >( 120960 );
+ (*this)[2] = static_cast< Value >( 242653 ) / static_cast< Value >( 13440 );
+ (*this)[3] = -static_cast< Value >( 296053 ) / static_cast< Value >( 13440 );
+ (*this)[4] = static_cast< Value >( 2102243 ) / static_cast< Value >( 120960 );
+ (*this)[5] = -static_cast< Value >( 115747 ) / static_cast< Value >( 13440 );
+ (*this)[6] = static_cast< Value >( 32863 ) / static_cast< Value >( 13440 );
+ (*this)[7] = -static_cast< Value >( 5257 ) / static_cast< Value >( 17280 );
+ }
+};
+
+
+
+
+
+
+
+} // detail
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_BASHFORTH_COEFFICIENTS_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp b/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp
new file mode 100644
index 0000000..b6f5f2a
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp
@@ -0,0 +1,148 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/adams_moulton_call_algebra.hpp
+
+ [begin_description]
+ Algebra caller for the Adams Moulton method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_CALL_ALGEBRA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_CALL_ALGEBRA_HPP_INCLUDED
+
+#include <boost/assert.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< size_t Step , class Algebra , class Operations >
+struct adams_moulton_call_algebra;
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 1 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage& /* steps */ , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each3( out , in , dxdt , typename Operations::template scale_sum2< value_type , Time >( 1.0 , dt * coef[0] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 2 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each4( out , in , dxdt , steps[0].m_v ,
+ typename Operations::template scale_sum3< value_type , Time , Time >( 1.0 , dt * coef[0] , dt * coef[1] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 3 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each5( out , in , dxdt , steps[0].m_v , steps[1].m_v ,
+ typename Operations::template scale_sum4< value_type , Time , Time >( 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 4 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each6( out , in , dxdt , steps[0].m_v , steps[1].m_v , steps[2].m_v ,
+ typename Operations::template scale_sum5< value_type , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 5 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each7( out , in , dxdt , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v ,
+ typename Operations::template scale_sum6< value_type , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 6 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each8( out , in , dxdt , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v ,
+ typename Operations::template scale_sum7< value_type , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 7 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each9( out , in , dxdt , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v , steps[5].m_v ,
+ typename Operations::template scale_sum8< value_type , Time , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] , dt * coef[6] ) );
+ }
+};
+
+
+template< class Algebra , class Operations >
+struct adams_moulton_call_algebra< 8 , Algebra , Operations >
+{
+ template< class StateIn , class StateOut , class DerivIn , class StepStorage , class Coefficients , class Time >
+ void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
+ {
+ typedef typename Coefficients::value_type value_type;
+ algebra.for_each10( out , in , dxdt , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v , steps[5].m_v , steps[6].m_v ,
+ typename Operations::template scale_sum9< value_type , Time , Time , Time , Time , Time , Time , Time >(
+ 1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] , dt * coef[5] , dt * coef[6] , dt * coef[7] ) );
+ }
+};
+
+
+
+
+} // detail
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_CALL_ALGEBRA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp
new file mode 100644
index 0000000..8047fa8
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp
@@ -0,0 +1,168 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp
+
+ [begin_description]
+ Coefficients for the Adams Moulton method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_COEFFICIENTS_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_COEFFICIENTS_HPP_INCLUDED
+
+
+#include <boost/array.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< class Value , size_t Steps >
+class adams_moulton_coefficients ;
+
+template< class Value >
+class adams_moulton_coefficients< Value , 1 > : public boost::array< Value , 1 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 1 >()
+ {
+ (*this)[0] = static_cast< Value >( 1 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 2 > : public boost::array< Value , 2 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 2 >()
+ {
+ (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 3 > : public boost::array< Value , 3 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 3 >()
+ {
+ (*this)[0] = static_cast< Value >( 5 ) / static_cast< Value >( 12 );
+ (*this)[1] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
+ (*this)[2] = -static_cast< Value >( 1 ) / static_cast< Value >( 12 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 4 > : public boost::array< Value , 4 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 4 >()
+ {
+ (*this)[0] = static_cast< Value >( 3 ) / static_cast< Value >( 8 );
+ (*this)[1] = static_cast< Value >( 19 ) / static_cast< Value >( 24 );
+ (*this)[2] = -static_cast< Value >( 5 ) / static_cast< Value >( 24 );
+ (*this)[3] = static_cast< Value >( 1 ) / static_cast< Value >( 24 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 5 > : public boost::array< Value , 5 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 5 >()
+ {
+ (*this)[0] = static_cast< Value >( 251 ) / static_cast< Value >( 720 );
+ (*this)[1] = static_cast< Value >( 323 ) / static_cast< Value >( 360 );
+ (*this)[2] = -static_cast< Value >( 11 ) / static_cast< Value >( 30 );
+ (*this)[3] = static_cast< Value >( 53 ) / static_cast< Value >( 360 );
+ (*this)[4] = -static_cast< Value >( 19 ) / static_cast< Value >( 720 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 6 > : public boost::array< Value , 6 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 6 >()
+ {
+ (*this)[0] = static_cast< Value >( 95 ) / static_cast< Value >( 288 );
+ (*this)[1] = static_cast< Value >( 1427 ) / static_cast< Value >( 1440 );
+ (*this)[2] = -static_cast< Value >( 133 ) / static_cast< Value >( 240 );
+ (*this)[3] = static_cast< Value >( 241 ) / static_cast< Value >( 720 );
+ (*this)[4] = -static_cast< Value >( 173 ) / static_cast< Value >( 1440 );
+ (*this)[5] = static_cast< Value >( 3 ) / static_cast< Value >( 160 );
+ }
+};
+
+template< class Value >
+class adams_moulton_coefficients< Value , 7 > : public boost::array< Value , 7 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 7 >()
+ {
+ (*this)[0] = static_cast< Value >( 19087 ) / static_cast< Value >( 60480 );
+ (*this)[1] = static_cast< Value >( 2713 ) / static_cast< Value >( 2520 );
+ (*this)[2] = -static_cast< Value >( 15487 ) / static_cast< Value >( 20160 );
+ (*this)[3] = static_cast< Value >( 586 ) / static_cast< Value >( 945 );
+ (*this)[4] = -static_cast< Value >( 6737 ) / static_cast< Value >( 20160 );
+ (*this)[5] = static_cast< Value >( 263 ) / static_cast< Value >( 2520 );
+ (*this)[6] = -static_cast< Value >( 863 ) / static_cast< Value >( 60480 );
+ }
+};
+
+
+template< class Value >
+class adams_moulton_coefficients< Value , 8 > : public boost::array< Value , 8 >
+{
+public:
+ adams_moulton_coefficients( void )
+ : boost::array< Value , 8 >()
+ {
+ (*this)[0] = static_cast< Value >( 5257 ) / static_cast< Value >( 17280 );
+ (*this)[1] = static_cast< Value >( 139849 ) / static_cast< Value >( 120960 );
+ (*this)[2] = -static_cast< Value >( 4511 ) / static_cast< Value >( 4480 );
+ (*this)[3] = static_cast< Value >( 123133 ) / static_cast< Value >( 120960 );
+ (*this)[4] = -static_cast< Value >( 88547 ) / static_cast< Value >( 120960 );
+ (*this)[5] = static_cast< Value >( 1537 ) / static_cast< Value >( 4480 );
+ (*this)[6] = -static_cast< Value >( 11351 ) / static_cast< Value >( 120960 );
+ (*this)[7] = static_cast< Value >( 275 ) / static_cast< Value >( 24192 );
+ }
+};
+
+
+
+
+
+
+
+} // detail
+} // odeint
+} // numeric
+} // boost
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAMS_MOULTON_COEFFICIENTS_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp b/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp
new file mode 100644
index 0000000..ab74b24
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp
@@ -0,0 +1,247 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp
+
+ [begin_description]
+ Implementation of the generic Runge-Kutta method.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_ALGORITHM_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_ALGORITHM_HPP_INCLUDED
+
+#include <boost/static_assert.hpp>
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/for_each.hpp>
+#include <boost/mpl/range_c.hpp>
+#include <boost/mpl/copy.hpp>
+#include <boost/mpl/size_t.hpp>
+
+#include <boost/fusion/algorithm.hpp>
+#include <boost/fusion/iterator.hpp>
+#include <boost/fusion/mpl.hpp>
+#include <boost/fusion/sequence.hpp>
+
+#include <boost/array.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp>
+#include <boost/numeric/odeint/util/bind.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< class T , class Constant >
+struct array_wrapper
+{
+ typedef const typename boost::array< T , Constant::value > type;
+};
+
+template< class T , size_t i >
+struct stage
+{
+ T c;
+ boost::array< T , i > a;
+};
+
+
+template< class T , class Constant >
+struct stage_wrapper
+{
+ typedef stage< T , Constant::value > type;
+};
+
+
+template<
+size_t StageCount,
+class Value ,
+class Algebra ,
+class Operations
+>
+class generic_rk_algorithm {
+
+public:
+ typedef mpl::range_c< size_t , 1 , StageCount > stage_indices;
+
+ typedef typename boost::fusion::result_of::as_vector
+ <
+ typename boost::mpl::copy
+ <
+ stage_indices ,
+ boost::mpl::inserter
+ <
+ boost::mpl::vector0< > ,
+ boost::mpl::push_back< boost::mpl::_1 , array_wrapper< Value , boost::mpl::_2 > >
+ >
+ >::type
+ >::type coef_a_type;
+
+ typedef boost::array< Value , StageCount > coef_b_type;
+ typedef boost::array< Value , StageCount > coef_c_type;
+
+ typedef typename boost::fusion::result_of::as_vector
+ <
+ typename boost::mpl::push_back
+ <
+ typename boost::mpl::copy
+ <
+ stage_indices,
+ boost::mpl::inserter
+ <
+ boost::mpl::vector0<> ,
+ boost::mpl::push_back< boost::mpl::_1 , stage_wrapper< Value , boost::mpl::_2 > >
+ >
+ >::type ,
+ stage< Value , StageCount >
+ >::type
+ >::type stage_vector_base;
+
+
+ struct stage_vector : public stage_vector_base
+ {
+ struct do_insertion
+ {
+ stage_vector_base &m_base;
+ const coef_a_type &m_a;
+ const coef_c_type &m_c;
+
+ do_insertion( stage_vector_base &base , const coef_a_type &a , const coef_c_type &c )
+ : m_base( base ) , m_a( a ) , m_c( c ) { }
+
+ template< class Index >
+ void operator()( Index ) const
+ {
+ //boost::fusion::at< Index >( m_base ) = stage< double , Index::value+1 , intermediate_stage >( m_c[ Index::value ] , boost::fusion::at< Index >( m_a ) );
+ boost::fusion::at< Index >( m_base ).c = m_c[ Index::value ];
+ boost::fusion::at< Index >( m_base ).a = boost::fusion::at< Index >( m_a );
+ }
+ };
+
+ struct print_butcher
+ {
+ const stage_vector_base &m_base;
+ std::ostream &m_os;
+
+ print_butcher( const stage_vector_base &base , std::ostream &os )
+ : m_base( base ) , m_os( os )
+ { }
+
+ template<class Index>
+ void operator()(Index) const {
+ m_os << boost::fusion::at<Index>(m_base).c << " | ";
+ for( size_t i=0 ; i<Index::value ; ++i )
+ m_os << boost::fusion::at<Index>(m_base).a[i] << " ";
+ m_os << std::endl;
+ }
+ };
+
+
+ stage_vector( const coef_a_type &a , const coef_b_type &b , const coef_c_type &c )
+ {
+ typedef boost::mpl::range_c< size_t , 0 , StageCount-1 > indices;
+ boost::mpl::for_each< indices >( do_insertion( *this , a , c ) );
+ boost::fusion::at_c< StageCount - 1 >( *this ).c = c[ StageCount - 1 ];
+ boost::fusion::at_c< StageCount - 1 >( *this ).a = b;
+ }
+
+ void print( std::ostream &os ) const
+ {
+ typedef boost::mpl::range_c< size_t , 0 , StageCount > indices;
+ boost::mpl::for_each< indices >( print_butcher( *this , os ) );
+ }
+ };
+
+
+
+ template< class System , class StateIn , class StateTemp , class DerivIn , class Deriv ,
+ class StateOut , class Time >
+ struct calculate_stage
+ {
+ Algebra &algebra;
+ System &system;
+ const StateIn &x;
+ StateTemp &x_tmp;
+ StateOut &x_out;
+ const DerivIn &dxdt;
+ Deriv *F;
+ Time t;
+ Time dt;
+
+ calculate_stage( Algebra &_algebra , System &_system , const StateIn &_x , const DerivIn &_dxdt , StateOut &_out ,
+ StateTemp &_x_tmp , Deriv *_F , Time _t , Time _dt )
+ : algebra( _algebra ) , system( _system ) , x( _x ) , x_tmp( _x_tmp ) , x_out( _out) , dxdt( _dxdt ) , F( _F ) , t( _t ) , dt( _dt )
+ {}
+
+
+ template< typename T , size_t stage_number >
+ void inline operator()( stage< T , stage_number > const &stage ) const
+ //typename stage_fusion_wrapper< T , mpl::size_t< stage_number > , intermediate_stage >::type const &stage ) const
+ {
+ if( stage_number > 1 )
+ {
+#ifdef BOOST_MSVC
+#pragma warning( disable : 4307 34 )
+#endif
+ system( x_tmp , F[stage_number-2].m_v , t + stage.c * dt );
+#ifdef BOOST_MSVC
+#pragma warning( default : 4307 34 )
+#endif
+ }
+ //std::cout << stage_number-2 << ", t': " << t + stage.c * dt << std::endl;
+
+ if( stage_number < StageCount )
+ detail::template generic_rk_call_algebra< stage_number , Algebra >()( algebra , x_tmp , x , dxdt , F ,
+ detail::generic_rk_scale_sum< stage_number , Operations , Value , Time >( stage.a , dt) );
+ // algebra_type::template for_eachn<stage_number>( x_tmp , x , dxdt , F ,
+ // typename operations_type::template scale_sumn< stage_number , time_type >( stage.a , dt ) );
+ else
+ detail::template generic_rk_call_algebra< stage_number , Algebra >()( algebra , x_out , x , dxdt , F ,
+ detail::generic_rk_scale_sum< stage_number , Operations , Value , Time >( stage.a , dt ) );
+ // algebra_type::template for_eachn<stage_number>( x_out , x , dxdt , F ,
+ // typename operations_type::template scale_sumn< stage_number , time_type >( stage.a , dt ) );
+ }
+
+ };
+
+ generic_rk_algorithm( const coef_a_type &a , const coef_b_type &b , const coef_c_type &c )
+ : m_stages( a , b , c )
+ { }
+
+ template< class System , class StateIn , class DerivIn , class Time , class StateOut , class StateTemp , class Deriv >
+ void inline do_step( Algebra &algebra , System system , const StateIn &in , const DerivIn &dxdt ,
+ Time t , StateOut &out , Time dt ,
+ StateTemp &x_tmp , Deriv F[StageCount-1] ) const
+ {
+ typedef typename odeint::unwrap_reference< System >::type unwrapped_system_type;
+ unwrapped_system_type &sys = system;
+ boost::fusion::for_each( m_stages , calculate_stage<
+ unwrapped_system_type , StateIn , StateTemp , DerivIn , Deriv , StateOut , Time >
+ ( algebra , sys , in , dxdt , out , x_tmp , F , t , dt ) );
+ }
+
+private:
+ stage_vector m_stages;
+};
+
+
+}
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_ALGORITHM_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp b/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp
new file mode 100644
index 0000000..0249d86
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp
@@ -0,0 +1,263 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp
+
+ [begin_description]
+ Algebra caller for the generic Runge-Kutta methods.
+ [end_description]
+
+ Copyright 2011-2012 Mario Mulansky
+ Copyright 2011-2012 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_CALL_ALGEBRA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_CALL_ALGEBRA_HPP_INCLUDED
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< size_t StageNumber , class Algebra >
+struct generic_rk_call_algebra;
+
+template< class Algebra >
+struct generic_rk_call_algebra< 1 , Algebra >
+{
+ typedef Algebra algebra_type;
+
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( algebra_type &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 * /* s4_array */ , Op op ) const
+ {
+ algebra.for_each3( s1 , s2 , s3 , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( algebra_type &algebra , S1 &s1 , S2 &s2 , S4 * /* s4_array */ , Op op ) const
+ {
+ algebra.for_each2( s1 , s2 , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 2 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[1] , Op op ) const
+ {
+ algebra.for_each4( s1 , s2 , s3 , s4_array[0].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[1] , Op op ) const
+ {
+ algebra.for_each3( s1 , s2 , s4_array[0].m_v , op );
+ }
+};
+
+
+template< class Algebra >
+struct generic_rk_call_algebra< 3 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[2] , Op op ) const
+ {
+ algebra.for_each5( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[2] , Op op ) const
+ {
+ algebra.for_each4( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , op );
+ }
+};
+
+
+template< class Algebra >
+struct generic_rk_call_algebra< 4 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[3] , Op op ) const
+ {
+ algebra.for_each6( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[3] , Op op ) const
+ {
+ algebra.for_each5( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , op );
+ }
+};
+
+
+template< class Algebra >
+struct generic_rk_call_algebra< 5 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[4] , Op op ) const
+ {
+ algebra.for_each7( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[4] , Op op ) const
+ {
+ algebra.for_each6( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 6 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[5] , Op op ) const
+ {
+ algebra.for_each8( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[5] , Op op ) const
+ {
+ algebra.for_each7( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 7 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[6] , Op op ) const
+ {
+ algebra.for_each9( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[6] , Op op ) const
+ {
+ algebra.for_each8( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 8 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[7] , Op op ) const
+ {
+ algebra.for_each10( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[7] , Op op ) const
+ {
+ algebra.for_each9( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 9 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[8] , Op op ) const
+ {
+ algebra.for_each11( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[8] , Op op ) const
+ {
+ algebra.for_each10( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 10 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[9] , Op op ) const
+ {
+ algebra.for_each12( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[9] , Op op ) const
+ {
+ algebra.for_each11( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , op );
+ }
+};
+
+
+template< class Algebra >
+struct generic_rk_call_algebra< 11 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[10] , Op op ) const
+ {
+ algebra.for_each13( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[10] , Op op ) const
+ {
+ algebra.for_each12( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 12 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[11] , Op op ) const
+ {
+ algebra.for_each14( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , s4_array[10].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[11] , Op op ) const
+ {
+ algebra.for_each13( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , s4_array[10].m_v , op );
+ }
+};
+
+template< class Algebra >
+struct generic_rk_call_algebra< 13 , Algebra >
+{
+ template< class S1 , class S2 , class S3 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[12] , Op op ) const
+ {
+ algebra.for_each15( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , s4_array[10].m_v , s4_array[11].m_v , op );
+ }
+
+ template< class S1 , class S2 , class S4 , class Op>
+ void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[12] , Op op ) const
+ {
+ algebra.for_each14( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
+ s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , s4_array[10].m_v , s4_array[11].m_v , op );
+ }
+};
+
+}
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_CALL_ALGEBRA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp b/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp
new file mode 100644
index 0000000..2cce3f4
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp
@@ -0,0 +1,252 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp
+
+ [begin_description]
+ Operations caller for the generic Runge Kutta method.
+ [end_description]
+
+ Copyright 2011 Mario Mulansky
+ Copyright 2011-2012 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_OPERATIONS_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_OPERATIONS_HPP_INCLUDED
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< size_t StageNumber , class Operations , class Fac , class Time >
+struct generic_rk_scale_sum;
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 1 , Operations , Fac , Time > : public Operations::template scale_sum2< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,1> &a , Time dt ) : Operations::template scale_sum2< Fac , Time >( 1.0 , a[0]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 2 , Operations , Fac , Time > : public Operations::template scale_sum3< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,2> &a , Time dt )
+ : Operations::template scale_sum3< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 3 , Operations , Fac , Time > : public Operations::template scale_sum4< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,3> &a , Time dt )
+ : Operations::template scale_sum4< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 4 , Operations , Fac , Time > : public Operations::template scale_sum5< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,4> &a , Time dt )
+ : Operations::template scale_sum5< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 5 , Operations , Fac , Time > : public Operations::template scale_sum6< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,5> &a , Time dt )
+ : Operations::template scale_sum6< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 6 , Operations , Fac , Time > : public Operations::template scale_sum7< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,6> &a , Time dt )
+ : Operations::template scale_sum7< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt , a[5]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 7 , Operations , Fac , Time > : public Operations::template scale_sum8< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,7> &a , Time dt )
+ : Operations::template scale_sum8< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt , a[5]*dt , a[6]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 8 , Operations , Fac , Time > : public Operations::template scale_sum9< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,8> &a , Time dt )
+ : Operations::template scale_sum9< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 9 , Operations , Fac , Time > : public Operations::template scale_sum10< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,9> &a , Time dt )
+ : Operations::template scale_sum10< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt , a[8]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 10 , Operations , Fac , Time > : public Operations::template scale_sum11< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,10> &a , Time dt )
+ : Operations::template scale_sum11< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt , a[8]*dt , a[9]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 11 , Operations , Fac , Time > : public Operations::template scale_sum12< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,11> &a , Time dt )
+ : Operations::template scale_sum12< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt , a[8]*dt , a[9]*dt , a[10]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 12 , Operations , Fac , Time > : public Operations::template scale_sum13< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,12> &a , Time dt )
+ : Operations::template scale_sum13< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt , a[8]*dt , a[9]*dt , a[10]*dt , a[11]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum< 13 , Operations , Fac , Time > : public Operations::template scale_sum14< Fac , Time >
+{
+ generic_rk_scale_sum( const boost::array<Fac,13> &a , Time dt )
+ : Operations::template scale_sum14< Fac , Time >( 1.0 , a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt ,
+ a[5]*dt , a[6]*dt , a[7]*dt , a[8]*dt , a[9]*dt , a[10]*dt , a[11]*dt , a[12]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+// for error estimates
+template< size_t StageNumber , class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err;
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 1 , Operations , Fac , Time > : public Operations::template scale_sum1< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,1> &a , Time dt ) : Operations::template scale_sum1< Time >( a[0]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 2 , Operations , Fac , Time > : public Operations::template scale_sum2< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,2> &a , Time dt )
+ : Operations::template scale_sum2< Time >( a[0]*dt , a[1]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 3 , Operations , Fac , Time > : public Operations::template scale_sum3< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,3> &a , Time dt )
+ : Operations::template scale_sum3< Time >( a[0]*dt , a[1]*dt , a[2]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 4 , Operations , Fac , Time > : public Operations::template scale_sum4< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,4> &a , Time dt )
+ : Operations::template scale_sum4< Time >( a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 5 , Operations , Fac , Time > : public Operations::template scale_sum5< Fac >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,5> &a , Time dt )
+ : Operations::template scale_sum5< Time >( a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 6 , Operations , Fac , Time > : public Operations::template scale_sum6< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,6> &a , Time dt )
+ : Operations::template scale_sum6< Time >( a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt , a[5]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+// for rk87
+template< class Operations , class Fac , class Time >
+struct generic_rk_scale_sum_err< 13 , Operations , Fac , Time > : public Operations::template scale_sum13< Time >
+{
+ generic_rk_scale_sum_err( const boost::array<Fac,13> &a , Time dt )
+ : Operations::template scale_sum13< Time >( a[0]*dt , a[1]*dt , a[2]*dt , a[3]*dt , a[4]*dt , a[5]*dt ,
+ a[6]*dt , a[7]*dt , a[8]*dt , a[9]*dt , a[10]*dt , a[11]*dt , a[12]*dt )
+ { }
+
+ typedef void result_type;
+};
+
+
+}
+}
+}
+}
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_GENERIC_RK_OPERATIONS_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp b/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp
new file mode 100644
index 0000000..2338afd
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/detail/rotating_buffer.hpp
@@ -0,0 +1,84 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/detail/rotating_buffer.hpp
+
+ [begin_description]
+ Implemetation of a rotating (cyclic) buffer for use in the Adam Bashforth stepper
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ROTATING_BUFFER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ROTATING_BUFFER_HPP_INCLUDED
+
+#include <boost/array.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+namespace detail {
+
+template< class T , size_t N >
+class rotating_buffer
+{
+public:
+
+ typedef T value_type;
+ const static size_t dim = N;
+
+ rotating_buffer( void ) : m_first( 0 )
+ { }
+
+ size_t size( void ) const
+ {
+ return dim;
+ }
+
+ value_type& operator[]( size_t i )
+ {
+ return m_data[ get_index( i ) ];
+ }
+
+ const value_type& operator[]( size_t i ) const
+ {
+ return m_data[ get_index( i ) ];
+ }
+
+ void rotate( void )
+ {
+ if( m_first == 0 )
+ m_first = dim-1;
+ else
+ --m_first;
+ }
+
+protected:
+
+ value_type m_data[N];
+
+private:
+
+ size_t get_index( size_t i ) const
+ {
+ return ( ( i + m_first ) % dim );
+ }
+
+ size_t m_first;
+
+};
+
+
+} // detail
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ROTATING_BUFFER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/euler.hpp b/include/boost/numeric/odeint/stepper/euler.hpp
new file mode 100644
index 0000000..1c7c126
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/euler.hpp
@@ -0,0 +1,166 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/euler.hpp
+
+ [begin_description]
+ Implementation of the classical explicit Euler stepper. This method is really simple and should only
+ be used for demonstration purposes.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2013 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_EULER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_EULER_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class euler
+: public explicit_stepper_base<
+ euler< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 1 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class euler : public explicit_stepper_base
+#endif
+{
+public :
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_stepper_base< euler< State , Value , Deriv , Time , Algebra , Operations , Resizer > , 1 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+ #else
+ typedef explicit_stepper_base< euler< ... > , ... > stepper_base_type;
+ #endif
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ #endif
+
+
+ euler( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
+ { }
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System /* system */ , const StateIn &in , const DerivIn &dxdt , time_type /* t */ , StateOut &out , time_type dt )
+ {
+ stepper_base_type::m_algebra.for_each3( out , in , dxdt ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , dt ) );
+
+ }
+
+ template< class StateOut , class StateIn1 , class StateIn2 >
+ void calc_state( StateOut &x , time_type t , const StateIn1 &old_state , time_type t_old , const StateIn2 & /*current_state*/ , time_type /* t_new */ ) const
+ {
+ const time_type delta = t - t_old;
+ stepper_base_type::m_algebra.for_each3( x , old_state , stepper_base_type::m_dxdt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , delta ) );
+ }
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ stepper_base_type::adjust_size( x );
+ }
+};
+
+
+
+/********** DOXYGEN ***********/
+
+/**
+ * \class euler
+ * \brief An implementation of the Euler method.
+ *
+ * The Euler method is a very simply solver for ordinary differential equations. This method should not be used
+ * for real applications. It is only useful for demonstration purposes. Step size control is not provided but
+ * trivial continuous output is available.
+ *
+ * This class derives from explicit_stepper_base and inherits its interface via CRTP (current recurring template pattern),
+ * see explicit_stepper_base
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+ /**
+ * \fn euler::euler( const algebra_type &algebra )
+ * \brief Constructs the euler class. This constructor can be used as a default
+ * constructor of the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn euler::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out of place, hence the input is in `in` and the output in `out`.
+ * Access to this step functionality is provided by explicit_stepper_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn euler::calc_state( StateOut &x , time_type t , const StateIn1 &old_state , time_type t_old , const StateIn2 ¤t_state , time_type t_new ) const
+ * \brief This method is used for continuous output and it calculates the state `x` at a time `t` from the
+ * knowledge of two states `old_state` and `current_state` at time points `t_old` and `t_new`.
+ */
+
+ /**
+ * \fn euler::adjust_size( const StateType &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_EULER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp b/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp
new file mode 100644
index 0000000..3c59810
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp
@@ -0,0 +1,255 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp
+
+ [begin_description]
+ Implementation of the generic Runge Kutta error stepper. Base class for many RK error steppers.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_ERROR_GENERIC_RK_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_ERROR_GENERIC_RK_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp>
+
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_call_algebra.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_operations.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template<
+size_t StageCount,
+size_t Order,
+size_t StepperOrder ,
+size_t ErrorOrder ,
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class explicit_error_generic_rk
+: public explicit_error_stepper_base<
+ explicit_error_generic_rk< StageCount , Order , StepperOrder , ErrorOrder , State ,
+ Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ Order , StepperOrder , ErrorOrder , State , Value , Deriv , Time , Algebra ,
+ Operations , Resizer >
+#else
+class explicit_error_generic_rk : public explicit_error_stepper_base
+#endif
+{
+
+public:
+#ifndef DOXYGEN_SKIP
+ typedef explicit_error_stepper_base<
+ explicit_error_generic_rk< StageCount , Order , StepperOrder , ErrorOrder , State ,
+ Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ Order , StepperOrder , ErrorOrder , State , Value , Deriv , Time , Algebra ,
+ Operations , Resizer > stepper_base_type;
+#else
+ typedef explicit_stepper_base< ... > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+#ifndef DOXYGEN_SKIP
+ typedef explicit_error_generic_rk< StageCount , Order , StepperOrder , ErrorOrder , State ,
+ Value , Deriv , Time , Algebra , Operations , Resizer > stepper_type;
+#endif
+ typedef detail::generic_rk_algorithm< StageCount , Value , Algebra , Operations > rk_algorithm_type;
+
+ typedef typename rk_algorithm_type::coef_a_type coef_a_type;
+ typedef typename rk_algorithm_type::coef_b_type coef_b_type;
+ typedef typename rk_algorithm_type::coef_c_type coef_c_type;
+
+ static const size_t stage_count = StageCount;
+
+private:
+
+
+public:
+
+ // we use an explicit_generic_rk to do the normal rk step
+ // and add a separate calculation of the error estimate afterwards
+ explicit_error_generic_rk( const coef_a_type &a ,
+ const coef_b_type &b ,
+ const coef_b_type &b2 ,
+ const coef_c_type &c ,
+ const algebra_type &algebra = algebra_type() )
+ : stepper_base_type( algebra ) , m_rk_algorithm( a , b , c ) , m_b2( b2 )
+ { }
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut , class Err >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt ,
+ time_type t , StateOut &out , time_type dt , Err &xerr )
+ {
+ // normal step
+ do_step_impl( system , in , dxdt , t , out , dt );
+
+ // additionally, perform the error calculation
+ detail::template generic_rk_call_algebra< StageCount , algebra_type >()( stepper_base_type::m_algebra ,
+ xerr , dxdt , m_F , detail::generic_rk_scale_sum_err< StageCount , operations_type , value_type , time_type >( m_b2 , dt) );
+ }
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt ,
+ time_type t , StateOut &out , time_type dt )
+ {
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ // actual calculation done in generic_rk.hpp
+ m_rk_algorithm.do_step( stepper_base_type::m_algebra , system , in , dxdt , t , out , dt , m_x_tmp.m_v , m_F );
+ }
+
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
+ for( size_t i = 0 ; i < StageCount-1 ; ++i )
+ {
+ resized |= adjust_size_by_resizeability( m_F[i] , x , typename is_resizeable<deriv_type>::type() );
+ }
+ return resized;
+ }
+
+
+ rk_algorithm_type m_rk_algorithm;
+ coef_b_type m_b2;
+
+ resizer_type m_resizer;
+
+ wrapped_state_type m_x_tmp;
+ wrapped_deriv_type m_F[StageCount-1];
+
+};
+
+
+/********* DOXYGEN *********/
+
+/**
+ * \class explicit_error_generic_rk
+ * \brief A generic implementation of explicit Runge-Kutta algorithms with error estimation. This class is as a
+ * base class for all explicit Runge-Kutta steppers with error estimation.
+ *
+ * This class implements the explicit Runge-Kutta algorithms with error estimation in a generic way.
+ * The Butcher tableau is passed to the stepper which constructs the stepper scheme with the help of a
+ * template-metaprogramming algorithm. ToDo : Add example!
+ *
+ * This class derives explicit_error_stepper_base which provides the stepper interface.
+ *
+ * \tparam StageCount The number of stages of the Runge-Kutta algorithm.
+ * \tparam Order The order of a stepper if the stepper is used without error estimation.
+ * \tparam StepperOrder The order of a step if the stepper is used with error estimation. Usually Order and StepperOrder have
+ * the same value.
+ * \tparam ErrorOrder The order of the error step if the stepper is used with error estimation.
+ * \tparam State The type representing the state of the ODE.
+ * \tparam Value The floating point type which is used in the computations.
+ * \tparam Time The type representing the independent variable - the time - of the ODE.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn explicit_error_generic_rk::explicit_error_generic_rk( const coef_a_type &a , const coef_b_type &b , const coef_b_type &b2 , const coef_c_type &c , const algebra_type &algebra )
+ * \brief Constructs the explicit_error_generik_rk class with the given parameters a, b, b2 and c. See examples section for details on the coefficients.
+ *
+ * \param a Triangular matrix of parameters b in the Butcher tableau.
+ * \param b Last row of the butcher tableau.
+ * \param b2 Parameters for lower-order evaluation to estimate the error.
+ * \param c Parameters to calculate the time points in the Butcher tableau.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+
+ /**
+ * \fn explicit_error_generic_rk::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out-of-place, hence the input is in `in` and the output in `out`. Futhermore, an
+ * estimation of the error is stored in `xerr`. `do_step_impl` is used by explicit_error_stepper_base.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ * \param xerr The result of the error estimation is written in xerr.
+ */
+
+ /**
+ * \fn explicit_error_generic_rk::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out-of-place, hence the input is in `in` and the output in `out`.
+ * Access to this step functionality is provided by explicit_stepper_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn explicit_error_generic_rk::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+}
+}
+}
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_ERROR_GENERIC_RK_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp b/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp
new file mode 100644
index 0000000..f8edc20
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/explicit_generic_rk.hpp
@@ -0,0 +1,246 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/explicit_generic_rk.hpp
+
+ [begin_description]
+ Implementation of the generic Runge-Kutta steppers. This is the base class for many Runge-Kutta steppers.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_GENERIC_RK_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_GENERIC_RK_HPP_INCLUDED
+
+
+#include <boost/array.hpp>
+
+
+#include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/stepper/detail/generic_rk_algorithm.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+//forward declarations
+
+#ifndef DOXYGEN_SKIP
+template<
+size_t StageCount,
+size_t Order,
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+class explicit_generic_rk;
+
+
+struct stage_vector;
+
+template< class T , class Constant >
+struct array_wrapper
+{
+ typedef const typename boost::array< T , Constant::value > type;
+};
+
+template< class T , size_t i >
+struct stage
+{
+ T c;
+ boost::array< T , i > a;
+};
+
+
+template< class T , class Constant >
+struct stage_wrapper
+{
+ typedef stage< T , Constant::value > type;
+};
+#endif
+
+
+template<
+size_t StageCount,
+size_t Order,
+class State ,
+class Value ,
+class Deriv ,
+class Time ,
+class Algebra ,
+class Operations ,
+class Resizer
+>
+#ifndef DOXYGEN_SKIP
+class explicit_generic_rk : public explicit_stepper_base<
+explicit_generic_rk< StageCount , Order , State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+Order , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class explicit_generic_rk : public explicit_stepper_base
+#endif
+{
+
+public:
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_stepper_base<
+ explicit_generic_rk< StageCount , Order , State , Value , Deriv ,Time , Algebra , Operations , Resizer > ,
+ Order , State , Value , Deriv , Time , Algebra ,
+ Operations , Resizer > stepper_base_type;
+ #else
+ typedef explicit_stepper_base< ... > stepper_base_type;
+ #endif
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_generic_rk< StageCount , Order , State , Value , Deriv ,Time , Algebra , Operations , Resizer > stepper_type;
+ #endif
+
+ typedef detail::generic_rk_algorithm< StageCount , Value , Algebra , Operations > rk_algorithm_type;
+
+ typedef typename rk_algorithm_type::coef_a_type coef_a_type;
+ typedef typename rk_algorithm_type::coef_b_type coef_b_type;
+ typedef typename rk_algorithm_type::coef_c_type coef_c_type;
+
+ #ifndef DOXYGEN_SKIP
+ static const size_t stage_count = StageCount;
+ #endif
+
+public:
+
+ explicit_generic_rk( const coef_a_type &a , const coef_b_type &b , const coef_c_type &c ,
+ const algebra_type &algebra = algebra_type() )
+ : stepper_base_type( algebra ) , m_rk_algorithm( a , b , c )
+ { }
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt ,
+ time_type t , StateOut &out , time_type dt )
+ {
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ // actual calculation done in generic_rk.hpp
+ m_rk_algorithm.do_step( stepper_base_type::m_algebra , system , in , dxdt , t , out , dt , m_x_tmp.m_v , m_F );
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
+ for( size_t i = 0 ; i < StageCount-1 ; ++i )
+ {
+ resized |= adjust_size_by_resizeability( m_F[i] , x , typename is_resizeable<deriv_type>::type() );
+ }
+ return resized;
+ }
+
+
+ rk_algorithm_type m_rk_algorithm;
+
+ resizer_type m_resizer;
+
+ wrapped_state_type m_x_tmp;
+ wrapped_deriv_type m_F[StageCount-1];
+
+};
+
+
+
+/*********** DOXYGEN *************/
+
+/**
+ * \class explicit_generic_rk
+ * \brief A generic implementation of explicit Runge-Kutta algorithms. This class is as a base class
+ * for all explicit Runge-Kutta steppers.
+ *
+ * This class implements the explicit Runge-Kutta algorithms without error estimation in a generic way.
+ * The Butcher tableau is passed to the stepper which constructs the stepper scheme with the help of a
+ * template-metaprogramming algorithm. ToDo : Add example!
+ *
+ * This class derives explicit_stepper_base which provides the stepper interface.
+ *
+ * \tparam StageCount The number of stages of the Runge-Kutta algorithm.
+ * \tparam Order The order of the stepper.
+ * \tparam State The type representing the state of the ODE.
+ * \tparam Value The floating point type which is used in the computations.
+ * \tparam Time The type representing the independent variable - the time - of the ODE.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+ /**
+ * \fn explicit_generic_rk::explicit_generic_rk( const coef_a_type &a , const coef_b_type &b , const coef_c_type &c , const algebra_type &algebra )
+ * \brief Constructs the explicit_generic_rk class. See examples section for details on the coefficients.
+ * \param a Triangular matrix of parameters b in the Butcher tableau.
+ * \param b Last row of the butcher tableau.
+ * \param c Parameters to calculate the time points in the Butcher tableau.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn explicit_generic_rk::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out of place, hence the input is in `in` and the output in `out`.
+ * Access to this step functionality is provided by explicit_stepper_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn explicit_generic_rk::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+}
+}
+}
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_EXPLICIT_GENERIC_RK_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp b/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp
new file mode 100644
index 0000000..3b688e9
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/extrapolation_stepper.hpp
@@ -0,0 +1,293 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/extrapolation_stepper.hpp
+
+ [begin_description]
+ extrapolation stepper
+ [end_description]
+
+ Copyright 2009-2015 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_EXTRAPOLATION_STEPPER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_EXTRAPOLATION_STEPPER_HPP_INCLUDED
+
+#include <iostream>
+
+#include <algorithm>
+
+#include <boost/config.hpp> // for min/max guidelines
+#include <boost/static_assert.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp>
+#include <boost/numeric/odeint/stepper/modified_midpoint.hpp>
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/unit_helper.hpp>
+#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
+
+namespace boost
+{
+namespace numeric
+{
+namespace odeint
+{
+
+template < unsigned short Order, class State, class Value = double,
+ class Deriv = State, class Time = Value,
+ class Algebra = typename algebra_dispatcher< State >::algebra_type,
+ class Operations =
+ typename operations_dispatcher< State >::operations_type,
+ class Resizer = initially_resizer >
+#ifndef DOXYGEN_SKIP
+class extrapolation_stepper
+ : public explicit_error_stepper_base<
+ extrapolation_stepper< Order, State, Value, Deriv, Time, Algebra,
+ Operations, Resizer >,
+ Order, Order, Order - 2, State, Value, Deriv, Time, Algebra,
+ Operations, Resizer >
+#else
+class extrapolation_stepper : public explicit_error_stepper_base
+#endif
+{
+
+ private:
+ // check for Order being odd
+ BOOST_STATIC_ASSERT_MSG(
+ ( ( Order % 2 ) == 0 ) && ( Order > 2 ),
+ "extrapolation_stepper requires even Order larger than 2" );
+
+ public:
+#ifndef DOXYGEN_SKIP
+ typedef explicit_error_stepper_base<
+ extrapolation_stepper< Order, State, Value, Deriv, Time, Algebra,
+ Operations, Resizer >,
+ Order, Order, Order - 2, State, Value, Deriv, Time, Algebra, Operations,
+ Resizer > stepper_base_type;
+#else
+ typedef explicit_error_stepper_base< extrapolation_stepper< ... >, ... >
+ stepper_base_type;
+#endif
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+#ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+
+ typedef std::vector< value_type > value_vector;
+ typedef std::vector< value_vector > value_matrix;
+ typedef std::vector< size_t > int_vector;
+ typedef std::vector< wrapped_state_type > state_table_type;
+ typedef modified_midpoint< state_type, value_type, deriv_type, time_type,
+ algebra_type, operations_type,
+ resizer_type > midpoint_stepper_type;
+
+#endif // DOXYGEN_SKIP
+
+ typedef unsigned short order_type;
+ static const order_type order_value = stepper_base_type::order_value;
+ static const order_type stepper_order_value =
+ stepper_base_type::stepper_order_value;
+ static const order_type error_order_value =
+ stepper_base_type::error_order_value;
+
+ const static size_t m_k_max = ( order_value - 2 ) / 2;
+
+ extrapolation_stepper( const algebra_type &algebra = algebra_type() )
+ : stepper_base_type( algebra ), m_interval_sequence( m_k_max + 1 ),
+ m_coeff( m_k_max + 1 ), m_table( m_k_max )
+ {
+ for ( unsigned short i = 0; i < m_k_max + 1; i++ )
+ {
+ m_interval_sequence[i] = 2 * ( i + 1 );
+ m_coeff[i].resize( i );
+ for ( size_t k = 0; k < i; ++k )
+ {
+ const value_type r =
+ static_cast< value_type >( m_interval_sequence[i] ) /
+ static_cast< value_type >( m_interval_sequence[k] );
+ m_coeff[i][k] =
+ static_cast< value_type >( 1 ) /
+ ( r * r - static_cast< value_type >(
+ 1 ) ); // coefficients for extrapolation
+ }
+ }
+ }
+
+ template < class System, class StateIn, class DerivIn, class StateOut,
+ class Err >
+ void do_step_impl( System system, const StateIn &in, const DerivIn &dxdt,
+ time_type t, StateOut &out, time_type dt, Err &xerr )
+ {
+ // std::cout << "dt: " << dt << std::endl;
+ // normal step
+ do_step_impl( system, in, dxdt, t, out, dt );
+
+ static const value_type val1( 1.0 );
+ // additionally, perform the error calculation
+ stepper_base_type::m_algebra.for_each3(
+ xerr, out, m_table[0].m_v,
+ typename operations_type::template scale_sum2<
+ value_type, value_type >( val1, -val1 ) );
+ }
+
+ template < class System, class StateInOut, class DerivIn, class Err >
+ void do_step_impl_io( System system, StateInOut &inout, const DerivIn &dxdt,
+ time_type t, time_type dt, Err &xerr )
+ {
+ // normal step
+ do_step_impl_io( system, inout, dxdt, t, dt );
+
+ static const value_type val1( 1.0 );
+ // additionally, perform the error calculation
+ stepper_base_type::m_algebra.for_each3(
+ xerr, inout, m_table[0].m_v,
+ typename operations_type::template scale_sum2<
+ value_type, value_type >( val1, -val1 ) );
+ }
+
+ template < class System, class StateIn, class DerivIn, class StateOut >
+ void do_step_impl( System system, const StateIn &in, const DerivIn &dxdt,
+ time_type t, StateOut &out, time_type dt )
+ {
+ m_resizer.adjust_size(
+ in, detail::bind( &stepper_type::template resize_impl< StateIn >,
+ detail::ref( *this ), detail::_1 ) );
+ size_t k = 0;
+ m_midpoint.set_steps( m_interval_sequence[k] );
+ m_midpoint.do_step( system, in, dxdt, t, out, dt );
+ for ( k = 1; k <= m_k_max; ++k )
+ {
+ m_midpoint.set_steps( m_interval_sequence[k] );
+ m_midpoint.do_step( system, in, dxdt, t, m_table[k - 1].m_v, dt );
+ extrapolate( k, m_table, m_coeff, out );
+ }
+ }
+
+ template < class System, class StateInOut, class DerivIn >
+ void do_step_impl_io( System system, StateInOut &inout, const DerivIn &dxdt,
+ time_type t, time_type dt )
+ {
+ // special care for inout
+ m_xout_resizer.adjust_size(
+ inout,
+ detail::bind( &stepper_type::template resize_m_xout< StateInOut >,
+ detail::ref( *this ), detail::_1 ) );
+ do_step_impl( system, inout, dxdt, t, m_xout.m_v, dt );
+ boost::numeric::odeint::copy( m_xout.m_v, inout );
+ }
+
+ template < class System, class StateInOut, class DerivIn >
+ void do_step_dxdt_impl( System system, StateInOut &x, const DerivIn &dxdt,
+ time_type t, time_type dt )
+ {
+ do_step_impl_io( system , x , dxdt , t , dt );
+ }
+
+ template < class System, class StateIn, class DerivIn, class StateOut >
+ void do_step_dxdt_impl( System system, const StateIn &in,
+ const DerivIn &dxdt, time_type t, StateOut &out,
+ time_type dt )
+ {
+ do_step_impl( system , in , dxdt , t , out , dt );
+ }
+
+
+ template < class StateIn > void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ m_midpoint.adjust_size( x );
+ }
+
+ private:
+ template < class StateIn > bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ for ( size_t i = 0; i < m_k_max; ++i )
+ resized |= adjust_size_by_resizeability(
+ m_table[i], x, typename is_resizeable< state_type >::type() );
+ return resized;
+ }
+
+ template < class StateIn > bool resize_m_xout( const StateIn &x )
+ {
+ return adjust_size_by_resizeability(
+ m_xout, x, typename is_resizeable< state_type >::type() );
+ }
+
+ template < class StateInOut >
+ void extrapolate( size_t k, state_table_type &table,
+ const value_matrix &coeff, StateInOut &xest )
+ /* polynomial extrapolation, see http://www.nr.com/webnotes/nr3web21.pdf
+ uses the obtained intermediate results to extrapolate to dt->0
+ */
+ {
+ static const value_type val1 = static_cast< value_type >( 1.0 );
+
+ for ( int j = k - 1; j > 0; --j )
+ {
+ stepper_base_type::m_algebra.for_each3(
+ table[j - 1].m_v, table[j].m_v, table[j - 1].m_v,
+ typename operations_type::template scale_sum2<
+ value_type, value_type >( val1 + coeff[k][j],
+ -coeff[k][j] ) );
+ }
+ stepper_base_type::m_algebra.for_each3(
+ xest, table[0].m_v, xest,
+ typename operations_type::template scale_sum2<
+ value_type, value_type >( val1 + coeff[k][0], -coeff[k][0] ) );
+ }
+
+ private:
+ midpoint_stepper_type m_midpoint;
+
+ resizer_type m_resizer;
+ resizer_type m_xout_resizer;
+
+ int_vector m_interval_sequence; // stores the successive interval counts
+ value_matrix m_coeff;
+
+ wrapped_state_type m_xout;
+ state_table_type m_table; // sequence of states for extrapolation
+};
+
+/******** DOXYGEN *******/
+
+/**
+ * \class extrapolation_stepper
+ * \brief Extrapolation stepper with configurable order, and error estimation.
+ *
+ * The extrapolation stepper is a stepper with error estimation and configurable
+ * order. The order is given as template parameter and needs to be an _odd_
+ * number. The stepper is based on several executions of the modified midpoint
+ * method and a Richardson extrapolation. This is essentially the same technique
+ * as for bulirsch_stoer, but without the variable order.
+ *
+ * \note The Order parameter has to be an even number greater 2.
+ */
+}
+}
+}
+#endif
diff --git a/include/boost/numeric/odeint/stepper/generation.hpp b/include/boost/numeric/odeint/stepper/generation.hpp
new file mode 100644
index 0000000..90ad2b9
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation.hpp
@@ -0,0 +1,36 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation.hpp
+
+ [begin_description]
+ Forward header for the factory functions. Includes all files from the generation directory.
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_dense_output.hpp>
+
+#include <boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp>
+
+#include <boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp>
+#include <boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp>
+#include <boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp>
+#include <boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp>
+
+
+#include <boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp>
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp
new file mode 100644
index 0000000..bad2bed
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp
@@ -0,0 +1,61 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_controlled_runge_kutta.hpp
+
+ [begin_description]
+ Specialization of the controller factory for the controlled_runge_kutta class.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+// controller factory for controlled_runge_kutta
+template< class Stepper >
+struct controller_factory< Stepper , controlled_runge_kutta< Stepper > >
+{
+ typedef Stepper stepper_type;
+ typedef controlled_runge_kutta< stepper_type > controller_type;
+ typedef typename controller_type::error_checker_type error_checker_type;
+ typedef typename controller_type::step_adjuster_type step_adjuster_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::value_type time_type;
+
+ controller_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper )
+ {
+ return controller_type( error_checker_type( abs_error , rel_error ) ,
+ step_adjuster_type() , stepper );
+ }
+
+ controller_type operator()( value_type abs_error , value_type rel_error ,
+ time_type max_dt, const stepper_type &stepper )
+ {
+ return controller_type( error_checker_type( abs_error , rel_error ) ,
+ step_adjuster_type(max_dt) , stepper );
+ }
+};
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_CONTROLLED_RUNGE_KUTTA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp
new file mode 100644
index 0000000..276358a
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp
@@ -0,0 +1,65 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_dense_output_runge_kutta.hpp
+
+ [begin_description]
+ Specialization of the controller factory for the dense_output_runge_kutta class.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_dense_output.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+// controller factory for controlled_runge_kutta
+template< class Stepper >
+struct dense_output_factory< Stepper , dense_output_runge_kutta< controlled_runge_kutta< Stepper > > >
+{
+ typedef Stepper stepper_type;
+ typedef controlled_runge_kutta< stepper_type > controller_type;
+ typedef typename controller_type::error_checker_type error_checker_type;
+ typedef typename controller_type::step_adjuster_type step_adjuster_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef dense_output_runge_kutta< controller_type > dense_output_type;
+
+ dense_output_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper )
+ {
+ return dense_output_type( controller_type( error_checker_type( abs_error , rel_error ) ,
+ step_adjuster_type() , stepper ) );
+ }
+
+ dense_output_type operator()( value_type abs_error , value_type rel_error ,
+ time_type max_dt , const stepper_type &stepper )
+ {
+ return dense_output_type(
+ controller_type( error_checker_type( abs_error , rel_error) ,
+ step_adjuster_type( max_dt ) , stepper ) );
+ }
+};
+
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_DENSE_OUTPUT_RUNGE_KUTTA_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp b/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp
new file mode 100644
index 0000000..366cb5e
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp
@@ -0,0 +1,79 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_rosenbrock4.hpp
+
+ [begin_description]
+ Enable the factory functions for the controller and the dense output of the Rosenbrock4 method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_ROSENBROCK4_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_ROSENBROCK4_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/rosenbrock4.hpp>
+#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp>
+#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template< class Value , class Coefficients , class Resize >
+struct get_controller< rosenbrock4< Value , Coefficients , Resize > >
+{
+ typedef rosenbrock4< Value , Coefficients , Resize > stepper_type;
+ typedef rosenbrock4_controller< stepper_type > type;
+};
+
+
+
+template< class Value , class Coefficients , class Resize >
+struct get_dense_output< rosenbrock4< Value , Coefficients , Resize > >
+{
+ typedef rosenbrock4< Value , Coefficients , Resize > stepper_type;
+ typedef rosenbrock4_controller< stepper_type > controller_type;
+ typedef rosenbrock4_dense_output< controller_type > type;
+};
+
+
+
+// controller factory for controlled_runge_kutta
+template< class Stepper >
+struct dense_output_factory< Stepper , rosenbrock4_dense_output< rosenbrock4_controller< Stepper > > >
+{
+ typedef Stepper stepper_type;
+ typedef rosenbrock4_controller< stepper_type > controller_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef rosenbrock4_dense_output< controller_type > dense_output_type;
+
+ dense_output_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper )
+ {
+ return dense_output_type( controller_type( abs_error , rel_error , stepper ) );
+ }
+
+ dense_output_type operator()( value_type abs_error , value_type rel_error ,
+ time_type max_dt, const stepper_type &stepper )
+ {
+ return dense_output_type( controller_type( abs_error , rel_error , max_dt , stepper ) );
+ }
+};
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_ROSENBROCK4_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp
new file mode 100644
index 0000000..24ae547
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp
@@ -0,0 +1,47 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54.hpp
+
+ [begin_description]
+ Enable the factory functions for the controller and the dense output of the Runge-Kutta-Cash-Karp 54 method.
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+// Specializations for runge_kutta_cash_karp54
+template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resize >
+struct get_controller< runge_kutta_cash_karp54< State , Value , Deriv , Time , Algebra , Operations , Resize > >
+{
+ typedef runge_kutta_cash_karp54< State , Value , Deriv , Time , Algebra , Operations , Resize > stepper_type;
+ typedef controlled_runge_kutta< stepper_type > type;
+};
+
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp
new file mode 100644
index 0000000..1cc0f91
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp
@@ -0,0 +1,48 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_runge_kutta_cash_karp54_classic.hpp
+
+ [begin_description]
+ Enable the factory functions for the controller and the dense output of the
+ Runge-Kutta-Cash-Karp 54 method with the classical implementation.
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+// Specializations for runge_kutta_cash_karp54
+template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resize >
+struct get_controller< runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resize > >
+{
+ typedef runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resize > stepper_type;
+ typedef controlled_runge_kutta< stepper_type > type;
+};
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp
new file mode 100644
index 0000000..1a607f3
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp
@@ -0,0 +1,56 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_runge_kutta_dopri5.hpp
+
+ [begin_description]
+ Enable the factory functions for the controller and the dense output of the Runge-Kutta-Dormand-Prince5 method.
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_dense_output.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resize >
+struct get_controller< runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resize > >
+{
+ typedef runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resize > stepper_type;
+ typedef controlled_runge_kutta< stepper_type > type;
+};
+
+
+template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resize >
+struct get_dense_output< runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resize > >
+{
+ typedef runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resize > stepper_type;
+ typedef controlled_runge_kutta< stepper_type > controller_type;
+ typedef dense_output_runge_kutta< controller_type > type;
+};
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp
new file mode 100644
index 0000000..d89343b
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp
@@ -0,0 +1,46 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/generation_runge_kutta_fehlberg78.hpp
+
+ [begin_description]
+ Enable the factory functions for the controller and the dense output of the Runge-Kutta-Fehlberg 78 method.
+ [end_description]
+
+ Copyright 2011 Karsten Ahnert
+ Copyright 2011 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_FEHLBERG78_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_FEHLBERG78_HPP_INCLUDED
+
+#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp>
+#include <boost/numeric/odeint/stepper/generation/make_controlled.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+template< class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resize >
+struct get_controller< runge_kutta_fehlberg78< State , Value , Deriv , Time , Algebra , Operations , Resize > >
+{
+ typedef runge_kutta_fehlberg78< State , Value , Deriv , Time , Algebra , Operations , Resize > stepper_type;
+ typedef controlled_runge_kutta< stepper_type > type;
+};
+
+
+
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_GENERATION_RUNGE_KUTTA_FEHLBERG78_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp b/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp
new file mode 100644
index 0000000..61bc8f1
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/make_controlled.hpp
@@ -0,0 +1,103 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/make_controlled.hpp
+
+ [begin_description]
+ Factory function to simplify the creation of controlled steppers from error steppers.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_CONTROLLED_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_CONTROLLED_HPP_INCLUDED
+
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+
+// default template for the controller
+template< class Stepper > struct get_controller { };
+
+
+
+// default controller factory
+template< class Stepper , class Controller >
+struct controller_factory
+{
+ Controller operator()(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ const Stepper &stepper )
+ {
+ return Controller( abs_error , rel_error , stepper );
+ }
+
+ Controller operator()(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ typename Stepper::time_type max_dt ,
+ const Stepper &stepper )
+ {
+ return Controller( abs_error , rel_error , max_dt, stepper );
+ }
+};
+
+
+
+
+namespace result_of
+{
+ template< class Stepper >
+ struct make_controlled
+ {
+ typedef typename get_controller< Stepper >::type type;
+ };
+}
+
+
+template< class Stepper >
+typename result_of::make_controlled< Stepper >::type make_controlled(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ const Stepper & stepper = Stepper() )
+{
+ typedef Stepper stepper_type;
+ typedef typename result_of::make_controlled< stepper_type >::type controller_type;
+ typedef controller_factory< stepper_type , controller_type > factory_type;
+ factory_type factory;
+ return factory( abs_error , rel_error , stepper );
+}
+
+
+template< class Stepper >
+typename result_of::make_controlled< Stepper >::type make_controlled(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ typename Stepper::time_type max_dt ,
+ const Stepper & stepper = Stepper() )
+{
+ typedef Stepper stepper_type;
+ typedef typename result_of::make_controlled< stepper_type >::type controller_type;
+ typedef controller_factory< stepper_type , controller_type > factory_type;
+ factory_type factory;
+ return factory( abs_error , rel_error , max_dt, stepper );
+}
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_CONTROLLED_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp b/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp
new file mode 100644
index 0000000..fff3590
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/generation/make_dense_output.hpp
@@ -0,0 +1,100 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/generation/make_dense_output.hpp
+
+ [begin_description]
+ Factory function to simplify the creation of dense output steppers from error steppers.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_DENSE_OUTPUT_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_DENSE_OUTPUT_HPP_INCLUDED
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+// default template for the dense output
+template< class Stepper > struct get_dense_output { };
+
+
+
+// default dense output factory
+template< class Stepper , class DenseOutput >
+struct dense_output_factory
+{
+ DenseOutput operator()(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ const Stepper &stepper )
+ {
+ return DenseOutput( abs_error , rel_error , stepper );
+ }
+
+ DenseOutput operator()(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ typename Stepper::time_type max_dt ,
+ const Stepper &stepper )
+ {
+ return DenseOutput( abs_error , rel_error , max_dt , stepper );
+ }
+};
+
+
+
+namespace result_of
+{
+ template< class Stepper >
+ struct make_dense_output
+ {
+ typedef typename get_dense_output< Stepper >::type type;
+ };
+}
+
+
+
+template< class Stepper >
+typename result_of::make_dense_output< Stepper >::type make_dense_output(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ const Stepper &stepper = Stepper() )
+{
+ typedef Stepper stepper_type;
+ typedef typename result_of::make_dense_output< stepper_type >::type dense_output_type;
+ typedef dense_output_factory< stepper_type , dense_output_type > factory_type;
+ factory_type factory;
+ return factory( abs_error , rel_error , stepper );
+}
+
+
+template< class Stepper >
+typename result_of::make_dense_output< Stepper >::type make_dense_output(
+ typename Stepper::value_type abs_error ,
+ typename Stepper::value_type rel_error ,
+ typename Stepper::time_type max_dt ,
+ const Stepper &stepper = Stepper() )
+{
+ typedef Stepper stepper_type;
+ typedef typename result_of::make_dense_output< stepper_type >::type dense_output_type;
+ typedef dense_output_factory< stepper_type , dense_output_type > factory_type;
+ factory_type factory;
+ return factory( abs_error , rel_error , max_dt, stepper );
+}
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_GENERATION_MAKE_DENSE_OUTPUT_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/implicit_euler.hpp b/include/boost/numeric/odeint/stepper/implicit_euler.hpp
new file mode 100644
index 0000000..e1c6416
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/implicit_euler.hpp
@@ -0,0 +1,170 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/implicit_euler.hpp
+
+ [begin_description]
+ Impementation of the implicit Euler method. Works with ublas::vector as state type.
+ [end_description]
+
+ Copyright 2010-2012 Mario Mulansky
+ Copyright 2010-2012 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_IMPLICIT_EULER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_IMPLICIT_EULER_HPP_INCLUDED
+
+
+#include <utility>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/util/ublas_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/lu.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+
+
+
+
+
+
+template< class ValueType , class Resizer = initially_resizer >
+class implicit_euler
+{
+
+public:
+
+ typedef ValueType value_type;
+ typedef value_type time_type;
+ typedef boost::numeric::ublas::vector< value_type > state_type;
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_type deriv_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef boost::numeric::ublas::matrix< value_type > matrix_type;
+ typedef state_wrapper< matrix_type > wrapped_matrix_type;
+ typedef boost::numeric::ublas::permutation_matrix< size_t > pmatrix_type;
+ typedef state_wrapper< pmatrix_type > wrapped_pmatrix_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+ typedef implicit_euler< ValueType , Resizer > stepper_type;
+
+ implicit_euler( value_type epsilon = 1E-6 )
+ : m_epsilon( epsilon )
+ { }
+
+
+ template< class System >
+ void do_step( System system , state_type &x , time_type t , time_type dt )
+ {
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ typedef typename odeint::unwrap_reference< typename system_type::first_type >::type deriv_func_type;
+ typedef typename odeint::unwrap_reference< typename system_type::second_type >::type jacobi_func_type;
+ system_type &sys = system;
+ deriv_func_type &deriv_func = sys.first;
+ jacobi_func_type &jacobi_func = sys.second;
+
+ m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl<state_type> , detail::ref( *this ) , detail::_1 ) );
+
+ for( size_t i=0 ; i<x.size() ; ++i )
+ m_pm.m_v[i] = i;
+
+ t += dt;
+
+ // apply first Newton step
+ deriv_func( x , m_dxdt.m_v , t );
+
+ m_b.m_v = dt * m_dxdt.m_v;
+
+ jacobi_func( x , m_jacobi.m_v , t );
+ m_jacobi.m_v *= dt;
+ m_jacobi.m_v -= boost::numeric::ublas::identity_matrix< value_type >( x.size() );
+
+ solve( m_b.m_v , m_jacobi.m_v );
+
+ m_x.m_v = x - m_b.m_v;
+
+ // iterate Newton until some precision is reached
+ // ToDo: maybe we should apply only one Newton step -> linear implicit one-step scheme
+ while( boost::numeric::ublas::norm_2( m_b.m_v ) > m_epsilon )
+ {
+ deriv_func( m_x.m_v , m_dxdt.m_v , t );
+ m_b.m_v = x - m_x.m_v + dt*m_dxdt.m_v;
+
+ // simplified version, only the first Jacobian is used
+ // jacobi( m_x , m_jacobi , t );
+ // m_jacobi *= dt;
+ // m_jacobi -= boost::numeric::ublas::identity_matrix< value_type >( x.size() );
+
+ solve( m_b.m_v , m_jacobi.m_v );
+
+ m_x.m_v -= m_b.m_v;
+ }
+ x = m_x.m_v;
+ }
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ }
+
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_b , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_jacobi , x , typename is_resizeable<matrix_type>::type() );
+ resized |= adjust_size_by_resizeability( m_pm , x , typename is_resizeable<pmatrix_type>::type() );
+ return resized;
+ }
+
+
+ void solve( state_type &x , matrix_type &m )
+ {
+ int res = boost::numeric::ublas::lu_factorize( m , m_pm.m_v );
+ if( res != 0 ) std::exit(0);
+ boost::numeric::ublas::lu_substitute( m , m_pm.m_v , x );
+ }
+
+private:
+
+ value_type m_epsilon;
+ resizer_type m_resizer;
+ wrapped_deriv_type m_dxdt;
+ wrapped_state_type m_x;
+ wrapped_deriv_type m_b;
+ wrapped_matrix_type m_jacobi;
+ wrapped_pmatrix_type m_pm;
+
+
+};
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_IMPLICIT_EULER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/modified_midpoint.hpp b/include/boost/numeric/odeint/stepper/modified_midpoint.hpp
new file mode 100644
index 0000000..9e34c7d
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/modified_midpoint.hpp
@@ -0,0 +1,315 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/modified_midpoint.hpp
+
+ [begin_description]
+ Modified midpoint method for the use in Burlish-Stoer stepper.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_MODIFIED_MIDPOINT_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_MODIFIED_MIDPOINT_HPP_INCLUDED
+
+#include <vector>
+
+#include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/util/copy.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class modified_midpoint
+: public explicit_stepper_base<
+ modified_midpoint< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 2 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class modified_midpoint : public explicit_stepper_base
+#endif
+{
+
+public :
+
+ typedef explicit_stepper_base<
+ modified_midpoint< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 2 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+ typedef typename stepper_base_type::stepper_type stepper_type;
+
+
+ modified_midpoint( unsigned short steps = 2 , const algebra_type &algebra = algebra_type() )
+ : stepper_base_type( algebra ) , m_steps( steps )
+ { }
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ {
+ static const value_type val1 = static_cast< value_type >( 1 );
+ static const value_type val05 = static_cast< value_type >( 1 ) / static_cast< value_type >( 2 );
+
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ const time_type h = dt / static_cast<value_type>( m_steps );
+ const time_type h2 = static_cast<value_type>(2) * h;
+
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ time_type th = t + h;
+
+ // m_x1 = x + h*dxdt
+ stepper_base_type::m_algebra.for_each3( m_x1.m_v , in , dxdt ,
+ typename operations_type::template scale_sum2< value_type , time_type >( val1 , h ) );
+
+ sys( m_x1.m_v , m_dxdt.m_v , th );
+
+ boost::numeric::odeint::copy( in , m_x0.m_v );
+
+ unsigned short i = 1;
+ while( i != m_steps )
+ {
+ // general step
+ //tmp = m_x1; m_x1 = m_x0 + h2*m_dxdt; m_x0 = tmp
+ stepper_base_type::m_algebra.for_each3( m_x1.m_v , m_x0.m_v , m_dxdt.m_v ,
+ typename operations_type::template scale_sum_swap2< value_type , time_type >( val1 , h2 ) );
+ th += h;
+ sys( m_x1.m_v , m_dxdt.m_v , th);
+ i++;
+ }
+
+ // last step
+ // x = 0.5*( m_x0 + m_x1 + h*m_dxdt )
+ stepper_base_type::m_algebra.for_each4( out , m_x0.m_v , m_x1.m_v , m_dxdt.m_v ,
+ typename operations_type::template scale_sum3< value_type , value_type , time_type >( val05 , val05 , val05*h ) );
+ }
+
+
+ void set_steps( unsigned short steps )
+ { m_steps = steps; }
+
+
+ unsigned short steps( void ) const
+ { return m_steps; }
+
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized( false );
+ resized |= adjust_size_by_resizeability( m_x0 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ return resized;
+ }
+
+
+ unsigned short m_steps;
+
+ resizer_type m_resizer;
+
+ wrapped_state_type m_x0;
+ wrapped_state_type m_x1;
+ wrapped_deriv_type m_dxdt;
+
+};
+
+
+/* Modified midpoint which stores derivatives and state at dt/2 in some external storage for later usage in dense output calculation
+ * This Stepper is for use in Bulirsch Stoer only. It DOES NOT meet any stepper concept.
+ */
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+class modified_midpoint_dense_out
+{
+
+public :
+
+ typedef State state_type;
+ typedef Value value_type;
+ typedef Deriv deriv_type;
+ typedef Time time_type;
+ typedef Algebra algebra_type;
+ typedef Operations operations_type;
+ typedef Resizer resizer_type;
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+
+ typedef modified_midpoint_dense_out< State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_type;
+ typedef std::vector< wrapped_deriv_type > deriv_table_type;
+
+ modified_midpoint_dense_out( unsigned short steps = 2 , const algebra_type &algebra = algebra_type() )
+ : m_algebra( algebra ) , m_steps( steps )
+ { }
+
+ /*
+ * performs a modified midpoint step with m_steps intermediate points
+ * stores approximation for x(t+dt/2) in x_mp and all evaluated function results in derivs
+ *
+ */
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt ,
+ state_type &x_mp , deriv_table_type &derivs )
+ {
+
+ static const value_type val1 = static_cast< value_type >( 1 );
+ static const value_type val05 = static_cast< value_type >( 1 ) / static_cast< value_type >( 2 );
+
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ const time_type h = dt / static_cast<value_type>( m_steps );
+ const time_type h2 = static_cast<value_type>( 2 ) * h;
+
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ time_type th = t + h;
+
+ // m_x1 = x + h*dxdt
+ m_algebra.for_each3( m_x1.m_v , in , dxdt ,
+ typename operations_type::template scale_sum2< value_type , time_type >( val1 , h ) );
+
+ if( m_steps == 2 )
+ // result of first step already gives approximation at the center of the interval
+ boost::numeric::odeint::copy( m_x1.m_v , x_mp );
+
+ sys( m_x1.m_v , derivs[0].m_v , th );
+
+ boost::numeric::odeint::copy( in , m_x0.m_v );
+
+ unsigned short i = 1;
+ while( i != m_steps )
+ {
+ // general step
+ //tmp = m_x1; m_x1 = m_x0 + h2*m_dxdt; m_x0 = tmp
+ m_algebra.for_each3( m_x1.m_v , m_x0.m_v , derivs[i-1].m_v ,
+ typename operations_type::template scale_sum_swap2< value_type , time_type >( val1 , h2 ) );
+ if( i == m_steps/2-1 )
+ // save approximation at the center of the interval
+ boost::numeric::odeint::copy( m_x1.m_v , x_mp );
+
+ th += h;
+ sys( m_x1.m_v , derivs[i].m_v , th);
+ i++;
+ }
+
+ // last step
+ // x = 0.5*( m_x0 + m_x1 + h*m_dxdt )
+ m_algebra.for_each4( out , m_x0.m_v , m_x1.m_v , derivs[m_steps-1].m_v ,
+ typename operations_type::template scale_sum3< value_type , value_type , time_type >( val05 , val05 , val05*h ) );
+ }
+
+
+ void set_steps( unsigned short steps )
+ { m_steps = steps; }
+
+
+ unsigned short steps( void ) const
+ { return m_steps; }
+
+
+ template< class StateIn >
+ bool resize( const StateIn &x )
+ {
+ bool resized( false );
+ resized |= adjust_size_by_resizeability( m_x0 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ return resized;
+ }
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize( x );
+ }
+
+private:
+
+ algebra_type m_algebra;
+
+ unsigned short m_steps;
+
+ resizer_type m_resizer;
+
+ wrapped_state_type m_x0;
+ wrapped_state_type m_x1;
+
+};
+
+
+
+/********** DOXYGEN ***********/
+
+/**
+ * \class modified_midpoint
+ *
+ * Implementation of the modified midpoint method with a configurable
+ * number of intermediate steps. This class is used by the Bulirsch-Stoer
+ * algorithm and is not meant for direct usage.
+ */
+
+
+/**
+ * \class modified_midpoint_dense_out
+ *
+ * Implementation of the modified midpoint method with a configurable
+ * number of intermediate steps. This class is used by the dense output
+ * Bulirsch-Stoer algorithm and is not meant for direct usage.
+ * \note This stepper is for internal use only and does not meet
+ * any stepper concept.
+ */
+
+
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_MODIFIED_MIDPOINT_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4.hpp
new file mode 100644
index 0000000..8613698
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/rosenbrock4.hpp
@@ -0,0 +1,346 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/rosenbrock4.hpp
+
+ [begin_description]
+ Implementation of the Rosenbrock 4 method for solving stiff ODEs. Note, that a
+ controller and a dense-output stepper exist for this method,
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/lu.hpp>
+
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/util/ublas_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/lu.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+/*
+ * ToDo:
+ *
+ * 2. Interfacing for odeint, check if controlled_error_stepper can be used
+ * 3. dense output
+ */
+
+
+
+template< class Value >
+struct default_rosenbrock_coefficients
+{
+ typedef Value value_type;
+ typedef unsigned short order_type;
+
+ default_rosenbrock_coefficients( void )
+ : gamma ( static_cast< value_type >( 0.25 ) ) ,
+ d1 ( static_cast< value_type >( 0.25 ) ) ,
+ d2 ( static_cast< value_type >( -0.1043 ) ) ,
+ d3 ( static_cast< value_type >( 0.1035 ) ) ,
+ d4 ( static_cast< value_type >( 0.3620000000000023e-01 ) ) ,
+ c2 ( static_cast< value_type >( 0.386 ) ) ,
+ c3 ( static_cast< value_type >( 0.21 ) ) ,
+ c4 ( static_cast< value_type >( 0.63 ) ) ,
+ c21 ( static_cast< value_type >( -0.5668800000000000e+01 ) ) ,
+ a21 ( static_cast< value_type >( 0.1544000000000000e+01 ) ) ,
+ c31 ( static_cast< value_type >( -0.2430093356833875e+01 ) ) ,
+ c32 ( static_cast< value_type >( -0.2063599157091915e+00 ) ) ,
+ a31 ( static_cast< value_type >( 0.9466785280815826e+00 ) ) ,
+ a32 ( static_cast< value_type >( 0.2557011698983284e+00 ) ) ,
+ c41 ( static_cast< value_type >( -0.1073529058151375e+00 ) ) ,
+ c42 ( static_cast< value_type >( -0.9594562251023355e+01 ) ) ,
+ c43 ( static_cast< value_type >( -0.2047028614809616e+02 ) ) ,
+ a41 ( static_cast< value_type >( 0.3314825187068521e+01 ) ) ,
+ a42 ( static_cast< value_type >( 0.2896124015972201e+01 ) ) ,
+ a43 ( static_cast< value_type >( 0.9986419139977817e+00 ) ) ,
+ c51 ( static_cast< value_type >( 0.7496443313967647e+01 ) ) ,
+ c52 ( static_cast< value_type >( -0.1024680431464352e+02 ) ) ,
+ c53 ( static_cast< value_type >( -0.3399990352819905e+02 ) ) ,
+ c54 ( static_cast< value_type >( 0.1170890893206160e+02 ) ) ,
+ a51 ( static_cast< value_type >( 0.1221224509226641e+01 ) ) ,
+ a52 ( static_cast< value_type >( 0.6019134481288629e+01 ) ) ,
+ a53 ( static_cast< value_type >( 0.1253708332932087e+02 ) ) ,
+ a54 ( static_cast< value_type >( -0.6878860361058950e+00 ) ) ,
+ c61 ( static_cast< value_type >( 0.8083246795921522e+01 ) ) ,
+ c62 ( static_cast< value_type >( -0.7981132988064893e+01 ) ) ,
+ c63 ( static_cast< value_type >( -0.3152159432874371e+02 ) ) ,
+ c64 ( static_cast< value_type >( 0.1631930543123136e+02 ) ) ,
+ c65 ( static_cast< value_type >( -0.6058818238834054e+01 ) ) ,
+ d21 ( static_cast< value_type >( 0.1012623508344586e+02 ) ) ,
+ d22 ( static_cast< value_type >( -0.7487995877610167e+01 ) ) ,
+ d23 ( static_cast< value_type >( -0.3480091861555747e+02 ) ) ,
+ d24 ( static_cast< value_type >( -0.7992771707568823e+01 ) ) ,
+ d25 ( static_cast< value_type >( 0.1025137723295662e+01 ) ) ,
+ d31 ( static_cast< value_type >( -0.6762803392801253e+00 ) ) ,
+ d32 ( static_cast< value_type >( 0.6087714651680015e+01 ) ) ,
+ d33 ( static_cast< value_type >( 0.1643084320892478e+02 ) ) ,
+ d34 ( static_cast< value_type >( 0.2476722511418386e+02 ) ) ,
+ d35 ( static_cast< value_type >( -0.6594389125716872e+01 ) )
+ {}
+
+ const value_type gamma;
+ const value_type d1 , d2 , d3 , d4;
+ const value_type c2 , c3 , c4;
+ const value_type c21 ;
+ const value_type a21;
+ const value_type c31 , c32;
+ const value_type a31 , a32;
+ const value_type c41 , c42 , c43;
+ const value_type a41 , a42 , a43;
+ const value_type c51 , c52 , c53 , c54;
+ const value_type a51 , a52 , a53 , a54;
+ const value_type c61 , c62 , c63 , c64 , c65;
+ const value_type d21 , d22 , d23 , d24 , d25;
+ const value_type d31 , d32 , d33 , d34 , d35;
+
+ static const order_type stepper_order = 4;
+ static const order_type error_order = 3;
+};
+
+
+
+template< class Value , class Coefficients = default_rosenbrock_coefficients< Value > , class Resizer = initially_resizer >
+class rosenbrock4
+{
+private:
+
+public:
+
+ typedef Value value_type;
+ typedef boost::numeric::ublas::vector< value_type > state_type;
+ typedef state_type deriv_type;
+ typedef value_type time_type;
+ typedef boost::numeric::ublas::matrix< value_type > matrix_type;
+ typedef boost::numeric::ublas::permutation_matrix< size_t > pmatrix_type;
+ typedef Resizer resizer_type;
+ typedef Coefficients rosenbrock_coefficients;
+ typedef stepper_tag stepper_category;
+ typedef unsigned short order_type;
+
+ typedef state_wrapper< state_type > wrapped_state_type;
+ typedef state_wrapper< deriv_type > wrapped_deriv_type;
+ typedef state_wrapper< matrix_type > wrapped_matrix_type;
+ typedef state_wrapper< pmatrix_type > wrapped_pmatrix_type;
+
+ typedef rosenbrock4< Value , Coefficients , Resizer > stepper_type;
+
+ const static order_type stepper_order = rosenbrock_coefficients::stepper_order;
+ const static order_type error_order = rosenbrock_coefficients::error_order;
+
+ rosenbrock4( void )
+ : m_resizer() , m_x_err_resizer() ,
+ m_jac() , m_pm() ,
+ m_dfdt() , m_dxdt() , m_dxdtnew() ,
+ m_g1() , m_g2() , m_g3() , m_g4() , m_g5() ,
+ m_cont3() , m_cont4() , m_xtmp() , m_x_err() ,
+ m_coef()
+ { }
+
+
+ order_type order() const { return stepper_order; }
+
+ template< class System >
+ void do_step( System system , const state_type &x , time_type t , state_type &xout , time_type dt , state_type &xerr )
+ {
+ // get the system and jacobi function
+ typedef typename odeint::unwrap_reference< System >::type system_type;
+ typedef typename odeint::unwrap_reference< typename system_type::first_type >::type deriv_func_type;
+ typedef typename odeint::unwrap_reference< typename system_type::second_type >::type jacobi_func_type;
+ system_type &sys = system;
+ deriv_func_type &deriv_func = sys.first;
+ jacobi_func_type &jacobi_func = sys.second;
+
+ const size_t n = x.size();
+
+ m_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_impl<state_type> , detail::ref( *this ) , detail::_1 ) );
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_pm.m_v( i ) = i;
+
+ deriv_func( x , m_dxdt.m_v , t );
+ jacobi_func( x , m_jac.m_v , t , m_dfdt.m_v );
+
+ m_jac.m_v *= -1.0;
+ m_jac.m_v += 1.0 / m_coef.gamma / dt * boost::numeric::ublas::identity_matrix< value_type >( n );
+ boost::numeric::ublas::lu_factorize( m_jac.m_v , m_pm.m_v );
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_g1.m_v[i] = m_dxdt.m_v[i] + dt * m_coef.d1 * m_dfdt.m_v[i];
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , m_g1.m_v );
+
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_xtmp.m_v[i] = x[i] + m_coef.a21 * m_g1.m_v[i];
+ deriv_func( m_xtmp.m_v , m_dxdtnew.m_v , t + m_coef.c2 * dt );
+ for( size_t i=0 ; i<n ; ++i )
+ m_g2.m_v[i] = m_dxdtnew.m_v[i] + dt * m_coef.d2 * m_dfdt.m_v[i] + m_coef.c21 * m_g1.m_v[i] / dt;
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , m_g2.m_v );
+
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_xtmp.m_v[i] = x[i] + m_coef.a31 * m_g1.m_v[i] + m_coef.a32 * m_g2.m_v[i];
+ deriv_func( m_xtmp.m_v , m_dxdtnew.m_v , t + m_coef.c3 * dt );
+ for( size_t i=0 ; i<n ; ++i )
+ m_g3.m_v[i] = m_dxdtnew.m_v[i] + dt * m_coef.d3 * m_dfdt.m_v[i] + ( m_coef.c31 * m_g1.m_v[i] + m_coef.c32 * m_g2.m_v[i] ) / dt;
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , m_g3.m_v );
+
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_xtmp.m_v[i] = x[i] + m_coef.a41 * m_g1.m_v[i] + m_coef.a42 * m_g2.m_v[i] + m_coef.a43 * m_g3.m_v[i];
+ deriv_func( m_xtmp.m_v , m_dxdtnew.m_v , t + m_coef.c4 * dt );
+ for( size_t i=0 ; i<n ; ++i )
+ m_g4.m_v[i] = m_dxdtnew.m_v[i] + dt * m_coef.d4 * m_dfdt.m_v[i] + ( m_coef.c41 * m_g1.m_v[i] + m_coef.c42 * m_g2.m_v[i] + m_coef.c43 * m_g3.m_v[i] ) / dt;
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , m_g4.m_v );
+
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_xtmp.m_v[i] = x[i] + m_coef.a51 * m_g1.m_v[i] + m_coef.a52 * m_g2.m_v[i] + m_coef.a53 * m_g3.m_v[i] + m_coef.a54 * m_g4.m_v[i];
+ deriv_func( m_xtmp.m_v , m_dxdtnew.m_v , t + dt );
+ for( size_t i=0 ; i<n ; ++i )
+ m_g5.m_v[i] = m_dxdtnew.m_v[i] + ( m_coef.c51 * m_g1.m_v[i] + m_coef.c52 * m_g2.m_v[i] + m_coef.c53 * m_g3.m_v[i] + m_coef.c54 * m_g4.m_v[i] ) / dt;
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , m_g5.m_v );
+
+ for( size_t i=0 ; i<n ; ++i )
+ m_xtmp.m_v[i] += m_g5.m_v[i];
+ deriv_func( m_xtmp.m_v , m_dxdtnew.m_v , t + dt );
+ for( size_t i=0 ; i<n ; ++i )
+ xerr[i] = m_dxdtnew.m_v[i] + ( m_coef.c61 * m_g1.m_v[i] + m_coef.c62 * m_g2.m_v[i] + m_coef.c63 * m_g3.m_v[i] + m_coef.c64 * m_g4.m_v[i] + m_coef.c65 * m_g5.m_v[i] ) / dt;
+ boost::numeric::ublas::lu_substitute( m_jac.m_v , m_pm.m_v , xerr );
+
+ for( size_t i=0 ; i<n ; ++i )
+ xout[i] = m_xtmp.m_v[i] + xerr[i];
+ }
+
+ template< class System >
+ void do_step( System system , state_type &x , time_type t , time_type dt , state_type &xerr )
+ {
+ do_step( system , x , t , x , dt , xerr );
+ }
+
+ /*
+ * do_step without error output - just calls above functions with and neglects the error estimate
+ */
+ template< class System >
+ void do_step( System system , const state_type &x , time_type t , state_type &xout , time_type dt )
+ {
+ m_x_err_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_x_err<state_type> , detail::ref( *this ) , detail::_1 ) );
+ do_step( system , x , t , xout , dt , m_x_err.m_v );
+ }
+
+ template< class System >
+ void do_step( System system , state_type &x , time_type t , time_type dt )
+ {
+ m_x_err_resizer.adjust_size( x , detail::bind( &stepper_type::template resize_x_err<state_type> , detail::ref( *this ) , detail::_1 ) );
+ do_step( system , x , t , dt , m_x_err.m_v );
+ }
+
+ void prepare_dense_output()
+ {
+ const size_t n = m_g1.m_v.size();
+ for( size_t i=0 ; i<n ; ++i )
+ {
+ m_cont3.m_v[i] = m_coef.d21 * m_g1.m_v[i] + m_coef.d22 * m_g2.m_v[i] + m_coef.d23 * m_g3.m_v[i] + m_coef.d24 * m_g4.m_v[i] + m_coef.d25 * m_g5.m_v[i];
+ m_cont4.m_v[i] = m_coef.d31 * m_g1.m_v[i] + m_coef.d32 * m_g2.m_v[i] + m_coef.d33 * m_g3.m_v[i] + m_coef.d34 * m_g4.m_v[i] + m_coef.d35 * m_g5.m_v[i];
+ }
+ }
+
+
+ void calc_state( time_type t , state_type &x ,
+ const state_type &x_old , time_type t_old ,
+ const state_type &x_new , time_type t_new )
+ {
+ const size_t n = m_g1.m_v.size();
+ time_type dt = t_new - t_old;
+ time_type s = ( t - t_old ) / dt;
+ time_type s1 = 1.0 - s;
+ for( size_t i=0 ; i<n ; ++i )
+ x[i] = x_old[i] * s1 + s * ( x_new[i] + s1 * ( m_cont3.m_v[i] + s * m_cont4.m_v[i] ) );
+ }
+
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ resize_x_err( x );
+ }
+
+
+protected:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_dxdt , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dfdt , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxdtnew , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_xtmp , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_g1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_g2 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_g3 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_g4 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_g5 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_cont3 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_cont4 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_jac , x , typename is_resizeable<matrix_type>::type() );
+ resized |= adjust_size_by_resizeability( m_pm , x , typename is_resizeable<pmatrix_type>::type() );
+ return resized;
+ }
+
+ template< class StateIn >
+ bool resize_x_err( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_x_err , x , typename is_resizeable<state_type>::type() );
+ }
+
+private:
+
+
+ resizer_type m_resizer;
+ resizer_type m_x_err_resizer;
+
+ wrapped_matrix_type m_jac;
+ wrapped_pmatrix_type m_pm;
+ wrapped_deriv_type m_dfdt , m_dxdt , m_dxdtnew;
+ wrapped_state_type m_g1 , m_g2 , m_g3 , m_g4 , m_g5;
+ wrapped_state_type m_cont3 , m_cont4;
+ wrapped_state_type m_xtmp;
+ wrapped_state_type m_x_err;
+
+ const rosenbrock_coefficients m_coef;
+};
+
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp
new file mode 100644
index 0000000..61d6e51
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp
@@ -0,0 +1,240 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/rosenbrock4_controller.hpp
+
+ [begin_description]
+ Controller for the Rosenbrock4 method.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2012 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_CONTROLLER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_CONTROLLER_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/util/copy.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
+
+#include <boost/numeric/odeint/stepper/rosenbrock4.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template< class Stepper >
+class rosenbrock4_controller
+{
+private:
+
+
+public:
+
+ typedef Stepper stepper_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_type::resizer_type resizer_type;
+ typedef controlled_stepper_tag stepper_category;
+
+ typedef rosenbrock4_controller< Stepper > controller_type;
+
+
+ rosenbrock4_controller( value_type atol = 1.0e-6 , value_type rtol = 1.0e-6 ,
+ const stepper_type &stepper = stepper_type() )
+ : m_stepper( stepper ) , m_atol( atol ) , m_rtol( rtol ) ,
+ m_max_dt( static_cast<time_type>(0) ) ,
+ m_first_step( true ) , m_err_old( 0.0 ) , m_dt_old( 0.0 ) ,
+ m_last_rejected( false )
+ { }
+
+ rosenbrock4_controller( value_type atol, value_type rtol, time_type max_dt,
+ const stepper_type &stepper = stepper_type() )
+ : m_stepper( stepper ) , m_atol( atol ) , m_rtol( rtol ) , m_max_dt( max_dt ) ,
+ m_first_step( true ) , m_err_old( 0.0 ) , m_dt_old( 0.0 ) ,
+ m_last_rejected( false )
+ { }
+
+ value_type error( const state_type &x , const state_type &xold , const state_type &xerr )
+ {
+ BOOST_USING_STD_MAX();
+ using std::abs;
+ using std::sqrt;
+
+ const size_t n = x.size();
+ value_type err = 0.0 , sk = 0.0;
+ for( size_t i=0 ; i<n ; ++i )
+ {
+ sk = m_atol + m_rtol * max BOOST_PREVENT_MACRO_SUBSTITUTION ( abs( xold[i] ) , abs( x[i] ) );
+ err += xerr[i] * xerr[i] / sk / sk;
+ }
+ return sqrt( err / value_type( n ) );
+ }
+
+ value_type last_error( void ) const
+ {
+ return m_err_old;
+ }
+
+
+
+
+ template< class System >
+ boost::numeric::odeint::controlled_step_result
+ try_step( System sys , state_type &x , time_type &t , time_type &dt )
+ {
+ m_xnew_resizer.adjust_size( x , detail::bind( &controller_type::template resize_m_xnew< state_type > , detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::controlled_step_result res = try_step( sys , x , t , m_xnew.m_v , dt );
+ if( res == success )
+ {
+ boost::numeric::odeint::copy( m_xnew.m_v , x );
+ }
+ return res;
+ }
+
+
+ template< class System >
+ boost::numeric::odeint::controlled_step_result
+ try_step( System sys , const state_type &x , time_type &t , state_type &xout , time_type &dt )
+ {
+ if( m_max_dt != static_cast<time_type>(0) && detail::less_with_sign(m_max_dt, dt, dt) )
+ {
+ // given step size is bigger then max_dt
+ // set limit and return fail
+ dt = m_max_dt;
+ return fail;
+ }
+
+ BOOST_USING_STD_MIN();
+ BOOST_USING_STD_MAX();
+ using std::pow;
+
+ static const value_type safe = 0.9 , fac1 = 5.0 , fac2 = 1.0 / 6.0;
+
+ m_xerr_resizer.adjust_size( x , detail::bind( &controller_type::template resize_m_xerr< state_type > , detail::ref( *this ) , detail::_1 ) );
+
+ m_stepper.do_step( sys , x , t , xout , dt , m_xerr.m_v );
+ value_type err = error( xout , x , m_xerr.m_v );
+
+ value_type fac = max BOOST_PREVENT_MACRO_SUBSTITUTION (
+ fac2 , min BOOST_PREVENT_MACRO_SUBSTITUTION (
+ fac1 ,
+ static_cast< value_type >( pow( err , 0.25 ) / safe ) ) );
+ value_type dt_new = dt / fac;
+ if ( err <= 1.0 )
+ {
+ if( m_first_step )
+ {
+ m_first_step = false;
+ }
+ else
+ {
+ value_type fac_pred = ( m_dt_old / dt ) * pow( err * err / m_err_old , 0.25 ) / safe;
+ fac_pred = max BOOST_PREVENT_MACRO_SUBSTITUTION (
+ fac2 , min BOOST_PREVENT_MACRO_SUBSTITUTION ( fac1 , fac_pred ) );
+ fac = max BOOST_PREVENT_MACRO_SUBSTITUTION ( fac , fac_pred );
+ dt_new = dt / fac;
+ }
+
+ m_dt_old = dt;
+ m_err_old = max BOOST_PREVENT_MACRO_SUBSTITUTION ( static_cast< value_type >( 0.01 ) , err );
+ if( m_last_rejected )
+ dt_new = ( dt >= 0.0 ?
+ min BOOST_PREVENT_MACRO_SUBSTITUTION ( dt_new , dt ) :
+ max BOOST_PREVENT_MACRO_SUBSTITUTION ( dt_new , dt ) );
+ t += dt;
+ // limit step size to max_dt
+ if( m_max_dt != static_cast<time_type>(0) )
+ {
+ dt = detail::min_abs(m_max_dt, dt_new);
+ } else {
+ dt = dt_new;
+ }
+ m_last_rejected = false;
+ return success;
+ }
+ else
+ {
+ dt = dt_new;
+ m_last_rejected = true;
+ return fail;
+ }
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_m_xerr( x );
+ resize_m_xnew( x );
+ }
+
+
+
+ stepper_type& stepper( void )
+ {
+ return m_stepper;
+ }
+
+ const stepper_type& stepper( void ) const
+ {
+ return m_stepper;
+ }
+
+
+
+
+private:
+
+ template< class StateIn >
+ bool resize_m_xerr( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xerr , x , typename is_resizeable<state_type>::type() );
+ }
+
+ template< class StateIn >
+ bool resize_m_xnew( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_xnew , x , typename is_resizeable<state_type>::type() );
+ }
+
+
+ stepper_type m_stepper;
+ resizer_type m_xerr_resizer;
+ resizer_type m_xnew_resizer;
+ wrapped_state_type m_xerr;
+ wrapped_state_type m_xnew;
+ value_type m_atol , m_rtol;
+ time_type m_max_dt;
+ bool m_first_step;
+ value_type m_err_old , m_dt_old;
+ bool m_last_rejected;
+};
+
+
+
+
+
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_CONTROLLER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp
new file mode 100644
index 0000000..6695ba6
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp
@@ -0,0 +1,199 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp
+
+ [begin_description]
+ Dense output for Rosenbrock 4.
+ [end_description]
+
+ Copyright 2011-2012 Karsten Ahnert
+ Copyright 2011-2015 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED
+
+
+#include <utility>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+
+#include <boost/numeric/odeint/integrate/max_step_checker.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template< class ControlledStepper >
+class rosenbrock4_dense_output
+{
+
+public:
+
+ typedef ControlledStepper controlled_stepper_type;
+ typedef typename controlled_stepper_type::stepper_type stepper_type;
+ typedef typename stepper_type::value_type value_type;
+ typedef typename stepper_type::state_type state_type;
+ typedef typename stepper_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_type::time_type time_type;
+ typedef typename stepper_type::deriv_type deriv_type;
+ typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_type::resizer_type resizer_type;
+ typedef dense_output_stepper_tag stepper_category;
+
+ typedef rosenbrock4_dense_output< ControlledStepper > dense_output_stepper_type;
+
+ rosenbrock4_dense_output( const controlled_stepper_type &stepper = controlled_stepper_type() )
+ : m_stepper( stepper ) ,
+ m_x1() , m_x2() ,
+ m_current_state_x1( true ) ,
+ m_t() , m_t_old() , m_dt()
+ {
+ }
+
+
+
+ template< class StateType >
+ void initialize( const StateType &x0 , time_type t0 , time_type dt0 )
+ {
+ m_resizer.adjust_size( x0 , detail::bind( &dense_output_stepper_type::template resize_impl< StateType > , detail::ref( *this ) , detail::_1 ) );
+ get_current_state() = x0;
+ m_t = t0;
+ m_dt = dt0;
+ }
+
+ template< class System >
+ std::pair< time_type , time_type > do_step( System system )
+ {
+ failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails
+ controlled_step_result res = fail;
+ m_t_old = m_t;
+ do
+ {
+ res = m_stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt );
+ fail_checker(); // check for overflow of failed steps
+ }
+ while( res == fail );
+ m_stepper.stepper().prepare_dense_output();
+ this->toggle_current_state();
+ return std::make_pair( m_t_old , m_t );
+ }
+
+
+ /*
+ * The two overloads are needed in order to solve the forwarding problem.
+ */
+ template< class StateOut >
+ void calc_state( time_type t , StateOut &x )
+ {
+ m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t );
+ }
+
+ template< class StateOut >
+ void calc_state( time_type t , const StateOut &x )
+ {
+ m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t );
+ }
+
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ m_stepper.adjust_size( x );
+ resize_impl( x );
+ }
+
+
+
+
+ const state_type& current_state( void ) const
+ {
+ return get_current_state();
+ }
+
+ time_type current_time( void ) const
+ {
+ return m_t;
+ }
+
+ const state_type& previous_state( void ) const
+ {
+ return get_old_state();
+ }
+
+ time_type previous_time( void ) const
+ {
+ return m_t_old;
+ }
+
+ time_type current_time_step( void ) const
+ {
+ return m_dt;
+ }
+
+
+
+
+private:
+
+ state_type& get_current_state( void )
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ const state_type& get_current_state( void ) const
+ {
+ return m_current_state_x1 ? m_x1.m_v : m_x2.m_v ;
+ }
+
+ state_type& get_old_state( void )
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ const state_type& get_old_state( void ) const
+ {
+ return m_current_state_x1 ? m_x2.m_v : m_x1.m_v ;
+ }
+
+ void toggle_current_state( void )
+ {
+ m_current_state_x1 = ! m_current_state_x1;
+ }
+
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x1 , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_x2 , x , typename is_resizeable<state_type>::type() );
+ return resized;
+ }
+
+
+ controlled_stepper_type m_stepper;
+ resizer_type m_resizer;
+ wrapped_state_type m_x1 , m_x2;
+ bool m_current_state_x1;
+ time_type m_t , m_t_old , m_dt;
+};
+
+
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_ROSENBROCK4_DENSE_OUTPUT_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta4.hpp b/include/boost/numeric/odeint/stepper/runge_kutta4.hpp
new file mode 100644
index 0000000..2410774
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta4.hpp
@@ -0,0 +1,181 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta4.hpp
+
+ [begin_description]
+ Implementation of the classical Runge-Kutta stepper with the generic stepper.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_HPP_INCLUDED
+
+
+
+
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/container/generation/make_vector.hpp>
+
+#include <boost/numeric/odeint/stepper/explicit_generic_rk.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/array.hpp>
+
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+#ifndef DOXYGEN_SKIP
+template< class Value = double >
+struct rk4_coefficients_a1 : boost::array< Value , 1 >
+{
+ rk4_coefficients_a1( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ }
+};
+
+template< class Value = double >
+struct rk4_coefficients_a2 : boost::array< Value , 2 >
+{
+ rk4_coefficients_a2( void )
+ {
+ (*this)[0] = static_cast<Value>(0);
+ (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ }
+};
+
+
+template< class Value = double >
+struct rk4_coefficients_a3 : boost::array< Value , 3 >
+{
+ rk4_coefficients_a3( void )
+ {
+ (*this)[0] = static_cast<Value>(0);
+ (*this)[1] = static_cast<Value>(0);
+ (*this)[2] = static_cast<Value>(1);
+ }
+};
+
+template< class Value = double >
+struct rk4_coefficients_b : boost::array< Value , 4 >
+{
+ rk4_coefficients_b( void )
+ {
+ (*this)[0] = static_cast<Value>(1)/static_cast<Value>(6);
+ (*this)[1] = static_cast<Value>(1)/static_cast<Value>(3);
+ (*this)[2] = static_cast<Value>(1)/static_cast<Value>(3);
+ (*this)[3] = static_cast<Value>(1)/static_cast<Value>(6);
+ }
+};
+
+template< class Value = double >
+struct rk4_coefficients_c : boost::array< Value , 4 >
+{
+ rk4_coefficients_c( void )
+ {
+ (*this)[0] = static_cast<Value>(0);
+ (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ (*this)[2] = static_cast< Value >( 1 ) / static_cast< Value >( 2 );
+ (*this)[3] = static_cast<Value>(1);
+ }
+};
+#endif
+
+
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class runge_kutta4 : public explicit_generic_rk< 4 , 4 , State , Value , Deriv , Time ,
+Algebra , Operations , Resizer >
+#else
+class runge_kutta4 : public explicit_generic_rk
+#endif
+{
+
+public:
+
+#ifndef DOXYGEN_SKIP
+ typedef explicit_generic_rk< 4 , 4 , State , Value , Deriv , Time ,
+ Algebra , Operations , Resizer > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ #endif
+
+ runge_kutta4( const algebra_type &algebra = algebra_type() ) : stepper_base_type(
+ boost::fusion::make_vector( rk4_coefficients_a1<Value>() , rk4_coefficients_a2<Value>() , rk4_coefficients_a3<Value>() ) ,
+ rk4_coefficients_b<Value>() , rk4_coefficients_c<Value>() , algebra )
+ { }
+
+};
+
+/**
+ * \class runge_kutta4
+ * \brief The classical Runge-Kutta stepper of fourth order.
+ *
+ * The Runge-Kutta method of fourth order is one standard method for
+ * solving ordinary differential equations and is widely used, see also
+ * <a href="http://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods">en.wikipedia.org/wiki/Runge-Kutta_methods</a>
+ * The method is explicit and fulfills the Stepper concept. Step size control
+ * or continuous output are not provided.
+ *
+ * This class derives from explicit_stepper_base and inherits its interface via CRTP (current recurring template pattern).
+ * Furthermore, it derivs from explicit_generic_rk which is a generic Runge-Kutta algorithm. For more details see
+ * explicit_stepper_base and explicit_generic_rk.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+/**
+ * \fn runge_kutta4::runge_kutta4( const algebra_type &algebra = algebra_type() )
+ * \brief Constructs the runge_kutta4 class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+}
+}
+}
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp b/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp
new file mode 100644
index 0000000..32bda0b
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta4_classic.hpp
@@ -0,0 +1,232 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta4_classic.hpp
+
+ [begin_description]
+ Implementation for the classical Runge Kutta stepper.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_CLASSIC_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_CLASSIC_HPP_INCLUDED
+
+
+
+#include <boost/numeric/odeint/stepper/base/explicit_stepper_base.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class runge_kutta4_classic
+: public explicit_stepper_base<
+ runge_kutta4_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class runge_kutta4_classic : public explicit_stepper_base
+#endif
+{
+
+public :
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_stepper_base<
+ runge_kutta4_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+ #else
+ typedef explicit_stepper_base< runge_kutta4_classic< ... > , ... > stepper_base_type;
+ #endif
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ #endif // DOXYGEN_SKIP
+
+
+
+ runge_kutta4_classic( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
+ { }
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ {
+ // ToDo : check if size of in,dxdt,out are equal?
+
+ static const value_type val1 = static_cast< value_type >( 1 );
+
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateIn > , detail::ref( *this ) , detail::_1 ) );
+
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ const time_type dh = dt / static_cast< value_type >( 2 );
+ const time_type th = t + dh;
+
+ // dt * dxdt = k1
+ // m_x_tmp = x + dh*dxdt
+ stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , dxdt ,
+ typename operations_type::template scale_sum2< value_type , time_type >( val1 , dh ) );
+
+
+ // dt * m_dxt = k2
+ sys( m_x_tmp.m_v , m_dxt.m_v , th );
+
+ // m_x_tmp = x + dh*m_dxt
+ stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , m_dxt.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( val1 , dh ) );
+
+
+ // dt * m_dxm = k3
+ sys( m_x_tmp.m_v , m_dxm.m_v , th );
+ //m_x_tmp = x + dt*m_dxm
+ stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , m_dxm.m_v ,
+ typename operations_type::template scale_sum2< value_type , time_type >( val1 , dt ) );
+
+
+ // dt * m_dxh = k4
+ sys( m_x_tmp.m_v , m_dxh.m_v , t + dt );
+
+ //x += dt/6 * ( m_dxdt + m_dxt + val2*m_dxm )
+ time_type dt6 = dt / static_cast< value_type >( 6 );
+ time_type dt3 = dt / static_cast< value_type >( 3 );
+ stepper_base_type::m_algebra.for_each6( out , in , dxdt , m_dxt.m_v , m_dxm.m_v , m_dxh.m_v ,
+ typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt6 , dt3 , dt3 , dt6 ) );
+
+ // x += dt/6 * m_dxdt + dt/3 * m_dxt )
+ // stepper_base_type::m_algebra.for_each4( out , in , dxdt , m_dxt.m_v ,
+ // typename operations_type::template scale_sum3< value_type , time_type , time_type >( 1.0 , dt6 , dt3 ) );
+ // // x += dt/3 * m_dxm + dt/6 * m_dxh )
+ // stepper_base_type::m_algebra.for_each4( out , out , m_dxm.m_v , m_dxh.m_v ,
+ // typename operations_type::template scale_sum3< value_type , time_type , time_type >( 1.0 , dt3 , dt6 ) );
+
+ }
+
+ template< class StateType >
+ void adjust_size( const StateType &x )
+ {
+ resize_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxm , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxt , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_dxh , x , typename is_resizeable<deriv_type>::type() );
+ return resized;
+ }
+
+
+ resizer_type m_resizer;
+
+ wrapped_deriv_type m_dxt;
+ wrapped_deriv_type m_dxm;
+ wrapped_deriv_type m_dxh;
+ wrapped_state_type m_x_tmp;
+
+};
+
+
+/********* DOXYGEN *********/
+
+/**
+ * \class runge_kutta4_classic
+ * \brief The classical Runge-Kutta stepper of fourth order.
+ *
+ * The Runge-Kutta method of fourth order is one standard method for
+ * solving ordinary differential equations and is widely used, see also
+ * <a href="http://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods">en.wikipedia.org/wiki/Runge-Kutta_methods</a>
+ * The method is explicit and fulfills the Stepper concept. Step size control
+ * or continuous output are not provided. This class implements the method directly, hence the
+ * generic Runge-Kutta algorithm is not used.
+ *
+ * This class derives from explicit_stepper_base and inherits its interface via
+ * CRTP (current recurring template pattern). For more details see
+ * explicit_stepper_base.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+ /**
+ * \fn runge_kutta4_classic::runge_kutta4_classic( const algebra_type &algebra )
+ * \brief Constructs the runge_kutta4_classic class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+
+ /**
+ * \fn runge_kutta4_classic::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out of place, hence the input is in `in` and the output in `out`.
+ * Access to this step functionality is provided by explicit_stepper_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn runge_kutta4_classic::adjust_size( const StateType &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA4_CLASSIC_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp
new file mode 100644
index 0000000..beecb3f
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp
@@ -0,0 +1,231 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp
+
+ [begin_description]
+ Implementation of the Runge Kutta Cash Karp 5(4) method. It uses the generic error stepper.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2011-2013 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
+
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/container/generation/make_vector.hpp>
+
+#include <boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/array.hpp>
+
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+#ifndef DOXYGEN_SKIP
+template< class Value = double >
+struct rk54_ck_coefficients_a1 : boost::array< Value , 1 >
+{
+ rk54_ck_coefficients_a1( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 )/static_cast< Value >( 5 );
+ }
+};
+
+template< class Value = double >
+struct rk54_ck_coefficients_a2 : boost::array< Value , 2 >
+{
+ rk54_ck_coefficients_a2( void )
+ {
+ (*this)[0] = static_cast<Value>( 3 )/static_cast<Value>( 40 );
+ (*this)[1] = static_cast<Value>( 9 )/static_cast<Value>( 40 );
+ }
+};
+
+
+template< class Value = double >
+struct rk54_ck_coefficients_a3 : boost::array< Value , 3 >
+{
+ rk54_ck_coefficients_a3( void )
+ {
+ (*this)[0] = static_cast<Value>( 3 )/static_cast<Value>( 10 );
+ (*this)[1] = static_cast<Value>( -9 )/static_cast<Value>( 10 );
+ (*this)[2] = static_cast<Value>( 6 )/static_cast<Value>( 5 );
+ }
+};
+
+template< class Value = double >
+struct rk54_ck_coefficients_a4 : boost::array< Value , 4 >
+{
+ rk54_ck_coefficients_a4( void )
+ {
+ (*this)[0] = static_cast<Value>( -11 )/static_cast<Value>( 54 );
+ (*this)[1] = static_cast<Value>( 5 )/static_cast<Value>( 2 );
+ (*this)[2] = static_cast<Value>( -70 )/static_cast<Value>( 27 );
+ (*this)[3] = static_cast<Value>( 35 )/static_cast<Value>( 27 );
+ }
+};
+
+template< class Value = double >
+struct rk54_ck_coefficients_a5 : boost::array< Value , 5 >
+{
+ rk54_ck_coefficients_a5( void )
+ {
+ (*this)[0] = static_cast<Value>( 1631 )/static_cast<Value>( 55296 );
+ (*this)[1] = static_cast<Value>( 175 )/static_cast<Value>( 512 );
+ (*this)[2] = static_cast<Value>( 575 )/static_cast<Value>( 13824 );
+ (*this)[3] = static_cast<Value>( 44275 )/static_cast<Value>( 110592 );
+ (*this)[4] = static_cast<Value>( 253 )/static_cast<Value>( 4096 );
+ }
+};
+
+template< class Value = double >
+struct rk54_ck_coefficients_b : boost::array< Value , 6 >
+{
+ rk54_ck_coefficients_b( void )
+ {
+ (*this)[0] = static_cast<Value>( 37 )/static_cast<Value>( 378 );
+ (*this)[1] = static_cast<Value>( 0 );
+ (*this)[2] = static_cast<Value>( 250 )/static_cast<Value>( 621 );
+ (*this)[3] = static_cast<Value>( 125 )/static_cast<Value>( 594 );
+ (*this)[4] = static_cast<Value>( 0 );
+ (*this)[5] = static_cast<Value>( 512 )/static_cast<Value>( 1771 );
+ }
+};
+
+template< class Value = double >
+struct rk54_ck_coefficients_db : boost::array< Value , 6 >
+{
+ rk54_ck_coefficients_db( void )
+ {
+ (*this)[0] = static_cast<Value>( 37 )/static_cast<Value>( 378 ) - static_cast<Value>( 2825 )/static_cast<Value>( 27648 );
+ (*this)[1] = static_cast<Value>( 0 );
+ (*this)[2] = static_cast<Value>( 250 )/static_cast<Value>( 621 ) - static_cast<Value>( 18575 )/static_cast<Value>( 48384 );
+ (*this)[3] = static_cast<Value>( 125 )/static_cast<Value>( 594 ) - static_cast<Value>( 13525 )/static_cast<Value>( 55296 );
+ (*this)[4] = static_cast<Value>( -277 )/static_cast<Value>( 14336 );
+ (*this)[5] = static_cast<Value>( 512 )/static_cast<Value>( 1771 ) - static_cast<Value>( 1 )/static_cast<Value>( 4 );
+ }
+};
+
+
+template< class Value = double >
+struct rk54_ck_coefficients_c : boost::array< Value , 6 >
+{
+ rk54_ck_coefficients_c( void )
+ {
+ (*this)[0] = static_cast<Value>(0);
+ (*this)[1] = static_cast<Value>( 1 )/static_cast<Value>( 5 );
+ (*this)[2] = static_cast<Value>( 3 )/static_cast<Value>( 10 );
+ (*this)[3] = static_cast<Value>( 3 )/static_cast<Value>( 5 );
+ (*this)[4] = static_cast<Value>( 1 );
+ (*this)[5] = static_cast<Value>( 7 )/static_cast<Value>( 8 );
+ }
+};
+#endif
+
+
+template<
+ class State ,
+ class Value = double ,
+ class Deriv = State ,
+ class Time = Value ,
+ class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+ class Operations = typename operations_dispatcher< State >::operations_type ,
+ class Resizer = initially_resizer
+ >
+#ifndef DOXYGEN_SKIP
+class runge_kutta_cash_karp54 : public explicit_error_generic_rk< 6 , 5 , 5 , 4 ,
+ State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class runge_kutta_cash_karp54 : public explicit_error_generic_rk
+#endif
+{
+
+public:
+#ifndef DOXYGEN_SKIP
+ typedef explicit_error_generic_rk< 6 , 5 , 5 , 4 , State , Value , Deriv , Time ,
+ Algebra , Operations , Resizer > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_typ;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ #endif
+
+
+ runge_kutta_cash_karp54( const algebra_type &algebra = algebra_type() ) : stepper_base_type(
+ boost::fusion::make_vector( rk54_ck_coefficients_a1<Value>() ,
+ rk54_ck_coefficients_a2<Value>() ,
+ rk54_ck_coefficients_a3<Value>() ,
+ rk54_ck_coefficients_a4<Value>() ,
+ rk54_ck_coefficients_a5<Value>() ) ,
+ rk54_ck_coefficients_b<Value>() , rk54_ck_coefficients_db<Value>() , rk54_ck_coefficients_c<Value>() ,
+ algebra )
+ { }
+};
+
+
+/********** DOXYGEN **********/
+
+/**
+ * \class runge_kutta_cash_karp54
+ * \brief The Runge-Kutta Cash-Karp method.
+ *
+ * The Runge-Kutta Cash-Karp method is one of the standard methods for
+ * solving ordinary differential equations, see
+ * <a href="http://en.wikipedia.org/wiki/Cash%E2%80%93Karp_methods">en.wikipedia.org/wiki/Cash-Karp_methods</a>.
+ * The method is explicit and fulfills the Error Stepper concept. Step size control
+ * is provided but continuous output is not available for this method.
+ *
+ * This class derives from explicit_error_stepper_base and inherits its interface via CRTP (current recurring template pattern).
+ * Furthermore, it derivs from explicit_error_generic_rk which is a generic Runge-Kutta algorithm with error estimation.
+ * For more details see explicit_error_stepper_base and explicit_error_generic_rk.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn runge_kutta_cash_karp54::runge_kutta_cash_karp54( const algebra_type &algebra )
+ * \brief Constructs the runge_kutta_cash_karp54 class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+}
+}
+}
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp
new file mode 100644
index 0000000..80f1a3c
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp
@@ -0,0 +1,289 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp
+
+ [begin_description]
+ Classical implementation of the Runge-Kutta Cash-Karp 5(4) method.
+ [end_description]
+
+ Copyright 2010-2013 Mario Mulansky
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class runge_kutta_cash_karp54_classic
+: public explicit_error_stepper_base<
+ runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+class runge_kutta_cash_karp54_classic : public explicit_error_stepper_base
+#endif
+{
+
+
+public :
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_error_stepper_base<
+ runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+ #else
+ typedef explicit_error_stepper_base< runge_kutta_cash_karp54_classic< ... > , ... > stepper_base_type;
+ #endif
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ #endif
+
+
+ runge_kutta_cash_karp54_classic( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
+ { }
+
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut , class Err >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
+ {
+ const value_type c1 = static_cast<value_type> ( 37 ) / static_cast<value_type>( 378 );
+ const value_type c3 = static_cast<value_type> ( 250 ) / static_cast<value_type>( 621 );
+ const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 594 );
+ const value_type c6 = static_cast<value_type> ( 512 ) / static_cast<value_type>( 1771 );
+
+ const value_type dc1 = c1 - static_cast<value_type> ( 2825 ) / static_cast<value_type>( 27648 );
+ const value_type dc3 = c3 - static_cast<value_type> ( 18575 ) / static_cast<value_type>( 48384 );
+ const value_type dc4 = c4 - static_cast<value_type> ( 13525 ) / static_cast<value_type>( 55296 );
+ const value_type dc5 = static_cast<value_type> ( -277 ) / static_cast<value_type>( 14336 );
+ const value_type dc6 = c6 - static_cast<value_type> ( 1 ) / static_cast<value_type> ( 4 );
+
+ do_step_impl( system , in , dxdt , t , out , dt );
+
+ //error estimate
+ stepper_base_type::m_algebra.for_each6( xerr , dxdt , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v ,
+ typename operations_type::template scale_sum5< time_type , time_type , time_type , time_type , time_type >( dt*dc1 , dt*dc3 , dt*dc4 , dt*dc5 , dt*dc6 ));
+
+ }
+
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ {
+ const value_type a2 = static_cast<value_type> ( 1 ) / static_cast<value_type> ( 5 );
+ const value_type a3 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
+ const value_type a4 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 5 );
+ const value_type a5 = static_cast<value_type> ( 1 );
+ const value_type a6 = static_cast<value_type> ( 7 ) / static_cast<value_type> ( 8 );
+
+ const value_type b21 = static_cast<value_type> ( 1 ) / static_cast<value_type> ( 5 );
+ const value_type b31 = static_cast<value_type> ( 3 ) / static_cast<value_type>( 40 );
+ const value_type b32 = static_cast<value_type> ( 9 ) / static_cast<value_type>( 40 );
+ const value_type b41 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
+ const value_type b42 = static_cast<value_type> ( -9 ) / static_cast<value_type> ( 10 );
+ const value_type b43 = static_cast<value_type> ( 6 ) / static_cast<value_type> ( 5 );
+ const value_type b51 = static_cast<value_type> ( -11 ) / static_cast<value_type>( 54 );
+ const value_type b52 = static_cast<value_type> ( 5 ) / static_cast<value_type> ( 2 );
+ const value_type b53 = static_cast<value_type> ( -70 ) / static_cast<value_type>( 27 );
+ const value_type b54 = static_cast<value_type> ( 35 ) / static_cast<value_type>( 27 );
+ const value_type b61 = static_cast<value_type> ( 1631 ) / static_cast<value_type>( 55296 );
+ const value_type b62 = static_cast<value_type> ( 175 ) / static_cast<value_type>( 512 );
+ const value_type b63 = static_cast<value_type> ( 575 ) / static_cast<value_type>( 13824 );
+ const value_type b64 = static_cast<value_type> ( 44275 ) / static_cast<value_type>( 110592 );
+ const value_type b65 = static_cast<value_type> ( 253 ) / static_cast<value_type>( 4096 );
+
+ const value_type c1 = static_cast<value_type> ( 37 ) / static_cast<value_type>( 378 );
+ const value_type c3 = static_cast<value_type> ( 250 ) / static_cast<value_type>( 621 );
+ const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 594 );
+ const value_type c6 = static_cast<value_type> ( 512 ) / static_cast<value_type>( 1771 );
+
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+
+ //m_x1 = x + dt*b21*dxdt
+ stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , dxdt ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , dt*b21 ) );
+
+ sys( m_x_tmp.m_v , m_k2.m_v , t + dt*a2 );
+ // m_x_tmp = x + dt*b31*dxdt + dt*b32*m_x2
+ stepper_base_type::m_algebra.for_each4( m_x_tmp.m_v , in , dxdt , m_k2.m_v ,
+ typename operations_type::template scale_sum3< value_type , time_type , time_type >( 1.0 , dt*b31 , dt*b32 ));
+
+ sys( m_x_tmp.m_v , m_k3.m_v , t + dt*a3 );
+ // m_x_tmp = x + dt * (b41*dxdt + b42*m_x2 + b43*m_x3)
+ stepper_base_type::m_algebra.for_each5( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v ,
+ typename operations_type::template scale_sum4< value_type , time_type , time_type , time_type >( 1.0 , dt*b41 , dt*b42 , dt*b43 ));
+
+ sys( m_x_tmp.m_v, m_k4.m_v , t + dt*a4 );
+ stepper_base_type::m_algebra.for_each6( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v , m_k4.m_v ,
+ typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b51 , dt*b52 , dt*b53 , dt*b54 ));
+
+ sys( m_x_tmp.m_v , m_k5.m_v , t + dt*a5 );
+ stepper_base_type::m_algebra.for_each7( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v , m_k4.m_v , m_k5.m_v ,
+ typename operations_type::template scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b61 , dt*b62 , dt*b63 , dt*b64 , dt*b65 ));
+
+ sys( m_x_tmp.m_v , m_k6.m_v , t + dt*a6 );
+ stepper_base_type::m_algebra.for_each6( out , in , dxdt , m_k3.m_v , m_k4.m_v , m_k6.m_v ,
+ typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt*c1 , dt*c3 , dt*c4 , dt*c6 ));
+
+ }
+
+ /**
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+private:
+
+ template< class StateIn >
+ bool resize_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k2 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k3 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k4 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k5 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k6 , x , typename is_resizeable<deriv_type>::type() );
+ return resized;
+ }
+
+
+ wrapped_state_type m_x_tmp;
+ wrapped_deriv_type m_k2, m_k3, m_k4, m_k5, m_k6;
+ resizer_type m_resizer;
+
+};
+
+
+
+/************ DOXYGEN *************/
+
+/**
+ * \class runge_kutta_cash_karp54_classic
+ * \brief The Runge-Kutta Cash-Karp method implemented without the generic Runge-Kutta algorithm.
+ *
+ * The Runge-Kutta Cash-Karp method is one of the standard methods for
+ * solving ordinary differential equations, see
+ * <a href="http://en.wikipedia.org/wiki/Cash%E2%80%93Karp_method">en.wikipedia.org/wiki/Cash-Karp_method</a>.
+ * The method is explicit and fulfills the Error Stepper concept. Step size control
+ * is provided but continuous output is not available for this method.
+ *
+ * This class derives from explicit_error_stepper_base and inherits its interface via CRTP (current recurring
+ * template pattern). This class implements the method directly, hence the generic Runge-Kutta algorithm is not used.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn runge_kutta_cash_karp54_classic::runge_kutta_cash_karp54_classic( const algebra_type &algebra )
+ * \brief Constructs the runge_kutta_cash_karp54_classic class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+
+ /**
+ * \fn runge_kutta_cash_karp54_classic::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ *
+ * The result is updated out-of-place, hence the input is in `in` and the output in `out`. Futhermore, an
+ * estimation of the error is stored in `xerr`.
+ * Access to this step functionality is provided by explicit_error_stepper_base and
+ * `do_step_impl` should not be called directly.
+
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ * \param xerr The result of the error estimation is written in xerr.
+ */
+
+ /**
+ * \fn runge_kutta_cash_karp54_classic::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt` of `in` at the time `t` is passed to the method.
+ * The result is updated out-of-place, hence the input is in `in` and the output in `out`.
+ * Access to this step functionality is provided by explicit_error_stepper_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt The derivative of x at t.
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dt The step size.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp
new file mode 100644
index 0000000..260cd74
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp
@@ -0,0 +1,403 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp
+
+ [begin_description]
+ Implementation of the Dormand-Prince 5(4) method. This stepper can also be used with the dense-output controlled stepper.
+ [end_description]
+
+ Copyright 2010-2013 Karsten Ahnert
+ Copyright 2010-2013 Mario Mulansky
+ Copyright 2012 Christoph Koke
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/util/bind.hpp>
+
+#include <boost/numeric/odeint/stepper/base/explicit_error_stepper_fsal_base.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/same_instance.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+class runge_kutta_dopri5
+#ifndef DOXYGEN_SKIP
+: public explicit_error_stepper_fsal_base<
+ runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
+#else
+: public explicit_error_stepper_fsal_base
+#endif
+{
+
+public :
+
+ #ifndef DOXYGEN_SKIP
+ typedef explicit_error_stepper_fsal_base<
+ runge_kutta_dopri5< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
+ 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+ #else
+ typedef explicit_error_stepper_fsal_base< runge_kutta_dopri5< ... > , ... > stepper_base_type;
+ #endif
+
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ #endif // DOXYGEN_SKIP
+
+
+ runge_kutta_dopri5( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
+ { }
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t ,
+ StateOut &out , DerivOut &dxdt_out , time_type dt )
+ {
+ const value_type a2 = static_cast<value_type> ( 1 ) / static_cast<value_type>( 5 );
+ const value_type a3 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
+ const value_type a4 = static_cast<value_type> ( 4 ) / static_cast<value_type> ( 5 );
+ const value_type a5 = static_cast<value_type> ( 8 )/static_cast<value_type> ( 9 );
+
+ const value_type b21 = static_cast<value_type> ( 1 ) / static_cast<value_type> ( 5 );
+
+ const value_type b31 = static_cast<value_type> ( 3 ) / static_cast<value_type>( 40 );
+ const value_type b32 = static_cast<value_type> ( 9 ) / static_cast<value_type>( 40 );
+
+ const value_type b41 = static_cast<value_type> ( 44 ) / static_cast<value_type> ( 45 );
+ const value_type b42 = static_cast<value_type> ( -56 ) / static_cast<value_type> ( 15 );
+ const value_type b43 = static_cast<value_type> ( 32 ) / static_cast<value_type> ( 9 );
+
+ const value_type b51 = static_cast<value_type> ( 19372 ) / static_cast<value_type>( 6561 );
+ const value_type b52 = static_cast<value_type> ( -25360 ) / static_cast<value_type> ( 2187 );
+ const value_type b53 = static_cast<value_type> ( 64448 ) / static_cast<value_type>( 6561 );
+ const value_type b54 = static_cast<value_type> ( -212 ) / static_cast<value_type>( 729 );
+
+ const value_type b61 = static_cast<value_type> ( 9017 ) / static_cast<value_type>( 3168 );
+ const value_type b62 = static_cast<value_type> ( -355 ) / static_cast<value_type>( 33 );
+ const value_type b63 = static_cast<value_type> ( 46732 ) / static_cast<value_type>( 5247 );
+ const value_type b64 = static_cast<value_type> ( 49 ) / static_cast<value_type>( 176 );
+ const value_type b65 = static_cast<value_type> ( -5103 ) / static_cast<value_type>( 18656 );
+
+ const value_type c1 = static_cast<value_type> ( 35 ) / static_cast<value_type>( 384 );
+ const value_type c3 = static_cast<value_type> ( 500 ) / static_cast<value_type>( 1113 );
+ const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 192 );
+ const value_type c5 = static_cast<value_type> ( -2187 ) / static_cast<value_type>( 6784 );
+ const value_type c6 = static_cast<value_type> ( 11 ) / static_cast<value_type>( 84 );
+
+ typename odeint::unwrap_reference< System >::type &sys = system;
+
+ m_k_x_tmp_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_k_x_tmp_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+
+ //m_x_tmp = x + dt*b21*dxdt
+ stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , dxdt_in ,
+ typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , dt*b21 ) );
+
+ sys( m_x_tmp.m_v , m_k2.m_v , t + dt*a2 );
+ // m_x_tmp = x + dt*b31*dxdt + dt*b32*m_k2
+ stepper_base_type::m_algebra.for_each4( m_x_tmp.m_v , in , dxdt_in , m_k2.m_v ,
+ typename operations_type::template scale_sum3< value_type , time_type , time_type >( 1.0 , dt*b31 , dt*b32 ));
+
+ sys( m_x_tmp.m_v , m_k3.m_v , t + dt*a3 );
+ // m_x_tmp = x + dt * (b41*dxdt + b42*m_k2 + b43*m_k3)
+ stepper_base_type::m_algebra.for_each5( m_x_tmp.m_v , in , dxdt_in , m_k2.m_v , m_k3.m_v ,
+ typename operations_type::template scale_sum4< value_type , time_type , time_type , time_type >( 1.0 , dt*b41 , dt*b42 , dt*b43 ));
+
+ sys( m_x_tmp.m_v, m_k4.m_v , t + dt*a4 );
+ stepper_base_type::m_algebra.for_each6( m_x_tmp.m_v , in , dxdt_in , m_k2.m_v , m_k3.m_v , m_k4.m_v ,
+ typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b51 , dt*b52 , dt*b53 , dt*b54 ));
+
+ sys( m_x_tmp.m_v , m_k5.m_v , t + dt*a5 );
+ stepper_base_type::m_algebra.for_each7( m_x_tmp.m_v , in , dxdt_in , m_k2.m_v , m_k3.m_v , m_k4.m_v , m_k5.m_v ,
+ typename operations_type::template scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b61 , dt*b62 , dt*b63 , dt*b64 , dt*b65 ));
+
+ sys( m_x_tmp.m_v , m_k6.m_v , t + dt );
+ stepper_base_type::m_algebra.for_each7( out , in , dxdt_in , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v ,
+ typename operations_type::template scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt*c1 , dt*c3 , dt*c4 , dt*c5 , dt*c6 ));
+
+ // the new derivative
+ sys( out , dxdt_out , t + dt );
+ }
+
+
+
+ template< class System , class StateIn , class DerivIn , class StateOut , class DerivOut , class Err >
+ void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t ,
+ StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr )
+ {
+ const value_type c1 = static_cast<value_type> ( 35 ) / static_cast<value_type>( 384 );
+ const value_type c3 = static_cast<value_type> ( 500 ) / static_cast<value_type>( 1113 );
+ const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 192 );
+ const value_type c5 = static_cast<value_type> ( -2187 ) / static_cast<value_type>( 6784 );
+ const value_type c6 = static_cast<value_type> ( 11 ) / static_cast<value_type>( 84 );
+
+ const value_type dc1 = c1 - static_cast<value_type> ( 5179 ) / static_cast<value_type>( 57600 );
+ const value_type dc3 = c3 - static_cast<value_type> ( 7571 ) / static_cast<value_type>( 16695 );
+ const value_type dc4 = c4 - static_cast<value_type> ( 393 ) / static_cast<value_type>( 640 );
+ const value_type dc5 = c5 - static_cast<value_type> ( -92097 ) / static_cast<value_type>( 339200 );
+ const value_type dc6 = c6 - static_cast<value_type> ( 187 ) / static_cast<value_type>( 2100 );
+ const value_type dc7 = static_cast<value_type>( -1 ) / static_cast<value_type> ( 40 );
+
+ /* ToDo: copy only if &dxdt_in == &dxdt_out ? */
+ if( same_instance( dxdt_in , dxdt_out ) )
+ {
+ m_dxdt_tmp_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_tmp_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::copy( dxdt_in , m_dxdt_tmp.m_v );
+ do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt );
+ //error estimate
+ stepper_base_type::m_algebra.for_each7( xerr , m_dxdt_tmp.m_v , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v , dxdt_out ,
+ typename operations_type::template scale_sum6< time_type , time_type , time_type , time_type , time_type , time_type >( dt*dc1 , dt*dc3 , dt*dc4 , dt*dc5 , dt*dc6 , dt*dc7 ) );
+
+ }
+ else
+ {
+ do_step_impl( system , in , dxdt_in , t , out , dxdt_out , dt );
+ //error estimate
+ stepper_base_type::m_algebra.for_each7( xerr , dxdt_in , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v , dxdt_out ,
+ typename operations_type::template scale_sum6< time_type , time_type , time_type , time_type , time_type , time_type >( dt*dc1 , dt*dc3 , dt*dc4 , dt*dc5 , dt*dc6 , dt*dc7 ) );
+
+ }
+
+ }
+
+
+ /*
+ * Calculates Dense-Output for Dopri5
+ *
+ * See Hairer, Norsett, Wanner: Solving Ordinary Differential Equations, Nonstiff Problems. I, p.191/192
+ *
+ * y(t+theta) = y(t) + h * sum_i^7 b_i(theta) * k_i
+ *
+ * A = theta^2 * ( 3 - 2 theta )
+ * B = theta^2 * ( theta - 1 )
+ * C = theta^2 * ( theta - 1 )^2
+ * D = theta * ( theta - 1 )^2
+ *
+ * b_1( theta ) = A * b_1 - C * X1( theta ) + D
+ * b_2( theta ) = 0
+ * b_3( theta ) = A * b_3 + C * X3( theta )
+ * b_4( theta ) = A * b_4 - C * X4( theta )
+ * b_5( theta ) = A * b_5 + C * X5( theta )
+ * b_6( theta ) = A * b_6 - C * X6( theta )
+ * b_7( theta ) = B + C * X7( theta )
+ *
+ * An alternative Method is described in:
+ *
+ * www-m2.ma.tum.de/homepages/simeon/numerik3/kap3.ps
+ */
+ template< class StateOut , class StateIn1 , class DerivIn1 , class StateIn2 , class DerivIn2 >
+ void calc_state( time_type t , StateOut &x ,
+ const StateIn1 &x_old , const DerivIn1 &deriv_old , time_type t_old ,
+ const StateIn2 & /* x_new */ , const DerivIn2 &deriv_new , time_type t_new ) const
+ {
+ const value_type b1 = static_cast<value_type> ( 35 ) / static_cast<value_type>( 384 );
+ const value_type b3 = static_cast<value_type> ( 500 ) / static_cast<value_type>( 1113 );
+ const value_type b4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 192 );
+ const value_type b5 = static_cast<value_type> ( -2187 ) / static_cast<value_type>( 6784 );
+ const value_type b6 = static_cast<value_type> ( 11 ) / static_cast<value_type>( 84 );
+
+ const time_type dt = ( t_new - t_old );
+ const value_type theta = ( t - t_old ) / dt;
+ const value_type X1 = static_cast< value_type >( 5 ) * ( static_cast< value_type >( 2558722523LL ) - static_cast< value_type >( 31403016 ) * theta ) / static_cast< value_type >( 11282082432LL );
+ const value_type X3 = static_cast< value_type >( 100 ) * ( static_cast< value_type >( 882725551 ) - static_cast< value_type >( 15701508 ) * theta ) / static_cast< value_type >( 32700410799LL );
+ const value_type X4 = static_cast< value_type >( 25 ) * ( static_cast< value_type >( 443332067 ) - static_cast< value_type >( 31403016 ) * theta ) / static_cast< value_type >( 1880347072LL ) ;
+ const value_type X5 = static_cast< value_type >( 32805 ) * ( static_cast< value_type >( 23143187 ) - static_cast< value_type >( 3489224 ) * theta ) / static_cast< value_type >( 199316789632LL );
+ const value_type X6 = static_cast< value_type >( 55 ) * ( static_cast< value_type >( 29972135 ) - static_cast< value_type >( 7076736 ) * theta ) / static_cast< value_type >( 822651844 );
+ const value_type X7 = static_cast< value_type >( 10 ) * ( static_cast< value_type >( 7414447 ) - static_cast< value_type >( 829305 ) * theta ) / static_cast< value_type >( 29380423 );
+
+ const value_type theta_m_1 = theta - static_cast< value_type >( 1 );
+ const value_type theta_sq = theta * theta;
+ const value_type A = theta_sq * ( static_cast< value_type >( 3 ) - static_cast< value_type >( 2 ) * theta );
+ const value_type B = theta_sq * theta_m_1;
+ const value_type C = theta_sq * theta_m_1 * theta_m_1;
+ const value_type D = theta * theta_m_1 * theta_m_1;
+
+ const value_type b1_theta = A * b1 - C * X1 + D;
+ const value_type b3_theta = A * b3 + C * X3;
+ const value_type b4_theta = A * b4 - C * X4;
+ const value_type b5_theta = A * b5 + C * X5;
+ const value_type b6_theta = A * b6 - C * X6;
+ const value_type b7_theta = B + C * X7;
+
+ // const state_type &k1 = *m_old_deriv;
+ // const state_type &k3 = dopri5().m_k3;
+ // const state_type &k4 = dopri5().m_k4;
+ // const state_type &k5 = dopri5().m_k5;
+ // const state_type &k6 = dopri5().m_k6;
+ // const state_type &k7 = *m_current_deriv;
+
+ stepper_base_type::m_algebra.for_each8( x , x_old , deriv_old , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v , deriv_new ,
+ typename operations_type::template scale_sum7< value_type , time_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt * b1_theta , dt * b3_theta , dt * b4_theta , dt * b5_theta , dt * b6_theta , dt * b7_theta ) );
+ }
+
+
+ template< class StateIn >
+ void adjust_size( const StateIn &x )
+ {
+ resize_k_x_tmp_impl( x );
+ resize_dxdt_tmp_impl( x );
+ stepper_base_type::adjust_size( x );
+ }
+
+
+private:
+
+ template< class StateIn >
+ bool resize_k_x_tmp_impl( const StateIn &x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k2 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k3 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k4 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k5 , x , typename is_resizeable<deriv_type>::type() );
+ resized |= adjust_size_by_resizeability( m_k6 , x , typename is_resizeable<deriv_type>::type() );
+ return resized;
+ }
+
+ template< class StateIn >
+ bool resize_dxdt_tmp_impl( const StateIn &x )
+ {
+ return adjust_size_by_resizeability( m_dxdt_tmp , x , typename is_resizeable<deriv_type>::type() );
+ }
+
+
+
+ wrapped_state_type m_x_tmp;
+ wrapped_deriv_type m_k2 , m_k3 , m_k4 , m_k5 , m_k6 ;
+ wrapped_deriv_type m_dxdt_tmp;
+ resizer_type m_k_x_tmp_resizer;
+ resizer_type m_dxdt_tmp_resizer;
+};
+
+
+
+/************* DOXYGEN ************/
+/**
+ * \class runge_kutta_dopri5
+ * \brief The Runge-Kutta Dormand-Prince 5 method.
+ *
+ * The Runge-Kutta Dormand-Prince 5 method is a very popular method for solving ODEs, see
+ * <a href=""></a>.
+ * The method is explicit and fulfills the Error Stepper concept. Step size control
+ * is provided but continuous output is available which make this method favourable for many applications.
+ *
+ * This class derives from explicit_error_stepper_fsal_base and inherits its interface via CRTP (current recurring
+ * template pattern). The method possesses the FSAL (first-same-as-last) property. See
+ * explicit_error_stepper_fsal_base for more details.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn runge_kutta_dopri5::runge_kutta_dopri5( const algebra_type &algebra )
+ * \brief Constructs the runge_kutta_dopri5 class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+ /**
+ * \fn runge_kutta_dopri5::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt )
+ * \brief This method performs one step. The derivative `dxdt_in` of `in` at the time `t` is passed to the
+ * method. The result is updated out-of-place, hence the input is in `in` and the output in `out`. Furthermore,
+ * the derivative is update out-of-place, hence the input is assumed to be in `dxdt_in` and the output in
+ * `dxdt_out`.
+ * Access to this step functionality is provided by explicit_error_stepper_fsal_base and
+ * `do_step_impl` should not be called directly.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt_in The derivative of x at t. dxdt_in is not modified by this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dxdt_out The result of the new derivative at time t+dt.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn runge_kutta_dopri5::do_step_impl( System system , const StateIn &in , const DerivIn &dxdt_in , time_type t , StateOut &out , DerivOut &dxdt_out , time_type dt , Err &xerr )
+ * \brief This method performs one step. The derivative `dxdt_in` of `in` at the time `t` is passed to the
+ * method. The result is updated out-of-place, hence the input is in `in` and the output in `out`. Furthermore,
+ * the derivative is update out-of-place, hence the input is assumed to be in `dxdt_in` and the output in
+ * `dxdt_out`.
+ * Access to this step functionality is provided by explicit_error_stepper_fsal_base and
+ * `do_step_impl` should not be called directly.
+ * An estimation of the error is calculated.
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ODE. It must fulfill the
+ * Simple System concept.
+ * \param in The state of the ODE which should be solved. in is not modified in this method
+ * \param dxdt_in The derivative of x at t. dxdt_in is not modified by this method
+ * \param t The value of the time, at which the step should be performed.
+ * \param out The result of the step is written in out.
+ * \param dxdt_out The result of the new derivative at time t+dt.
+ * \param dt The step size.
+ * \param xerr An estimation of the error.
+ */
+
+ /**
+ * \fn runge_kutta_dopri5::calc_state( time_type t , StateOut &x , const StateIn1 &x_old , const DerivIn1 &deriv_old , time_type t_old , const StateIn2 & , const DerivIn2 &deriv_new , time_type t_new ) const
+ * \brief This method is used for continuous output and it calculates the state `x` at a time `t` from the
+ * knowledge of two states `old_state` and `current_state` at time points `t_old` and `t_new`. It also uses
+ * internal variables to calculate the result. Hence this method must be called after two successful `do_step`
+ * calls.
+ */
+
+ /**
+ * \fn runge_kutta_dopri5::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_DOPRI5_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp
new file mode 100644
index 0000000..f2f8251
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp
@@ -0,0 +1,374 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/runge_kutta_fehlberg87.hpp
+
+ [begin_description]
+ Implementation of the Runge-Kutta-Fehlberg stepper with the generic stepper.
+ [end_description]
+
+ Copyright 2011-2013 Mario Mulansky
+ Copyright 2012-2013 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_FEHLBERG87_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_FEHLBERG87_HPP_INCLUDED
+
+
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/container/generation/make_vector.hpp>
+
+#include <boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp>
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/array.hpp>
+
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/is_resizeable.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+#ifndef DOXYGEN_SKIP
+template< class Value = double >
+struct rk78_coefficients_a1 : boost::array< Value , 1 >
+{
+ rk78_coefficients_a1( void )
+ {
+ (*this)[0] = static_cast< Value >( 2 )/static_cast< Value >( 27 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a2 : boost::array< Value , 2 >
+{
+ rk78_coefficients_a2( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 )/static_cast< Value >( 36 );
+ (*this)[1] = static_cast< Value >( 1 )/static_cast< Value >( 12 );
+ }
+};
+
+
+template< class Value = double >
+struct rk78_coefficients_a3 : boost::array< Value , 3 >
+{
+ rk78_coefficients_a3( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 )/static_cast< Value >( 24 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 1 )/static_cast< Value >( 8 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a4 : boost::array< Value , 4 >
+{
+ rk78_coefficients_a4( void )
+ {
+ (*this)[0] = static_cast< Value >( 5 )/static_cast< Value >( 12 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( -25 )/static_cast< Value >( 16 );
+ (*this)[3] = static_cast< Value >( 25 )/static_cast< Value >( 16 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a5 : boost::array< Value , 5 >
+{
+ rk78_coefficients_a5( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 )/static_cast< Value >( 20 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 1 )/static_cast< Value >( 4 );
+ (*this)[4] = static_cast< Value >( 1 )/static_cast< Value >( 5 );
+ }
+};
+
+
+template< class Value = double >
+struct rk78_coefficients_a6 : boost::array< Value , 6 >
+{
+ rk78_coefficients_a6( void )
+ {
+ (*this)[0] = static_cast< Value >( -25 )/static_cast< Value >( 108 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 125 )/static_cast< Value >( 108 );
+ (*this)[4] = static_cast< Value >( -65 )/static_cast< Value >( 27 );
+ (*this)[5] = static_cast< Value >( 125 )/static_cast< Value >( 54 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a7 : boost::array< Value , 7 >
+{
+ rk78_coefficients_a7( void )
+ {
+ (*this)[0] = static_cast< Value >( 31 )/static_cast< Value >( 300 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 0 );
+ (*this)[4] = static_cast< Value >( 61 )/static_cast< Value >( 225 );
+ (*this)[5] = static_cast< Value >( -2 )/static_cast< Value >( 9 );
+ (*this)[6] = static_cast< Value >( 13 )/static_cast< Value >( 900 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a8 : boost::array< Value , 8 >
+{
+ rk78_coefficients_a8( void )
+ {
+ (*this)[0] = static_cast< Value >( 2 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( -53 )/static_cast< Value >( 6 );
+ (*this)[4] = static_cast< Value >( 704 )/static_cast< Value >( 45 );
+ (*this)[5] = static_cast< Value >( -107 )/static_cast< Value >( 9 );
+ (*this)[6] = static_cast< Value >( 67 )/static_cast< Value >( 90 );
+ (*this)[7] = static_cast< Value >( 3 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a9 : boost::array< Value , 9 >
+{
+ rk78_coefficients_a9( void )
+ {
+ (*this)[0] = static_cast< Value >( -91 )/static_cast< Value >( 108 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 23 )/static_cast< Value >( 108 );
+ (*this)[4] = static_cast< Value >( -976 )/static_cast< Value >( 135 );
+ (*this)[5] = static_cast< Value >( 311 )/static_cast< Value >( 54 );
+ (*this)[6] = static_cast< Value >( -19 )/static_cast< Value >( 60 );
+ (*this)[7] = static_cast< Value >( 17 )/static_cast< Value >( 6 );
+ (*this)[8] = static_cast< Value >( -1 )/static_cast< Value >( 12 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a10 : boost::array< Value , 10 >
+{
+ rk78_coefficients_a10( void )
+ {
+ (*this)[0] = static_cast< Value >( 2383 )/static_cast< Value >( 4100 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( -341 )/static_cast< Value >( 164 );
+ (*this)[4] = static_cast< Value >( 4496 )/static_cast< Value >( 1025 );
+ (*this)[5] = static_cast< Value >( -301 )/static_cast< Value >( 82 );
+ (*this)[6] = static_cast< Value >( 2133 )/static_cast< Value >( 4100 );
+ (*this)[7] = static_cast< Value >( 45 )/static_cast< Value >( 82 );
+ (*this)[8] = static_cast< Value >( 45 )/static_cast< Value >( 164 );
+ (*this)[9] = static_cast< Value >( 18 )/static_cast< Value >( 41 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a11 : boost::array< Value , 11 >
+{
+ rk78_coefficients_a11( void )
+ {
+ (*this)[0] = static_cast< Value >( 3 )/static_cast< Value >( 205 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 0 );
+ (*this)[4] = static_cast< Value >( 0 );
+ (*this)[5] = static_cast< Value >( -6 )/static_cast< Value >( 41 );
+ (*this)[6] = static_cast< Value >( -3 )/static_cast< Value >( 205 );
+ (*this)[7] = static_cast< Value >( -3 )/static_cast< Value >( 41 );
+ (*this)[8] = static_cast< Value >( 3 )/static_cast< Value >( 41 );
+ (*this)[9] = static_cast< Value >( 6 )/static_cast< Value >( 41 );
+ (*this)[10] = static_cast< Value >( 0 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_a12 : boost::array< Value , 12 >
+{
+ rk78_coefficients_a12( void )
+ {
+ (*this)[0] = static_cast< Value >( -1777 )/static_cast< Value >( 4100 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( -341 )/static_cast< Value >( 164 );
+ (*this)[4] = static_cast< Value >( 4496 )/static_cast< Value >( 1025 );
+ (*this)[5] = static_cast< Value >( -289 )/static_cast< Value >( 82 );
+ (*this)[6] = static_cast< Value >( 2193 )/static_cast< Value >( 4100 );
+ (*this)[7] = static_cast< Value >( 51 )/static_cast< Value >( 82 );
+ (*this)[8] = static_cast< Value >( 33 )/static_cast< Value >( 164 );
+ (*this)[9] = static_cast< Value >( 12 )/static_cast< Value >( 41 );
+ (*this)[10] = static_cast< Value >( 0 );
+ (*this)[11] = static_cast< Value >( 1 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_b : boost::array< Value , 13 >
+{
+ rk78_coefficients_b( void )
+ {
+ (*this)[0] = static_cast< Value >( 0 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 0 );
+ (*this)[4] = static_cast< Value >( 0 );
+ (*this)[5] = static_cast< Value >( 34 )/static_cast<Value>( 105 );
+ (*this)[6] = static_cast< Value >( 9 )/static_cast<Value>( 35 );
+ (*this)[7] = static_cast< Value >( 9 )/static_cast<Value>( 35 );
+ (*this)[8] = static_cast< Value >( 9 )/static_cast<Value>( 280 );
+ (*this)[9] = static_cast< Value >( 9 )/static_cast<Value>( 280 );
+ (*this)[10] = static_cast< Value >( 0 );
+ (*this)[11] = static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ (*this)[12] = static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ }
+};
+
+template< class Value = double >
+struct rk78_coefficients_db : boost::array< Value , 13 >
+{
+ rk78_coefficients_db( void )
+ {
+ (*this)[0] = static_cast< Value >( 0 ) - static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ (*this)[1] = static_cast< Value >( 0 );
+ (*this)[2] = static_cast< Value >( 0 );
+ (*this)[3] = static_cast< Value >( 0 );
+ (*this)[4] = static_cast< Value >( 0 );
+ (*this)[5] = static_cast< Value >( 0 );
+ (*this)[6] = static_cast< Value >( 0 );
+ (*this)[7] = static_cast< Value >( 0 );
+ (*this)[8] = static_cast< Value >( 0 );
+ (*this)[9] = static_cast< Value >( 0 );
+ (*this)[10] = static_cast< Value >( 0 ) - static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ (*this)[11] = static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ (*this)[12] = static_cast< Value >( 41 )/static_cast<Value>( 840 );
+ }
+};
+
+
+template< class Value = double >
+struct rk78_coefficients_c : boost::array< Value , 13 >
+{
+ rk78_coefficients_c( void )
+ {
+ (*this)[0] = static_cast< Value >( 0 );
+ (*this)[1] = static_cast< Value >( 2 )/static_cast< Value >( 27 );
+ (*this)[2] = static_cast< Value >( 1 )/static_cast< Value >( 9 );
+ (*this)[3] = static_cast< Value >( 1 )/static_cast<Value>( 6 );
+ (*this)[4] = static_cast< Value >( 5 )/static_cast<Value>( 12 );
+ (*this)[5] = static_cast< Value >( 1 )/static_cast<Value>( 2 );
+ (*this)[6] = static_cast< Value >( 5 )/static_cast<Value>( 6 );
+ (*this)[7] = static_cast< Value >( 1 )/static_cast<Value>( 6 );
+ (*this)[8] = static_cast< Value >( 2 )/static_cast<Value>( 3 );
+ (*this)[9] = static_cast< Value >( 1 )/static_cast<Value>( 3 );
+ (*this)[10] = static_cast< Value >( 1 );
+ (*this)[11] = static_cast< Value >( 0 );
+ (*this)[12] = static_cast< Value >( 1 );
+ }
+};
+#endif // DOXYGEN_SKIP
+
+
+
+
+
+template<
+class State ,
+class Value = double ,
+class Deriv = State ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< State >::algebra_type ,
+class Operations = typename operations_dispatcher< State >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class runge_kutta_fehlberg78 : public explicit_error_generic_rk< 13 , 8 , 8 , 7 , State , Value , Deriv , Time ,
+Algebra , Operations , Resizer >
+#else
+class runge_kutta_fehlberg78 : public explicit_error_generic_rk
+#endif
+{
+
+public:
+#ifndef DOXYGEN_SKIP
+ typedef explicit_error_generic_rk< 13 , 8 , 8 , 7 , State , Value , Deriv , Time ,
+ Algebra , Operations , Resizer > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::state_type state_type;
+ typedef typename stepper_base_type::value_type value_type;
+ typedef typename stepper_base_type::deriv_type deriv_type;
+ typedef typename stepper_base_type::time_type time_type;
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::operations_type operations_type;
+ typedef typename stepper_base_type::resizer_type resizer_type;
+
+ #ifndef DOXYGEN_SKIP
+ typedef typename stepper_base_type::stepper_type stepper_type;
+ typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
+ typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
+ #endif // DOXYGEN_SKIP
+
+
+ runge_kutta_fehlberg78( const algebra_type &algebra = algebra_type() ) : stepper_base_type(
+ boost::fusion::make_vector( rk78_coefficients_a1<Value>() , rk78_coefficients_a2<Value>() , rk78_coefficients_a3<Value>() ,
+ rk78_coefficients_a4<Value>() , rk78_coefficients_a5<Value>() , rk78_coefficients_a6<Value>() ,
+ rk78_coefficients_a7<Value>() , rk78_coefficients_a8<Value>() , rk78_coefficients_a9<Value>() ,
+ rk78_coefficients_a10<Value>() , rk78_coefficients_a11<Value>() , rk78_coefficients_a12<Value>() ) ,
+ rk78_coefficients_b<Value>() , rk78_coefficients_db<Value>() , rk78_coefficients_c<Value>() , algebra )
+ { }
+};
+
+
+
+/************* DOXYGEN *************/
+
+/**
+ * \class runge_kutta_fehlberg78
+ * \brief The Runge-Kutta Fehlberg 78 method.
+ *
+ * The Runge-Kutta Fehlberg 78 method is a standard method for high-precision applications.
+ * The method is explicit and fulfills the Error Stepper concept. Step size control
+ * is provided but continuous output is not available for this method.
+ *
+ * This class derives from explicit_error_stepper_base and inherits its interface via CRTP (current recurring template pattern).
+ * Furthermore, it derivs from explicit_error_generic_rk which is a generic Runge-Kutta algorithm with error estimation.
+ * For more details see explicit_error_stepper_base and explicit_error_generic_rk.
+ *
+ * \tparam State The state type.
+ * \tparam Value The value type.
+ * \tparam Deriv The type representing the time derivative of the state.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam Algebra The algebra type.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn runge_kutta_fehlberg78::runge_kutta_fehlberg78( const algebra_type &algebra )
+ * \brief Constructs the runge_kutta_cash_fehlberg78 class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+}
+}
+}
+
+#endif //BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_FEHLBERG87_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/stepper_categories.hpp b/include/boost/numeric/odeint/stepper/stepper_categories.hpp
new file mode 100644
index 0000000..9bc5372
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/stepper_categories.hpp
@@ -0,0 +1,68 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/stepper_categories.hpp
+
+ [begin_description]
+ Definition of all stepper categories.
+ [end_description]
+
+ Copyright 2010-2011 Mario Mulansky
+ Copyright 2010-2012 Karsten Ahnert
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_STEPPER_CATEGORIES_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_STEPPER_CATEGORIES_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+/*
+ * Tags to specify stepper types
+ *
+ * These tags are used by integrate() to choose which integration method is used
+ */
+
+struct stepper_tag {};
+// struct explicit_stepper_tag : stepper_tag {};
+// struct implicit_stepper_tag : stepper_tag {};
+
+
+struct error_stepper_tag : stepper_tag {};
+struct explicit_error_stepper_tag : error_stepper_tag {};
+struct explicit_error_stepper_fsal_tag : error_stepper_tag {};
+
+struct controlled_stepper_tag {};
+struct explicit_controlled_stepper_tag : controlled_stepper_tag {};
+struct explicit_controlled_stepper_fsal_tag : controlled_stepper_tag {};
+
+struct dense_output_stepper_tag {};
+
+
+template< class tag > struct base_tag ;
+template< > struct base_tag< stepper_tag > { typedef stepper_tag type; };
+template< > struct base_tag< error_stepper_tag > { typedef stepper_tag type; };
+template< > struct base_tag< explicit_error_stepper_tag > { typedef stepper_tag type; };
+template< > struct base_tag< explicit_error_stepper_fsal_tag > { typedef stepper_tag type; };
+
+template< > struct base_tag< controlled_stepper_tag > { typedef controlled_stepper_tag type; };
+template< > struct base_tag< explicit_controlled_stepper_tag > { typedef controlled_stepper_tag type; };
+template< > struct base_tag< explicit_controlled_stepper_fsal_tag > { typedef controlled_stepper_tag type; };
+
+template< > struct base_tag< dense_output_stepper_tag > { typedef dense_output_stepper_tag type; };
+
+
+} // odeint
+} // numeric
+} // boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_STEPPER_CATEGORIES_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/symplectic_euler.hpp b/include/boost/numeric/odeint/stepper/symplectic_euler.hpp
new file mode 100644
index 0000000..bd40860
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/symplectic_euler.hpp
@@ -0,0 +1,136 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/symplectic_euler.hpp
+
+ [begin_description]
+ Implementation of the symplectic Euler for separable Hamiltonian systems.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_EULER_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_EULER_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/array.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+#ifndef DOXYGEN_SKIP
+namespace detail {
+namespace symplectic_euler_coef {
+
+template< class Value >
+struct coef_a_type : public boost::array< Value , 1 >
+{
+ coef_a_type( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 );
+ }
+};
+
+template< class Value >
+struct coef_b_type : public boost::array< Value , 1 >
+{
+ coef_b_type( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 );
+ }
+};
+
+} // namespace symplectic_euler_coef
+} // namespace detail
+#endif
+
+
+
+template<
+class Coor ,
+class Momentum = Coor ,
+class Value = double ,
+class CoorDeriv = Coor ,
+class MomentumDeriv = Coor ,
+class Time = Value ,
+class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
+class Operations = typename operations_dispatcher< Coor >::operations_type ,
+class Resizer = initially_resizer
+>
+#ifndef DOXYGEN_SKIP
+class symplectic_euler :
+public symplectic_nystroem_stepper_base
+<
+1 , 1 ,
+Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
+>
+#else
+class symplectic_euler : public symplectic_nystroem_stepper_base
+#endif
+{
+public:
+
+#ifndef DOXYGEN_SKIP
+ typedef symplectic_nystroem_stepper_base<
+ 1 , 1 , Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::value_type value_type;
+
+
+ symplectic_euler( const algebra_type &algebra = algebra_type() )
+ : stepper_base_type( detail::symplectic_euler_coef::coef_a_type< value_type >() ,
+ detail::symplectic_euler_coef::coef_b_type< value_type >() ,
+ algebra )
+ { }
+};
+
+
+/*************** DOXYGEN ***************/
+
+/**
+ * \class symplectic_euler
+ * \brief Implementation of the symplectic Euler method.
+ *
+ * The method is of first order and has one stage. It is described HERE.
+ *
+ * \tparam Order The order of the stepper.
+ * \tparam Coor The type representing the coordinates q.
+ * \tparam Momentum The type representing the coordinates p.
+ * \tparam Value The basic value type. Should be something like float, double or a high-precision type.
+ * \tparam CoorDeriv The type representing the time derivative of the coordinate dq/dt.
+ * \tparam MomemtnumDeriv The type representing the time derivative of the momentum dp/dt.
+ * \tparam Time The type representing the time t.
+ * \tparam Algebra The algebra.
+ * \tparam Operations The operations.
+ * \tparam Resizer The resizer policy.
+ */
+
+ /**
+ * \fn symplectic_euler::symplectic_euler( const algebra_type &algebra )
+ * \brief Constructs the symplectic_euler. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_EULER_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp b/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp
new file mode 100644
index 0000000..b33773e
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp
@@ -0,0 +1,160 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp
+
+ [begin_description]
+ tba.
+ [end_description]
+
+ Copyright 2012-2013 Karsten Ahnert
+ Copyright 2012-2013 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_M4_MCLACHLAN_HPP_DEFINED
+#define BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_M4_MCLACHLAN_HPP_DEFINED
+
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+#ifndef DOXYGEN_SKIP
+namespace detail {
+namespace symplectic_rkn_sb3a_m4_mclachlan {
+
+ /*
+ exp( a1 t A ) exp( b1 t B )
+ exp( a2 t A ) exp( b2 t B )
+ exp( a3 t A )
+ exp( b2 t B ) exp( a2 t A )
+ exp( b1 t B ) exp( a1 t A )
+ */
+
+
+
+ template< class Value >
+ struct coef_a_type : public boost::array< Value , 5 >
+ {
+ coef_a_type( void )
+ {
+ using std::sqrt;
+
+ Value z = sqrt( static_cast< Value >( 7 ) / static_cast< Value >( 8 ) ) / static_cast< Value >( 3 );
+ (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 2 ) - z ;
+ (*this)[1] = static_cast< Value >( -1 ) / static_cast< Value >( 3 ) + z ;
+ (*this)[2] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
+ (*this)[3] = (*this)[1];
+ (*this)[4] = (*this)[0];
+ }
+ };
+
+ template< class Value >
+ struct coef_b_type : public boost::array< Value , 5 >
+ {
+ coef_b_type( void )
+ {
+ (*this)[0] = static_cast< Value >( 1 );
+ (*this)[1] = static_cast< Value >( -1 ) / static_cast< Value >( 2 );
+ (*this)[2] = (*this)[1];
+ (*this)[3] = (*this)[0];
+ (*this)[4] = static_cast< Value >( 0 );
+ }
+ };
+
+} // namespace symplectic_rkn_sb3a_m4_mclachlan
+} // namespace detail
+#endif // DOXYGEN_SKIP
+
+
+
+
+template<
+ class Coor ,
+ class Momentum = Coor ,
+ class Value = double ,
+ class CoorDeriv = Coor ,
+ class MomentumDeriv = Coor ,
+ class Time = Value ,
+ class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
+ class Operations = typename operations_dispatcher< Coor >::operations_type ,
+ class Resizer = initially_resizer
+ >
+#ifndef DOXYGEN_SKIP
+class symplectic_rkn_sb3a_m4_mclachlan :
+ public symplectic_nystroem_stepper_base
+<
+ 5 , 4 ,
+ Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
+ >
+#else
+class symplectic_rkn_sb3a_m4_mclachlan : public symplectic_nystroem_stepper_base
+#endif
+{
+public:
+#ifndef DOXYGEN_SKIP
+ typedef symplectic_nystroem_stepper_base
+ <
+ 5 , 4 ,
+ Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
+ > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::value_type value_type;
+
+
+ symplectic_rkn_sb3a_m4_mclachlan( const algebra_type &algebra = algebra_type() )
+ : stepper_base_type(
+ detail::symplectic_rkn_sb3a_m4_mclachlan::coef_a_type< value_type >() ,
+ detail::symplectic_rkn_sb3a_m4_mclachlan::coef_b_type< value_type >() ,
+ algebra )
+ { }
+};
+
+
+/***************** DOXYGEN ***************/
+
+/**
+ * \class symplectic_rkn_sb3a_m4_mclachlan
+ * \brief Implementation of the symmetric B3A Runge-Kutta Nystroem method of fifth order.
+ *
+ * The method is of fourth order and has five stages. It is described HERE. This method can be used
+ * with multiprecision types since the coefficients are defined analytically.
+ *
+ * ToDo: add reference to paper.
+ *
+ * \tparam Order The order of the stepper.
+ * \tparam Coor The type representing the coordinates q.
+ * \tparam Momentum The type representing the coordinates p.
+ * \tparam Value The basic value type. Should be something like float, double or a high-precision type.
+ * \tparam CoorDeriv The type representing the time derivative of the coordinate dq/dt.
+ * \tparam MomemtnumDeriv The type representing the time derivative of the momentum dp/dt.
+ * \tparam Time The type representing the time t.
+ * \tparam Algebra The algebra.
+ * \tparam Operations The operations.
+ * \tparam Resizer The resizer policy.
+ */
+
+ /**
+ * \fn symplectic_rkn_sb3a_m4_mclachlan::symplectic_rkn_sb3a_m4_mclachlan( const algebra_type &algebra )
+ * \brief Constructs the symplectic_rkn_sb3a_m4_mclachlan. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_M4_MCLACHLAN_HPP_DEFINED
diff --git a/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp b/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp
new file mode 100644
index 0000000..d75c535
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp
@@ -0,0 +1,162 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp
+
+ [begin_description]
+ Implementation of the symplectic MacLachlan stepper for separable Hamiltonian system.
+ [end_description]
+
+ Copyright 2011-2013 Karsten Ahnert
+ Copyright 2011-2013 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
+#define BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
+
+
+#include <boost/numeric/odeint/stepper/base/symplectic_rkn_stepper_base.hpp>
+
+#include <boost/numeric/odeint/algebra/range_algebra.hpp>
+#include <boost/numeric/odeint/algebra/default_operations.hpp>
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+
+#include <boost/numeric/odeint/util/resizer.hpp>
+
+#include <boost/array.hpp>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+#ifndef DOXYGEN_SKIP
+namespace detail {
+namespace symplectic_rkn_sb3a_mclachlan {
+
+ /*
+ exp( a1 t A ) exp( b1 t B )
+ exp( a2 t A ) exp( b2 t B )
+ exp( a3 t A ) exp( b3 t B ) exp( a3 t A )
+ exp( b2 t B ) exp( a2 t A )
+ exp( b1 t B ) exp( a1 t A )
+ */
+
+ template< class Value >
+ struct coef_a_type : public boost::array< Value , 6 >
+ {
+ coef_a_type( void )
+ {
+ (*this)[0] = static_cast< Value >( 0.40518861839525227722 );
+ (*this)[1] = static_cast< Value >( -0.28714404081652408900 );
+ (*this)[2] = static_cast< Value >( 1 ) / static_cast< Value >( 2 ) - ( (*this)[0] + (*this)[1] );
+ (*this)[3] = (*this)[2];
+ (*this)[4] = (*this)[1];
+ (*this)[5] = (*this)[0];
+
+ }
+ };
+
+ template< class Value >
+ struct coef_b_type : public boost::array< Value , 6 >
+ {
+ coef_b_type( void )
+ {
+ (*this)[0] = static_cast< Value >( -3 ) / static_cast< Value >( 73 );
+ (*this)[1] = static_cast< Value >( 17 ) / static_cast< Value >( 59 );
+ (*this)[2] = static_cast< Value >( 1 ) - static_cast< Value >( 2 ) * ( (*this)[0] + (*this)[1] );
+ (*this)[3] = (*this)[1];
+ (*this)[4] = (*this)[0];
+ (*this)[5] = static_cast< Value >( 0 );
+ }
+ };
+
+} // namespace symplectic_rkn_sb3a_mclachlan
+} // namespace detail
+#endif // DOXYGEN_SKIP
+
+
+
+template<
+ class Coor ,
+ class Momentum = Coor ,
+ class Value = double ,
+ class CoorDeriv = Coor ,
+ class MomentumDeriv = Coor ,
+ class Time = Value ,
+ class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
+ class Operations = typename operations_dispatcher< Coor >::operations_type ,
+ class Resizer = initially_resizer
+ >
+#ifndef DOXYGEN_SKIP
+class symplectic_rkn_sb3a_mclachlan :
+ public symplectic_nystroem_stepper_base
+<
+ 6 , 4 ,
+ Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
+ >
+#else
+class symplectic_rkn_sb3a_mclachlan : public symplectic_nystroem_stepper_base
+#endif
+{
+public:
+#ifndef DOXYGEN_SKIP
+ typedef symplectic_nystroem_stepper_base
+ <
+ 6 , 4 ,
+ Coor , Momentum , Value , CoorDeriv , MomentumDeriv , Time , Algebra , Operations , Resizer
+ > stepper_base_type;
+#endif
+ typedef typename stepper_base_type::algebra_type algebra_type;
+ typedef typename stepper_base_type::value_type value_type;
+
+
+ symplectic_rkn_sb3a_mclachlan( const algebra_type &algebra = algebra_type() )
+ : stepper_base_type(
+ detail::symplectic_rkn_sb3a_mclachlan::coef_a_type< value_type >() ,
+ detail::symplectic_rkn_sb3a_mclachlan::coef_b_type< value_type >() ,
+ algebra )
+ { }
+};
+
+
+/************* DOXYGEN ***********/
+
+/**
+ * \class symplectic_rkn_sb3a_mclachlan
+ * \brief Implement of the symmetric B3A method of Runge-Kutta-Nystroem method of sixth order.
+ *
+ * The method is of fourth order and has six stages. It is described HERE. This method cannot be used
+ * with multiprecision types since the coefficients are not defined analytically.
+ *
+ * ToDo Add reference to the paper.
+ *
+ * \tparam Order The order of the stepper.
+ * \tparam Coor The type representing the coordinates q.
+ * \tparam Momentum The type representing the coordinates p.
+ * \tparam Value The basic value type. Should be something like float, double or a high-precision type.
+ * \tparam CoorDeriv The type representing the time derivative of the coordinate dq/dt.
+ * \tparam MomemtnumDeriv The type representing the time derivative of the momentum dp/dt.
+ * \tparam Time The type representing the time t.
+ * \tparam Algebra The algebra.
+ * \tparam Operations The operations.
+ * \tparam Resizer The resizer policy.
+ */
+
+ /**
+ * \fn symplectic_rkn_sb3a_mclachlan::symplectic_rkn_sb3a_mclachlan( const algebra_type &algebra )
+ * \brief Constructs the symplectic_rkn_sb3a_mclachlan. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored inside explicit_stepper_base.
+ */
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_SYMPLECTIC_RKN_SB3A_MCLACHLAN_HPP_INCLUDED
diff --git a/include/boost/numeric/odeint/stepper/velocity_verlet.hpp b/include/boost/numeric/odeint/stepper/velocity_verlet.hpp
new file mode 100644
index 0000000..3a20fc2
--- /dev/null
+++ b/include/boost/numeric/odeint/stepper/velocity_verlet.hpp
@@ -0,0 +1,381 @@
+/*
+ [auto_generated]
+ boost/numeric/odeint/stepper/velocity_verlet.hpp
+
+ [begin_description]
+ tba.
+ [end_description]
+
+ Copyright 2009-2012 Karsten Ahnert
+ Copyright 2009-2012 Mario Mulansky
+
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or
+ copy at http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+
+#ifndef BOOST_NUMERIC_ODEINT_STEPPER_VELOCITY_VERLET_HPP_DEFINED
+#define BOOST_NUMERIC_ODEINT_STEPPER_VELOCITY_VERLET_HPP_DEFINED
+
+#include <boost/numeric/odeint/stepper/base/algebra_stepper_base.hpp>
+#include <boost/numeric/odeint/stepper/stepper_categories.hpp>
+
+#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
+#include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+#include <boost/numeric/odeint/util/state_wrapper.hpp>
+#include <boost/numeric/odeint/util/unwrap_reference.hpp>
+
+#include <boost/numeric/odeint/util/bind.hpp>
+#include <boost/numeric/odeint/util/copy.hpp>
+#include <boost/numeric/odeint/util/resizer.hpp>
+// #include <boost/numeric/odeint/util/is_pair.hpp>
+// #include <boost/array.hpp>
+
+
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+
+
+template <
+ class Coor ,
+ class Velocity = Coor ,
+ class Value = double ,
+ class Acceleration = Coor ,
+ class Time = Value ,
+ class TimeSq = Time ,
+ class Algebra = typename algebra_dispatcher< Coor >::algebra_type ,
+ class Operations = typename operations_dispatcher< Coor >::operations_type ,
+ class Resizer = initially_resizer
+ >
+class velocity_verlet : public algebra_stepper_base< Algebra , Operations >
+{
+public:
+
+ typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type;
+ typedef typename algebra_stepper_base_type::algebra_type algebra_type;
+ typedef typename algebra_stepper_base_type::operations_type operations_type;
+
+ typedef Coor coor_type;
+ typedef Velocity velocity_type;
+ typedef Acceleration acceleration_type;
+ typedef std::pair< coor_type , velocity_type > state_type;
+ typedef std::pair< velocity_type , acceleration_type > deriv_type;
+ typedef state_wrapper< acceleration_type > wrapped_acceleration_type;
+ typedef Value value_type;
+ typedef Time time_type;
+ typedef TimeSq time_square_type;
+ typedef Resizer resizer_type;
+ typedef stepper_tag stepper_category;
+
+ typedef unsigned short order_type;
+
+ static const order_type order_value = 1;
+
+ /**
+ * \return Returns the order of the stepper.
+ */
+ order_type order( void ) const
+ {
+ return order_value;
+ }
+
+
+ velocity_verlet( const algebra_type & algebra = algebra_type() )
+ : algebra_stepper_base_type( algebra ) , m_first_call( true )
+ , m_a1() , m_a2() , m_current_a1( true ) { }
+
+
+ template< class System , class StateInOut >
+ void do_step( System system , StateInOut & x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+
+ template< class System , class StateInOut >
+ void do_step( System system , const StateInOut & x , time_type t , time_type dt )
+ {
+ do_step_v1( system , x , t , dt );
+ }
+
+
+ template< class System , class CoorIn , class VelocityIn , class AccelerationIn ,
+ class CoorOut , class VelocityOut , class AccelerationOut >
+ void do_step( System system , CoorIn const & qin , VelocityIn const & pin , AccelerationIn const & ain ,
+ CoorOut & qout , VelocityOut & pout , AccelerationOut & aout , time_type t , time_type dt )
+ {
+ const value_type one = static_cast< value_type >( 1.0 );
+ const value_type one_half = static_cast< value_type >( 0.5 );
+
+ algebra_stepper_base_type::m_algebra.for_each4(
+ qout , qin , pin , ain ,
+ typename operations_type::template scale_sum3< value_type , time_type , time_square_type >( one , one * dt , one_half * dt * dt ) );
+
+ typename odeint::unwrap_reference< System >::type & sys = system;
+
+ sys( qout , pin , aout , t + dt );
+
+ algebra_stepper_base_type::m_algebra.for_each4(
+ pout , pin , ain , aout ,
+ typename operations_type::template scale_sum3< value_type , time_type , time_type >( one , one_half * dt , one_half * dt ) );
+ }
+
+
+ template< class StateIn >
+ void adjust_size( const StateIn & x )
+ {
+ if( resize_impl( x ) )
+ m_first_call = true;
+ }
+
+ void reset( void )
+ {
+ m_first_call = true;
+ }
+
+
+ /**
+ * \fn velocity_verlet::initialize( const AccelerationIn &qin )
+ * \brief Initializes the internal state of the stepper.
+ * \param deriv The acceleration of x. The next call of `do_step` expects that the acceleration of `x` passed to `do_step`
+ * has the value of `qin`.
+ */
+ template< class AccelerationIn >
+ void initialize( const AccelerationIn & ain )
+ {
+ // alloc a
+ m_resizer.adjust_size( ain ,
+ detail::bind( &velocity_verlet::template resize_impl< AccelerationIn > ,
+ detail::ref( *this ) , detail::_1 ) );
+ boost::numeric::odeint::copy( ain , get_current_acc() );
+ m_first_call = false;
+ }
+
+
+ template< class System , class CoorIn , class VelocityIn >
+ void initialize( System system , const CoorIn & qin , const VelocityIn & pin , time_type t )
+ {
+ m_resizer.adjust_size( qin ,
+ detail::bind( &velocity_verlet::template resize_impl< CoorIn > ,
+ detail::ref( *this ) , detail::_1 ) );
+ initialize_acc( system , qin , pin , t );
+ }
+
+ bool is_initialized( void ) const
+ {
+ return ! m_first_call;
+ }
+
+
+private:
+
+ template< class System , class CoorIn , class VelocityIn >
+ void initialize_acc( System system , const CoorIn & qin , const VelocityIn & pin , time_type t )
+ {
+ typename odeint::unwrap_reference< System >::type & sys = system;
+ sys( qin , pin , get_current_acc() , t );
+ m_first_call = false;
+ }
+
+ template< class System , class StateInOut >
+ void do_step_v1( System system , StateInOut & x , time_type t , time_type dt )
+ {
+ typedef typename odeint::unwrap_reference< StateInOut >::type state_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::first_type >::type coor_in_type;
+ typedef typename odeint::unwrap_reference< typename state_in_type::second_type >::type momentum_in_type;
+
+ typedef typename boost::remove_reference< coor_in_type >::type xyz_type;
+ state_in_type & statein = x;
+ coor_in_type & qinout = statein.first;
+ momentum_in_type & pinout = statein.second;
+
+ // alloc a
+ if( m_resizer.adjust_size( qinout ,
+ detail::bind( &velocity_verlet::template resize_impl< xyz_type > ,
+ detail::ref( *this ) , detail::_1 ) )
+ || m_first_call )
+ {
+ initialize_acc( system , qinout , pinout , t );
+ }
+
+ // check first
+ do_step( system , qinout , pinout , get_current_acc() , qinout , pinout , get_old_acc() , t , dt );
+ toggle_current_acc();
+ }
+
+ template< class StateIn >
+ bool resize_impl( const StateIn & x )
+ {
+ bool resized = false;
+ resized |= adjust_size_by_resizeability( m_a1 , x , typename is_resizeable< acceleration_type >::type() );
+ resized |= adjust_size_by_resizeability( m_a2 , x , typename is_resizeable< acceleration_type >::type() );
+ return resized;
+ }
+
+ acceleration_type & get_current_acc( void )
+ {
+ return m_current_a1 ? m_a1.m_v : m_a2.m_v ;
+ }
+
+ const acceleration_type & get_current_acc( void ) const
+ {
+ return m_current_a1 ? m_a1.m_v : m_a2.m_v ;
+ }
+
+ acceleration_type & get_old_acc( void )
+ {
+ return m_current_a1 ? m_a2.m_v : m_a1.m_v ;
+ }
+
+ const acceleration_type & get_old_acc( void ) const
+ {
+ return m_current_a1 ? m_a2.m_v : m_a1.m_v ;
+ }
+
+ void toggle_current_acc( void )
+ {
+ m_current_a1 = ! m_current_a1;
+ }
+
+ resizer_type m_resizer;
+ bool m_first_call;
+ wrapped_acceleration_type m_a1 , m_a2;
+ bool m_current_a1;
+};
+
+/**
+ * \class velocity_verlet
+ * \brief The Velocity-Verlet algorithm.
+ *
+ * <a href="http://en.wikipedia.org/wiki/Verlet_integration" >The Velocity-Verlet algorithm</a> is a method for simulation of molecular dynamics systems. It solves the ODE
+ * a=f(r,v',t) where r are the coordinates, v are the velocities and a are the accelerations, hence v = dr/dt, a=dv/dt.
+ *
+ * \tparam Coor The type representing the coordinates.
+ * \tparam Velocity The type representing the velocities.
+ * \tparam Value The type value type.
+ * \tparam Acceleration The type representing the acceleration.
+ * \tparam Time The time representing the independent variable - the time.
+ * \tparam TimeSq The time representing the square of the time.
+ * \tparam Algebra The algebra.
+ * \tparam Operations The operations type.
+ * \tparam Resizer The resizer policy type.
+ */
+
+
+ /**
+ * \fn velocity_verlet::velocity_verlet( const algebra_type &algebra )
+ * \brief Constructs the velocity_verlet class. This constructor can be used as a default
+ * constructor if the algebra has a default constructor.
+ * \param algebra A copy of algebra is made and stored.
+ */
+
+
+ /**
+ * \fn velocity_verlet::do_step( System system , StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * It can be used like
+ * \code
+ * pair< coordinates , velocities > state;
+ * stepper.do_step( sys , x , t , dt );
+ * \endcode
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Second Order System concept.
+ * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+ /**
+ * \fn velocity_verlet::do_step( System system , const StateInOut &x , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place.
+ *
+ * It can be used like
+ * \code
+ * pair< coordinates , velocities > state;
+ * stepper.do_step( sys , x , t , dt );
+ * \endcode
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Second Order System concept.
+ * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+
+
+ /**
+ * \fn velocity_verlet::do_step( System system , CoorIn const & qin , VelocityIn const & pin , AccelerationIn const & ain , CoorOut & qout , VelocityOut & pout , AccelerationOut & aout , time_type t , time_type dt )
+ * \brief This method performs one step. It transforms the result in-place. Additionally to the other methods
+ * the coordinates, velocities and accelerations are passed directly to do_step and they are transformed out-of-place.
+ *
+ * It can be used like
+ * \code
+ * coordinates qin , qout;
+ * velocities pin , pout;
+ * accelerations ain, aout;
+ * stepper.do_step( sys , qin , pin , ain , qout , pout , aout , t , dt );
+ * \endcode
+ *
+ * \param system The system function to solve, hence the r.h.s. of the ordinary differential equation. It must fulfill the
+ * Second Order System concept.
+ * \param x The state of the ODE which should be solved. The state is pair of Coor and Velocity.
+ * \param t The value of the time, at which the step should be performed.
+ * \param dt The step size.
+ */
+
+
+ /**
+ * \fn void velocity_verlet::adjust_size( const StateIn &x )
+ * \brief Adjust the size of all temporaries in the stepper manually.
+ * \param x A state from which the size of the temporaries to be resized is deduced.
+ */
+
+
+ /**
+ * \fn velocity_verlet::reset( void )
+ * \brief Resets the internal state of this stepper. After calling this method it is safe to use all
+ * `do_step` method without explicitly initializing the stepper.
+ */
+
+
+
+ /**
+ * \fn velocity_verlet::initialize( System system , const CoorIn &qin , const VelocityIn &pin , time_type t )
+ * \brief Initializes the internal state of the stepper.
+ *
+ * This method is equivalent to
+ * \code
+ * Acceleration a;
+ * system( qin , pin , a , t );
+ * stepper.initialize( a );
+ * \endcode
+ *
+ * \param system The system function for the next calls of `do_step`.
+ * \param qin The current coordinates of the ODE.
+ * \param pin The current velocities of the ODE.
+ * \param t The current time of the ODE.
+ */
+
+
+ /**
+ * \fn velocity_verlet::is_initialized()
+ * \returns Returns if the stepper is initialized.
+ */
+
+
+
+
+} // namespace odeint
+} // namespace numeric
+} // namespace boost
+
+
+#endif // BOOST_NUMERIC_ODEINT_STEPPER_VELOCITY_VERLET_HPP_DEFINED