|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r57818 - in sandbox/odeint: boost/numeric boost/numeric/odeint libs/numeric/odeint/examples
From: mario.mulansky_at_[hidden]
Date: 2009-11-20 09:29:22
Author: mariomulansky
Date: 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
New Revision: 57818
URL: http://svn.boost.org/trac/boost/changeset/57818
Log:
changed stepsize_controller to controlled stepper
Added:
sandbox/odeint/boost/numeric/odeint/controlled_stepper_standard.hpp
- copied, changed from r57806, /sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp
Removed:
sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp
Text files modified:
sandbox/odeint/boost/numeric/odeint.hpp | 2
sandbox/odeint/boost/numeric/odeint/controlled_stepper_standard.hpp | 103 +++++++++++++++++++++++----------------
sandbox/odeint/boost/numeric/odeint/integrator_adaptive_stepsize.hpp | 91 ++++++++++++++++------------------
sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp | 5 +
sandbox/odeint/libs/numeric/odeint/examples/lorenz_integrator.cpp | 17 ++++-
sandbox/odeint/libs/numeric/odeint/examples/pendulum_vibrating_pivot.cpp | 5 +
6 files changed, 123 insertions(+), 100 deletions(-)
Modified: sandbox/odeint/boost/numeric/odeint.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint.hpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -23,7 +23,7 @@
#include <boost/numeric/odeint/stepper_half_step.hpp>
#include <boost/numeric/odeint/stepper_midpoint.hpp>
-#include <boost/numeric/odeint/stepsize_controller_standard.hpp>
+#include <boost/numeric/odeint/controlled_stepper_standard.hpp>
#include <boost/numeric/odeint/integrator_adaptive_stepsize.hpp>
#include <boost/numeric/odeint/integrator_constant_stepsize.hpp>
Copied: sandbox/odeint/boost/numeric/odeint/controlled_stepper_standard.hpp (from r57806, /sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp)
==============================================================================
--- /sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint/controlled_stepper_standard.hpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -1,17 +1,18 @@
-/* Boost odeint/stepsize_controller_standard.hpp header file
+/* Boost odeint/controlled_stepper_standard.hpp header file
Copyright 2009 Karsten Ahnert
Copyright 2009 Mario Mulansky
- This file includes the standard step size controller
+ This file includes the standard controlled stepper that should be
+ used with runge kutta routines.
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_STEPSIZE_CONTROLLER_STANDARD_HPP
-#define BOOST_NUMERIC_ODEINT_STEPSIZE_CONTROLLER_STANDARD_HPP
+#ifndef BOOST_NUMERIC_ODEINT_CONTROLLED_STEPPER_STANDARD_HPP
+#define BOOST_NUMERIC_ODEINT_CONTROLLED_STEPPER_STANDARD_HPP
#include <cmath> // for pow( ) and abs()
#include <complex>
@@ -30,14 +31,6 @@
/*
The initial state is given in x.
- t is an vector including the times at which the state will be written into
- the vector x_vec.
- x_vec must provide enough space to hold times.size() states.
- dt is the initial step size (will be adjusted according to the errors).
- This function returns the total number of steps required to integrate the
- whole intervale times.begin() - times.end().
- Note that the values in times don't influence the stepsize, but only the
- time points at which the state is stored into x_vec.
The stepsize is adjust such that the following maximal relative error is
small enough for each step:
@@ -59,53 +52,77 @@
*/
template<
- class ContainerType,
- class T,
- class ResizeType = resizer< ContainerType > >
- class step_controller_standard {
-
- typedef typename ContainerType::iterator iterator;
-
- T eps_abs;
- T eps_rel;
- T a_x;
- T a_dxdt;
- ContainerType dxdt;
- ContainerType x_tmp;
- ContainerType x_err;
- ResizeType resizer;
-
+ class ErrorStepper,
+ class ResizeType = resizer< typename ErrorStepper::container_type > >
+ class controlled_stepper_standard {
+
public:
- typedef ContainerType container_type;
+ // forward types from ErrorStepper
+ typedef typename ErrorStepper::container_type container_type;
+ typedef typename ErrorStepper::resizer_type resizer_type;
+ typedef typename ErrorStepper::time_type time_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::iterator iterator;
+
+ typedef const unsigned short order_type;
+
+ // private members
+ private:
+ ErrorStepper &m_stepper;
+
+ time_type eps_abs;
+ time_type eps_rel;
+ time_type a_x;
+ time_type a_dxdt;
+ container_type dxdt;
+ container_type x_tmp;
+ container_type x_err;
+ resizer_type resizer;
+
+
+ // public functions
+ public:
- step_controller_standard( T abs_err, T rel_err, T factor_x, T factor_dxdt )
- : eps_abs(abs_err), eps_rel(rel_err), a_x(factor_x), a_dxdt(factor_dxdt)
+ controlled_stepper_standard(
+ ErrorStepper &stepper,
+ time_type abs_err, time_type rel_err,
+ time_type factor_x, time_type factor_dxdt )
+ : m_stepper(stepper),
+ eps_abs(abs_err), eps_rel(rel_err), a_x(factor_x), a_dxdt(factor_dxdt)
{ }
- template< class Step, class DynamicalSystem >
- controlled_step_result controlled_step( Step &stepper,
- DynamicalSystem &system,
- ContainerType &x,
- T &t,
- T &dt )
+
+ /* Tries a controlled step with the given stepsize dt. If dt is too large,
+ x remains unchanged, an appropriate stepsize is assigned to dt and
+ step_size_decreased is returned. If dt is too small, the small step is
+ accomplished, a larger stepsize is assigned to dt and step_size_increased
+ is returned. If dt is appropriate, the step is accomplished and success
+ is returned.
+ */
+ template< class DynamicalSystem >
+ controlled_step_result next_step(
+ DynamicalSystem &system,
+ container_type &x,
+ time_type &t,
+ time_type &dt )
{
resizer.adjust_size(x, x_err);
x_tmp = x; // copy current state
system( x, dxdt, t ); // compute dxdt
- stepper.next_step(system, x, dxdt, t, dt, x_err ); // do step forward with error
+ m_stepper.next_step(system, x, dxdt, t, dt, x_err ); // do step forward with error
iterator x_start = x_tmp.begin();
iterator dxdt_start = dxdt.begin();
iterator x_err_start = x_err.begin();
- T max_rel_err = 0.0;
+ time_type max_rel_err = 0.0;
while( x_start != x_tmp.end() ) {
// get the maximal value of x_err/D where
// D = eps_abs + eps_rel * (a_x*|x| + a_dxdt*|dxdt|);
- T err = eps_abs + eps_rel * (a_x * std::abs(*x_start++) +
- a_dxdt * dt * std::abs(*dxdt_start++));
+ time_type err = eps_abs + eps_rel * (a_x * std::abs(*x_start++) +
+ a_dxdt * dt * std::abs(*dxdt_start++));
max_rel_err = max( std::abs(*x_err_start++)/err , max_rel_err );
}
@@ -113,14 +130,14 @@
if( max_rel_err > 1.1 ) { // error too large - decrease dt
// limit scaling factor to 0.2
- dt *= max( 0.9*pow(max_rel_err , -1.0/(stepper.order_error()-1.0)) , 0.2 );
+ dt *= max( 0.9*pow(max_rel_err , -1.0/(m_stepper.order_error()-1.0)) , 0.2 );
// reset state
x = x_tmp;
return step_size_decreased;
} else if( max_rel_err < 0.5 ) { //error too small - increase dt
t += dt; // we keep the evolution -> increase time
// limit scaling factor to 5.0
- dt *= min( 0.9*pow(max_rel_err , -1.0/stepper.order()), 5.0 );
+ dt *= min( 0.9*pow(max_rel_err , -1.0/m_stepper.order()), 5.0 );
return step_size_increased;
} else {
t += dt;
Modified: sandbox/odeint/boost/numeric/odeint/integrator_adaptive_stepsize.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint/integrator_adaptive_stepsize.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint/integrator_adaptive_stepsize.hpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -13,7 +13,7 @@
#ifndef BOOST_NUMERIC_ODEINT_INTEGRATOR_ADAPTIVE_STEPSIZE_HPP
#define BOOST_NUMERIC_ODEINT_INTEGRATOR_ADAPTIVE_STEPSIZE_HPP
-#include <boost/numeric/odeint/stepsize_controller_standard.hpp>
+#include <boost/numeric/odeint/controlled_stepper_standard.hpp>
#include <boost/numeric/odeint/resizer.hpp>
#include <boost/numeric/odeint/observer.hpp>
#include <vector>
@@ -25,32 +25,30 @@
template<
- class Stepper,
+ class ControlledStepper,
class DynamicalSystem,
- class StepController,
class Observer
>
size_t integrate_adaptive(
- Stepper &stepper,
+ ControlledStepper &stepper,
DynamicalSystem &system,
- StepController &controller,
- typename Stepper::container_type &state,
- typename Stepper::time_type start_time,
- typename Stepper::time_type end_time,
- typename Stepper::time_type dt,
+ typename ControlledStepper::container_type &state,
+ typename ControlledStepper::time_type start_time,
+ typename ControlledStepper::time_type end_time,
+ typename ControlledStepper::time_type dt,
Observer &observer )
{
controlled_step_result result;
size_t iterations = 0;
- typename Stepper::time_type t = start_time;
- typename Stepper::time_type dt_ = dt;
+ typename ControlledStepper::time_type t = start_time;
+ typename ControlledStepper::time_type dt_ = dt;
observer(t, state, system);
while( t < end_time )
{
// do a controlled step
- result = controller.controlled_step( stepper, system, state, t, dt_ );
+ result = stepper.next_step( system, state, t, dt_ );
if( result != step_size_decreased )
{ // we actually did a step forward (dt was small enough)
@@ -65,26 +63,24 @@
}
template<
- class Stepper,
- class DynamicalSystem,
- class StepController
+ class ControlledStepper,
+ class DynamicalSystem
>
size_t integrate_adaptive(
- Stepper &stepper,
+ ControlledStepper &stepper,
DynamicalSystem &system,
- StepController &controller,
- typename Stepper::container_type &state,
- typename Stepper::time_type start_time,
- typename Stepper::time_type end_time,
- typename Stepper::time_type dt )
+ typename ControlledStepper::container_type &state,
+ typename ControlledStepper::time_type start_time,
+ typename ControlledStepper::time_type end_time,
+ typename ControlledStepper::time_type dt )
{
return integrate_adaptive(
- stepper , system , controller ,
- state, start_time , end_time,
- do_nothing_observer<
- typename Stepper::time_type ,
- typename Stepper::container_type ,
- DynamicalSystem >
+ stepper, system ,
+ state, start_time , end_time,
+ do_nothing_observer<
+ typename ControlledStepper::time_type ,
+ typename ControlledStepper::container_type ,
+ DynamicalSystem >
);
}
@@ -105,26 +101,24 @@
time points at which the state is stored into x_vec.
*/
template<
- class Stepper,
+ class ControlledStepper,
class DynamicalSystem,
- class StepController,
class TimeSequence,
class InsertIterator
>
size_t integrate(
- Stepper &stepper,
+ ControlledStepper &stepper,
DynamicalSystem &system,
- StepController &controller,
- typename Stepper::container_type &state,
+ typename ControlledStepper::container_type &state,
TimeSequence ×,
- typename Stepper::time_type &dt,
+ typename ControlledStepper::time_type dt,
InsertIterator state_inserter)
{
if( times.empty() ) return 0;
else
{
state_copy_observer<InsertIterator, TimeSequence> observer(times, state_inserter);
- return integrate_adaptive(stepper, system, controller, state,
+ return integrate_adaptive(stepper, system, state,
times.front() , times.back(), dt , observer);
}
}
@@ -137,32 +131,33 @@
given below.
*/
template<
- class Stepper,
class DynamicalSystem,
- class InsertIterator ,
- class TimeSequence
+ class ContainerType,
+ class InsertIterator,
+ class TimeSequence,
+ class T
>
size_t integrate(
- Stepper &stepper,
DynamicalSystem &system,
- typename Stepper::container_type &x,
+ ContainerType &x,
TimeSequence ×,
InsertIterator state_inserter,
- typename Stepper::time_type dt = 1E-4,
- typename Stepper::time_type eps_abs = 1E-6,
- typename Stepper::time_type eps_rel = 1E-7,
- typename Stepper::time_type a_x = 1.0 ,
- typename Stepper::time_type a_dxdt = 1.0
+ T dt = 1E-4,
+ T eps_abs = 1E-6,
+ T eps_rel = 1E-7,
+ T a_x = 1.0 ,
+ T a_dxdt = 1.0
)
{
+ // we use cash karp stepper as base stepper
+ stepper_rk5_ck< ContainerType > stepper_cash_karp;
// we use the standard controller for this adaptive integrator
- step_controller_standard< typename Stepper::container_type,
- typename Stepper::time_type,
- typename Stepper::resizer_type > controller(eps_abs, eps_rel, a_x, a_dxdt );
+ controlled_stepper_standard< ContainerType, T>
+ controlled_stepper(stepper_cash_karp, eps_abs, eps_rel, a_x, a_dxdt );
// initialized with values from above
// call the normal integrator
- return integrate(stepper, system, controller, x, times, dt, state_inserter);
+ return integrate(controlled_stepper, system, x, times, dt, state_inserter);
}
Deleted: sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint/stepsize_controller_standard.hpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
+++ (empty file)
@@ -1,137 +0,0 @@
-/* Boost odeint/stepsize_controller_standard.hpp header file
-
- Copyright 2009 Karsten Ahnert
- Copyright 2009 Mario Mulansky
-
- This file includes the standard step size controller
-
- 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_STEPSIZE_CONTROLLER_STANDARD_HPP
-#define BOOST_NUMERIC_ODEINT_STEPSIZE_CONTROLLER_STANDARD_HPP
-
-#include <cmath> // for pow( ) and abs()
-#include <complex>
-
-#include <boost/concept_check.hpp>
-
-#include <boost/numeric/odeint/detail/iterator_algebra.hpp>
-#include <boost/numeric/odeint/concepts/state_concept.hpp>
-#include <boost/numeric/odeint/resizer.hpp>
-
-namespace boost {
-namespace numeric {
-namespace odeint {
-
- typedef enum{success, step_size_decreased, step_size_increased} controlled_step_result;
-
- /*
- The initial state is given in x.
- t is an vector including the times at which the state will be written into
- the vector x_vec.
- x_vec must provide enough space to hold times.size() states.
- dt is the initial step size (will be adjusted according to the errors).
- This function returns the total number of steps required to integrate the
- whole intervale times.begin() - times.end().
- Note that the values in times don't influence the stepsize, but only the
- time points at which the state is stored into x_vec.
-
- The stepsize is adjust such that the following maximal relative error is
- small enough for each step:
- R = max( x_err_n / [eps_abs + eps_rel*( a_x * |x_n| + a_dxdt * |dxdt_n| )] )
- where the max refers to the componentwise maximum the expression.
-
- if R > 1.1 the stepsize is decreased:
- dt = dt*S*R^(-1/(q-1))
-
- if R < 0.5 the stepsize is increased:
- dt = dt*S*R^(-1/q))
-
- q is the order of the error term provided by the stepper.order_error() function
- (e.g. 2 for simple euler and 5 for rk5_ck) and S is a safety factor set to
- S = 0.9. See e.g. Numerical Recipes for more details on this strategy.
-
- To avoid extensive chages in dt, the decrease factor is limited to 0.2 and
- the increase factor to 5.0.
- */
-
- template<
- class ContainerType,
- class T,
- class ResizeType = resizer< ContainerType > >
- class step_controller_standard {
-
- typedef typename ContainerType::iterator iterator;
-
- T eps_abs;
- T eps_rel;
- T a_x;
- T a_dxdt;
- ContainerType dxdt;
- ContainerType x_tmp;
- ContainerType x_err;
- ResizeType resizer;
-
- public:
-
- typedef ContainerType container_type;
-
- step_controller_standard( T abs_err, T rel_err, T factor_x, T factor_dxdt )
- : eps_abs(abs_err), eps_rel(rel_err), a_x(factor_x), a_dxdt(factor_dxdt)
- { }
-
- template< class Step, class DynamicalSystem >
- controlled_step_result controlled_step( Step &stepper,
- DynamicalSystem &system,
- ContainerType &x,
- T &t,
- T &dt )
- {
- resizer.adjust_size(x, x_err);
-
- x_tmp = x; // copy current state
- system( x, dxdt, t ); // compute dxdt
- stepper.next_step(system, x, dxdt, t, dt, x_err ); // do step forward with error
-
- iterator x_start = x_tmp.begin();
- iterator dxdt_start = dxdt.begin();
- iterator x_err_start = x_err.begin();
- T max_rel_err = 0.0;
-
- while( x_start != x_tmp.end() ) {
- // get the maximal value of x_err/D where
- // D = eps_abs + eps_rel * (a_x*|x| + a_dxdt*|dxdt|);
- T err = eps_abs + eps_rel * (a_x * std::abs(*x_start++) +
- a_dxdt * dt * std::abs(*dxdt_start++));
- max_rel_err = max( std::abs(*x_err_start++)/err , max_rel_err );
- }
-
- //std::cout<<max_rel_err<<std::endl;
-
- if( max_rel_err > 1.1 ) { // error too large - decrease dt
- // limit scaling factor to 0.2
- dt *= max( 0.9*pow(max_rel_err , -1.0/(stepper.order_error()-1.0)) , 0.2 );
- // reset state
- x = x_tmp;
- return step_size_decreased;
- } else if( max_rel_err < 0.5 ) { //error too small - increase dt
- t += dt; // we keep the evolution -> increase time
- // limit scaling factor to 5.0
- dt *= min( 0.9*pow(max_rel_err , -1.0/stepper.order()), 5.0 );
- return step_size_increased;
- } else {
- t += dt;
- return success;
- }
- }
- };
-
-} // namespace odeint
-} // namespace numeric
-} // namespace boost
-
-
-#endif // BOOST_NUMERIC_ODEINT_STEPSIZE_CONTROLLER_STANDARD_HPP
Modified: sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp
==============================================================================
--- sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp (original)
+++ sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -61,12 +61,13 @@
x[2] = 20.0;
stepper_half_step< stepper_euler< state_type > > euler;
- step_controller_standard< state_type, double > controller( eps_abs , eps_rel, 1.0, 1.0);
+ controlled_stepper_standard< stepper_half_step< stepper_euler< state_type > > >
+ controlled_stepper( euler, eps_abs , eps_rel, 1.0, 1.0);
cout.precision(5);
cout.setf(ios::fixed,ios::floatfield);
- size_t steps = integrate_adaptive( euler, lorenz, controller, x, 0.0, 10.0, 1E-4, print_state );
+ size_t steps = integrate_adaptive( controlled_stepper, lorenz, x, 0.0, 10.0, 1E-4, print_state );
clog << "Number of steps: " << steps << endl;
Modified: sandbox/odeint/libs/numeric/odeint/examples/lorenz_integrator.cpp
==============================================================================
--- sandbox/odeint/libs/numeric/odeint/examples/lorenz_integrator.cpp (original)
+++ sandbox/odeint/libs/numeric/odeint/examples/lorenz_integrator.cpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -35,8 +35,8 @@
const double R = 28.0;
const double b = 8.0 / 3.0;
-const double eps_abs = 1E-3;
-const double eps_rel = 1E-3;
+const double eps_abs = 1E-6;
+const double eps_rel = 1E-7;
const size_t time_points = 101;
@@ -68,18 +68,25 @@
}
stepper_half_step< stepper_euler< state_type > > euler;
- size_t steps = integrate( euler, lorenz, x1, times, back_inserter(x1_t_vec));
+ controlled_stepper_standard< stepper_half_step< stepper_euler< state_type > > >
+ euler_controlled( euler , eps_abs, eps_rel, 1.0, 1.0);
+ size_t steps = integrate( euler_controlled, lorenz, x1,
+ times, 1E-4, back_inserter(x1_t_vec));
clog << "Euler Half Step: #steps " << steps << endl;
stepper_half_step< stepper_rk4< state_type > > rk4;
- steps = integrate( rk4, lorenz, x2, times, back_inserter(x2_t_vec));
+ controlled_stepper_standard< stepper_half_step< stepper_rk4< state_type > > >
+ rk4_controlled( rk4 , eps_abs, eps_rel, 1.0, 1.0);
+ steps = integrate( rk4_controlled, lorenz, x2, times, 1E-4, back_inserter(x2_t_vec));
clog << "RK4 Half Step: #steps " << steps << endl;
stepper_rk5_ck< state_type > rk5;
- steps = integrate( rk5, lorenz, x3, times, back_inserter(x3_t_vec));
+ controlled_stepper_standard< stepper_rk5_ck< state_type > >
+ rk5_controlled( rk5 , eps_abs, eps_rel, 1.0, 1.0);
+ steps = integrate( rk5_controlled, lorenz, x3, times, 1E-4, back_inserter(x3_t_vec));
clog << "RK5 Cash-Karp: #steps: " << steps << endl;
Modified: sandbox/odeint/libs/numeric/odeint/examples/pendulum_vibrating_pivot.cpp
==============================================================================
--- sandbox/odeint/libs/numeric/odeint/examples/pendulum_vibrating_pivot.cpp (original)
+++ sandbox/odeint/libs/numeric/odeint/examples/pendulum_vibrating_pivot.cpp 2009-11-20 09:29:20 EST (Fri, 20 Nov 2009)
@@ -59,7 +59,10 @@
stepper_half_step< stepper_rk4< state_type > > stepper;
- size_t steps = integrate( stepper, my_system, x, times, back_inserter(x_t_vec));
+ controlled_stepper_standard< stepper_half_step< stepper_rk4< state_type > > >
+ controlled_stepper( stepper, 1E-6 , 1E-7 , 1.0 , 1.0 );
+
+ size_t steps = integrate( controlled_stepper, my_system, x, times, 1E-4, back_inserter(x_t_vec)); \
clog << "Steps: " << steps << endl;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk