...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Home | Libraries | People | FAQ | More |
Integrate functions perform the time evolution of a given ODE from some starting
time t0 to a given end time t1
and starting at state x0 by subsequent calls of a given
stepper's do_step
function.
Additionally, the user can provide an __observer to analyze the state during
time evolution, and a max_step_checker
to throw an
exception if too many steps are taken between observer calls (i.e. too small
step size). There are five different integrate functions which have different
strategies on when to call the observer function during integration. All
of the integrate functions except integrate_n_steps
can be called with any stepper following one of the stepper concepts: Stepper , Error
Stepper , Controlled
Stepper , Dense
Output Stepper. Depending on the abilities of the stepper, the integrate
functions make use of step-size control or dense output.
If observer calls at equidistant time intervals dt are
needed, the integrate_const
or integrate_n_steps
function
should be used. We start with explaining integrate_const
:
integrate_const(
stepper ,
system ,
x0 ,
t0 ,
t1 ,
dt )
integrate_const(
stepper ,
system ,
x0 ,
t0 ,
t1 ,
dt ,
observer )
integrate_const(
stepper ,
system ,
x0 ,
t0 ,
t1 ,
dt ,
observer ,
max_step_checker )
These integrate the ODE given by system
with subsequent steps from stepper
.
Integration start at t0
and
x0
and ends at some t'
= t0 + n dt with n such that t1 -
dt < t' <= t1. x0
is changed to the approximative solution x(t') at the
end of integration. If provided, the observer
is invoked at times t0, t0 + dt,
t0 + 2dt, ... ,t'. If provided,
the max_step_checker
counts
the number of steps between observer calls and throws a no_progress_error
this exceeds some limit (default: 500). integrate_const
returns the number of steps performed during the integration. Note that if
you are using a simple Stepper
or Error Stepper
and want to make exactly n
steps you should prefer the integrate_n_steps
function below.
stepper
is a Stepper or Error Stepper
then dt
is also the step
size used for integration and the observer is called just after every
step.
stepper
is a Controlled
Stepper then dt
is the initial step size. The actual step size will change due to error
control during time evolution. However, if an observer is provided the
step size will be adjusted such that the algorithm always calculates
x(t) at t = t0 + n dt and calls
the observer at that point. Note that the use of Controlled
Stepper is reasonable here only if dt
is considerably larger than typical step sizes used by the stepper.
stepper
is a Dense Output
Stepper then dt
is the initial step size. The actual step size will be adjusted during
integration due to error control. If an observer is provided dense output
is used to calculate x(t) at t = t0 + n
dt.
This function is very similar to integrate_const
above. The only difference is that it does not take the end time as parameter,
but rather the number of steps. The integration is then performed until the
time t0+n*dt
.
integrate_n_steps(
stepper ,
system ,
x0 ,
t0 ,
dt ,
n )
integrate_n_steps(
stepper ,
system ,
x0 ,
t0 ,
dt ,
n , observer )
integrate_n_steps(
stepper ,
system ,
x0 ,
t0 ,
dt ,
n , observer , max_step_checker )
Integrates the ODE given by system
with subsequent steps from stepper
starting at x0 and t0. If provided,
observer
is called after
every step and at the beginning with t0
,
similar as above. Again, providing a max_step_checker
will throw a no_progress_error
if too many steps are performed between observer calls. The approximate result
for x( t0 + n dt ) is stored in x0
.
This function returns the end time t0
+ n*dt
.
If the observer should be called at each time step then the integrate_adaptive
function should be used.
Note that in the case of Controlled
Stepper or Dense
Output Stepper this leads to non-equidistant observer calls as the
step size changes.
integrate_adaptive(
stepper ,
system ,
x0 ,
t0 ,
t1 ,
dt )
integrate_adaptive(
stepper ,
system ,
x0 ,
t0 ,
t1 ,
dt ,
observer )
Integrates the ODE given by system
with subsequent steps from stepper
.
Integration start at t0
and
x0
and ends at t1.
x0
is changed to the approximative
solution x(t1) at the end of integration. If provided,
the observer
is called after
each step (and before the first step at t0
).
integrate_adaptive
returns
the number of steps performed during the integration.
Note | |
---|---|
|
stepper
is a Stepper or Error Stepper
then dt
is the step size
used for integration and integrate_adaptive
behaves like integrate_const
except that for the last step the step size is reduced to ensure we end
exactly at t1
. If provided,
the observer is called at each step.
stepper
is a Controlled
Stepper then dt
is the initial step size. The actual step size is changed according to
error control of the stepper. For the last step, the step size will be
reduced to ensure we end exactly at t1
.
If provided, the observer is called after each time step (and before
the first step at t0
).
dt
is the initial step size and integrate_adaptive
behaves just like for Controlled
Stepper above. No dense output is used.
If the observer should be called at some user given time points the integrate_times
function should be used.
The times for observer calls are provided as a sequence of time values. The
sequence is either defined via two iterators pointing to begin and end of
the sequence or in terms of a Boost.Range
object.
integrate_times(
stepper ,
system ,
x0 ,
times_start ,
times_end ,
dt ,
observer )
integrate_times(
stepper ,
system ,
x0 ,
time_range ,
dt ,
observer )
Integrates the ODE given by system
with subsequent steps from stepper
.
Integration starts at *times_start
and ends exactly at *(times_end-1)
.
x0
contains the approximate
solution at the end point of integration. This function requires an observer
which is invoked at the subsequent times *times_start++
until times_start ==
times_end
. If called with a Boost.Range
time_range
the function behaves
the same with times_start = boost::begin( time_range
)
and times_end
= boost::end(
time_range )
.
Additionally, a max_step_checker
can be provided,
e.g.:
integrate_times(
stepper ,
system ,
x0 ,
times_start ,
times_end ,
dt ,
observer ,
max_step_checker)
As above, this will throw a no_progress_error
if too many steps are performed between observer calls.
integrate_times
returns the
number of steps performed during the integration.
stepper
is a Stepper or Error Stepper
dt
is the step size used
for integration. However, whenever a time point from the sequence is
approached the step size dt
will be reduced to obtain the state x(t) exactly
at the time point.
stepper
is a Controlled
Stepper then dt
is the initial step size. The actual step size is adjusted during integration
according to error control. However, if a time point from the sequence
is approached the step size is reduced to obtain the state x(t)
exactly at the time point.
stepper
is a Dense Output
Stepper then dt
is the initial step size. The actual step size is adjusted during integration
according to error control. Dense output is used to obtain the states
x(t) at the time points from the sequence.
Additionally to the sophisticated integrate function above odeint also provides
a simple integrate
routine
which uses a dense output stepper based on runge_kutta_dopri5
with standard error bounds 10-6 for the steps.
integrate(
system ,
x0 ,
t0 ,
t1 ,
dt )
integrate(
system ,
x0 ,
t0 ,
t1 ,
dt ,
observer )
This function behaves exactly like integrate_adaptive
above but no stepper has to be provided. It also returns the number of steps
performed during the integration.