|  | Home | Libraries | People | FAQ | More | 
        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 | 
|---|---|---|
| 
                   | 
                   | ax=1, adxdt=1 | 
| 
                   | 
                   | ax=1, adxdt=1 | 
| 
                   | 
                   | a x=1, adxdt=1 | 
| 
                   | 
                   | - | 
Table 1.8. Generation functions make_dense_output( abs_error , rel_error , stepper )
| Stepper | Result of make_dense_output | Remarks | 
|---|---|---|
| 
                   | 
                   | a x=1, adxdt=1 | 
| 
                   | 
                   | - |