Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Generation functions

In the Tutorial we have learned how we can use the generation functions make_controlled and make_dense_output to create controlled and dense output stepper from a simple stepper or an error stepper. The syntax of these two functions is very simple:

auto stepper1 = make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() );
// or with max step size limit:
// auto stepper1 = make_controlled( 1.0e-6 , 1.0e-6 , 0.01, stepper_type() );

auto stepper2 = make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() );

The first two parameters are the absolute and the relative error tolerances and the third parameter is the stepper. Additionally, a second version exists where additionally a maximal step size is supplied which ensures the the step size is not increased above this value. In C++03 you can infer the type from the result_of mechanism:

boost::numeric::odeint::result_of::make_controlled< stepper_type >::type stepper3 = make_controlled( 1.0e-6 , 1.0e-6 , stepper_type() );
(void)stepper3;
boost::numeric::odeint::result_of::make_dense_output< stepper_type >::type stepper4 = make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() );
(void)stepper4;

To use your own steppers with the make_controlled or make_dense_output you need to specialize two class templates. Suppose your steppers are called custom_stepper, custom_controller and custom_dense_output. Then, the first class you need to specialize is boost::numeric::get_controller, a meta function returning the type of the controller:

namespace boost { namespace numeric { namespace odeint {

template<>
struct get_controller< custom_stepper >
{
    typedef custom_controller type;
};

} } }

The second one is a factory class boost::numeric::odeint::controller_factory which constructs the controller from the tolerances and the stepper. In our dummy implementation this class is

namespace boost { namespace numeric { namespace odeint {

template<>
struct controller_factory< custom_stepper , custom_controller >
{
    custom_controller operator()( double abs_tol , double rel_tol , const custom_stepper & ) const
    {
        return custom_controller();
    }

    custom_controller operator()( double abs_tol , double rel_tol , double max_dt ,
                                  const custom_stepper & ) const
    {
        // version with maximal allowed step size max_dt
        return custom_controller();
    }
};

} } }

This is all to use the make_controlled mechanism. Now you can use your controller via

auto stepper5 = make_controlled( 1.0e-6 , 1.0e-6 , custom_stepper() );

For the dense_output_stepper everything works similar. Here you have to specialize boost::numeric::odeint::get_dense_output and boost::numeric::odeint::dense_output_factory. These two classes have the same syntax as their relatives get_controller and controller_factory.

All controllers and dense-output steppers in odeint can be used with these mechanisms. In the table below you will find, which steppers is constructed from make_controlled or make_dense_output if applied on a stepper from odeint:

Table 1.7. Generation functions make_controlled( abs_error , rel_error , stepper )

Stepper

Result of make_controlled

Remarks

runge_kutta_cash_karp54

controlled_runge_kutta< runge_kutta_cash_karp54 , default_error_checker<...> >

ax=1, adxdt=1

runge_kutta_fehlberg78

controlled_runge_kutta< runge_kutta_fehlberg78 , default_error_checker<...> >

ax=1, adxdt=1

runge_kutta_dopri5

controlled_runge_kutta< runge_kutta_dopri5 , default_error_checker<...> >

a x=1, adxdt=1

rosenbrock4

rosenbrock4_controlled< rosenbrock4 >

-


Table 1.8. Generation functions make_dense_output( abs_error , rel_error , stepper )

Stepper

Result of make_dense_output

Remarks

runge_kutta_dopri5

dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5 , default_error_checker<...> > >

a x=1, adxdt=1

rosenbrock4

rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4 > >

-



PrevUpHomeNext