diff --git a/doc/boost_sandbox_numeric_odeint/concepts/controlled_stepper.html b/doc/boost_sandbox_numeric_odeint/concepts/controlled_stepper.html index f5e3cc46..d493a24a 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/controlled_stepper.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/controlled_stepper.html @@ -31,7 +31,7 @@

A controlled stepper following this Controlled Stepper concept provides the - possibilty to perform one step of the solution x(t) + possibility to perform one step of the solution x(t) of an ODE with step-size dt to obtain x(t+dt) with a given step-size dt. Depending on an error estimate of the solution the step might be rejected and a smaller step-size is suggested. @@ -135,7 +135,7 @@

Tries one step of step size dt. - If the step was succesfull, success + If the step was successful, success is returned, the resulting state is written to x, the new time is stored in t and dt now contains diff --git a/doc/boost_sandbox_numeric_odeint/concepts/dense_output_stepper.html b/doc/boost_sandbox_numeric_odeint/concepts/dense_output_stepper.html index 2e9f4fc9..cd0ab6b3 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/dense_output_stepper.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/dense_output_stepper.html @@ -21,7 +21,7 @@ Output Stepper

- This concept specifies the interface a dense ouput stepper has to fulfill + This concept specifies the interface a dense output stepper has to fulfill to be used within integrate functions.

@@ -30,7 +30,7 @@ Description

- A dense ouput stepper following this Dense Output Stepper concept provides + A dense output stepper following this Dense Output Stepper concept provides the possibility to perform a single step of the solution x(t) of an ODE to obtain x(t+dt). The step-size dt might be adjusted automatically due to error control. Dense output steppers also can interpolate the solution diff --git a/doc/boost_sandbox_numeric_odeint/concepts/observer.html b/doc/boost_sandbox_numeric_odeint/concepts/observer.html index c58f79c1..d43e0d61 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/observer.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/observer.html @@ -119,8 +119,8 @@

- Calls the observer which can do some analyzation of the state - x at time t. + Calls the observer which can do some analysis or output of the + state x at time t.

diff --git a/doc/boost_sandbox_numeric_odeint/concepts/state_algebra_operations.html b/doc/boost_sandbox_numeric_odeint/concepts/state_algebra_operations.html index 3e61e5c6..47f09a54 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/state_algebra_operations.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/state_algebra_operations.html @@ -35,7 +35,7 @@

The following does not apply to implicit steppers like implicit_euler or - rosenbrock 4 as there the state_type + Rosenbrock 4 as there the state_type can not be changed from ublas::vector and no algebra/operations are used.

@@ -672,7 +672,7 @@

Anything that defines operators + within itself and * with scalar - (Mathematically spoken, anyhting that is a vector space). + (Mathematically spoken, anything that is a vector space).

diff --git a/doc/boost_sandbox_numeric_odeint/concepts/stepper.html b/doc/boost_sandbox_numeric_odeint/concepts/stepper.html index c4633fb5..a3d0b621 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/stepper.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/stepper.html @@ -20,7 +20,7 @@ Stepper

- This concepts specifies the interface a simple stepper has to fullfill to + This concepts specifies the interface a simple stepper has to fulfill to be used within the integrate functions.

diff --git a/doc/boost_sandbox_numeric_odeint/concepts/system.html b/doc/boost_sandbox_numeric_odeint/concepts/system.html index d3e50519..7968f3ee 100644 --- a/doc/boost_sandbox_numeric_odeint/concepts/system.html +++ b/doc/boost_sandbox_numeric_odeint/concepts/system.html @@ -27,7 +27,7 @@ The System concept models the algorithmic implementation of the rhs. of the ODE x' = f(x,t). The only requirement for this concept is that it should be callable with a specific parameter syntax (see below). - A System is typically implemented as a function or a functor. Systems fullfilling + A System is typically implemented as a function or a functor. Systems fulfilling this concept are required by all Runge-Kutta steppers as well as the Bulirsch-Stoer steppers. However, symplectic and implicit steppers work with other system concepts, see Symplectic diff --git a/doc/boost_sandbox_numeric_odeint/getting_started/overview.html b/doc/boost_sandbox_numeric_odeint/getting_started/overview.html index 963854c8..d514b137 100644 --- a/doc/boost_sandbox_numeric_odeint/getting_started/overview.html +++ b/doc/boost_sandbox_numeric_odeint/getting_started/overview.html @@ -33,7 +33,7 @@ differential equations. Mathematically, these problems are formulated as follows: x'(t) = f(x,t), x(0) = x0. x and f can be vectors and the - solution is some function x(t) fullfilling both equations + solution is some function x(t) fulfilling both equations above. In the following we will refer to x'(t) also dxdt which is also our notation for the derivative in the source code. @@ -388,7 +388,7 @@

- Standard method with error control and dense ouput, to be used + Standard method with error control and dense output, to be used in controlled_error_stepper and in dense_output_controlled_explicit_fsal.

@@ -676,9 +676,9 @@

- Dense ouput for Stepper + Dense output for Stepper and Error - Stepper from above if they provide dense ouput functionality + Stepper from above if they provide dense output functionality (like euler and runge_kutta_dopri5). Order depends on the given stepper. @@ -778,8 +778,8 @@

- Stepper with step size and order control as well as dense ouput. - Very good if high precision and dense ouput is required. + Stepper with step size and order control as well as dense output. + Very good if high precision and dense output is required.

@@ -936,12 +936,12 @@

- Dense Ouput Rosenbrock 4 + Dense Output Rosenbrock 4

- rosenbrock4_dense_ouput + rosenbrock4_dense_output

@@ -1090,7 +1090,7 @@ differential equations. Be sure, you will find them in every discipline. They also occur if partial differential equations (PDEs) are discretized in one coordinate. Then, a system of coupled ordinary differential occurs, - sometimes also refered as lattices ODEs. + sometimes also referred as lattices ODEs.

diff --git a/doc/boost_sandbox_numeric_odeint/getting_started/short_example.html b/doc/boost_sandbox_numeric_odeint/getting_started/short_example.html index e92f2639..ce13dde4 100644 --- a/doc/boost_sandbox_numeric_odeint/getting_started/short_example.html +++ b/doc/boost_sandbox_numeric_odeint/getting_started/short_example.html @@ -70,7 +70,7 @@ For the integration itself we'll use the integrate function, which is a convenient way to get quick results. It is based on the error-controlled runge_kutta_rk5_ck - stepper (5th order) and uses adaptive stepsize. + stepper (5th order) and uses adaptive step-size.

@@ -84,7 +84,7 @@ above, the initial state x, the start-and end-time of the integration as well as the initial time step. Note, that integrate - uses an adaptive stepsize during the integration steps so the time points + uses an adaptive step-size during the integration steps so the time points will not be equally spaced. The integration returns the number of steps that were applied.

diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/generation_functions.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/generation_functions.html index af9627af..42156507 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/generation_functions.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/generation_functions.html @@ -108,7 +108,7 @@

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

diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/integrate_functions.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/integrate_functions.html index a70d7a85..7648b277 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/integrate_functions.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/integrate_functions.html @@ -41,7 +41,7 @@ observer calls

- If observer calls at equdistant time intervals dt are + If observer calls at equidistant time intervals dt are needed, the integrate_const function should be used.

@@ -271,10 +271,10 @@
Warning

- This function works only with steppers fullfilling the Stepper + This function works only with steppers fulfilling the Stepper or Error Stepper concept! Providing a Controlled - Stepper or __dense_out_stepper results in a compilationerror. + Stepper or __dense_out_stepper results in a compilation error.

@@ -301,7 +301,7 @@ starting at x0 and t0. If provided, observer is called after every step and at the beginning with t0. - This function works only with steppers fullfilling the Stepper + This function works only with steppers fulfilling the Stepper or Error Stepper concept! It performs exactly n steps with fixed step size dt @@ -319,7 +319,7 @@

Additionally to the sophisticated integrate function above odeint also provides a simple integrate routine - which uses a dense ouput stepper based on runge_kutta_dopri5 + which uses a dense output stepper based on runge_kutta_dopri5 with standard error bounds 10-6 for the steps.

diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/state_types__algebras_and_operations.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/state_types__algebras_and_operations.html index f23eede8..b6a33d70 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/state_types__algebras_and_operations.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/state_types__algebras_and_operations.html @@ -33,7 +33,7 @@ the user full control over the state type and the mathematical operations for this state type. Technically, this is done by introducing three concepts: StateType, Algebra, Operations. Most of the steppers in odeint expect three - classes types fullfilling these concepts as template parameters. Note that + classes types fulfilling these concepts as template parameters. Note that these concepts are not fully independent of each other but rather a valid combination must be provided in order to make the steppers work. In the following we will give some examples on reasonable state_type-algebra-operations combinations. @@ -755,7 +755,7 @@

A similar class exists for the const version of the iterator. Then we have a function returning the end iterator - (similarily for const again): + (similarly for const again):

