summaryrefslogtreecommitdiff
path: root/gsl-1.9/doc/ode-initval.texi
diff options
context:
space:
mode:
Diffstat (limited to 'gsl-1.9/doc/ode-initval.texi')
-rw-r--r--gsl-1.9/doc/ode-initval.texi556
1 files changed, 556 insertions, 0 deletions
diff --git a/gsl-1.9/doc/ode-initval.texi b/gsl-1.9/doc/ode-initval.texi
new file mode 100644
index 0000000..ae8e68b
--- /dev/null
+++ b/gsl-1.9/doc/ode-initval.texi
@@ -0,0 +1,556 @@
+@cindex differential equations, initial value problems
+@cindex initial value problems, differential equations
+@cindex ordinary differential equations, initial value problem
+@cindex ODEs, initial value problems
+This chapter describes functions for solving ordinary differential
+equation (ODE) initial value problems. The library provides a variety
+of low-level methods, such as Runge-Kutta and Bulirsch-Stoer routines,
+and higher-level components for adaptive step-size control. The
+components can be combined by the user to achieve the desired solution,
+with full access to any intermediate steps.
+
+These functions are declared in the header file @file{gsl_odeiv.h}.
+
+@menu
+* Defining the ODE System::
+* Stepping Functions::
+* Adaptive Step-size Control::
+* Evolution::
+* ODE Example programs::
+* ODE References and Further Reading::
+@end menu
+
+@node Defining the ODE System
+@section Defining the ODE System
+
+The routines solve the general @math{n}-dimensional first-order system,
+@tex
+\beforedisplay
+$$
+{dy_i(t) \over dt} = f_i (t, y_1(t), \dots y_n(t))
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+dy_i(t)/dt = f_i(t, y_1(t), ..., y_n(t))
+@end example
+
+@end ifinfo
+@noindent
+for @math{i = 1, \dots, n}. The stepping functions rely on the vector
+of derivatives @math{f_i} and the Jacobian matrix,
+@c{$J_{ij} = \partial f_i(t, y(t)) / \partial y_j$}
+@math{J_@{ij@} = df_i(t,y(t)) / dy_j}.
+A system of equations is defined using the @code{gsl_odeiv_system}
+datatype.
+
+@deftp {Data Type} gsl_odeiv_system
+This data type defines a general ODE system with arbitrary parameters.
+
+@table @code
+@item int (* function) (double t, const double y[], double dydt[], void * params)
+This function should store the vector elements
+@c{$f_i(t,y,\hbox{\it params})$}
+@math{f_i(t,y,params)} in the array @var{dydt},
+for arguments (@var{t},@var{y}) and parameters @var{params}.
+The function should return @code{GSL_SUCCESS} if the calculation
+was completed successfully. Any other return value indicates
+an error.
+
+@item int (* jacobian) (double t, const double y[], double * dfdy, double dfdt[], void * params);
+This function should store the vector of derivative elements
+@c{$\partial f_i(t,y,params) / \partial t$}
+@math{df_i(t,y,params)/dt} in the array @var{dfdt} and the
+Jacobian matrix @c{$J_{ij}$}
+@math{J_@{ij@}} in the array
+@var{dfdy}, regarded as a row-ordered matrix @code{J(i,j) = dfdy[i * dimension + j]}
+where @code{dimension} is the dimension of the system.
+The function should return @code{GSL_SUCCESS} if the calculation
+was completed successfully. Any other return value indicates
+an error.
+
+Some of the simpler solver algorithms do not make use of the Jacobian
+matrix, so it is not always strictly necessary to provide it (the
+@code{jacobian} element of the struct can be replaced by a null pointer
+for those algorithms). However, it is useful to provide the Jacobian to allow
+the solver algorithms to be interchanged---the best algorithms make use
+of the Jacobian.
+
+@item size_t dimension;
+This is the dimension of the system of equations.
+
+@item void * params
+This is a pointer to the arbitrary parameters of the system.
+@end table
+@end deftp
+
+@node Stepping Functions
+@section Stepping Functions
+
+The lowest level components are the @dfn{stepping functions} which
+advance a solution from time @math{t} to @math{t+h} for a fixed
+step-size @math{h} and estimate the resulting local error.
+
+@deftypefun {gsl_odeiv_step *} gsl_odeiv_step_alloc (const gsl_odeiv_step_type * @var{T}, size_t @var{dim})
+This function returns a pointer to a newly allocated instance of a
+stepping function of type @var{T} for a system of @var{dim} dimensions.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_step_reset (gsl_odeiv_step * @var{s})
+This function resets the stepping function @var{s}. It should be used
+whenever the next use of @var{s} will not be a continuation of a
+previous step.
+@end deftypefun
+
+@deftypefun void gsl_odeiv_step_free (gsl_odeiv_step * @var{s})
+This function frees all the memory associated with the stepping function
+@var{s}.
+@end deftypefun
+
+@deftypefun {const char *} gsl_odeiv_step_name (const gsl_odeiv_step * @var{s})
+This function returns a pointer to the name of the stepping function.
+For example,
+
+@example
+printf ("step method is '%s'\n",
+ gsl_odeiv_step_name (s));
+@end example
+
+@noindent
+would print something like @code{step method is 'rk4'}.
+@end deftypefun
+
+@deftypefun {unsigned int} gsl_odeiv_step_order (const gsl_odeiv_step * @var{s})
+This function returns the order of the stepping function on the previous
+step. This order can vary if the stepping function itself is adaptive.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_step_apply (gsl_odeiv_step * @var{s}, double @var{t}, double @var{h}, double @var{y}[], double @var{yerr}[], const double @var{dydt_in}[], double @var{dydt_out}[], const gsl_odeiv_system * @var{dydt})
+This function applies the stepping function @var{s} to the system of
+equations defined by @var{dydt}, using the step size @var{h} to advance
+the system from time @var{t} and state @var{y} to time @var{t}+@var{h}.
+The new state of the system is stored in @var{y} on output, with an
+estimate of the absolute error in each component stored in @var{yerr}.
+If the argument @var{dydt_in} is not null it should point an array
+containing the derivatives for the system at time @var{t} on input. This
+is optional as the derivatives will be computed internally if they are
+not provided, but allows the reuse of existing derivative information.
+On output the new derivatives of the system at time @var{t}+@var{h} will
+be stored in @var{dydt_out} if it is not null.
+
+If the user-supplied functions defined in the system @var{dydt} return a
+status other than @code{GSL_SUCCESS} the step will be aborted. In this
+case, the elements of @var{y} will be restored to their pre-step values
+and the error code from the user-supplied function will be returned.
+The step-size @var{h} will be set to the step-size which caused the error.
+If the function is called again with a smaller step-size, e.g. @math{@var{h}/10},
+it should be possible to get closer to any singularity.
+To distinguish between error codes from the user-supplied functions and
+those from @code{gsl_odeiv_step_apply} itself, any user-defined return
+values should be distinct from the standard GSL error codes.
+@end deftypefun
+
+The following algorithms are available,
+
+@deffn {Step Type} gsl_odeiv_step_rk2
+@cindex RK2, Runge-Kutta method
+@cindex Runge-Kutta methods, ordinary differential equations
+Embedded Runge-Kutta (2, 3) method.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rk4
+@cindex RK4, Runge-Kutta method
+4th order (classical) Runge-Kutta.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rkf45
+@cindex Fehlberg method, differential equations
+@cindex RKF45, Runge-Kutta-Fehlberg method
+Embedded Runge-Kutta-Fehlberg (4, 5) method. This method is a good
+general-purpose integrator.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rkck
+@cindex Runge-Kutta Cash-Karp method
+@cindex Cash-Karp, Runge-Kutta method
+Embedded Runge-Kutta Cash-Karp (4, 5) method.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rk8pd
+@cindex Runge-Kutta Prince-Dormand method
+@cindex Prince-Dormand, Runge-Kutta method
+Embedded Runge-Kutta Prince-Dormand (8,9) method.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rk2imp
+Implicit 2nd order Runge-Kutta at Gaussian points.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_rk4imp
+Implicit 4th order Runge-Kutta at Gaussian points.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_bsimp
+@cindex Bulirsch-Stoer method
+@cindex Bader and Deuflhard, Bulirsch-Stoer method.
+@cindex Deuflhard and Bader, Bulirsch-Stoer method.
+Implicit Bulirsch-Stoer method of Bader and Deuflhard. This algorithm
+requires the Jacobian.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_gear1
+@cindex Gear method, differential equations
+M=1 implicit Gear method.
+@end deffn
+
+@deffn {Step Type} gsl_odeiv_step_gear2
+M=2 implicit Gear method.
+@end deffn
+
+@node Adaptive Step-size Control
+@section Adaptive Step-size Control
+@cindex Adaptive step-size control, differential equations
+
+The control function examines the proposed change to the solution
+produced by a stepping function and attempts to determine the optimal
+step-size for a user-specified level of error.
+
+@deftypefun {gsl_odeiv_control *} gsl_odeiv_control_standard_new (double @var{eps_abs}, double @var{eps_rel}, double @var{a_y}, double @var{a_dydt})
+The standard control object is a four parameter heuristic based on
+absolute and relative errors @var{eps_abs} and @var{eps_rel}, and
+scaling factors @var{a_y} and @var{a_dydt} for the system state
+@math{y(t)} and derivatives @math{y'(t)} respectively.
+
+The step-size adjustment procedure for this method begins by computing
+the desired error level @math{D_i} for each component,
+@tex
+\beforedisplay
+$$
+D_i = \epsilon_{abs} + \epsilon_{rel} * (a_{y} |y_i| + a_{dydt} h |y'_i|)
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+D_i = eps_abs + eps_rel * (a_y |y_i| + a_dydt h |y'_i|)
+@end example
+
+@end ifinfo
+@noindent
+and comparing it with the observed error @math{E_i = |yerr_i|}. If the
+observed error @var{E} exceeds the desired error level @var{D} by more
+than 10% for any component then the method reduces the step-size by an
+appropriate factor,
+@tex
+\beforedisplay
+$$
+h_{new} = h_{old} * S * (E/D)^{-1/q}
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+h_new = h_old * S * (E/D)^(-1/q)
+@end example
+
+@end ifinfo
+@noindent
+where @math{q} is the consistency order of the method (e.g. @math{q=4} for
+4(5) embedded RK), and @math{S} is a safety factor of 0.9. The ratio
+@math{E/D} is taken to be the maximum of the ratios
+@math{E_i/D_i}.
+
+If the observed error @math{E} is less than 50% of the desired error
+level @var{D} for the maximum ratio @math{E_i/D_i} then the algorithm
+takes the opportunity to increase the step-size to bring the error in
+line with the desired level,
+@tex
+\beforedisplay
+$$
+h_{new} = h_{old} * S * (E/D)^{-1/(q+1)}
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+h_new = h_old * S * (E/D)^(-1/(q+1))
+@end example
+
+@end ifinfo
+@noindent
+This encompasses all the standard error scaling methods. To avoid
+uncontrolled changes in the stepsize, the overall scaling factor is
+limited to the range @math{1/5} to 5.
+@end deftypefun
+
+@deftypefun {gsl_odeiv_control *} gsl_odeiv_control_y_new (double @var{eps_abs}, double @var{eps_rel})
+This function creates a new control object which will keep the local
+error on each step within an absolute error of @var{eps_abs} and
+relative error of @var{eps_rel} with respect to the solution @math{y_i(t)}.
+This is equivalent to the standard control object with @var{a_y}=1 and
+@var{a_dydt}=0.
+@end deftypefun
+
+@deftypefun {gsl_odeiv_control *} gsl_odeiv_control_yp_new (double @var{eps_abs}, double @var{eps_rel})
+This function creates a new control object which will keep the local
+error on each step within an absolute error of @var{eps_abs} and
+relative error of @var{eps_rel} with respect to the derivatives of the
+solution @math{y'_i(t)}. This is equivalent to the standard control
+object with @var{a_y}=0 and @var{a_dydt}=1.
+@end deftypefun
+
+
+@deftypefun {gsl_odeiv_control *} gsl_odeiv_control_scaled_new (double @var{eps_abs}, double @var{eps_rel}, double @var{a_y}, double @var{a_dydt}, const double @var{scale_abs}[], size_t @var{dim})
+This function creates a new control object which uses the same algorithm
+as @code{gsl_odeiv_control_standard_new} but with an absolute error
+which is scaled for each component by the array @var{scale_abs}.
+The formula for @math{D_i} for this control object is,
+@tex
+\beforedisplay
+$$
+D_i = \epsilon_{abs} s_i + \epsilon_{rel} * (a_{y} |y_i| + a_{dydt} h |y'_i|)
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+D_i = eps_abs * s_i + eps_rel * (a_y |y_i| + a_dydt h |y'_i|)
+@end example
+
+@end ifinfo
+@noindent
+where @math{s_i} is the @math{i}-th component of the array @var{scale_abs}.
+The same error control heuristic is used by the Matlab @sc{ode} suite.
+@end deftypefun
+
+@deftypefun {gsl_odeiv_control *} gsl_odeiv_control_alloc (const gsl_odeiv_control_type * @var{T})
+This function returns a pointer to a newly allocated instance of a
+control function of type @var{T}. This function is only needed for
+defining new types of control functions. For most purposes the standard
+control functions described above should be sufficient.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_control_init (gsl_odeiv_control * @var{c}, double @var{eps_abs}, double @var{eps_rel}, double @var{a_y}, double @var{a_dydt})
+This function initializes the control function @var{c} with the
+parameters @var{eps_abs} (absolute error), @var{eps_rel} (relative
+error), @var{a_y} (scaling factor for y) and @var{a_dydt} (scaling
+factor for derivatives).
+@end deftypefun
+
+@deftypefun void gsl_odeiv_control_free (gsl_odeiv_control * @var{c})
+This function frees all the memory associated with the control function
+@var{c}.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_control_hadjust (gsl_odeiv_control * @var{c}, gsl_odeiv_step * @var{s}, const double @var{y}[], const double @var{yerr}[], const double @var{dydt}[], double * @var{h})
+This function adjusts the step-size @var{h} using the control function
+@var{c}, and the current values of @var{y}, @var{yerr} and @var{dydt}.
+The stepping function @var{step} is also needed to determine the order
+of the method. If the error in the y-values @var{yerr} is found to be
+too large then the step-size @var{h} is reduced and the function returns
+@code{GSL_ODEIV_HADJ_DEC}. If the error is sufficiently small then
+@var{h} may be increased and @code{GSL_ODEIV_HADJ_INC} is returned. The
+function returns @code{GSL_ODEIV_HADJ_NIL} if the step-size is
+unchanged. The goal of the function is to estimate the largest
+step-size which satisfies the user-specified accuracy requirements for
+the current point.
+@end deftypefun
+
+@deftypefun {const char *} gsl_odeiv_control_name (const gsl_odeiv_control * @var{c})
+This function returns a pointer to the name of the control function.
+For example,
+
+@example
+printf ("control method is '%s'\n",
+ gsl_odeiv_control_name (c));
+@end example
+
+@noindent
+would print something like @code{control method is 'standard'}
+@end deftypefun
+
+
+@node Evolution
+@section Evolution
+
+The highest level of the system is the evolution function which combines
+the results of a stepping function and control function to reliably
+advance the solution forward over an interval @math{(t_0, t_1)}. If the
+control function signals that the step-size should be decreased the
+evolution function backs out of the current step and tries the proposed
+smaller step-size. This process is continued until an acceptable
+step-size is found.
+
+@deftypefun {gsl_odeiv_evolve *} gsl_odeiv_evolve_alloc (size_t @var{dim})
+This function returns a pointer to a newly allocated instance of an
+evolution function for a system of @var{dim} dimensions.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_evolve_apply (gsl_odeiv_evolve * @var{e}, gsl_odeiv_control * @var{con}, gsl_odeiv_step * @var{step}, const gsl_odeiv_system * @var{dydt}, double * @var{t}, double @var{t1}, double * @var{h}, double @var{y}[])
+This function advances the system (@var{e}, @var{dydt}) from time
+@var{t} and position @var{y} using the stepping function @var{step}.
+The new time and position are stored in @var{t} and @var{y} on output.
+The initial step-size is taken as @var{h}, but this will be modified
+using the control function @var{c} to achieve the appropriate error
+bound if necessary. The routine may make several calls to @var{step} in
+order to determine the optimum step-size. An estimate of
+the local error for the step can be obtained from the components of the array @code{@var{e}->yerr[]}.
+If the step-size has been changed the value of @var{h} will be modified on output.
+The maximum time @var{t1} is guaranteed not to be exceeded by the time-step. On the
+final time-step the value of @var{t} will be set to @var{t1} exactly.
+
+If the user-supplied functions defined in the system @var{dydt} return a
+status other than @code{GSL_SUCCESS} the step will be aborted. In this
+case, @var{t} and @var{y} will be restored to their pre-step values
+and the error code from the user-supplied function will be returned. To
+distinguish between error codes from the user-supplied functions and
+those from @code{gsl_odeiv_evolve_apply} itself, any user-defined return
+values should be distinct from the standard GSL error codes.
+@end deftypefun
+
+@deftypefun int gsl_odeiv_evolve_reset (gsl_odeiv_evolve * @var{e})
+This function resets the evolution function @var{e}. It should be used
+whenever the next use of @var{e} will not be a continuation of a
+previous step.
+@end deftypefun
+
+@deftypefun void gsl_odeiv_evolve_free (gsl_odeiv_evolve * @var{e})
+This function frees all the memory associated with the evolution function
+@var{e}.
+@end deftypefun
+
+@node ODE Example programs
+@section Examples
+@cindex Van der Pol oscillator, example
+The following program solves the second-order nonlinear Van der Pol
+oscillator equation,
+@tex
+\beforedisplay
+$$
+x''(t) + \mu x'(t) (x(t)^2 - 1) + x(t) = 0
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+x''(t) + \mu x'(t) (x(t)^2 - 1) + x(t) = 0
+@end example
+
+@end ifinfo
+@noindent
+This can be converted into a first order system suitable for use with
+the routines described in this chapter by introducing a separate
+variable for the velocity, @math{y = x'(t)},
+@tex
+\beforedisplay
+$$
+\eqalign{
+x' &= y\cr
+y' &= -x + \mu y (1-x^2)
+}
+$$
+\afterdisplay
+@end tex
+@ifinfo
+
+@example
+x' = y
+y' = -x + \mu y (1-x^2)
+@end example
+
+@end ifinfo
+@noindent
+The program begins by defining functions for these derivatives and
+their Jacobian,
+
+@example
+@verbatiminclude examples/ode-initval.c
+@end example
+
+@noindent
+For functions with multiple parameters, the appropriate information
+can be passed in through the @var{params} argument using a pointer to
+a struct.
+
+The main loop of the program evolves the solution from @math{(y, y') =
+(1, 0)} at @math{t=0} to @math{t=100}. The step-size @math{h} is
+automatically adjusted by the controller to maintain an absolute
+accuracy of @c{$10^{-6}$}
+@math{10^@{-6@}} in the function values @var{y}.
+
+@iftex
+@sp 1
+@center @image{vdp,3.4in}
+@center Numerical solution of the Van der Pol oscillator equation
+@center using Prince-Dormand 8th order Runge-Kutta.
+@end iftex
+
+@noindent
+To obtain the values at regular intervals, rather than the variable
+spacings chosen by the control function, the main loop can be modified
+to advance the solution from one point to the next. For example, the
+following main loop prints the solution at the fixed points @math{t = 0,
+1, 2, \dots, 100},
+
+@example
+ for (i = 1; i <= 100; i++)
+ @{
+ double ti = i * t1 / 100.0;
+
+ while (t < ti)
+ @{
+ gsl_odeiv_evolve_apply (e, c, s,
+ &sys,
+ &t, ti, &h,
+ y);
+ @}
+
+ printf ("%.5e %.5e %.5e\n", t, y[0], y[1]);
+ @}
+@end example
+
+@noindent
+It is also possible to work with a non-adaptive integrator, using only
+the stepping function itself. The following program uses the @code{rk4}
+fourth-order Runge-Kutta stepping function with a fixed stepsize of
+0.01,
+
+@example
+@verbatiminclude examples/odefixed.c
+@end example
+
+@noindent
+The derivatives must be initialized for the starting point @math{t=0}
+before the first step is taken. Subsequent steps use the output
+derivatives @var{dydt_out} as inputs to the next step by copying their
+values into @var{dydt_in}.
+
+@node ODE References and Further Reading
+@section References and Further Reading
+
+Many of the basic Runge-Kutta formulas can be found in the Handbook of
+Mathematical Functions,
+
+@itemize @asis
+@item
+Abramowitz & Stegun (eds.), @cite{Handbook of Mathematical Functions},
+Section 25.5.
+@end itemize
+
+@noindent
+The implicit Bulirsch-Stoer algorithm @code{bsimp} is described in the
+following paper,
+
+@itemize @asis
+@item
+G. Bader and P. Deuflhard, ``A Semi-Implicit Mid-Point Rule for Stiff
+Systems of Ordinary Differential Equations.'', Numer.@: Math.@: 41, 373--398,
+1983.
+@end itemize