gsl_vector_iterator end_iterator( gsl_vector *x )
 {
@@ -786,7 +786,7 @@
             Again with similar definitions for the const
             versions. This eventually makes odeint work with gsl vectors as state
             types. The full code for these bindings is found in gsl_wrapper.hpp.
-            It might look rather complicated but keep in mind that gsl is a pre compiled
+            It might look rather complicated but keep in mind that gsl is a pre-compiled
             C library so it is quite an achievement that it's possible to get it
             working at all in the first place.
           

@@ -934,7 +934,7 @@

- Definign these operators makes your state type work with any basic Runge-Kutta + Defining these operators makes your state type work with any basic Runge-Kutta stepper. However, if you want to use step-size control, some more functionality is required. Specifically, operations like maxi( |erri| / (alpha * |si|) ) have to be performed. err and @@ -992,7 +992,7 @@

- Calculates the elementwise division 'x/y' + Calculates the element-wise division 'x/y'

@@ -1074,7 +1074,7 @@

As an example for the employment of the vector_space_algebra we will adopt ublas::vector from Boost.UBlas - to work as a state type in odeint. This is particularily easy because + to work as a state type in odeint. This is particularly easy because ublas::vector supports vector-vector addition and scalar-vector multiplication described above as well as boost::size. It also has a resize member function so all that has to be done in this case is to declare resizability: @@ -1230,7 +1230,7 @@ use controlled steppers. For simple steppers definition of the simple += and *= operators are sufficient. Having defined such a point type, we can easily - perform the integration on a lorenz system by using the vector_space_algebra again: + perform the integration on a Lorenz system by using the vector_space_algebra again:

diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/steppers.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/steppers.html index e58d3df5..b7bf08e3 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/steppers.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/steppers.html @@ -40,7 +40,7 @@ own steppers

- Solving ordinary differential equation numerically is ususally done iteratively, + Solving ordinary differential equation numerically is usually done iteratively, that is a given state of an ordinary differential equation is iterated forward x(t) -> x(t+dt) -> x(t+2dt). The steppers in odeint perform one single step. The most general stepper type is described by the @@ -50,7 +50,7 @@ we briefly present the mathematical and numerical details of the steppers. The Stepper has two versions of the do_step - method, one with an in-place transform of the currrent state and one with + method, one with an in-place transform of the current state and one with an out-of-place transform:

@@ -90,7 +90,7 @@

Other types of system function represent Hamiltonian systems or system which - also compute the Jacobian needed in implicit steppers. For informations which + also compute the Jacobian needed in implicit steppers. For information which stepper uses which system function see the stepper table below. It might be possible, that odeint will introduce new system types in near future. Since the system function is strongly related to the stepper type, such an @@ -171,7 +171,7 @@ This method also fills the derivative at time t+dt into dxdtout. Of course, the performance gain of such FSAL steppers only appears when combining - with intergrate error estimation, like in the Runge-Kutta-Dopri5 stepper. + with integrate error estimation, like in the Runge-Kutta-Dopri5 stepper. The FSAL-trick is sometimes also referred as the Fehlberg-Trick. An example how the FSAL steppers can be used is

@@ -221,11 +221,11 @@ A special class of symplectic systems are separable systems which can be written in the form dqdt/dt = f1(p), dpdt/dt = f2(q), where (q,p) are the state of system. - The space of (q,p) is sometimes refered as the phase + The space of (q,p) is sometimes referred as the phase space and q and p are said the be the phase space variables. Symplectic systems in this special form occur widely in nature. For example the complete classical mechanics as written - down by Newton, Lagrange and Hamilton can be forumulated in this framework. + down by Newton, Lagrange and Hamilton can be formulated in this framework. Of course, the separability of the system depends on the specific choice of coordinates.

@@ -233,7 +233,7 @@ Integrable symplectic systems can be solved by odeint by means of the symplectic_euler stepper and a symplectic Runge-Kutta-Nystrom method of sixth-order. These stepper assume that the system is autonomous, hence the time will not explicitly - occur. Furhter they fullfil in principle the default Stepper concept, but + occur. Further they fulfill in principle the default Stepper concept, but they expect the system to be a pair of callable objects. The first entry of this pair calculates f1(p) while the second calculates f2(q). The syntax is sys.first(p,dqdt) @@ -314,7 +314,7 @@ form. This kind of system can be used in the symplectic solvers, by simply passing f(p) to the do_step method, again f(p) will be represented by a simple - C-function or a functor. Here, the above example of the harmonic oscaillator + C-function or a functor. Here, the above example of the harmonic oscillator can be written as

@@ -331,7 +331,7 @@ is exactly the same function as in the above examples.

- Note, that the state of the ODE must not be contructed explicitly via + Note, that the state of the ODE must not be constructed explicitly via pair< vector_type , vector_type > @@ -369,7 +369,7 @@ system possesses two or more time scales of very different order. Solvers for stiff systems are usually implicit, meaning that they solve equations like x(t+dt) = x(t) + dt * f(x(t+1)). This particular - scheme is the implicit euler method. Implicit methods usually solve the + scheme is the implicit Euler method. Implicit methods usually solve the system of equations by a root finding algorithm like the Newton method and therefore need to know the Jacobian of the system J​ij = df​i / dx​j. @@ -392,15 +392,15 @@

Another large class of solvers are multi-step method. They save a small part of the history of the solution and compute the next step with the - help of this history. Since multistep methods know a part of their history + help of this history. Since multi-step methods know a part of their history they do not need to compute the system function very often, usually it - is only computed once. This makes multistep methods preferable if a call + is only computed once. This makes multi-step methods preferable if a call of the system function is expensive. Examples are ODEs defined on networks, where the computation of the interaction is usually where expensive (and might be of order O(N^2)).

- Multistep methods differ from the normal steppers. They safe a part of + Multi-step methods differ from the normal steppers. They safe a part of their history and this part has to be explicitly calculated and initialized. In the following example an Adams-Bashforth-stepper with a history of 5 steps is instantiated and initialized; @@ -429,7 +429,7 @@

- Many multistep methods are also explicit steppers, hence the parameter + Many multi-step methods are also explicit steppers, hence the parameter of do_step method do not differ from the explicit steppers.

@@ -439,7 +439,7 @@ Caution

- The multistep methods have some internal variables which depend on the + The multi-step methods have some internal variables which depend on the explicit solution. Hence you can not exchange the system of the state between two consecutive calls of do_step since then the internal variable do not correspond with the ODE and the @@ -456,7 +456,7 @@

Many of the above introduced steppers possess the possibility to use adaptive - stepsize control. Adaptive step size integration works in principle as + step-size control. Adaptive step size integration works in principle as follows:

    @@ -469,8 +469,8 @@
  1. This error is compared against some predefined error tolerances. Are - the tolerance violated the step is reject and the stepsize is decreases. - Otherwise the step is accepted and possibly the stepsize is increased. + the tolerance violated the step is reject and the step-size is decreases. + Otherwise the step is accepted and possibly the step-size is increased.

@@ -478,8 +478,8 @@ Stepper concept. They are usually constructed from the underlying error steppers. An example is the controller for the explicit Runge-Kutta steppers. The Runge-Kutta steppers enter the controller as a template argument. - Additionally one can pass the Runge-Kutta stepper to the contructor, but - this step is not neccessary; the stepper is default-constructed if possible. + Additionally one can pass the Runge-Kutta stepper to the constructor, but + this step is not necessary; the stepper is default-constructed if possible.

Different step size controlling mechanism exist. They all have in common @@ -491,7 +491,7 @@ in the integration functions.

- A classical way to decide wether a step is rejected or accepted is + A classical way to decide whether a step is rejected or accepted is

val = || | err​i | / ( ε​abs + ε​rel * ( a​x | x​i | + a​dxdt | | dxdt​i | )|| @@ -663,8 +663,9 @@

To ease to generation of the controlled stepper generation functions exist which take the absolute and relative error tolerances and a predefined - error stepper and contruct from this knowledge an appropirate controlled - stepper. The generation functions are explained in detail in XYZ. + error stepper and construct from this knowledge an appropriate controlled + stepper. The generation functions are explained in detail in Generation + functions.

@@ -695,11 +696,11 @@

Dense output stepper have their own concept. The main difference is that they control the state by them-self. If you call do_step, - only the ODE is passed as argument. Furhtermore do_step + only the ODE is passed as argument. Furthermore do_step return the last time interval, hence you interpolate the solution between these two times points. Another difference is that they must be initialized with initialize, otherwise - the internal state of the stepper is default contructed which might produce + the internal state of the stepper is default constructed which might produce funny errors or bugs.

@@ -716,8 +717,8 @@

- Of course, this statement is also lengthly; it demonstrates how make_dense_output can be used with the - result_of protocoll. The + Of course, this statement is also lengthy; it demonstrates how make_dense_output can be used with the + result_of protocol. The parameters to make_dense_output are the absolute error tolerance, the relative error tolerance and the stepper. This explicitly assumes that the underlying stepper is a controlled @@ -739,8 +740,8 @@ steppers

- This section contains some general informations about the usage of the - steppers in odeint. + This section contains some general information about the usage of the steppers + in odeint.

Steppers are copied by value @@ -763,13 +764,13 @@

- Some steppers require to store some informations about the state of the - ODE between two steps. Examples are the multistep method which store a + Some steppers require to store some information about the state of the + ODE between two steps. Examples are the multi-step method which store a part of the solution during the evolution of the ODE, or the FSAL steppers which store the last derivative at time t+dt, to be used in the next step. In both cases the steppers expect that consecutive calls of do_step are from - the same solution and the same ODE. In this case it is absolutely neccessary + the same solution and the same ODE. In this case it is absolutely necessary that you call do_step with the same system function and the same state, see also the examples for the FSAL steppers above. @@ -789,10 +790,10 @@

All these stepper have in common, that they initially fill their internal - state by themself. Hence you are not required to call initialize. See how - this works for the Adams-Bashforth-Moulton stepper: in the example we instantiate - a fourth order Adams-Bashforth-Moulton stepper, meaning that it will store - 4 internal derivatives of the solution at times (t-dt,t-2dt,t-3dt,t-4dt). + state by themselves. Hence you are not required to call initialize. See + how this works for the Adams-Bashforth-Moulton stepper: in the example + we instantiate a fourth order Adams-Bashforth-Moulton stepper, meaning + that it will store 4 internal derivatives of the solution at times (t-dt,t-2dt,t-3dt,t-4dt).

@@ -826,7 +827,7 @@ all stepper have a method adjust_size which takes a parameter representing a state type and which manually adjusts the size of the internal variables. Before performing the actual resizing - odeint always checks if the sizes of the state and the interal variable + odeint always checks if the sizes of the state and the internal variable differ and only resizes if they are different.

@@ -836,7 +837,7 @@ system and your state you have to call adjust_size by hand. The second resizer is the always_resizer which tries to resize the internal variables at every call of do_step. Typical use cases for this kind - of resizer are self expanding lattics like shown in the tutorial or partial + of resizer are self expanding lattices like shown in the tutorial or partial differential equations with an adaptive grid. The third class of resizer is the never_resizer which means that the internal variables are never adjusted automatically and @@ -844,15 +845,13 @@

There is a second mechanism which influences the resizing and which controls - if a state type is at least resizeable - a metafunction is_resizeable. - This metafunction returns a static boolean value if any type is resizable. - For example it will return true - for std::vector< - T > - but false for tr1::array< T >. + if a state type is at least resizeable - a meta-function is_resizeable. This meta-function returns + a static boolean value if any type is resizable. For example it will return + true for std::vector< T > but false + for tr1::array< T >. By default and for unknown types is_resizeable returns false, so if you have - your own type you need to specialize this metafunction. For more details + your own type you need to specialize this meta-function. For more details on the resizing mechanism see the section Adapt you own state types.

@@ -875,7 +874,7 @@
  • runge_kutta4 is a good stepper for constant step sizes. It is widely used and very well known. - If you need to create artifical time series this stepper should be + If you need to create artificial time series this stepper should be the first choice.
  • @@ -1193,7 +1192,7 @@

    - Standard method with error control and dense ouput, to be used + Standard method with error control and dense output, to be used in controlled_error_stepper and in dense_output_controlled_explicit_fsal.

    @@ -1481,9 +1480,9 @@

    - Dense ouput for Stepper + Dense output for Stepper and Error - Stepper from above if they provide dense ouput functionality + Stepper from above if they provide dense output functionality (like euler and runge_kutta_dopri5). Order depends on the given stepper. @@ -1583,8 +1582,8 @@

    - Stepper with step size and order control as well as dense ouput. - Very good if high precision and dense ouput is required. + Stepper with step size and order control as well as dense output. + Very good if high precision and dense output is required.

    @@ -1741,12 +1740,12 @@

    - Dense Ouput Rosenbrock 4 + Dense Output Rosenbrock 4

    - rosenbrock4_dense_ouput + rosenbrock4_dense_output

    @@ -1899,12 +1898,12 @@

    Of course, one can write own steppers which are fully compatible with odeint. - They only have to fullfil one or several of the stepper Concepts + They only have to fulfill one or several of the stepper Concepts of odeint.

    We will illustrate how to write your own stepper with the example of the - stochastic euler method. This method is suited to solve stochastic differential + stochastic Euler method. This method is suited to solve stochastic differential equations (SDEs). A SDE has the form

    @@ -1918,8 +1917,8 @@ the SDE is said to have additive noise. It is not possible to solve SDE with the classical solvers for ODEs since the noisy part of the SDE has to be scaled differently then the deterministic part with respect to the - time step. BUt there exist many solvers for SDEs. A classical and easy - method is the stochastic euler solver. It works by iterating + time step. But there exist many solvers for SDEs. A classical and easy + method is the stochastic Euler solver. It works by iterating

    x(t+Δ t) = x(t) + Δ t f(x(t)) + Δ t1/2 g(x) ξ(t) @@ -1953,7 +1952,7 @@

    The types are needed in order to fulfill the stepper concept. As internal - state and deriv type we use simple arrays in the stochastic euler, they + state and deriv type we use simple arrays in the stochastic Euler, they are needed for the temporaries. The stepper has the order one which is returned from the order() function.

    @@ -1988,7 +1987,7 @@

    - This is all. It is quite simple and the stochastic euler stepper implement + This is all. It is quite simple and the stochastic Euler stepper implement here is quite general. Of course it can be enhanced, for example

      @@ -2018,7 +2017,7 @@

      where ξ is Gaussian white noise with standard deviation σ. Implementing the Ornstein-Uhlenbeck process is quite simple. We need two - functions or funtors - one for the deterministic and one for the stochastic + functions or functors - one for the deterministic and one for the stochastic part:

      diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__range.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__range.html index 908503b2..7890a0f9 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__range.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__range.html @@ -22,7 +22,7 @@

    Most steppers in odeint also accept the state give as a range. A range is - sequence of values modelled by a range concept. See Boost.Range + sequence of values modeled by a range concept. See Boost.Range for an overview over existing concepts and examples of ranges. This means that the state_type of the stepper must not necessarily used to call the do_step @@ -40,7 +40,7 @@

    Another use case is a system consisting of coupled units where you want to initialize each unit separately with the ODE of the uncoupled unit. An example - is a chain of coupled van-der-Pol-oscillators which are initialized uniformily + is a chain of coupled van-der-Pol-oscillators which are initialized uniformly from the uncoupled van-der-Pol-oscillator. Then you can use Boost.Range to solve only one individual oscillator in the chain.

    @@ -207,8 +207,8 @@
    -

    Table 1.11. Algebra supporting Boost.Range

    -
    +

    Table 1.11. Algebras supporting Boost.Range

    +
    diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/chaotic_systems_and_lyapunov_exponents.html b/doc/boost_sandbox_numeric_odeint/tutorial/chaotic_systems_and_lyapunov_exponents.html index 566791b9..a35a275a 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/chaotic_systems_and_lyapunov_exponents.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/chaotic_systems_and_lyapunov_exponents.html @@ -37,16 +37,16 @@ system. In principle n of these perturbations exit, they form a hypercube and evolve in the time. The Lyapunov exponents are then defined as logarithmic growth rates of the perturbations. If one Lyapunov - exponent is larger then zero nearby trajectories divergy exponentially hence + exponent is larger then zero nearby trajectories diverge exponentially hence they are chaotic. If the largest Lyapunov exponent is zero one is usually faced with periodic motion. In the case of a largest Lyapunov exponent smaller - then zero the converges the a fixed point. More informations about Lyapunov + then zero the converges the a fixed point. More information's about Lyapunov exponents and nonlinear dynamical systems can be found in many textbooks, see for example .

    To calculate the Lyapunov exponents numerically one usually solves the equations - of motion for n perturbations und orthonormalized them + of motion for n perturbations and orthonormalizes them every k steps. The Lyapunov exponent is the average the logarithm of the stretching factor of each perturbation.

    @@ -78,7 +78,7 @@

    We need also need to integrate the set of the perturbations. This is done in parallel to the original system, hence within one system function. Of - course, we want to use the above defintion of the Lorenz system, hence the + course, we want to use the above definition of the Lorenz system, hence the definition of the system function including the Lorenz system itself and the perturbation could look like:

    @@ -161,7 +161,7 @@ The problem is now, that x is the full state containing also the perturbations and integrate_n_steps does not know that it should only use 3 element. In detail, odeint and its - steppers determine the length of the system under consideration be determing + steppers determine the length of the system under consideration be determining the length of the state. In the classical solvers from the problem was solved by pointer to the state and an appropriate length, something similar to

    @@ -219,7 +219,7 @@
  • We initialize the perturbations. They are stored linearly behind the state of the Lorenz system. The perturbation are initialized such that - they fullfill < p ​i , p​j > = δ ​ij where <,> + they fulfill < p ​i , p​j > = δ ​ij where <,> is the classical scalar product and δ ​ij is the Kronecker symbol.
  • diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/harmonic_oscillator.html b/doc/boost_sandbox_numeric_odeint/tutorial/harmonic_oscillator.html index 5332e1bd..1a68df0f 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/harmonic_oscillator.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/harmonic_oscillator.html @@ -36,12 +36,12 @@ the ODE

    - First of all, you have to specify the datatype that represents a state + First of all, you have to specify the data type that represents a state of your system x. Mathematically, this usually is an n-dimensional vector with real numbers or complex numbers as scalar objects. For odeint the most natural way is to use vector< double > or vector< complex< double > > to represent the system state. However, odeint can deal with other container - types as well, e.g. tr1::array< double , N > as long as it is fullfils some requirements + types as well, e.g. tr1::array< double , N > as long as it is fulfills some requirements defined below.

    @@ -108,10 +108,10 @@

    Numerical integration works iteratively, that means you start at a state - x(t) and perform a timestep of length dt + x(t) and perform a time-step of length dt to obtain the approximate state x(t+dt). There exist - many different methods to perform such a timestep each of which has a certain - order q. If the order of a method is q + many different methods to perform such a time-step each of which has a + certain order q. If the order of a method is q than it is accurate up to term ~dtq that means the error in x made by such a step is ~dtq+1. odeint provides several steppers of different orders from which you can @@ -414,7 +414,7 @@

    @@ -702,9 +702,9 @@ @@ -962,12 +962,12 @@

    diff --git a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__ref.html b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__ref.html index deb6f3fc..0a058e10 100644 --- a/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__ref.html +++ b/doc/boost_sandbox_numeric_odeint/odeint_in_detail/using_boost__ref.html @@ -33,7 +33,7 @@

    - This behaviour is suitable for most systems, especially if your system only + This behavior is suitable for most systems, especially if your system only does not contain any data or only a few parameters. However, in some cases you might pass some large amount of data with you system function and passing them by value is not desired since the data will be copied. @@ -41,8 +41,8 @@

    In such cases you can easily use boost::ref (and its relative boost::cref) which passes its argument by reference - (or const reference). odeint will unpack the arguments and no copying at - all of you system will take place: + (or constant reference). odeint will unpack the arguments and no copying + at all of you system will take place:

    diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/all_examples.html b/doc/boost_sandbox_numeric_odeint/tutorial/all_examples.html index 3051d566..673e40a5 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/all_examples.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/all_examples.html @@ -155,7 +155,7 @@

    - The 2D phase oscillator example shows how a two-dimenstional lattice + The 2D phase oscillator example shows how a two-dimensional lattice can used with odeint and how matrix types can be used as state types in odeint.

    @@ -210,7 +210,7 @@

    - The Lorenz paramaters examples show how ensembles of ordinary differential + The Lorenz parameters examples show how ensembles of ordinary differential equations can be solved by means of Thrust to study the dependence of an ODE on some parameters.

    @@ -224,7 +224,7 @@

    - The MTL-Gauss-packet example shows how the mtl can be easily used + The MTL-Gauss-packet example shows how the MTL can be easily used with odeint.

    - Standard method with error control and dense ouput, to be used + Standard method with error control and dense output, to be used in controlled_error_stepper and in dense_output_controlled_explicit_fsal.

    - Dense ouput for Stepper + Dense output for Stepper and Error - Stepper from above if they provide dense ouput functionality + Stepper from above if they provide dense output functionality (like euler and runge_kutta_dopri5). Order depends on the given stepper. @@ -804,8 +804,8 @@

    - Stepper with step size and order control as well as dense ouput. - Very good if high precision and dense ouput is required. + Stepper with step size and order control as well as dense output. + Very good if high precision and dense output is required.

    - Dense Ouput Rosenbrock 4 + Dense Output Rosenbrock 4

    - rosenbrock4_dense_ouput + rosenbrock4_dense_output

    @@ -1124,15 +1124,16 @@ with Constant Step Size

    - The basic stepper just performs one timestep and doesn't give you any information - about the error that was made (except that you know it is of order q+1). - Such steppers are used with constant step size that should be chosen small - enough to have reasonable small errors. However, you should apply some - sort of validity check of your results (such as observing conserved quantities) - becasue you have no other control of the error. The following example defines - a basic stepper based on the classical Runge-Kutta scheme of 4th order. - The declaration of the stepper requires the state type as template parameter. - The integration can now be done by using the integrate_const( Stepper, System, state, start_time, end_time, step_size + The basic stepper just performs one time-step and doesn't give you any + information about the error that was made (except that you know it is of + order q+1). Such steppers are used with constant step + size that should be chosen small enough to have reasonable small errors. + However, you should apply some sort of validity check of your results (such + as observing conserved quantities) because you have no other control of + the error. The following example defines a basic stepper based on the classical + Runge-Kutta scheme of 4th order. The declaration of the stepper requires + the state type as template parameter. The integration can now be done by + using the integrate_const( Stepper, System, state, start_time, end_time, step_size ) function from odeint:

    @@ -1145,7 +1146,7 @@

    This call integrates the system defined by harmonic_oscillator using the RK4 method from t=0 to 10 - with a stepsize dt=0.01 and the initial condition + with a step-size dt=0.01 and the initial condition given in x. The result, x(t=10) is stored in x (in-place). Each stepper defines a do_step @@ -1207,7 +1208,7 @@ This is a nice technique; however one drawback is that one always needs to define both steppers. Of course, one could also write the instantiation of the controlled stepper into the call of the integrate function but a - complete knowledge of the underlying stepper types is still neccessary. + complete knowledge of the underlying stepper types is still necessary. Another point is, that the error tolerances for the step size control are not easily included into the controlled stepper. Both issues can be solved by using make_controlled: @@ -1257,7 +1258,7 @@

    In the tables below, one can find all steppers which are working with - make_controlled and make_dense_output which is the analogon + make_controlled and make_dense_output which is the analog for the dense output steppers.

    diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/references.html b/doc/boost_sandbox_numeric_odeint/tutorial/references.html index 86871b10..2c041023 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/references.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/references.html @@ -20,7 +20,7 @@ References

    - General informations about numerical integration of + General information about numerical integration of ordinary differential equations:

    diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/solar_system.html b/doc/boost_sandbox_numeric_odeint/tutorial/solar_system.html index 927dddd0..1449f43b 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/solar_system.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/solar_system.html @@ -81,7 +81,7 @@ to ensure these conservation laws. The odeint library provides classes for separable Hamiltonian systems, which can be written in the form H = Σ p​i2 / (2m​i) + H​q(q), where H​q(q) only - depends on the coordinates. Alltough this functional form might look a + depends on the coordinates. Although this functional form might look a bit arbitrary it covers nearly all classical mechanical systems with inertia and without dissipation, or where the equations of motion can be written in the form dq​i / dt = p​i / m​i , dp​i / dt = @@ -151,7 +151,7 @@ pair< container_type , container_type > - since it needs the informations about the coordinates and the momenta. + since it needs the information about the coordinates and the momenta.

    As system function we have to provide f(p) and f(q): @@ -206,7 +206,7 @@

    In general a three body-system is chaotic, hence we can not expect that - arbitray initial conditions of the system will lead to a dynamic which + arbitrary initial conditions of the system will lead to a dynamic which is comparable with the solar system. That is we have to define proper initial conditions, which are taken from the book of Hairer, Wannier, Lubich.

    diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/special_topics.html b/doc/boost_sandbox_numeric_odeint/tutorial/special_topics.html index e6697b7d..009676b3 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/special_topics.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/special_topics.html @@ -84,7 +84,7 @@

    - Of courst, one can also use classical functions to implement the state + Of course, one can also use classical functions to implement the state function. In this cast the Stuart-Landau oscillator looks like

    @@ -148,7 +148,7 @@ The FPU is solved again by a symplectic solver, but in our case we can speed up the computation because the q components trivially reduce to dq​i / dt = p​i. odeint is capable - of doing this peformance improvement. All you have to do is to call the + of doing this performance improvement. All you have to do is to call the symplectic solver with an state function for the p components. Here, is how this function looks like

    @@ -281,10 +281,10 @@ ​k / dt = ω​k + ε / N Σ​j sin( φ​j - φ​k )

    - The natural frequencies ω​i of each oscialltor follow + The natural frequencies ω​i of each oscillator follow some distribution and ε is the coupling strength. We choose here a Lorentzian distribution for ω​i. Interestingly - a phase transition can be observed if the coupling strenght exceeds a critical + a phase transition can be observed if the coupling strength exceeds a critical value. Above this value synchronization sets in and some of the oscillators oscillate with the same frequency despite their different natural frequencies. The transition is also called Kuramoto transition. Its behavior can be @@ -486,7 +486,7 @@ Note, that the state_type and the deriv_type are now a compile-time fusion sequences. They have to be explicitly defined. - Next, we define the ordinary differential equation which is completety + Next, we define the ordinary differential equation which is completely equivalent to the example in the first section of this tutorial

    @@ -588,7 +588,7 @@

    By default, odeint can be used with ublas::matrix< T > as state type for matrices. A simple example is a two-dimensional lattice of coupled phase oscillators. We like - phas oscillators, they are extremly easy and might serve for different + phase oscillators, they are extremely easy and might serve for different demonstration purposes. Other matrix types like mtl::dense_matrix or blitz arrays and matrices can used as well but need some kind of activation in order to work with odeint. This activation is described in following @@ -678,7 +678,7 @@ double, complex< double > you can also use arbitrary precision types, like the types from gmp and mpfr. But you have to be - carful about instantiating any numbers. + careful about instantiating any numbers.

    For gmp types you have to set the default precision before any number is @@ -766,8 +766,8 @@ and adjust it's internal storage accordingly.

    - We exemplarily show this for a Hamiltonian system of nonlinear, disordered - oscillators with nonlinear nearest neighbour coupling. + We exemplary show this for a Hamiltonian system of nonlinear, disordered + oscillators with nonlinear nearest neighbor coupling.

    The system function is implemented in terms of a class that also provides diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/stiff_systems.html b/doc/boost_sandbox_numeric_odeint/tutorial/stiff_systems.html index a874b455..b98d79c9 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/stiff_systems.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/stiff_systems.html @@ -24,7 +24,7 @@ An important class of ordinary differential equations are so called stiff system which are characterized by two or more time scales of different order. Examples of such systems are found in chemical systems where reaction rates - of individual subreaction might differ over large ranges. + of individual sub-reaction might differ over large ranges.

    CHECK: diff --git a/doc/boost_sandbox_numeric_odeint/tutorial/using_cuda_and_thrust.html b/doc/boost_sandbox_numeric_odeint/tutorial/using_cuda_and_thrust.html index ba716c69..51670ea6 100644 --- a/doc/boost_sandbox_numeric_odeint/tutorial/using_cuda_and_thrust.html +++ b/doc/boost_sandbox_numeric_odeint/tutorial/using_cuda_and_thrust.html @@ -82,7 +82,7 @@ perfectly suited for such kinds of problems where one needs a large number of particles (oscillators). We start by defining the state type which is a thrust::device_vector. The content of this vector - lives on the GPU. If you are not familar with this we recommend reading + lives on the GPU. If you are not familiar with this we recommend reading the Getting started section on the Thrust website.

    @@ -317,7 +317,7 @@ In principle we can use all the techniques from the previous phase oscillator ensemble example, but we have to take special care about the coupling of the oscillators. To efficiently implement the coupling you can use a very - elegant way employing Thrust's permutation iterator. A permuation iterator + elegant way employing Thrust's permutation iterator. A permutation iterator behaves like a normal iterator on a vector but it does not iterate along the usual order of the elements. It rather iterates along some permutation of the elements defined by some index map. To realize the nearest neighbor @@ -402,9 +402,9 @@ Note, how easy you can obtain the value for the left and right neighboring oscillator in the system functor using the permutation iterators. But, the call of the thrust::for_each - function looks relativ complicated. Every term of the r.h.s. of the ODE - is resembled by one iterator packed in exactly the same way as it is unpacked - in the functor above. + function looks relatively complicated. Every term of the r.h.s. of the + ODE is resembled by one iterator packed in exactly the same way as it is + unpacked in the functor above.

    Now we put everything together. We create random initial conditions and @@ -456,8 +456,8 @@ and Cuda are parameter studies of relatively small systems. Consider for example the three-dimensional Lorenz system from the chaotic systems example in the previous section which has three parameters. If you want to study - the behaviour of this system for different parameters you usually have - to integrate the system for many parameter values. Using thrust and odeint + the behavior of this system for different parameters you usually have to + integrate the system for many parameter values. Using thrust and odeint you can do this integration in parallel, hence you integrate a whole ensemble of Lorenz systems where each individual realization has a different parameter value. @@ -465,7 +465,7 @@

    In the following we will show how you can use Thrust to integrate the above mentioned ensemble of Lorenz systems. We will vary - only the parameter β but it is straightfoward to vary + only the parameter β but it is straightforward to vary other parameters or even two or all three parameters. Furthermore, we will use the largest Lyapunov exponent to quantify the behavior of the system (chaoticity). @@ -551,7 +551,7 @@ The length of the state is 3N where N is the number of systems. The system is encoded into this vector such that all x components come first, then every y - compoents and finally every z components. Implementing + components and finally every z components. Implementing the device function is then a simple task, you only have to decompose the tuple originating from the zip iterators.

    @@ -559,7 +559,7 @@ Besides the system without perturbations we furthermore need to calculate the system including linearized equations governing the time evolution of small perturbations. Using the method from above this is straightforward, - with a small difficulty that thrust's tuples have a maximal arity of 10. + with a small difficulty that Thrust's tuples have a maximal arity of 10. But this is only a small problem since we can create a zip iterator packed with zip iterators. So the top level zip iterator contains one zip iterator for the state, one normal iterator for the parameter, and one zip iterator @@ -604,10 +604,10 @@ We initialize them such that x=y=z=10, dx=1, and dy=dz=0. We define a stepper type, a controlled Runge-Kutta Dormand-Prince 5 stepper. We start with some integration to - overcome the transient behavior. For this, we do not involve the pertubation + overcome the transient behavior. For this, we do not involve the perturbation and run the algorithm only on the state x,y,z without any observer. Note, how Boost.Range - is used for partial integration of the state vector without pertubations + is used for partial integration of the state vector without perturbations (the first half of the whole state). After the transient, the full system with perturbations is integrated and the Lyapunov exponents are calculated and written to stdout. diff --git a/doc/index.html b/doc/index.html index 4aeac1c7..52cf60e0 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,20 +1,20 @@ -Chapter 1. boost.sandbox.numeric.odeint +Chapter 1. Boost.Numeric.Odeint - - + +

    -
    Next
    +
    Next
    - +

    Last revised: April 16, 2012 at 06:44:03 GMT

    Last revised: May 21, 2012 at 21:01:33 GMT


    -
    Next
    +
    Next
    diff --git a/doc/odeint/reference.html b/doc/odeint/reference.html index e8a7c0df..e773413a 100644 --- a/doc/odeint/reference.html +++ b/doc/odeint/reference.html @@ -4,16 +4,15 @@ Reference - - - - + + +

    -PrevUpHomeNext +PrevUpHome

    Reference

    @@ -28,7 +27,7 @@

    -PrevUpHomeNext +PrevUpHome
    diff --git a/libs/numeric/odeint/doc/concepts/controlled_stepper.qbk b/libs/numeric/odeint/doc/concepts/controlled_stepper.qbk index c56c323d..e8be60c9 100644 --- a/libs/numeric/odeint/doc/concepts/controlled_stepper.qbk +++ b/libs/numeric/odeint/doc/concepts/controlled_stepper.qbk @@ -4,7 +4,7 @@ This concept specifies the interface a controlled stepper has to fulfill to be u [heading Description] -A controlled stepper following this Controlled Stepper concept provides the possibilty to perform one step of the solution /x(t)/ of an ODE with step-size /dt/ to obtain /x(t+dt)/ with a given step-size /dt/. +A controlled stepper following this Controlled Stepper concept provides the possibility to perform one step of the solution /x(t)/ of an ODE with step-size /dt/ to obtain /x(t+dt)/ with a given step-size /dt/. Depending on an error estimate of the solution the step might be rejected and a smaller step-size is suggested. [heading Notation] @@ -23,7 +23,7 @@ Depending on an error estimate of the solution the step might be rejected and a [table [[Name] [Expression] [Type] [Semantics]] - [[Do step] [`stepper.try_step( sys , x , t , dt )`] [`controlled_step_result`] [Tries one step of step size `dt`. If the step was succesfull, `success` is returned, the resulting state is written to `x`, the new time is stored in `t` and `dt` now contains a new (possibly larger) step-size for the next step. If the error was too big, `rejected` is returned and the results are neglected - `x` and `t` are unchanged and `dt` now contains a reduced step-size to be used for the next try.] ] + [[Do step] [`stepper.try_step( sys , x , t , dt )`] [`controlled_step_result`] [Tries one step of step size `dt`. If the step was successful, `success` is returned, the resulting state is written to `x`, the new time is stored in `t` and `dt` now contains a new (possibly larger) step-size for the next step. If the error was too big, `rejected` is returned and the results are neglected - `x` and `t` are unchanged and `dt` now contains a reduced step-size to be used for the next try.] ] [[Do step with reference] [`stepper.try_step( boost::ref(sys) , x , t , dt )`] [`void`] [Same as above with `System` as reference] ] ] diff --git a/libs/numeric/odeint/doc/concepts/dense_output_stepper.qbk b/libs/numeric/odeint/doc/concepts/dense_output_stepper.qbk index 627b74e9..16562d34 100644 --- a/libs/numeric/odeint/doc/concepts/dense_output_stepper.qbk +++ b/libs/numeric/odeint/doc/concepts/dense_output_stepper.qbk @@ -1,9 +1,9 @@ [section Dense Output Stepper] -This concept specifies the interface a dense ouput stepper has to fulfill to be used within __integrate_functions. +This concept specifies the interface a dense output stepper has to fulfill to be used within __integrate_functions. [heading Description] -A dense ouput stepper following this Dense Output Stepper concept provides the possibility to perform a single step of the solution /x(t)/ of an ODE to obtain /x(t+dt)/. +A dense output stepper following this Dense Output Stepper concept provides the possibility to perform a single step of the solution /x(t)/ of an ODE to obtain /x(t+dt)/. The step-size `dt` might be adjusted automatically due to error control. Dense output steppers also can interpolate the solution to calculate the state /x(t')/ at any point /t <= t' <= t+dt/. diff --git a/libs/numeric/odeint/doc/concepts/observer.qbk b/libs/numeric/odeint/doc/concepts/observer.qbk index 02fa96bd..1d15d1b8 100644 --- a/libs/numeric/odeint/doc/concepts/observer.qbk +++ b/libs/numeric/odeint/doc/concepts/observer.qbk @@ -21,7 +21,7 @@ Provided to an `integrate` function, observers are called at each time step, at [table [[Name] [Expression] [Type] [Semantics]] - [[Perform the observation] [`obs( x , t )`] [`void`] [Calls the observer which can do some analyzation of the state /x/ at time /t/.] ] + [[Perform the observation] [`obs( x , t )`] [`void`] [Calls the observer which can do some analysis or output of the state /x/ at time /t/.] ] ] [endsect] \ No newline at end of file diff --git a/libs/numeric/odeint/doc/concepts/state_algebra_operations.qbk b/libs/numeric/odeint/doc/concepts/state_algebra_operations.qbk index 7315e5f9..471804ed 100644 --- a/libs/numeric/odeint/doc/concepts/state_algebra_operations.qbk +++ b/libs/numeric/odeint/doc/concepts/state_algebra_operations.qbk @@ -1,6 +1,6 @@ [section State Algebra Operations] -[note The following does not apply to implicit steppers like implicit_euler or rosenbrock 4 as there the `state_type` can not be changed from `ublas::vector` and no algebra/operations are used.] +[note The following does not apply to implicit steppers like implicit_euler or Rosenbrock 4 as there the `state_type` can not be changed from `ublas::vector` and no algebra/operations are used.] [heading Description] @@ -91,7 +91,7 @@ In the following we list the existing `Algebra`/`Operations` configurations that [[`State`] [`Algebra`] [`Operations`] [Remarks]] [[Anything supporting __boost_range, like `std::vector`, `std::list`, `boost::array`,... based on a `value_type` that supports operators +,* (typically `double`)] [`range_algebra`] [`default_operations`] [Standard implementation, applicable for most typical situations.]] [[`boost::array` based on a `value_type` that supports operators +,*] [`array_algebra`] [`default_operations`] [Special implementation for boost::array with better performance than `range_algebra`]] - [[Anything that defines operators + within itself and * with scalar (Mathematically spoken, anyhting that is a vector space).] [`vector_space_algebra`] [`default_operations`] [For the use of __controlled_stepper, the template `vector_space_reduce` has to be instantiated.]] + [[Anything that defines operators + within itself and * with scalar (Mathematically spoken, anything that is a vector space).] [`vector_space_algebra`] [`default_operations`] [For the use of __controlled_stepper, the template `vector_space_reduce` has to be instantiated.]] [[`thrust::device_vector`, `thrust::host_vector`] [`thrust_algebra`] [`thrust_operations`] [For running odeint on CUDA devices by using __thrust]] [[`boost::array` or anything which allocates the elements in a C-like manner] [`vector_space_algebra`] [`mkl_operations`] [Using the __intel_mkl in odeint for maximum performance. Currently, only the RK4 stepper is supported.]] ] diff --git a/libs/numeric/odeint/doc/concepts/stepper.qbk b/libs/numeric/odeint/doc/concepts/stepper.qbk index af93044e..76f5165d 100644 --- a/libs/numeric/odeint/doc/concepts/stepper.qbk +++ b/libs/numeric/odeint/doc/concepts/stepper.qbk @@ -1,6 +1,6 @@ [section Stepper] -This concepts specifies the interface a simple stepper has to fullfill to be used within the __integrate_functions. +This concepts specifies the interface a simple stepper has to fulfill to be used within the __integrate_functions. [heading Description] diff --git a/libs/numeric/odeint/doc/concepts/system.qbk b/libs/numeric/odeint/doc/concepts/system.qbk index 1a42119b..e0f432bf 100644 --- a/libs/numeric/odeint/doc/concepts/system.qbk +++ b/libs/numeric/odeint/doc/concepts/system.qbk @@ -5,7 +5,7 @@ The System concept models the algorithmic implementation of the rhs. of the ODE ['x' = f(x,t)]. The only requirement for this concept is that it should be callable with a specific parameter syntax (see below). A System is typically implemented as a function or a functor. -Systems fullfilling this concept are required by all Runge-Kutta steppers as well as the Bulirsch-Stoer steppers. +Systems fulfilling this concept are required by all Runge-Kutta steppers as well as the Bulirsch-Stoer steppers. However, symplectic and implicit steppers work with other system concepts, see __symplectic_system and __implicit_system. [heading Notation] diff --git a/libs/numeric/odeint/doc/concepts_old.qbk b/libs/numeric/odeint/doc/concepts_old.qbk deleted file mode 100644 index e4f2f4b3..00000000 --- a/libs/numeric/odeint/doc/concepts_old.qbk +++ /dev/null @@ -1,270 +0,0 @@ -[section Old Concepts] - -The odeint library defines three concepts for stepping objects. - -[/ - -[section Dynamical system] - -The dynamical system represents the right hand side of the differential equation: - -[* x'(t) = f(x(t) , t)] - -In this odeint library the dynamical system is realized by a callable object, -e.g. a function pointer, a functor or an instance of an object with an -appropriate `()`-operator. -The parameter structure has to be the following: - -`(const container_type &x, container_type &dxdt, const time_type t)` - -`x` is the current state of the system and `t` is the current time. -The result *x' = f(x,t)* is then returned in `dxdt`. -See the tutorial for examples on how to define the dynamical system. - -[endsect] - -] - - - -[section Basic stepper] - -Basic steppers execute one timestep of a specific order with a given stepsize. -They usually allocate internal memory to store intermediate function call -results. -If state types with variable size are used (e.g. `vector`), it has to be assured -that the stepper gets informed about any change of the state size by calling its -`adjust_size` method. - -[*Associated Types] -[table - [[] [] [Description]] - [[Time] [Stepper::time_type] [Type of the time variable, e.g. `double`]] - [[Container] [Stepper::container_type] [Type of the system state, e.g. `vector`]] - [[Value] [Stepper::value_type] [Value type of the state, e.g. `double`]] - [[Order Type] [Stepper::order_type] [Type of the order parameter, usually `unsigned short`]] -] - -[*Methods] - -*`Stepper()` Constructor. - -*`Stepper( container_type &x )` Constructor that allocates internal memory to -store intermediate results of the same size as `x`. - -*`void do_step( DynamicalSystem &system , - container_type &x , - time_type t , - time_type dt )` - -Executes one timestep with the given parameters: -[table - [[Parameter] [Type] [Description]] - [[system] [DynamicalSystem] [Function (callable object) that computes the rhs of the ode]] - [[x] [container_type] [The current state of the system *x(t)*]] - [[t] [time_type] [The current time *t*]] - [[dt] [time_type] [Length of the timestep to be executed]] -] -The result of this method is the (approximate) state of the system *x(t+dt)* and -is stored in the variable `x` (in-place). -Note, that the time `t` is not automatically increased by this method. - -*`void do_step( DynamicalSystem &system , - container_type &x , - const container_type &dxdt , - time_type t , - time_type dt )` - -The same as above but with the additional parameter `dxdt` that represents the -derivative [*x'(t) = f(x,t)] at the time *t*. - -*`void adjust_size( const container_type &x )` -Adjusts the internal memory to store intermediate results of the same size as -`x`. -This function /must/ be called whenever the system size changes during the -integration. - -*`order_type order_step()` -Returns the order of the algorithm. If *n* is the order of a method, then the -result of one iteration with the timestep *dt* is accurate up to *dt^n*. That -means the error made by the time discretization is of order *dt^(n+1)*. - -[*Stepper that model this concept] - -*`stepper_euler` -*`stepper_rk4` -*`stepper_rk78_fehlberg` - -[endsect] - -[section Error stepper] - -Error steppers execute one timestep of a specific order with a given stepsize. -Additionally, an error estimation of the obtained result is computed that can -be used to control the error introduced by the time discretization. -Like the basic steppers, error steppers usually allocate internal memory to store -intermediate function call results. If state types with variable size are used -(e.g. `vector`), it has to be assured that the stepper gets informed about any -change of the state size by calling its `adjust_size` method. - -[*Associated Types] - -Same as for /basic steppers/ above. - -[*Methods] - -*`Error_Stepper()` Constructor. - -*`Error_Stepper( container_type &x )` Constructor that allocates internal memory to -store intermediate results of the same size as `x`. - -*`void do_step( DynamicalSystem &system , - container_type &x , - time_type t , - time_type dt , - container_type &xerr)` - -Executes one timestep with the given parameters: -[table - [[Parameter] [Type] [Description]] - [[system] [DynamicalSystem] [Function (callable object) that computes the rhs of the ode]] - [[x] [container_type] [The current state of the system *x(t)*]] - [[t] [time_type] [The current time *t*]] - [[dt] [time_type] [Length of the timestep to be executed]] - [[xerr] [container_type] [Used by the method to return the error estimation of this computation]] -] -The result of this method is the (approximate) state of the system *x(t+dt)*, -which is returned in the variable `x` (in-place), and the corresponding error -estimation returned in `xerr`. -Note, that the time `t` is not automatically increased by this method. - -*`void do_step( DynamicalSystem &system , - container_type &x , - const container_type &dxdt , - time_type t , - time_type dt , - container_type &xerr)` - -The same as above but with the additional parameter `dxdt` that represents the -derivative [*x'(t) = f(x,t)] at the time *t*. - -*`void adjust_size( const container_type &x )` -Adjusts the internal memory to store intermediate results of the same size as -`x`. -This function /must/ be called whenever the system size changes during the -integration. - -*`order_type order_error_step()` -Returns the order of the result *x(t+dt)* of the algorithm. - -*`order_type order_error()` -Returns the order of the error estimation of the algorithm. - -[*Stepper that model this concept] - -*`stepper_rk5_ck` -*`stepper_rk78_fehlberg` -*`stepper_half_step` - -[endsect] - -[section Controlled stepper] - -Controlled steppers try to execute a timestep with a given error threshold. -If the estimated error of the obtained solution is too big, the result is -rejected and a new stepsize is proposed. -If the error is small enough the timestep is accepted and possibly an increased -stepsize is proposed. - -[*Associated Types] - -Same as for /basic steppers/ above. - -[*Methods] - -*`Controlled_Stepper( time_type abs_err, time_type rel_err, - time_type factor_x, time_type factor_dxdt )` - -Constructor that initializes the controlled stepper with several parameters of -the error control. The controlled stepper assures that the error done by each -individual timestep yields: - -[* xerr < 1.1 ( eps_abs + eps_rel * (factor_x |x| + factor_dxdt h |x'|) ) ] - -The factor 1.1 is for safety to avoid unnecessary many stepsize adjustings. -The above inequality should be understand to hold for /all/ components of the -possibly more dimensional vectors *x*, *x'* and *xerr*. -If the estimated error is too large, a reduced stepsize will be suggested. -If the estimated error is less than half of the desired error, an increased -stepsize will be suggested. - -*`Controlled_Stepper( container_type &x, time_type abs_err, time_type rel_err, - time_type factor_x, time_type factor_dxdt )` -Same as above, but with additional allocation of the internal memory to store -intermediate results of the same size as `x`. - -*`controlled_step_result try_step( - DynamicalSystem &system, - container_type &x, - time_type &t, - time_type &dt )` - -Tries one timestep with the given parameters -[table - [[Parameter] [Type] [Description]] - [[system] [DynamicalSystem] [Function (callable object) that computes the rhs of the ode]] - [[x] [container_type] [The current state of the system *x(t)*]] - [[t] [time_type] [The current time *t*]] - [[dt] [time_type] [Length of the timestep to be executed]] -] -This method has three possible outcomes represented by the returned value `result`: -If `result = success` the step has been applied and x contains the new state -*x(t)* where the time has also been increased *t += dt*. -If `result = step_size_increased` the step has also been accomplished, but the -estimated error was so small that a new stepsize is proposed in the variable -`dt`. -If `result = step_size_decreased` the step has been rejected due to a too big -error. `x` and `t` remain unchanged and `dt` now containes the suggested reduced -stepsize that should give an error below the desired level. - -*`controlled_step_result try_step( - DynamicalSystem &system, - container_type &x, - const container_type &dxdt, - time_type &t, - time_type &dt )` -Same as above but with the additional parameter `dxdt` that that represents the -derivative *x'(t) = f(x,t)* at the time *t*. - -*`void adjust_size( const container_type &x )` -Adjusts the internal memory to store intermediate results of the same size as -`x`. -This function /must/ be called whenever the system size changes during the -integration. - -*`order_type order_error_step()` -Returns the order of the result *x(t+dt)* of the algorithm. - -[*Stepper that model this concept] - -*`controlled_stepper_standard` -*`controlled_stepper_bs` - -[endsect] - - -[section Dense ouput stepper] - -[endsect] - -[section Size adjusting stepper] - -[endsect] - -[section CompositeStepper] - -[endsect] - -see the wiki - -[endsect] diff --git a/libs/numeric/odeint/doc/details.qbk b/libs/numeric/odeint/doc/details.qbk index 1511d62a..ed23cb61 100644 --- a/libs/numeric/odeint/doc/details.qbk +++ b/libs/numeric/odeint/doc/details.qbk @@ -1,4 +1,4 @@ -[section Odeint in detail] +[section odeint in detail] [include details_steppers.qbk] diff --git a/libs/numeric/odeint/doc/details_boost_range.qbk b/libs/numeric/odeint/doc/details_boost_range.qbk index 5b8d7731..e7c86bc8 100644 --- a/libs/numeric/odeint/doc/details_boost_range.qbk +++ b/libs/numeric/odeint/doc/details_boost_range.qbk @@ -1,10 +1,10 @@ [section Using boost::range] -Most steppers in odeint also accept the state give as a range. A range is sequence of values modelled by a range concept. See __boost_range for an overview over existing concepts and examples of ranges. This means that the `state_type` of the stepper must not necessarily used to call the `do_step` method. +Most steppers in odeint also accept the state give as a range. A range is sequence of values modeled by a range concept. See __boost_range for an overview over existing concepts and examples of ranges. This means that the `state_type` of the stepper must not necessarily used to call the `do_step` method. One use case for __boost_range in odeint has been shown in __tut_chaotic_system where the state consists of two parts: one for the original system and one for the perturbations. The ranges are used to initialize (solve) only the system part where the perturbation part is not touched, that is a range consisting only of the system part is used. After that the complete state including the perturbations is solved. -Another use case is a system consisting of coupled units where you want to initialize each unit separately with the ODE of the uncoupled unit. An example is a chain of coupled van-der-Pol-oscillators which are initialized uniformily from the uncoupled van-der-Pol-oscillator. Then you can use __boost_range to solve only one individual oscillator in the chain. +Another use case is a system consisting of coupled units where you want to initialize each unit separately with the ODE of the uncoupled unit. An example is a chain of coupled van-der-Pol-oscillators which are initialized uniformly from the uncoupled van-der-Pol-oscillator. Then you can use __boost_range to solve only one individual oscillator in the chain. In short, you can __boost_range to use one state within two system functions which expect states with different sizes. diff --git a/libs/numeric/odeint/doc/details_boost_ref.qbk b/libs/numeric/odeint/doc/details_boost_ref.qbk index f97f9f2c..d18ca7a5 100644 --- a/libs/numeric/odeint/doc/details_boost_ref.qbk +++ b/libs/numeric/odeint/doc/details_boost_ref.qbk @@ -7,9 +7,9 @@ In odeint all system functions and observers are passed by value. For example, i rk4.do_step( sys , x , t , dt ); // pass sys by value `` -This behaviour is suitable for most systems, especially if your system only does not contain any data or only a few parameters. However, in some cases you might pass some large amount of data with you system function and passing them by value is not desired since the data will be copied. +This behavior is suitable for most systems, especially if your system only does not contain any data or only a few parameters. However, in some cases you might pass some large amount of data with you system function and passing them by value is not desired since the data will be copied. -In such cases you can easily use `boost::ref` (and its relative `boost::cref`) which passes its argument by reference (or const reference). odeint will unpack the arguments and no copying at all of you system will take place: +In such cases you can easily use `boost::ref` (and its relative `boost::cref`) which passes its argument by reference (or constant reference). odeint will unpack the arguments and no copying at all of you system will take place: `` rk4.do_step( boost::ref( sys ) , x , t , dt ); // pass sys as references diff --git a/libs/numeric/odeint/doc/details_generation_functions.qbk b/libs/numeric/odeint/doc/details_generation_functions.qbk index 4bfe9353..617ba8a8 100644 --- a/libs/numeric/odeint/doc/details_generation_functions.qbk +++ b/libs/numeric/odeint/doc/details_generation_functions.qbk @@ -24,7 +24,7 @@ This is all to use the `make_controlled` mechanism. Now you can use your control 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`. -Of course, all controllers and dense-output steppers in odeint can be used with these mechanisms. In the table below you will find, which steppers is contructed from `make_controlled` or `make_dense_output` if applied on a stepper from odeint: +Of course, 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: [include make_controlled_table.qbk] [include make_dense_output_table.qbk] diff --git a/libs/numeric/odeint/doc/details_integrate_functions.qbk b/libs/numeric/odeint/doc/details_integrate_functions.qbk index 77652ca9..bd8a77fc 100644 --- a/libs/numeric/odeint/doc/details_integrate_functions.qbk +++ b/libs/numeric/odeint/doc/details_integrate_functions.qbk @@ -8,7 +8,7 @@ Depending on the abilities of the stepper, the integrate functions make use of s [heading Equidistant observer calls] -If observer calls at equdistant time intervals /dt/ are needed, the `integrate_const` function should be used. +If observer calls at equidistant time intervals /dt/ are needed, the `integrate_const` function should be used. `integrate_const( stepper , system , x0 , t0 , t1 , dt )` @@ -83,7 +83,7 @@ Dense output is used to obtain the states /x(t)/ at the time points from the seq If exactly `n` steps with fixed step size `dt` should be executed the `integrate_n_steps` function should be used. -[warning This function works only with steppers fullfilling the __stepper or __error_stepper concept! Providing a __controlled_stepper or __dense_out_stepper results in a compilationerror.] +[warning This function works only with steppers fulfilling the __stepper or __error_stepper concept! Providing a __controlled_stepper or __dense_out_stepper results in a compilation error.] `integrate_n_steps( stepper , system , x0 , t0 , dt , n )` @@ -91,14 +91,14 @@ If exactly `n` steps with fixed step size `dt` should be executed the `integrate Integrates the ODE given by `system` with subsequent steps from `stepper` starting at ['x[sub 0]] and ['t[sub 0]]. If provided, `observer` is called after every step and at the beginning with `t0`. -This function works only with steppers fullfilling the __stepper or __error_stepper concept! +This function works only with steppers fulfilling the __stepper or __error_stepper concept! It performs exactly `n` steps with fixed step size `dt` ending at `t0 + n*dt`. The approximate result for ['x( t[sub 0] + n dt )] is stored in `x0`. This function returns the end time `t0 + n*dt`. [heading Convenience integrate function] -Additionally to the sophisticated integrate function above odeint also provides a simple `integrate` routine which uses a dense ouput stepper based on `runge_kutta_dopri5` with standard error bounds ['10[super -6]] for the steps. +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[super -6]] for the steps. `integrate( system , x0 , t0 , t1 , dt )` diff --git a/libs/numeric/odeint/doc/details_state_types_algebras_operations.qbk b/libs/numeric/odeint/doc/details_state_types_algebras_operations.qbk index b0513780..7cd61674 100644 --- a/libs/numeric/odeint/doc/details_state_types_algebras_operations.qbk +++ b/libs/numeric/odeint/doc/details_state_types_algebras_operations.qbk @@ -6,7 +6,7 @@ This is realized by giving the user full control over the state type and the mathematical operations for this state type. Technically, this is done by introducing three concepts: StateType, Algebra, Operations. -Most of the steppers in odeint expect three classes types fullfilling these +Most of the steppers in odeint expect three classes types fulfilling these concepts as template parameters. Note that these concepts are not fully independent of each other but rather a valid combination must be provided in order to make the steppers work. @@ -282,7 +282,7 @@ private : }; `` A similar class exists for the `const` version of the iterator. -Then we have a function returning the end iterator (similarily for `const` again): +Then we have a function returning the end iterator (similarly for `const` again): `` gsl_vector_iterator end_iterator( gsl_vector *x ) { @@ -310,7 +310,7 @@ Again with similar definitions for the `const` versions. This eventually makes odeint work with gsl vectors as state types. The full code for these bindings is found in [github_link boost/numeric/odeint/external/gsl/gsl_wrapper.hpp gsl_wrapper.hpp]. -It might look rather complicated but keep in mind that gsl is a pre compiled C +It might look rather complicated but keep in mind that gsl is a pre-compiled C library so it is quite an achievement that it's possible to get it working at all in the first place. [endsect] @@ -337,7 +337,7 @@ state_type: [[Assign scalar multiplication] [`x *= a`] [`state_type`] [Performs in-place multiplication of vector x with scalar a.]] ] -Definign these operators makes your state type work with any basic Runge-Kutta +Defining these operators makes your state type work with any basic Runge-Kutta stepper. However, if you want to use step-size control, some more functionality is required. @@ -351,7 +351,7 @@ So for controlled steppers the following things have to be implemented: [table [[Name] [Expression] [Type] [Semantics]] - [[Division] [`x / y`] [`state_type`] [Calculates the elementwise division 'x/y']] + [[Division] [`x / y`] [`state_type`] [Calculates the element-wise division 'x/y']] [[Absolute value] [`abs( x )`] [`state_type`] [Element wise absolute value]] [[Reduce] [`vector_space_reduce_impl< state_type >::reduce( state , operator , init )`] [`value_type`] [Performs the operation `operator` for subsequently each element of `state` and returns the aggregate value. @@ -370,7 +370,7 @@ So for controlled steppers the following things have to be implemented: [section Boost.Ublas] As an example for the employment of the `vector_space_algebra` we will adopt `ublas::vector` from __ublas to work as a state type in odeint. -This is particularily easy because `ublas::vector` supports vector-vector +This is particularly easy because `ublas::vector` supports vector-vector addition and scalar-vector multiplication described above as well as `boost::size`. It also has a resize member function so all that has to be done in this case is to declare resizability: @@ -428,7 +428,7 @@ Again, note that the two last steps were only required if you want to use controlled steppers. For simple steppers definition of the simple `+=` and `*=` operators are sufficient. -Having defined such a point type, we can easily perform the integration on a lorenz +Having defined such a point type, we can easily perform the integration on a Lorenz system by using the `vector_space_algebra` again: [point3D_main] diff --git a/libs/numeric/odeint/doc/details_steppers.qbk b/libs/numeric/odeint/doc/details_steppers.qbk index 9016ca65..58dfbd65 100644 --- a/libs/numeric/odeint/doc/details_steppers.qbk +++ b/libs/numeric/odeint/doc/details_steppers.qbk @@ -2,7 +2,7 @@ [import ../examples/stepper_details.cpp] -Solving ordinary differential equation numerically is ususally done iteratively, that is a given state of an ordinary differential equation is iterated forward ['x(t) -> x(t+dt) -> x(t+2dt)]. The steppers in odeint perform one single step. The most general stepper type is described by the __stepper concept. The stepper concepts of odeint are described in detail in section __concepts, here we briefly present the mathematical and numerical details of the steppers. The __stepper has two versions of the `do_step` method, one with an in-place transform of the currrent state and one with an out-of-place transform: +Solving ordinary differential equation numerically is usually done iteratively, that is a given state of an ordinary differential equation is iterated forward ['x(t) -> x(t+dt) -> x(t+2dt)]. The steppers in odeint perform one single step. The most general stepper type is described by the __stepper concept. The stepper concepts of odeint are described in detail in section __concepts, here we briefly present the mathematical and numerical details of the steppers. The __stepper has two versions of the `do_step` method, one with an in-place transform of the current state and one with an out-of-place transform: `do_step( sys , inout , t , dt )` @@ -14,7 +14,7 @@ The first parameter is always the system function - a function describing the OD Up to now, we have nothing said about the system function. This function depends on the stepper. For the explicit Runge-Kutta steppers this function can be a simple callable object hence a simple (global) C-function or a functor. The parameter syntax is `sys( x , dxdt , t )` and it is assumed that it calculates ['dx/dt = f(x,t)]. -Other types of system function represent Hamiltonian systems or system which also compute the Jacobian needed in implicit steppers. For informations which stepper uses which system function see the stepper table below. It might be possible, that odeint will introduce new system types in near future. Since the system function is strongly related to the stepper type, such an introduction of a new stepper might result in a new type of system function. +Other types of system function represent Hamiltonian systems or system which also compute the Jacobian needed in implicit steppers. For information which stepper uses which system function see the stepper table below. It might be possible, that odeint will introduce new system types in near future. Since the system function is strongly related to the stepper type, such an introduction of a new stepper might result in a new type of system function. [section Explicit steppers] @@ -34,7 +34,7 @@ A special class of the explicit steppers are the FSAL (first-same-as-last) stepp `do_step( sys , in , dxdtin , out , dxdtout , t , dt )` -This method also fills the derivative at time ['t+dt] into `dxdtout`. Of course, the performance gain of such FSAL steppers only appears when combining with intergrate error estimation, like in the Runge-Kutta-Dopri5 stepper. The FSAL-trick is sometimes also referred as the Fehlberg-Trick. An example how the FSAL steppers can be used is +This method also fills the derivative at time ['t+dt] into `dxdtout`. Of course, the performance gain of such FSAL steppers only appears when combining with integrate error estimation, like in the Runge-Kutta-Dopri5 stepper. The FSAL-trick is sometimes also referred as the Fehlberg-Trick. An example how the FSAL steppers can be used is [fsal_stepper_detail_example] @@ -45,9 +45,9 @@ This method also fills the derivative at time ['t+dt] into `dxdtout`. Of course, [section Symplectic solvers] -As mentioned above symplectic solvers are used for Hamiltonian systems. Symplectic solvers conserve the phase space volume exactly and if the Hamiltonian system is energy conservative they also conserve the energy approximately. A special class of symplectic systems are separable systems which can be written in the form ['dqdt/dt = f1(p)], ['dpdt/dt = f2(q)], where ['(q,p)] are the state of system. The space of ['(q,p)] is sometimes refered as the phase space and ['q] and ['p] are said the be the phase space variables. Symplectic systems in this special form occur widely in nature. For example the complete classical mechanics as written down by Newton, Lagrange and Hamilton can be forumulated in this framework. Of course, the separability of the system depends on the specific choice of coordinates. +As mentioned above symplectic solvers are used for Hamiltonian systems. Symplectic solvers conserve the phase space volume exactly and if the Hamiltonian system is energy conservative they also conserve the energy approximately. A special class of symplectic systems are separable systems which can be written in the form ['dqdt/dt = f1(p)], ['dpdt/dt = f2(q)], where ['(q,p)] are the state of system. The space of ['(q,p)] is sometimes referred as the phase space and ['q] and ['p] are said the be the phase space variables. Symplectic systems in this special form occur widely in nature. For example the complete classical mechanics as written down by Newton, Lagrange and Hamilton can be formulated in this framework. Of course, the separability of the system depends on the specific choice of coordinates. -Integrable symplectic systems can be solved by odeint by means of the symplectic_euler stepper and a symplectic Runge-Kutta-Nystrom method of sixth-order. These stepper assume that the system is autonomous, hence the time will not explicitly occur. Furhter they fullfil in principle the default Stepper concept, but they expect the system to be a pair of callable objects. The first entry of this pair calculates ['f1(p)] while the second calculates ['f2(q)]. The syntax is `sys.first(p,dqdt)` and `sys.second(q,dpdt)`, where the first and second part can be again simple C-functions of functors. An example is the harmonic oscillator: +Integrable symplectic systems can be solved by odeint by means of the symplectic_euler stepper and a symplectic Runge-Kutta-Nystrom method of sixth-order. These stepper assume that the system is autonomous, hence the time will not explicitly occur. Further they fulfill in principle the default Stepper concept, but they expect the system to be a pair of callable objects. The first entry of this pair calculates ['f1(p)] while the second calculates ['f2(q)]. The syntax is `sys.first(p,dqdt)` and `sys.second(q,dpdt)`, where the first and second part can be again simple C-functions of functors. An example is the harmonic oscillator: [symplectic_stepper_detail_system_function] @@ -61,13 +61,13 @@ If you like to represent the system with one class you can easily bind two publi [symplectic_stepper_detail_system_class_example] -Many Hamiltonian system can be written as ['dq/dt=p], ['dp/dt=f(q)] which is computationally much easier then the full separable system. Very often, it is also possible to transform the original equations of motion to bring the system in this simplified form. This kind of system can be used in the symplectic solvers, by simply passing ['f(p)] to the `do_step` method, again ['f(p)] will be represented by a simple C-function or a functor. Here, the above example of the harmonic oscaillator can be written as +Many Hamiltonian system can be written as ['dq/dt=p], ['dp/dt=f(q)] which is computationally much easier then the full separable system. Very often, it is also possible to transform the original equations of motion to bring the system in this simplified form. This kind of system can be used in the symplectic solvers, by simply passing ['f(p)] to the `do_step` method, again ['f(p)] will be represented by a simple C-function or a functor. Here, the above example of the harmonic oscillator can be written as [simplified_symplectic_stepper_example] In this example the function `harm_osc_f1` is exactly the same function as in the above examples. -Note, that the state of the ODE must not be contructed explicitly via `pair< vector_type , vector_type > x`. One can also use a combination of `make_pair` and `ref`. Furthermore, a convenience version of `do_step` exists which takes q and p without combining them into a pair: +Note, that the state of the ODE must not be constructed explicitly via `pair< vector_type , vector_type > x`. One can also use a combination of `make_pair` and `ref`. Furthermore, a convenience version of `do_step` exists which takes q and p without combining them into a pair: [symplectic_stepper_detail_ref_usage] @@ -77,7 +77,7 @@ Note, that the state of the ODE must not be contructed explicitly via `pair< vec [caution This section is not up-to-date.] -For some kind of systems the stability properties of the classical Runge-Kutta are not sufficient, especially if the system is said to be stiff. A stiff system possesses two or more time scales of very different order. Solvers for stiff systems are usually implicit, meaning that they solve equations like ['x(t+dt) = x(t) + dt * f(x(t+1))]. This particular scheme is the implicit euler method. Implicit methods usually solve the system of equations by a root finding algorithm like the Newton method and therefore need to know the Jacobian of the system ['J[subl ij] = df[subl i] / dx[subl j]]. +For some kind of systems the stability properties of the classical Runge-Kutta are not sufficient, especially if the system is said to be stiff. A stiff system possesses two or more time scales of very different order. Solvers for stiff systems are usually implicit, meaning that they solve equations like ['x(t+dt) = x(t) + dt * f(x(t+1))]. This particular scheme is the implicit Euler method. Implicit methods usually solve the system of equations by a root finding algorithm like the Newton method and therefore need to know the Jacobian of the system ['J[subl ij] = df[subl i] / dx[subl j]]. For implicit solvers the system is again a pair, where the first component computes ['f(x,t)] and the second the Jacobian. The syntax is `sys.first( x , dxdt , t )` and `sys.second( x , J , t )`. For the implicit solver the `state_type` is `ublas::vector` and the Jacobian is represented by `ublas::matrix`. @@ -85,9 +85,9 @@ For implicit solvers the system is again a pair, where the first component compu [section Multistep methods] -Another large class of solvers are multi-step method. They save a small part of the history of the solution and compute the next step with the help of this history. Since multistep methods know a part of their history they do not need to compute the system function very often, usually it is only computed once. This makes multistep methods preferable if a call of the system function is expensive. Examples are ODEs defined on networks, where the computation of the interaction is usually where expensive (and might be of order O(N^2)). +Another large class of solvers are multi-step method. They save a small part of the history of the solution and compute the next step with the help of this history. Since multi-step methods know a part of their history they do not need to compute the system function very often, usually it is only computed once. This makes multi-step methods preferable if a call of the system function is expensive. Examples are ODEs defined on networks, where the computation of the interaction is usually where expensive (and might be of order O(N^2)). -Multistep methods differ from the normal steppers. They safe a part of their history and this part has to be explicitly calculated and initialized. In the following example an Adams-Bashforth-stepper with a history of 5 steps is instantiated and initialized; +Multi-step methods differ from the normal steppers. They safe a part of their history and this part has to be explicitly calculated and initialized. In the following example an Adams-Bashforth-stepper with a history of 5 steps is instantiated and initialized; [multistep_detail_example] @@ -95,25 +95,25 @@ The initialization uses a fourth-order Runge-Kutta stepper and after the call of [multistep_detail_own_stepper_initialization] -Many multistep methods are also explicit steppers, hence the parameter of `do_step` method do not differ from the explicit steppers. +Many multi-step methods are also explicit steppers, hence the parameter of `do_step` method do not differ from the explicit steppers. -[caution The multistep methods have some internal variables which depend on the explicit solution. Hence you can not exchange the system of the state between two consecutive calls of `do_step` since then the internal variable do not correspond with the ODE and the current solution. Of course, if you use the integrate functions this will be taken into account. See the __using_steppers section for more details.] +[caution The multi-step methods have some internal variables which depend on the explicit solution. Hence you can not exchange the system of the state between two consecutive calls of `do_step` since then the internal variable do not correspond with the ODE and the current solution. Of course, if you use the integrate functions this will be taken into account. See the __using_steppers section for more details.] [endsect] [section Controlled steppers] -Many of the above introduced steppers possess the possibility to use adaptive stepsize control. Adaptive step size integration works in principle as follows: +Many of the above introduced steppers possess the possibility to use adaptive step-size control. Adaptive step size integration works in principle as follows: # The error of one step is calculated. This is usually done by performing two steps with different orders. The difference between these two steps is then used as a measure for the error. Stepper which can calculate the error are __error_stepper and they form a own class with an separate concept. -# This error is compared against some predefined error tolerances. Are the tolerance violated the step is reject and the stepsize is decreases. Otherwise the step is accepted and possibly the stepsize is increased. +# This error is compared against some predefined error tolerances. Are the tolerance violated the step is reject and the step-size is decreases. Otherwise the step is accepted and possibly the step-size is increased. -The class of controlled steppers has its own concept in odeint - the __controlled_stepper concept. They are usually constructed from the underlying error steppers. An example is the controller for the explicit Runge-Kutta steppers. The Runge-Kutta steppers enter the controller as a template argument. Additionally one can pass the Runge-Kutta stepper to the contructor, but this step is not neccessary; the stepper is default-constructed if possible. +The class of controlled steppers has its own concept in odeint - the __controlled_stepper concept. They are usually constructed from the underlying error steppers. An example is the controller for the explicit Runge-Kutta steppers. The Runge-Kutta steppers enter the controller as a template argument. Additionally one can pass the Runge-Kutta stepper to the constructor, but this step is not necessary; the stepper is default-constructed if possible. Different step size controlling mechanism exist. They all have in common that they somehow compare predefined error tolerance against the error and that they might reject or accept a step. If a step is rejected the step size is usually decreased and the step is made again. Then the procedure of checking the error tolerances and accepting or rejecting a step is made again and repeated until the step is accepted. The procedure is implemented in the integration functions. -A classical way to decide wether a step is rejected or accepted is +A classical way to decide whether a step is rejected or accepted is ['val = || | err[subl i] | / ( __epsilon[subl abs] + __epsilon[subl rel] * ( a[subl x] | x[subl i] | + a[subl dxdt] | | dxdt[subl i] | )|| ] @@ -131,7 +131,7 @@ Here, ['O[subl S]] and ['O[subl E]] are the order of the stepper and the error s [include controlled_stepper_table.qbk] -To ease to generation of the controlled stepper generation functions exist which take the absolute and relative error tolerances and a predefined error stepper and contruct from this knowledge an appropirate controlled stepper. The generation functions are explained in detail in XYZ. +To ease to generation of the controlled stepper generation functions exist which take the absolute and relative error tolerances and a predefined error stepper and construct from this knowledge an appropriate controlled stepper. The generation functions are explained in detail in __generation_functions. [endsect] @@ -141,13 +141,13 @@ A fourth class of stepper exists which are the so called dense output steppers. [dense_output_detail_example] -Dense output stepper have their own concept. The main difference is that they control the state by them-self. If you call `do_step`, only the ODE is passed as argument. Furhtermore `do_step` return the last time interval, hence you interpolate the solution between these two times points. Another difference is that they must be initialized with `initialize`, otherwise the internal state of the stepper is default contructed which might produce funny errors or bugs. +Dense output stepper have their own concept. The main difference is that they control the state by them-self. If you call `do_step`, only the ODE is passed as argument. Furthermore `do_step` return the last time interval, hence you interpolate the solution between these two times points. Another difference is that they must be initialized with `initialize`, otherwise the internal state of the stepper is default constructed which might produce funny errors or bugs. The construction of the dense output stepper looks a little bit nasty, since in the case of the `dense_output_runge_kutta` stepper a controlled stepper and an error stepper have to be nested. To simplify the generation of the dense output stepper generation functions exist: [dense_output_detail_generation1] -Of course, this statement is also lengthly; it demonstrates how `make_dense_output` can be used with the `result_of` protocoll. The parameters to `make_dense_output` are the absolute error tolerance, the relative error tolerance and the stepper. This explicitly assumes that the underlying stepper is a controlled stepper and that this stepper has an absolute and a relative error tolerance. For details about the generation functions see __generation_functions. Of course, the generation functions have been designed for easy use with the integrate functions: +Of course, this statement is also lengthy; it demonstrates how `make_dense_output` can be used with the `result_of` protocol. The parameters to `make_dense_output` are the absolute error tolerance, the relative error tolerance and the stepper. This explicitly assumes that the underlying stepper is a controlled stepper and that this stepper has an absolute and a relative error tolerance. For details about the generation functions see __generation_functions. Of course, the generation functions have been designed for easy use with the integrate functions: [dense_output_detail_generation2] @@ -155,7 +155,7 @@ Of course, this statement is also lengthly; it demonstrates how `make_dense_outp [section Using steppers] -This section contains some general informations about the usage of the steppers in odeint. +This section contains some general information about the usage of the steppers in odeint. [* Steppers are copied by value] @@ -165,11 +165,11 @@ The stepper in odeint are always copied by values. They are copied for the creat [caution Some of the features described in this section are not yet implemented] -Some steppers require to store some informations about the state of the ODE between two steps. Examples are the multistep method which store a part of the solution during the evolution of the ODE, or the FSAL steppers which store the last derivative at time ['t+dt], to be used in the next step. In both cases the steppers expect that consecutive calls of `do_step` are from the same solution and the same ODE. In this case it is absolutely neccessary that you call `do_step` with the same system function and the same state, see also the examples for the FSAL steppers above. +Some steppers require to store some information about the state of the ODE between two steps. Examples are the multi-step method which store a part of the solution during the evolution of the ODE, or the FSAL steppers which store the last derivative at time ['t+dt], to be used in the next step. In both cases the steppers expect that consecutive calls of `do_step` are from the same solution and the same ODE. In this case it is absolutely necessary that you call `do_step` with the same system function and the same state, see also the examples for the FSAL steppers above. Stepper with an internal state support two additional methods: `reset` which resets the state and `initialize` which initializes the internal state. The parameters of `initialize` depend on the specific stepper. For example the Adams-Bashforth-Moulton stepper provides two initialize methods: `initialize( system , inout , t , dt )` which initializes the internal states with the help of the Runge-Kutta 4 stepper, and `initialize( stepper , system , inout , t , dt )` which initializes with the help of `stepper`. For the case of the FSAL steppers, `initialize` is `initialize( sys , in , t )` which simply calculates the r.h.s. of the ODE and assigns its value to the internal derivative. -All these stepper have in common, that they initially fill their internal state by themself. Hence you are not required to call initialize. See how this works for the Adams-Bashforth-Moulton stepper: in the example we instantiate a fourth order Adams-Bashforth-Moulton stepper, meaning that it will store 4 internal derivatives of the solution at times `(t-dt,t-2dt,t-3dt,t-4dt)`. +All these stepper have in common, that they initially fill their internal state by themselves. Hence you are not required to call initialize. See how this works for the Adams-Bashforth-Moulton stepper: in the example we instantiate a fourth order Adams-Bashforth-Moulton stepper, meaning that it will store 4 internal derivatives of the solution at times `(t-dt,t-2dt,t-3dt,t-4dt)`. `` adams_bashforth_moulton< 4 , state_type > stepper; @@ -185,11 +185,11 @@ In the stepper table at the bottom of this page one can see which stepper have a [* Stepper might be resizable] -Nearly all steppers in odeint need to store some intermediate results of the type `state_type` or `deriv_type`. To do this the size of these temporaries needs to be adjusted. So, most steppers in odeint provide an additional template parameter which controls the size adjustment of the internal variables - the resizer. In detail odeint provides three policy classes (resizers) `always_resizer`, `initially_resizer`, and `never_resizer`. Furthermore, all stepper have a method `adjust_size` which takes a parameter representing a state type and which manually adjusts the size of the internal variables. Before performing the actual resizing odeint always checks if the sizes of the state and the interal variable differ and only resizes if they are different. +Nearly all steppers in odeint need to store some intermediate results of the type `state_type` or `deriv_type`. To do this the size of these temporaries needs to be adjusted. So, most steppers in odeint provide an additional template parameter which controls the size adjustment of the internal variables - the resizer. In detail odeint provides three policy classes (resizers) `always_resizer`, `initially_resizer`, and `never_resizer`. Furthermore, all stepper have a method `adjust_size` which takes a parameter representing a state type and which manually adjusts the size of the internal variables. Before performing the actual resizing odeint always checks if the sizes of the state and the internal variable differ and only resizes if they are different. -By default the resizing parameter is `initially_resizer`, meaning that the first call to `do_step` performs the resizing. Of course, if you have changed the size of your system and your state you have to call `adjust_size` by hand. The second resizer is the `always_resizer` which tries to resize the internal variables at every call of `do_step`. Typical use cases for this kind of resizer are self expanding lattics like shown in the tutorial or partial differential equations with an adaptive grid. The third class of resizer is the `never_resizer` which means that the internal variables are never adjusted automatically and always have the adjust by hand. +By default the resizing parameter is `initially_resizer`, meaning that the first call to `do_step` performs the resizing. Of course, if you have changed the size of your system and your state you have to call `adjust_size` by hand. The second resizer is the `always_resizer` which tries to resize the internal variables at every call of `do_step`. Typical use cases for this kind of resizer are self expanding lattices like shown in the tutorial or partial differential equations with an adaptive grid. The third class of resizer is the `never_resizer` which means that the internal variables are never adjusted automatically and always have the adjust by hand. -There is a second mechanism which influences the resizing and which controls if a state type is at least resizeable - a metafunction `is_resizeable`. This metafunction returns a static boolean value if any type is resizable. For example it will return `true` for `std::vector< T >` but `false` for `tr1::array< T >`. By default and for unknown types `is_resizeable` returns `false`, so if you have your own type you need to specialize this metafunction. For more details on the resizing mechanism see the section __adapt_state_types. +There is a second mechanism which influences the resizing and which controls if a state type is at least resizeable - a meta-function `is_resizeable`. This meta-function returns a static boolean value if any type is resizable. For example it will return `true` for `std::vector< T >` but `false` for `tr1::array< T >`. By default and for unknown types `is_resizeable` returns `false`, so if you have your own type you need to specialize this meta-function. For more details on the resizing mechanism see the section __adapt_state_types. @@ -198,7 +198,7 @@ There is a second mechanism which influences the resizing and which controls if odeint provides a quite large number of different steppers such that the user is left with the question of which stepper fits his needs. Our personal recommendations are: * `runge_kutta_dopri5` is maybe the best default stepper. It has step size control as well as dense-output functionality. Simple create a dense-output stepper by `make_dense_output( 1.0e-6 , 1.0e-5 , runge_kutta_dopri5< state_type >() )`. -* `runge_kutta4` is a good stepper for constant step sizes. It is widely used and very well known. If you need to create artifical time series this stepper should be the first choice. +* `runge_kutta4` is a good stepper for constant step sizes. It is widely used and very well known. If you need to create artificial time series this stepper should be the first choice. * 'runge_kutta_fehlberg78' is similar to the 'runge_kutta4' with the advantage that it has higher precision. It can also be used with step size control. * `adams_bashforth_moulton` is very well suited for ODEs where the r.h.s. is expensive (in terms of computation time). It will calculate the system function only once during each step. @@ -215,13 +215,13 @@ odeint provides a quite large number of different steppers such that the user is [import ../examples/stochastic_euler.cpp] -Of course, one can write own steppers which are fully compatible with odeint. They only have to fullfil one or several of the stepper __concepts of odeint. +Of course, one can write own steppers which are fully compatible with odeint. They only have to fulfill one or several of the stepper __concepts of odeint. -We will illustrate how to write your own stepper with the example of the stochastic euler method. This method is suited to solve stochastic differential equations (SDEs). A SDE has the form +We will illustrate how to write your own stepper with the example of the stochastic Euler method. This method is suited to solve stochastic differential equations (SDEs). A SDE has the form ['dx/dt = f(x) + g(x) __xi(t)] -where ['__xi] is Gaussian white noise with zero mean and a standard deviation ['__sigma(t)]. ['f(x)] is said to be the deterministic part while [' g(x) __xi] is the noisy part. In case ['g(x)] is independent of ['x] the SDE is said to have additive noise. It is not possible to solve SDE with the classical solvers for ODEs since the noisy part of the SDE has to be scaled differently then the deterministic part with respect to the time step. BUt there exist many solvers for SDEs. A classical and easy method is the stochastic euler solver. It works by iterating +where ['__xi] is Gaussian white noise with zero mean and a standard deviation ['__sigma(t)]. ['f(x)] is said to be the deterministic part while [' g(x) __xi] is the noisy part. In case ['g(x)] is independent of ['x] the SDE is said to have additive noise. It is not possible to solve SDE with the classical solvers for ODEs since the noisy part of the SDE has to be scaled differently then the deterministic part with respect to the time step. But there exist many solvers for SDEs. A classical and easy method is the stochastic Euler solver. It works by iterating ['x(t+__Delta t) = x(t) + __Delta t f(x(t)) + __Delta t[super 1/2] g(x) __xi(t)] @@ -231,13 +231,13 @@ Now we will implement this method. We will call the stepper `stochastic_euler`. [stochastic_euler_class_definition] -The types are needed in order to fulfill the stepper concept. As internal state and deriv type we use simple arrays in the stochastic euler, they are needed for the temporaries. The stepper has the order one which is returned from the `order()` function. +The types are needed in order to fulfill the stepper concept. As internal state and deriv type we use simple arrays in the stochastic Euler, they are needed for the temporaries. The stepper has the order one which is returned from the `order()` function. The system functions needs to calculate the deterministic and the stochastic part of our stochastic differential equation. So it might be suitable that the system function itself is a pair of functions, one for computing the deterministic and one for the stochastic part. The first element of the pair simply computes the deterministic part while the second the stochastic one. Then, the second part also needs to calculate the random numbers in order to simulate the stochastic process. We can now implement the `do_step` method [stochastic_euler_do_step] -This is all. It is quite simple and the stochastic euler stepper implement here is quite general. Of course it can be enhanced, for example +This is all. It is quite simple and the stochastic Euler stepper implement here is quite general. Of course it can be enhanced, for example * use of operations and algebras as well as the resizing mechanism for maximal flexibility and portability * use of `boost::ref` for the system functions @@ -248,7 +248,7 @@ Now, lets look how we use the new stepper. A nice example is the Ornstein-Uhlenb ['dx/dt = - x + __xi] -where __xi is Gaussian white noise with standard deviation ['__sigma]. Implementing the Ornstein-Uhlenbeck process is quite simple. We need two functions or funtors - one for the deterministic and one for the stochastic part: +where __xi is Gaussian white noise with standard deviation ['__sigma]. Implementing the Ornstein-Uhlenbeck process is quite simple. We need two functions or functors - one for the deterministic and one for the stochastic part: [stochastic_euler_ornstein_uhlenbeck_def] diff --git a/libs/numeric/odeint/doc/examples_table.qbk b/libs/numeric/odeint/doc/examples_table.qbk index 3c607561..9dd941f3 100644 --- a/libs/numeric/odeint/doc/examples_table.qbk +++ b/libs/numeric/odeint/doc/examples_table.qbk @@ -8,11 +8,11 @@ [[[github_link libs/numeric/odeint/examples/fpu.cpp fpu.cpp]] [The Fermi-Pasta-Ulam (FPU) example shows how odeint can be used to integrate lattice systems.]] [[[github_link libs/numeric/odeint/examples/phase_oscillator_ensemble.cpp phase_oscillator_ensemble.cpp]] [The phase oscillator ensemble example shows how globally coupled oscillators can be analyzed and how statistical measures can be computed during integration.]] [[[github_link libs/numeric/odeint/examples/harmonic_oscillator_units.cpp harmonic_oscillator_units.cpp]] [This examples shows how __boost_units can be used with odeint.]] - [[[github_link libs/numeric/odeint/examples/two_dimensional_phase_lattice.cpp two_dimensional_phase_lattice.cpp]] [The 2D phase oscillator example shows how a two-dimenstional lattice can used with odeint and how matrix types can be used as state types in odeint.]] + [[[github_link libs/numeric/odeint/examples/two_dimensional_phase_lattice.cpp two_dimensional_phase_lattice.cpp]] [The 2D phase oscillator example shows how a two-dimensional lattice can used with odeint and how matrix types can be used as state types in odeint.]] [[[github_link libs/numeric/odeint/examples/lorenz_gmpxx.cpp lorenz_gmpxx.cpp]] [This examples integrates the Lorenz system by means of an arbitrary precision type.]] [[[github_link libs/numeric/odeint/examples/thrust/phase_oscillator_ensemble.cu phase_oscillator_ensemble.cu]] [The Thrust phase oscillator ensemble example shows how globally coupled oscillators can be analyzed with Thrust and CUDA, employing the power of modern graphic devices.]] [[[github_link libs/numeric/odeint/examples/thrust/phase_oscillator_chain.cu phase_oscillator_chain.cu]] [The Thrust phase oscillator chain example shows how chains of nearest neighbor coupled oscillators can be integrated with Thrust and odeint.]] - [[[github_link libs/numeric/odeint/examples/thrust/lorenz_parameters.cu lorenz_parameters.cu]] [The Lorenz paramaters examples show how ensembles of ordinary differential equations can be solved by means of Thrust to study the dependence of an ODE on some parameters.]] - [[[github_link libs/numeric/odeint/examples/mtl/gauss_packet.cpp gauss_packet.cpp]] [The MTL-Gauss-packet example shows how the mtl can be easily used with odeint.]] + [[[github_link libs/numeric/odeint/examples/thrust/lorenz_parameters.cu lorenz_parameters.cu]] [The Lorenz parameters examples show how ensembles of ordinary differential equations can be solved by means of Thrust to study the dependence of an ODE on some parameters.]] + [[[github_link libs/numeric/odeint/examples/mtl/gauss_packet.cpp gauss_packet.cpp]] [The MTL-Gauss-packet example shows how the MTL can be easily used with odeint.]] [[[github_link libs/numeric/odeint/examples/stochastic_euler.cpp stochastic_euler.cpp]] [Implementation of a custom stepper - the stochastic euler - for solving stochastic differential equations.]] ] diff --git a/libs/numeric/odeint/doc/getting_started.qbk b/libs/numeric/odeint/doc/getting_started.qbk index 256e5ff2..e7ab3b93 100644 --- a/libs/numeric/odeint/doc/getting_started.qbk +++ b/libs/numeric/odeint/doc/getting_started.qbk @@ -2,9 +2,9 @@ [section Overview] -[caution Boost.Odeint is not an official boost library!] +[caution Boost.Numeric.Odeint is not an official boost library!] -Odeint is a library for solving initial value problems (IVP) of ordinary differential equations. Mathematically, these problems are formulated as follows: ['x'(t) = f(x,t)], ['x(0) = x0]. ['x] and ['f] can be vectors and the solution is some function ['x(t)] fullfilling both equations above. In the following we will refer to ['x'(t)] also `dxdt` which is also our notation for the derivative in the source code. +odeint is a library for solving initial value problems (IVP) of ordinary differential equations. Mathematically, these problems are formulated as follows: ['x'(t) = f(x,t)], ['x(0) = x0]. ['x] and ['f] can be vectors and the solution is some function ['x(t)] fulfilling both equations above. In the following we will refer to ['x'(t)] also `dxdt` which is also our notation for the derivative in the source code. Numerical approximations for the solution ['x(t)] are calculated iteratively. The easiest algorithm is the Euler-Scheme, where starting at ['x(0)] one finds ['x(dt) = x(0) + dt f(x(0),0)]. Now one can use ['x(dt)] and obtain ['x(2dt)] in a similar way and so on. The Euler method is of order 1, that means the error at each step is ['~ dt[super 2]]. This is, of course, not very satisfying, which is why the Euler method is rarely used for real life problems and serves just as illustrative example. @@ -24,7 +24,7 @@ In odeint, the following algorithms are implemented: [include stepper_table.qbk] -Ordinary differential equations occur nearly everywhere in natural sciences. For example, the whole Newtonian mechanics are described by second order differential equations. Be sure, you will find them in every discipline. They also occur if partial differential equations (PDEs) are discretized in one coordinate. Then, a system of coupled ordinary differential occurs, sometimes also refered as lattices ODEs. +Ordinary differential equations occur nearly everywhere in natural sciences. For example, the whole Newtonian mechanics are described by second order differential equations. Be sure, you will find them in every discipline. They also occur if partial differential equations (PDEs) are discretized in one coordinate. Then, a system of coupled ordinary differential occurs, sometimes also referred as lattices ODEs. [endsect] @@ -32,7 +32,7 @@ Ordinary differential equations occur nearly everywhere in natural sciences. For [section Usage, Compilation, Headers] -Odeint is completely header-only, meaning that you do not link against any library. It can be include by +odeint is completely header-only, meaning that you do not link against any library. It can be include by `` #include @@ -52,17 +52,17 @@ Imaging, you want to numerically integrate a harmonic oscillator with friction. [import ../examples/harmonic_oscillator.cpp] [rhs_function] -Here we chose `vector` as the state type, but others are also possible, for example `tr1::array`. Odeint is designed in such a way that you can easily use your own state types. Next, we define the ODE which is in this case a simple function. The parameter signature of this function is crucial: the integration methods will always call them in the form `f(x, dxdt, t)`. So, even if there is no explicit time dependence, one has to define `t` as a function parameter. +Here we chose `vector` as the state type, but others are also possible, for example `tr1::array`. odeint is designed in such a way that you can easily use your own state types. Next, we define the ODE which is in this case a simple function. The parameter signature of this function is crucial: the integration methods will always call them in the form `f(x, dxdt, t)`. So, even if there is no explicit time dependence, one has to define `t` as a function parameter. Now, we have to define the initial state from which the integration should start: [state_initialization] -For the integration itself we'll use the [funcref boost::numeric::odeint::integrate integrate] function, which is a convenient way to get quick results. It is based on the error-controlled [classref boost::numeric::odeint::runge_kutta_rk5_ck runge_kutta_rk5_ck] stepper (5th order) and uses adaptive stepsize. +For the integration itself we'll use the [funcref boost::numeric::odeint::integrate integrate] function, which is a convenient way to get quick results. It is based on the error-controlled [classref boost::numeric::odeint::runge_kutta_rk5_ck runge_kutta_rk5_ck] stepper (5th order) and uses adaptive step-size. [integration] -The integrate function expects as parameters the rhs of the ode as defined above, the initial state `x`, the start-and end-time of the integration as well as the initial time step. Note, that [funcref boost::numeric::odeint::integrate integrate] uses an adaptive stepsize during the integration steps so the time points will not be equally spaced. The integration returns the number of steps that were applied. +The integrate function expects as parameters the rhs of the ode as defined above, the initial state `x`, the start-and end-time of the integration as well as the initial time step. Note, that [funcref boost::numeric::odeint::integrate integrate] uses an adaptive step-size during the integration steps so the time points will not be equally spaced. The integration returns the number of steps that were applied. It is, of course, also possible to implement the ode system as a class. The rhs must then be implemented as a functor having defined the ()-operator: diff --git a/libs/numeric/odeint/doc/odeint.qbk b/libs/numeric/odeint/doc/odeint.qbk index f517c6ec..85874d86 100644 --- a/libs/numeric/odeint/doc/odeint.qbk +++ b/libs/numeric/odeint/doc/odeint.qbk @@ -1,4 +1,4 @@ -[library boost.sandbox.numeric.odeint +[library Boost.Numeric.Odeint [quickbook 1.5] [id odeint] [dirname odeint] @@ -69,7 +69,7 @@ [def __tut_chaotic_system [link boost_sandbox_numeric_odeint.tutorial.chaotic_systems_and_lyapunov_exponents Chaotic system]] [def __using_steppers - [link boost_sandbox_numeric_odeint.odeint_in_detail.steppers.using_steppers Using steppers]] + [link boost_sandbox_numeric_odeint.odeint_in_detail.steppers.using_steppers Using steppers]] [def __generation_functions [link boost_sandbox_numeric_odeint.odeint_in_detail.generation_functions Generation functions]] [def __adapt_state_types @@ -107,7 +107,7 @@ [template subl[x]''''''__space[x]''''''] [template github_link[url text]''''''[text]''''''] -# [template github_link[url text]''''''[text]''''''] +[/ [template github_link[url text]''''''[text]'''''']] [include getting_started.qbk] @@ -117,11 +117,7 @@ [include concepts.qbk] -[xinclude reference.xml] - -[include concepts_old.qbk] - -[include reference_old.qbk] +[/ [xinclude reference.xml] ] [/ diff --git a/libs/numeric/odeint/doc/range_table.qbk b/libs/numeric/odeint/doc/range_table.qbk index 22d06f6d..0b87e04b 100644 --- a/libs/numeric/odeint/doc/range_table.qbk +++ b/libs/numeric/odeint/doc/range_table.qbk @@ -50,7 +50,7 @@ Algebras supporting __boost_range [[symplectic_rkn_sb3a_mclachlan]] ] -[table Algebra supporting Boost.Range +[table Algebras supporting Boost.Range [[algebra]] [[range_algebra]] [[thrust_algebra]] diff --git a/libs/numeric/odeint/doc/reference_integrate_functions.qbk b/libs/numeric/odeint/doc/reference_integrate_functions.qbk deleted file mode 100644 index 254d344e..00000000 --- a/libs/numeric/odeint/doc/reference_integrate_functions.qbk +++ /dev/null @@ -1,11 +0,0 @@ -[section Integration functions] - -[section Constant step-size functions] - -[endsect] - -[section Adaptive step-size functions] - -[endsect] - -[endsect] diff --git a/libs/numeric/odeint/doc/reference_old.qbk b/libs/numeric/odeint/doc/reference_old.qbk deleted file mode 100644 index 59693aa4..00000000 --- a/libs/numeric/odeint/doc/reference_old.qbk +++ /dev/null @@ -1,31 +0,0 @@ -[section Old Reference] - -[include reference_steppers.qbk] - -[include reference_integrate_functions.qbk] - -[section Algebras] - -[endsect] - -[section Operations] - -[endsect] - -[section Resizing] - -[endsect] - - - - - - - - - - - - - -[endsect] diff --git a/libs/numeric/odeint/doc/reference_steppers.qbk b/libs/numeric/odeint/doc/reference_steppers.qbk deleted file mode 100644 index b1b07388..00000000 --- a/libs/numeric/odeint/doc/reference_steppers.qbk +++ /dev/null @@ -1,118 +0,0 @@ -[section Stepper classes] - -[table Stepper Algorithms - [[Method] [Class] [Order] [Error Estimation]] - [[Euler] [stepper_euler] [1] [No]] - [[Runge-Kutta 4] [stepper_rk4] [4] [No]] - [[Runge-Kutta Cash-Karp] [stepper_rk5_ck] [5] [Yes (Order 4)]] - [[Runge-Kutta Fehlberg] [stepper_rk78_fehlberg] [7] [Yes (Order 8)]] - [[Midpoint] [stepper_midpoint] [variable] [No]] - [[Bulirsch-Stoer] [controlled_stepper_bs] [variable] [Controlled]] -] - -[/ - -[section stepper_euler] - -[*Concept:] [link boost_sandbox_numeric_odeint.stepper.concepts.basic_stepper Basic stepper] - -[*Accuracy:] The produced solution is accurate up to order 1. - -[*Complexity:] This method uses 1 function evaluation. - -[*Template Parameters:] -[template tpl_parameter_table_[] -[table - [[Parameter] [Default Value] [Description]] - [[class Container] [no default value] [Type of container that stores the state of the system]] - [[class Time] [double] [Type of the time variable in the ode]] - [[class Traits] [container_traits< Container >] [container_traits used by the stepper]] -]] -[tpl_parameter_table_] - -The Euler algorithm used in this class performs one integration -step according to the formula: -[: x(t+dt) = x(t) + dt*f(x,t)] -The Euler stepper is the most simple algorithm to integrate a -differential equation. It's only purpose in this library is for educational -reasons - use more sophisticated steppers for real life problems. - -[endsect] - -[section stepper_rk4] - -[*Concept:] [link boost_sandbox_numeric_odeint.stepper.concepts.basic_stepper Basic stepper] - -[*Accuracy:] The produced solution is accurate up to order 4. - -[*Complexity:] This method uses 4 function evaluations. - -[*Template Parameters:] - -[tpl_parameter_table_] - -The Runge-Kutta 4 algorithm is /the/ classical method to integrate odes. -The [@http://en.wikipedia.org/wiki/Runge–Kutta_methods#Explicit_Runge.E2.80.93Kutta_methods -Butcher Tableau] for this method is as follows: - -[pre -Butcher Tableau for Runge-Kutta 4 - 0 | - 1/2 | 1/2 - 1/2 | 0 1/2 - 1 | 0 0 1 - ------------------------ - | 1/6 1/3 1/3 1/6 -] -This method produces fast, though not too accurate solutions. Use it for quick -preliminary results and then switch to error controlled methods like Cash-Karp -for more reliable calculations. - -[endsect] - -[section stepper_rk5_ck] - -[*Concept:] [link boost_sandbox_numeric_odeint.stepper.concepts.error_stepper Error stepper] - -[*Accuracy:] The produced solution is accurate up to order 5 and the estimated -error is also of order 5. - -[*Complexity:] This method uses 6 function evaluation. - -[*Template Parameters:] - -[tpl_parameter_table_] - -The Runge-Kutta method of order 5 with Cash-Karp coefficients is a good trade-off -between numerical effort and obtained accuracy with error estimation. -It is the all-round method and suitable for most problems. -See [@http://en.wikipedia.org/wiki/Cash–Karp_method wikipedia] for details and -the Butcher tableau. - -[endsect] - -[section stepper_rk78_fehlberg] - -[*Concept:] [link boost_sandbox_numeric_odeint.stepper.concepts.error_stepper Error Stepper] - -[*Accuracy:] The produced solution is accurate up to order 7 and the estimated -error is of order 8. - -[*Complexity:] This method uses 13 function evaluations. - -[*Template Parameters:] - -[tpl_parameter_table_] - -The Runge-Kutta 78 Fehlberg method is a high-order algorithm that produces very -good accuracy but for the cost of high numerical effort. -Whenever extra-ordinarily high precision is required, you can fall back to this -method. - -[endsect] - - -] - -[endsect] - diff --git a/libs/numeric/odeint/doc/stepper_table.qbk b/libs/numeric/odeint/doc/stepper_table.qbk index a04c0a39..5f47abd5 100644 --- a/libs/numeric/odeint/doc/stepper_table.qbk +++ b/libs/numeric/odeint/doc/stepper_table.qbk @@ -4,7 +4,7 @@ [[Modified Midpoint] [`modified_midpoint`] [__stepper] [__system] [configurable (2)] [No] [No] [No] [Used in Bulirsch-Stoer implementation]] [[Runge-Kutta 4] [`runge_kutta4`] [__stepper] [__system] [4] [No] [No] [No] [The classical Runge Kutta scheme, good general scheme without error control]] [[Cash-Karp] [`runge_kutta_cash_karp54`] [__error_stepper] [__system] [5] [Yes (4)] [No] [No] [Good general scheme with error estimation, to be used in controlled_error_stepper]] - [[Dormand-Prince 5] [`runge_kutta_dopri5`] [__error_stepper] [__system] [5] [Yes (4)] [Yes] [Yes] [Standard method with error control and dense ouput, to be used in controlled_error_stepper and in dense_output_controlled_explicit_fsal.]] + [[Dormand-Prince 5] [`runge_kutta_dopri5`] [__error_stepper] [__system] [5] [Yes (4)] [Yes] [Yes] [Standard method with error control and dense output, to be used in controlled_error_stepper and in dense_output_controlled_explicit_fsal.]] [[Fehlberg 78] [`runge_kutta_fehlberg78`] [__error_stepper] [__system] [8] [Yes (7)] [No] [No] [Good high order method with error estimation, to be used in controlled_error_stepper.]] [[Adams Bashforth] [`adams_bashforth`] [__stepper] [__system] [configurable] [No] [No] [Yes] [Multistep method]] @@ -12,15 +12,15 @@ [[Adams Bashforth Moulton] [`adams_bashforth_moulton`] [__stepper] [__system] [configurable] [No] [No] [Yes] [Combined multistep method]] [[Controlled Runge Kutta] [`controlled_runge_kutta`] [__controlled_stepper] [__system] [depends] [Yes] [No] [depends] [Error control for __error_stepper. Requires an __error_stepper from above. Order depends on the given ErrorStepper]] - [[Dense Output Runge Kutta] [`dense_output_runge_kutta`] [__dense_output_stepper] [__system] [depends] [No] [Yes] [Yes] [Dense ouput for __stepper and __error_stepper from above if they provide dense ouput functionality (like `euler` and `runge_kutta_dopri5`). Order depends on the given stepper.]] + [[Dense Output Runge Kutta] [`dense_output_runge_kutta`] [__dense_output_stepper] [__system] [depends] [No] [Yes] [Yes] [Dense output for __stepper and __error_stepper from above if they provide dense output functionality (like `euler` and `runge_kutta_dopri5`). Order depends on the given stepper.]] [[Bulirsch-Stoer] [`bulirsch_stoer`] [__controlled_stepper] [__system] [variable] [Yes] [No] [No] [Stepper with step size and order control. Very good if high precision is required.]] - [[Bulirsch-Stoer Dense Output] [`bulirsch_stoer_dense_out`] [__dense_output_stepper] [__system] [variable] [Yes] [Yes] [No] [Stepper with step size and order control as well as dense ouput. Very good if high precision and dense ouput is required.]] + [[Bulirsch-Stoer Dense Output] [`bulirsch_stoer_dense_out`] [__dense_output_stepper] [__system] [variable] [Yes] [Yes] [No] [Stepper with step size and order control as well as dense output. Very good if high precision and dense output is required.]] [[Implicit Euler] [`implicit_euler`] [__stepper] [__implicit_system] [1] [No] [No] [No] [Basic implicit routine. Requires the Jacobian. Works only with __ublas vectors as state types.]] [[Rosenbrock 4] [`rosenbrock4`] [__error_stepper] [__implicit_system] [4] [Yes] [Yes] [No] [Good for stiff systems. Works only with __ublas vectors as state types.]] [[Controlled Rosenbrock 4] [`rosenbrock4_controller`] [__controlled_stepper] [__implicit_system] [4] [Yes] [Yes] [No] [Rosenbrock 4 with error control. Works only with __ublas vectors as state types.]] - [[Dense Ouput Rosenbrock 4] [`rosenbrock4_dense_ouput`] [__dense_output_stepper] [__implicit_system] [4] [Yes] [Yes] [No] [Controlled Rosenbrock 4 with dense output. Works only with __ublas vectors as state types.]] + [[Dense Output Rosenbrock 4] [`rosenbrock4_dense_output`] [__dense_output_stepper] [__implicit_system] [4] [Yes] [Yes] [No] [Controlled Rosenbrock 4 with dense output. Works only with __ublas vectors as state types.]] [[Symplectic Euler] [`symplectic_euler`] [__stepper] [__symplectic_system __simple_symplectic_system] [1] [No] [No] [No] [Basic symplectic solver for separable Hamiltonian system]] [[Symplectic RKN McLachlan] [`symplectic_rkn_sb3a_mclachlan`] [__stepper] [__symplectic_system __simple_symplectic_system] [6] [No] [No] [No] [Symplectic solver for separable Hamiltonian system with order 6]] diff --git a/libs/numeric/odeint/doc/tutorial.qbk b/libs/numeric/odeint/doc/tutorial.qbk index 1968d61c..9a992b38 100644 --- a/libs/numeric/odeint/doc/tutorial.qbk +++ b/libs/numeric/odeint/doc/tutorial.qbk @@ -25,7 +25,7 @@ The following table gives an overview over all examples. [section References] -[*General informations about numerical integration of ordinary differential equations:] +[*General information about numerical integration of ordinary differential equations:] [1] Press William H et al., Numerical Recipes 3rd Edition: The Art of Scientific Computing, 3rd ed. (Cambridge University Press, 2007). diff --git a/libs/numeric/odeint/doc/tutorial_chaotic_system.qbk b/libs/numeric/odeint/doc/tutorial_chaotic_system.qbk index f0dc23de..9f2c050b 100644 --- a/libs/numeric/odeint/doc/tutorial_chaotic_system.qbk +++ b/libs/numeric/odeint/doc/tutorial_chaotic_system.qbk @@ -2,13 +2,13 @@ [import ../examples/chaotic_system.cpp] -Odeint can easily be used to investigate the properties of chaotic deterministic systems. In mathematical terms chaotic refers to an exponential growth of perturbations. In order to observe this exponential growth one usually solves the equations for the tangential dynamics which is again an ordinary differential equation. These equations are linear but time dependent and can be obtained via +odeint can easily be used to investigate the properties of chaotic deterministic systems. In mathematical terms chaotic refers to an exponential growth of perturbations. In order to observe this exponential growth one usually solves the equations for the tangential dynamics which is again an ordinary differential equation. These equations are linear but time dependent and can be obtained via ['d __delta x / dt = J(x) __delta x] -where ['J] is the Jacobian of the system under consideration. ['__delta x] cam also be interpreted as a perturbation of the original system. In principle ['n] of these perturbations exit, they form a hypercube and evolve in the time. The Lyapunov exponents are then defined as logarithmic growth rates of the perturbations. If one Lyapunov exponent is larger then zero nearby trajectories divergy exponentially hence they are chaotic. If the largest Lyapunov exponent is zero one is usually faced with periodic motion. In the case of a largest Lyapunov exponent smaller then zero the converges the a fixed point. More informations about Lyapunov exponents and nonlinear dynamical systems can be found in many textbooks, see for example . +where ['J] is the Jacobian of the system under consideration. ['__delta x] cam also be interpreted as a perturbation of the original system. In principle ['n] of these perturbations exit, they form a hypercube and evolve in the time. The Lyapunov exponents are then defined as logarithmic growth rates of the perturbations. If one Lyapunov exponent is larger then zero nearby trajectories diverge exponentially hence they are chaotic. If the largest Lyapunov exponent is zero one is usually faced with periodic motion. In the case of a largest Lyapunov exponent smaller then zero the converges the a fixed point. More information's about Lyapunov exponents and nonlinear dynamical systems can be found in many textbooks, see for example . -To calculate the Lyapunov exponents numerically one usually solves the equations of motion for ['n] perturbations und orthonormalized them every ['k] steps. The Lyapunov exponent is the average the logarithm of the stretching factor of each perturbation. +To calculate the Lyapunov exponents numerically one usually solves the equations of motion for ['n] perturbations and orthonormalizes them every ['k] steps. The Lyapunov exponent is the average the logarithm of the stretching factor of each perturbation. To demonstrate how one can use odeint to determine the Lyapunov exponents we choose the Lorenz system. It is one of the most studied dynamical systems in the nonlinear dynamics community. For the standard parameters is possesses a strange attractor with non-integer dimension. The Lyapunov exponents take values of approximately 0.9, 0 and -12. @@ -28,7 +28,7 @@ void lorenz( const lorenz_state_type &x , lorenz_state_type &dxdt , double t ) dxdt[2] = -b * x[2] + x[0] * x[1]; } `` -We need also need to integrate the set of the perturbations. This is done in parallel to the original system, hence within one system function. Of course, we want to use the above defintion of the Lorenz system, hence the definition of the system function including the Lorenz system itself and the perturbation could look like: +We need also need to integrate the set of the perturbations. This is done in parallel to the original system, hence within one system function. Of course, we want to use the above definition of the Lorenz system, hence the definition of the system function including the Lorenz system itself and the perturbation could look like: `` const size_t n = 3; @@ -92,7 +92,7 @@ state_type x; explicit_rk4< state_type > rk4; integrate_n_steps( rk4 , lorenz , x , 0.0 , 0.01 , 1000 ); `` -The problem is now, that `x` is the full state containing also the perturbations and `integrate_n_steps` does not know that it should only use 3 element. In detail, odeint and its steppers determine the length of the system under consideration be determing the length of the state. In the classical solvers from the problem was solved by pointer to the state and an appropriate length, something similar to +The problem is now, that `x` is the full state containing also the perturbations and `integrate_n_steps` does not know that it should only use 3 element. In detail, odeint and its steppers determine the length of the system under consideration be determining the length of the state. In the classical solvers from the problem was solved by pointer to the state and an appropriate length, something similar to `` void lorenz( double* x , double *dxdt , double t, void* params ) @@ -114,7 +114,7 @@ This is in principle all. Now, we only have to call `integrate_n_steps` with an Having integrated a sufficient number of transients steps we are now able to calculate the Lyapunov exponents: -# We initialize the perturbations. They are stored linearly behind the state of the Lorenz system. The perturbation are initialized such that they fullfill +# We initialize the perturbations. They are stored linearly behind the state of the Lorenz system. The perturbation are initialized such that they fulfill [' < p [subl i] , p[subl j] > = __delta [subl ij] ] where ['<,>] is the classical scalar product and ['__delta [subl ij]] is the Kronecker symbol. # Integrate 100 steps of the full system with perturbations diff --git a/libs/numeric/odeint/doc/tutorial_harmonic_oscillator.qbk b/libs/numeric/odeint/doc/tutorial_harmonic_oscillator.qbk index 1464ae40..05057393 100644 --- a/libs/numeric/odeint/doc/tutorial_harmonic_oscillator.qbk +++ b/libs/numeric/odeint/doc/tutorial_harmonic_oscillator.qbk @@ -2,7 +2,7 @@ [section Define the ODE] -First of all, you have to specify the datatype that represents a state of your system ['x]. Mathematically, this usually is an n-dimensional vector with real numbers or complex numbers as scalar objects. For odeint the most natural way is to use `vector< double >` or `vector< complex< double > >` to represent the system state. However, odeint can deal with other container types as well, e.g. `tr1::array< double , N >` as long as it is fullfils some requirements defined below. +First of all, you have to specify the data type that represents a state of your system ['x]. Mathematically, this usually is an n-dimensional vector with real numbers or complex numbers as scalar objects. For odeint the most natural way is to use `vector< double >` or `vector< complex< double > >` to represent the system state. However, odeint can deal with other container types as well, e.g. `tr1::array< double , N >` as long as it is fulfills some requirements defined below. To integrate a differential equation numerically, one has to define the rhs of the equation ['x' = f(x)]. In odeint you supply this function in terms of an object that implements the ()-operator with a certain parameter structure. Hence, the straight forward way would be to just define a function, e.g: @@ -20,7 +20,7 @@ odeint can deal with instances of such classes instead of pure functions which a [section Stepper Types] -Numerical integration works iteratively, that means you start at a state ['x(t)] and perform a timestep of length ['dt] to obtain the approximate state ['x(t+dt)]. There exist many different methods to perform such a timestep each of which has a certain order ['q]. If the order of a method is ['q] than it is accurate up to term ['~dt[super q]] that means the error in ['x] made by such a step is ['~dt[super q+1]]. odeint provides several steppers of different orders from which you can choose: +Numerical integration works iteratively, that means you start at a state ['x(t)] and perform a time-step of length ['dt] to obtain the approximate state ['x(t+dt)]. There exist many different methods to perform such a time-step each of which has a certain order ['q]. If the order of a method is ['q] than it is accurate up to term ['~dt[super q]] that means the error in ['x] made by such a step is ['~dt[super q+1]]. odeint provides several steppers of different orders from which you can choose: [include stepper_table.qbk] @@ -30,11 +30,11 @@ Some of steppers in the table above are special: Some need the Jacobian of the O [section Integration with Constant Step Size] -The basic stepper just performs one timestep and doesn't give you any information about the error that was made (except that you know it is of order ['q+1]). Such steppers are used with constant step size that should be chosen small enough to have reasonable small errors. However, you should apply some sort of validity check of your results (such as observing conserved quantities) becasue you have no other control of the error. The following example defines a basic stepper based on the classical Runge-Kutta scheme of 4th order. The declaration of the stepper requires the state type as template parameter. The integration can now be done by using the `integrate_const( Stepper, System, state, start_time, end_time, step_size )` function from odeint: +The basic stepper just performs one time-step and doesn't give you any information about the error that was made (except that you know it is of order ['q+1]). Such steppers are used with constant step size that should be chosen small enough to have reasonable small errors. However, you should apply some sort of validity check of your results (such as observing conserved quantities) because you have no other control of the error. The following example defines a basic stepper based on the classical Runge-Kutta scheme of 4th order. The declaration of the stepper requires the state type as template parameter. The integration can now be done by using the `integrate_const( Stepper, System, state, start_time, end_time, step_size )` function from odeint: [define_const_stepper] -This call integrates the system defined by `harmonic_oscillator` using the RK4 method from ['t=0] to ['10] with a stepsize ['dt=0.01] and the initial condition given in `x`. The result, ['x(t=10)] is stored in `x` (in-place). Each stepper defines a `do_step` method which can used directly. So, you write down the above example as +This call integrates the system defined by `harmonic_oscillator` using the RK4 method from ['t=0] to ['10] with a step-size ['dt=0.01] and the initial condition given in `x`. The result, ['x(t=10)] is stored in `x` (in-place). Each stepper defines a `do_step` method which can used directly. So, you write down the above example as [integrate_const_loop] @@ -42,7 +42,7 @@ This call integrates the system defined by `harmonic_oscillator` using the RK4 m [section Integration with Adaptive Step Size] -To improve the numerical results and additionally minimize the computational effort, the application of a step size control is advisable. Step size control is realized via stepper algorithms that additionally provide an error estimation of the applied step. Odeint provides a number of such *ErrorSteppers* and we will show their usage on the example of `explicit_error_rk54_ck? -- a 5th order Runge-Kutta method with 4th order error estimation and coefficients introduced by Cash-Karp. +To improve the numerical results and additionally minimize the computational effort, the application of a step size control is advisable. Step size control is realized via stepper algorithms that additionally provide an error estimation of the applied step. odeint provides a number of such *ErrorSteppers* and we will show their usage on the example of `explicit_error_rk54_ck? -- a 5th order Runge-Kutta method with 4th order error estimation and coefficients introduced by Cash-Karp. [define_adapt_stepper] @@ -52,7 +52,7 @@ Given the error stepper, one still needs an instance that checks the error and a As above, this integrates the system defined by `harmonic_oscillator` using an adaptive step size method based on the Runge-Kutta Cash-Karp 54 scheme from ['t=0] to ['10] with an initial step size of ['dt=0.01] (will be adjusted) and the initial condition given in x. The result, [x(t=10)'], will also be stored in x (in-place). -In the above example an error stepper is nested in a controlled stepper. This is a nice technique; however one drawback is that one always needs to define both steppers. Of course, one could also write the instantiation of the controlled stepper into the call of the integrate function but a complete knowledge of the underlying stepper types is still neccessary. Another point is, that the error tolerances for the step size control are not easily included into the controlled stepper. Both issues can be solved by using `make_controlled`: +In the above example an error stepper is nested in a controlled stepper. This is a nice technique; however one drawback is that one always needs to define both steppers. Of course, one could also write the instantiation of the controlled stepper into the call of the integrate function but a complete knowledge of the underlying stepper types is still necessary. Another point is, that the error tolerances for the step size control are not easily included into the controlled stepper. Both issues can be solved by using `make_controlled`: [integrate_adapt_make_controlled] @@ -66,7 +66,7 @@ For the Runge Kutta controller the error made during one step is compared with [ When using `make_controlled` the parameter ['a[sub x]] and ['a[sub dxdt]] are used with their standard values of 1. -In the tables below, one can find all steppers which are working with `make_controlled` and `make_dense_output` which is the analogon for the dense output steppers. +In the tables below, one can find all steppers which are working with `make_controlled` and `make_dense_output` which is the analog for the dense output steppers. [include make_controlled_table.qbk] diff --git a/libs/numeric/odeint/doc/tutorial_solar_system.qbk b/libs/numeric/odeint/doc/tutorial_solar_system.qbk index 9bccccd0..90b398c6 100644 --- a/libs/numeric/odeint/doc/tutorial_solar_system.qbk +++ b/libs/numeric/odeint/doc/tutorial_solar_system.qbk @@ -27,7 +27,7 @@ equations of motion ['dp[subl i] / dt = -dH / dq[subl i]] -In time independent Hamiltonian system the energy and the phase space volume are conserved and special integration methods have to be applied in order to ensure these conservation laws. The odeint library provides classes for separable Hamiltonian systems, which can be written in the form ['H = __Sigma p[subl i][super 2] / (2m[subl i]) + H[subl q](q)], where ['H[subl q](q)] only depends on the coordinates. Alltough this functional form might look a bit arbitrary it covers nearly all classical mechanical systems with inertia and without dissipation, or where the equations of motion can be written in the form ['dq[subl i] / dt = p[subl i]] / m[subl i] , ['dp[subl i] / dt = f( q[subl i] )]. +In time independent Hamiltonian system the energy and the phase space volume are conserved and special integration methods have to be applied in order to ensure these conservation laws. The odeint library provides classes for separable Hamiltonian systems, which can be written in the form ['H = __Sigma p[subl i][super 2] / (2m[subl i]) + H[subl q](q)], where ['H[subl q](q)] only depends on the coordinates. Although this functional form might look a bit arbitrary it covers nearly all classical mechanical systems with inertia and without dissipation, or where the equations of motion can be written in the form ['dq[subl i] / dt = p[subl i]] / m[subl i] , ['dp[subl i] / dt = f( q[subl i] )]. [endsect] @@ -45,7 +45,7 @@ The next step is to define a container type storing the values of ['q] and ['p] [import ../examples/solar_system.cpp] [container_type_definition] -The `container_type` is different from the state type of the ODE. The state type of the ode is simply a `pair< container_type , container_type >` since it needs the informations about the coordinates and the momenta. +The `container_type` is different from the state type of the ODE. The state type of the ode is simply a `pair< container_type , container_type >` since it needs the information about the coordinates and the momenta. As system function we have to provide ['f(p)] and ['f(q)]: @@ -53,7 +53,7 @@ As system function we have to provide ['f(p)] and ['f(q)]: [momentum_function] -In general a three body-system is chaotic, hence we can not expect that arbitray initial conditions of the system will lead to a dynamic which is comparable with the solar system. That is we have to define proper initial conditions, which are taken from the book of Hairer, Wannier, Lubich. +In general a three body-system is chaotic, hence we can not expect that arbitrary initial conditions of the system will lead to a dynamic which is comparable with the solar system. That is we have to define proper initial conditions, which are taken from the book of Hairer, Wannier, Lubich. As mentioned above, we need to use some special integrators in order to conserve phase space volume and energy. There is a well known family of such integrators, the so-called Runge-Kutta-Nystroem solvers, which we apply here: diff --git a/libs/numeric/odeint/doc/tutorial_special_topics.qbk b/libs/numeric/odeint/doc/tutorial_special_topics.qbk index 93e3b82a..ebd7f6e0 100644 --- a/libs/numeric/odeint/doc/tutorial_special_topics.qbk +++ b/libs/numeric/odeint/doc/tutorial_special_topics.qbk @@ -1,7 +1,5 @@ [section Special topics] -explain boost::ref - [section Complex state types] [import ../examples/stuart_landau.cpp] @@ -14,7 +12,7 @@ where ['__Psi] and ['i] is a complex variable. Such systems can easily be repres [stuart_landau_system_function] -Of courst, one can also use classical functions to implement the state function. In this cast the Stuart-Landau oscillator looks like +Of course, one can also use classical functions to implement the state function. In this cast the Stuart-Landau oscillator looks like [stuart_landau_system_function_alternative] @@ -39,7 +37,7 @@ odeint can also be used to solved ordinary differential equations defined on lat Remarkably, the Fermi-Pasta-Ulam system was the first numerical experiment which has been implemented on a computer in 1953. It was studied at Los Alamos on one of the first computer (a MANIAC I) and it triggered a whole new tree of mathematical and physical science. -The FPU is solved again by a symplectic solver, but in our case we can speed up the computation because the ['q] components trivially reduce to ['dq[subl i] / dt = p[subl i]]. odeint is capable of doing this peformance improvement. All you have to do is to call the symplectic solver with an state function for the ['p] components. Here, is how this function looks like +The FPU is solved again by a symplectic solver, but in our case we can speed up the computation because the ['q] components trivially reduce to ['dq[subl i] / dt = p[subl i]]. odeint is capable of doing this performance improvement. All you have to do is to call the symplectic solver with an state function for the ['p] components. Here, is how this function looks like [fpu_system_function] @@ -65,7 +63,7 @@ Another import high dimensional system of coupled ordinary differential equation [' d__phi[subl k] / dt = __omega[subl k] + __epsilon / N __Sigma[subl j] sin( __phi[subl j] - __phi[subl k] )] -The natural frequencies ['__omega[subl i]] of each oscialltor follow some distribution and ['__epsilon] is the coupling strength. We choose here a Lorentzian distribution for ['__omega[subl i]]. Interestingly a phase transition can be observed if the coupling strenght exceeds a critical value. Above this value synchronization sets in and some of the oscillators oscillate with the same frequency despite their different natural frequencies. The transition is also called Kuramoto transition. Its behavior can be analyzed by employing the mean field of the phase +The natural frequencies ['__omega[subl i]] of each oscillator follow some distribution and ['__epsilon] is the coupling strength. We choose here a Lorentzian distribution for ['__omega[subl i]]. Interestingly a phase transition can be observed if the coupling strength exceeds a critical value. Above this value synchronization sets in and some of the oscillators oscillate with the same frequency despite their different natural frequencies. The transition is also called Kuramoto transition. Its behavior can be analyzed by employing the mean field of the phase ['Z = K e[super i __Theta] = 1 / N __Sigma[subl k]e[super i __phi[subl k]]] @@ -95,7 +93,7 @@ To illustrate how odeint works with __boost_units we use the harmonic oscillator [units_define_basic_quantities] -Note, that the `state_type` and the `deriv_type` are now a compile-time fusion sequences. They have to be explicitly defined. Next, we define the ordinary differential equation which is completety equivalent to the example in the first section of this tutorial +Note, that the `state_type` and the `deriv_type` are now a compile-time fusion sequences. They have to be explicitly defined. Next, we define the ordinary differential equation which is completely equivalent to the example in the first section of this tutorial [units_define_ode] @@ -121,7 +119,7 @@ The full cpp file for this example can be found here [github_link libs/numeric/o odeint works well with a variety of different state types. It is not restricted to pure vector-wise types, like `vector< double >`, `array< double , N >`, `fusion::vector< double , double >`, etc. but also works with types having a different topology then simple vectors. Here, we show how odeint can be used with matrices as states type, in the next section we will show how can be used to solve ODEs defined on complex networks. -By default, odeint can be used with `ublas::matrix< T >` as state type for matrices. A simple example is a two-dimensional lattice of coupled phase oscillators. We like phas oscillators, they are extremly easy and might serve for different demonstration purposes. Other matrix types like `mtl::dense_matrix` or blitz arrays and matrices can used as well but need some kind of activation in order to work with odeint. This activation is described in following sections, +By default, odeint can be used with `ublas::matrix< T >` as state type for matrices. A simple example is a two-dimensional lattice of coupled phase oscillators. We like phase oscillators, they are extremely easy and might serve for different demonstration purposes. Other matrix types like `mtl::dense_matrix` or blitz arrays and matrices can used as well but need some kind of activation in order to work with odeint. This activation is described in following sections, The definition of the system is @@ -155,7 +153,7 @@ Ginzburg-Landau [import ../examples/gmpxx/lorenz_gmpxx.cpp] -Besides the classical floating point number like `float`, `double`, `complex< double >` you can also use arbitrary precision types, like the types from [@http://gmplib.org/ gmp] and [@http://www.mpfr.org/ mpfr]. But you have to be carful about instantiating any numbers. +Besides the classical floating point number like `float`, `double`, `complex< double >` you can also use arbitrary precision types, like the types from [@http://gmplib.org/ gmp] and [@http://www.mpfr.org/ mpfr]. But you have to be careful about instantiating any numbers. For gmp types you have to set the default precision before any number is instantiated. This can be easily done by calling `mpf_set_default_prec( precision )` as the first function in your main program. Secondly, you can not use any global constant variables since they will not be set with the default precision you have already set. @@ -178,11 +176,11 @@ The full example can be found at [github_link libs/numeric/odeint/examples/loren [import ../examples/resizing_lattice.cpp] -Odeint supports changes of the state size during integration if a state_type is used which can be resized, like `std::vector`. +odeint supports changes of the state size during integration if a state_type is used which can be resized, like `std::vector`. The adjustment of the state type's size has to be done from outside and the stepper has to be instantiated with `always_resizer` as the template argument for the `resizer_type`. In this configuration, the stepper checks for changes in the state size and adjust it's internal storage accordingly. -We exemplarily show this for a Hamiltonian system of nonlinear, disordered oscillators with nonlinear nearest neighbour coupling. +We exemplary show this for a Hamiltonian system of nonlinear, disordered oscillators with nonlinear nearest neighbor coupling. The system function is implemented in terms of a class that also provides functions for calculating the energy. Note, that this class stores the random potential internally which is not resized, but rather a start index is kept which should be changed whenever the states' size change. diff --git a/libs/numeric/odeint/doc/tutorial_stiff_systems.qbk b/libs/numeric/odeint/doc/tutorial_stiff_systems.qbk index e9473b10..4b5144ae 100644 --- a/libs/numeric/odeint/doc/tutorial_stiff_systems.qbk +++ b/libs/numeric/odeint/doc/tutorial_stiff_systems.qbk @@ -2,13 +2,11 @@ [import ../examples/stiff_system.cpp] -An important class of ordinary differential equations are so called stiff system which are characterized by two or more time scales of different order. Examples of such systems are found in chemical systems where reaction rates of individual subreaction might differ over large ranges. +An important class of ordinary differential equations are so called stiff system which are characterized by two or more time scales of different order. Examples of such systems are found in chemical systems where reaction rates of individual sub-reaction might differ over large ranges. -CHECK: +['d S[subl 1] / dt = - 101 S[subl 2] - 100 S[subl 1]] -['d S[subl 1] / dt = - __gamma[subl 1] S[subl 1] S[subl 2]] - -['d S[subl 2] / dt = - __gamma[subl 1] S[subl 1] S[subl 2]] +['d S[subl 2] / dt = S[subl 1]] To solve stiff systems numerically the Jacobian diff --git a/libs/numeric/odeint/doc/tutorial_thrust_cuda.qbk b/libs/numeric/odeint/doc/tutorial_thrust_cuda.qbk index 4b1854bb..346c6c16 100644 --- a/libs/numeric/odeint/doc/tutorial_thrust_cuda.qbk +++ b/libs/numeric/odeint/doc/tutorial_thrust_cuda.qbk @@ -14,7 +14,7 @@ Typical applications for CUDA and odeint are large systems, like lattices or dis The first example is the phase oscillator ensemble from the previous section. It has a phase transition at ['__epsilon = 2] in the limit of infinite numbers of oscillators ['N]. In the case of finite ['N] this transition is smeared out but still clearly visible. -__thrust and Cuda are perfectly suited for such kinds of problems where one needs a large number of particles (oscillators). We start by defining the state type which is a `thrust::device_vector`. The content of this vector lives on the GPU. If you are not familar with this we recommend reading the ['Getting started] section on the __thrust website. +__thrust and Cuda are perfectly suited for such kinds of problems where one needs a large number of particles (oscillators). We start by defining the state type which is a `thrust::device_vector`. The content of this vector lives on the GPU. If you are not familiar with this we recommend reading the ['Getting started] section on the __thrust website. [thrust_phase_ensemble_state_type] @@ -84,12 +84,12 @@ The next example is a large, one-dimensional chain of nearest-neighbor coupled p ['d __phi[subl k] / dt = __omega[subl k] + sin( __phi[subl k+1] - __phi[subl k] ) + sin( __phi[subl k] - __phi[subl k-1])] -In principle we can use all the techniques from the previous phase oscillator ensemble example, but we have to take special care about the coupling of the oscillators. To efficiently implement the coupling you can use a very elegant way employing Thrust's permutation iterator. A permuation iterator behaves like a normal iterator on a vector but it does not iterate along the usual order of the elements. +In principle we can use all the techniques from the previous phase oscillator ensemble example, but we have to take special care about the coupling of the oscillators. To efficiently implement the coupling you can use a very elegant way employing Thrust's permutation iterator. A permutation iterator behaves like a normal iterator on a vector but it does not iterate along the usual order of the elements. It rather iterates along some permutation of the elements defined by some index map. To realize the nearest neighbor coupling we create one permutation iterator which travels one step behind a usual iterator and another permutation iterator which travels one step in front. The full system class is: [thrust_phase_chain_system] -Note, how easy you can obtain the value for the left and right neighboring oscillator in the system functor using the permutation iterators. But, the call of the `thrust::for_each` function looks relativ complicated. Every term of the r.h.s. of the ODE is resembled by one iterator packed in exactly the same way as it is unpacked in the functor above. +Note, how easy you can obtain the value for the left and right neighboring oscillator in the system functor using the permutation iterators. But, the call of the `thrust::for_each` function looks relatively complicated. Every term of the r.h.s. of the ODE is resembled by one iterator packed in exactly the same way as it is unpacked in the functor above. Now we put everything together. We create random initial conditions and decreasing frequencies such that we should get synchronization. We copy the frequencies and the initial conditions onto the device and finally initialize and perform the integration. As result we simply write out the current state, hence the phase of each oscillator. @@ -103,10 +103,10 @@ The full example can be found at [github_link libs/numeric/odeint/examples/thrus [import ../examples/thrust/lorenz_parameters.cu] -Another important use case for __thrust and Cuda are parameter studies of relatively small systems. Consider for example the three-dimensional Lorenz system from the chaotic systems example in the previous section which has three parameters. If you want to study the behaviour of this system for different parameters you usually have to integrate the system for many parameter values. Using thrust and odeint you can do this integration in parallel, hence you integrate a whole ensemble of Lorenz systems where each individual realization has a different parameter value. +Another important use case for __thrust and Cuda are parameter studies of relatively small systems. Consider for example the three-dimensional Lorenz system from the chaotic systems example in the previous section which has three parameters. If you want to study the behavior of this system for different parameters you usually have to integrate the system for many parameter values. Using thrust and odeint you can do this integration in parallel, hence you integrate a whole ensemble of Lorenz systems where each individual realization has a different parameter value. [/ The Lorenz system is dissipative, such that you can assume that different initial conditions will lead to the same attractor so . For Hamiltonian systems this is not the case. Here it might be interesting to study a range of initial conditions to quantify different regions in the phase space.] -In the following we will show how you can use __thrust to integrate the above mentioned ensemble of Lorenz systems. We will vary only the parameter ['__beta] but it is straightfoward to vary other parameters or even two or all three parameters. Furthermore, we will use the largest Lyapunov exponent to quantify the behavior of the system (chaoticity). +In the following we will show how you can use __thrust to integrate the above mentioned ensemble of Lorenz systems. We will vary only the parameter ['__beta] but it is straightforward to vary other parameters or even two or all three parameters. Furthermore, we will use the largest Lyapunov exponent to quantify the behavior of the system (chaoticity). We start be defining the range of the parameters we want to study. Of course, the state_type is again a `thrust::device_vector< value_type >`. @@ -116,9 +116,9 @@ The next thing we have to implement is the Lorenz system without perturbations. [thrust_lorenz_parameters_define_simple_system] -As `state_type` a `thrust::device_vector` or a __boost_range of a `device_vector` is used. The length of the state is ['3N] where ['N] is the number of systems. The system is encoded into this vector such that all ['x] components come first, then every ['y] compoents and finally every ['z] components. Implementing the device function is then a simple task, you only have to decompose the tuple originating from the zip iterators. +As `state_type` a `thrust::device_vector` or a __boost_range of a `device_vector` is used. The length of the state is ['3N] where ['N] is the number of systems. The system is encoded into this vector such that all ['x] components come first, then every ['y] components and finally every ['z] components. Implementing the device function is then a simple task, you only have to decompose the tuple originating from the zip iterators. -Besides the system without perturbations we furthermore need to calculate the system including linearized equations governing the time evolution of small perturbations. Using the method from above this is straightforward, with a small difficulty that thrust's tuples have a maximal arity of 10. But this is only a small problem since we can create a zip iterator packed with zip iterators. So the top level zip iterator contains one zip iterator for the state, one normal iterator for the parameter, and one zip iterator for the derivative. Accessing the elements of this tuple in the system function is then straightforward, you unpack the tuple with `thrust::get<>()`. We will not show the code here, it is to large. It can be found [github_link libs/numeric/odeint/examples/thrust/lorenz_parameters.cu here] and is easy to understand. +Besides the system without perturbations we furthermore need to calculate the system including linearized equations governing the time evolution of small perturbations. Using the method from above this is straightforward, with a small difficulty that Thrust's tuples have a maximal arity of 10. But this is only a small problem since we can create a zip iterator packed with zip iterators. So the top level zip iterator contains one zip iterator for the state, one normal iterator for the parameter, and one zip iterator for the derivative. Accessing the elements of this tuple in the system function is then straightforward, you unpack the tuple with `thrust::get<>()`. We will not show the code here, it is to large. It can be found [github_link libs/numeric/odeint/examples/thrust/lorenz_parameters.cu here] and is easy to understand. Furthermore, we need an observer which determines the norm of the perturbations, normalizes them and averages the logarithm of the norm. The device functor which is used within this observer is defined @@ -126,7 +126,7 @@ Furthermore, we need an observer which determines the norm of the perturbations, Note, that this functor manipulates the state, i.e. the perturbations. -Now we complete the whole code to calculate the Lyapunov exponents. First, we have to define a state vector. This vector contains ['6N] entries, the state ['x,y,z] and its perturbations ['dx,dy,dz]. We initialize them such that ['x=y=z=10], ['dx=1], and ['dy=dz=0]. We define a stepper type, a controlled Runge-Kutta Dormand-Prince 5 stepper. We start with some integration to overcome the transient behavior. For this, we do not involve the pertubation and run the algorithm only on the state ['x,y,z] without any observer. Note, how __boost_range is used for partial integration of the state vector without pertubations (the first half of the whole state). After the transient, the full system with perturbations is integrated and the Lyapunov exponents are calculated and written to `stdout`. +Now we complete the whole code to calculate the Lyapunov exponents. First, we have to define a state vector. This vector contains ['6N] entries, the state ['x,y,z] and its perturbations ['dx,dy,dz]. We initialize them such that ['x=y=z=10], ['dx=1], and ['dy=dz=0]. We define a stepper type, a controlled Runge-Kutta Dormand-Prince 5 stepper. We start with some integration to overcome the transient behavior. For this, we do not involve the perturbation and run the algorithm only on the state ['x,y,z] without any observer. Note, how __boost_range is used for partial integration of the state vector without perturbations (the first half of the whole state). After the transient, the full system with perturbations is integrated and the Lyapunov exponents are calculated and written to `stdout`. [thrust_lorenz_parameters_integration] diff --git a/libs/numeric/odeint/performance/Jamfile b/libs/numeric/odeint/performance/Jamfile index 7c56208c..d776affa 100644 --- a/libs/numeric/odeint/performance/Jamfile +++ b/libs/numeric/odeint/performance/Jamfile @@ -45,7 +45,7 @@ exe rt_generic_rk4_lorenz ; exe gsl_rk4_lorenz - : gsl_rk4_lorenz.cpp libgsl libgslcblas + : gsl_rk4_lorenz.cpp libgslcblas libgsl ; exe odeint_rk4_phase_lattice