mirror of
https://github.com/boostorg/odeint.git
synced 2025-05-09 23:24:01 +00:00
documentation: steppers and boost_ref
This commit is contained in:
parent
b40639d8c0
commit
83c55a4632
@ -1912,9 +1912,9 @@
|
||||
</p>
|
||||
<p>
|
||||
where <span class="emphasis"><em>ξ</em></span> is Gaussian white noise with zero mean and
|
||||
a standard deviation <span class="emphasis"><em>σ</em></span>. <span class="emphasis"><em>f(x)</em></span> is
|
||||
said to be the deterministic part while <span class="emphasis"><em>g(x) ξ</em></span> is the
|
||||
noisy part. In case <span class="emphasis"><em>g(x)</em></span> is independent of <span class="emphasis"><em>x</em></span>
|
||||
a standard deviation <span class="emphasis"><em>σ(t)</em></span>. <span class="emphasis"><em>f(x)</em></span>
|
||||
is said to be the deterministic part while <span class="emphasis"><em>g(x) ξ</em></span> is
|
||||
the noisy part. In case <span class="emphasis"><em>g(x)</em></span> is independent of <span class="emphasis"><em>x</em></span>
|
||||
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
|
||||
@ -1964,8 +1964,7 @@
|
||||
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
|
||||
order to simulate the stochastic process. We can now implement the <code class="computeroutput"><span class="identifier">do_step</span></code> method
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
@ -2009,7 +2008,65 @@
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
examples, with integrate function
|
||||
Now, lets look how we use the new stepper. A nice example is the Ornstein-Uhlenbeck
|
||||
process. It consists of a simple Brownian motion overlapped with an relaxation
|
||||
process. Its SDE reads
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em>dx/dt = - x + ξ</em></span>
|
||||
</p>
|
||||
<p>
|
||||
where ξ is Gaussian white noise with standard deviation <span class="emphasis"><em>σ</em></span>.
|
||||
Implementing the Ornstein-Uhlenbeck process is quite simple. We need two
|
||||
functions or funtors - one for the deterministic and one for the stochastic
|
||||
part:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">static</span> <span class="identifier">size_t</span> <span class="identifier">N</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
|
||||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="keyword">double</span> <span class="special">,</span> <span class="identifier">N</span> <span class="special">></span> <span class="identifier">state_type</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">ornstein_det</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">const</span> <span class="identifier">state_type</span> <span class="special">&</span><span class="identifier">x</span> <span class="special">,</span> <span class="identifier">state_type</span> <span class="special">&</span><span class="identifier">dxdt</span> <span class="special">)</span> <span class="keyword">const</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">dxdt</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="special">-</span><span class="identifier">x</span><span class="special">[</span><span class="number">0</span><span class="special">];</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">ornstein_stoch</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">mt19937</span> <span class="identifier">m_rng</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">normal_distribution</span><span class="special"><></span> <span class="identifier">m_dist</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">ornstein_stoch</span><span class="special">(</span> <span class="keyword">double</span> <span class="identifier">sigma</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">m_rng</span><span class="special">()</span> <span class="special">,</span> <span class="identifier">m_dist</span><span class="special">(</span> <span class="number">0.0</span> <span class="special">,</span> <span class="identifier">sigma</span> <span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="keyword">const</span> <span class="identifier">state_type</span> <span class="special">&</span><span class="identifier">x</span> <span class="special">,</span> <span class="identifier">state_type</span> <span class="special">&</span><span class="identifier">dxdt</span> <span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">dxdt</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">m_dist</span><span class="special">(</span> <span class="identifier">m_rng</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
In the stochastic part we have used the Mersenne twister for the random
|
||||
number generation and a Gaussian white noise generator <code class="computeroutput"><span class="identifier">normal_distribution</span></code>
|
||||
with standard deviation <span class="emphasis"><em>σ</em></span>. Now, we can use the stochastic
|
||||
Euler stepper with the integrate functions:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">dt</span> <span class="special">=</span> <span class="number">0.1</span><span class="special">;</span>
|
||||
<span class="identifier">state_type</span> <span class="identifier">x</span> <span class="special">=</span> <span class="special">{{</span> <span class="number">1.0</span> <span class="special">}};</span>
|
||||
<span class="identifier">integrate_const</span><span class="special">(</span> <span class="identifier">stochastic_euler</span><span class="special"><</span> <span class="identifier">N</span> <span class="special">>()</span> <span class="special">,</span> <span class="identifier">make_pair</span><span class="special">(</span> <span class="identifier">ornstein_det</span><span class="special">()</span> <span class="special">,</span> <span class="identifier">ornstein_stoch</span><span class="special">(</span> <span class="number">1.0</span> <span class="special">)</span> <span class="special">)</span> <span class="special">,</span>
|
||||
<span class="identifier">x</span> <span class="special">,</span> <span class="number">0.0</span> <span class="special">,</span> <span class="number">10.0</span> <span class="special">,</span> <span class="identifier">dt</span> <span class="special">,</span> <span class="identifier">streaming_observer</span><span class="special">()</span> <span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
Note, how we have used the <code class="computeroutput"><span class="identifier">make_pair</span></code>
|
||||
function for the generation of the system function.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,10 +15,26 @@
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="using_boost__ref.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../odeint_in_detail.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="../concepts.html"><img src="../../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section"><div class="titlepage"><div><div><h3 class="title">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_sandbox_numeric_odeint.odeint_in_detail.using_boost__range"></a><a class="link" href="using_boost__range.html" title="Using boost::range">Using
|
||||
boost::range</a>
|
||||
</h3></div></div></div></div>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Most steppers in odeint also accept the state give as a range. A range is
|
||||
sequence of values modelled by a range concept, see <a href="http://www.boost.org/doc/libs/release/libs/range/index.html" target="_top">Boost.Range</a>
|
||||
for an overview over existing concepts and examples of ranges.
|
||||
</p>
|
||||
<p>
|
||||
state type mus not necessary be used in the steppers
|
||||
</p>
|
||||
<p>
|
||||
example
|
||||
</p>
|
||||
<p>
|
||||
table which steppers support boost::range and with which algebra
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2009-2011 Karsten Ahnert
|
||||
|
@ -15,10 +15,45 @@
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="state_types__algebras_and_operations.html"><img src="../../images/prev.png" alt="Prev"></a><a accesskey="u" href="../odeint_in_detail.html"><img src="../../images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../images/home.png" alt="Home"></a><a accesskey="n" href="using_boost__range.html"><img src="../../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section"><div class="titlepage"><div><div><h3 class="title">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_sandbox_numeric_odeint.odeint_in_detail.using_boost__ref"></a><a class="link" href="using_boost__ref.html" title="Using boost::ref">Using
|
||||
boost::ref</a>
|
||||
</h3></div></div></div></div>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
In odeint all system functions and observers are passed by value. For example,
|
||||
if you call a <code class="computeroutput"><span class="identifier">do_step</span></code> method
|
||||
of a particular stepper or the integration functions your system and your
|
||||
stepper will be passed by value:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">rk4</span><span class="special">.</span><span class="identifier">do_step</span><span class="special">(</span> <span class="identifier">sys</span> <span class="special">,</span> <span class="identifier">x</span> <span class="special">,</span> <span class="identifier">t</span> <span class="special">,</span> <span class="identifier">dt</span> <span class="special">);</span> <span class="comment">// pass sys by value</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
In such cases you can easily use <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span></code> (and
|
||||
its relative <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span></code>) 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:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">rk4</span><span class="special">.</span><span class="identifier">do_step</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">ref</span><span class="special">(</span> <span class="identifier">sys</span> <span class="special">)</span> <span class="special">,</span> <span class="identifier">x</span> <span class="special">,</span> <span class="identifier">t</span> <span class="special">,</span> <span class="identifier">dt</span> <span class="special">);</span> <span class="comment">// pass sys as references</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
The same mechanism can for the observers in the integrate functions.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2009-2011 Karsten Ahnert
|
||||
|
@ -125,7 +125,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: April 02, 2012 at 06:51:21 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: April 02, 2012 at 16:04:40 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@ -1,3 +1,11 @@
|
||||
[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.
|
||||
|
||||
state type mus not necessary be used in the steppers
|
||||
|
||||
example
|
||||
|
||||
table which steppers support boost::range and with which algebra
|
||||
|
||||
[endsect]
|
||||
|
@ -1,3 +1,20 @@
|
||||
[section Using boost::ref]
|
||||
|
||||
In odeint all system functions and observers are passed by value. For example, if you call a `do_step` method of a particular stepper or the integration functions your system and your stepper will be passed by value:
|
||||
|
||||
[c++]
|
||||
``
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
``
|
||||
rk4.do_step( boost::ref( sys ) , x , t , dt ); // pass sys as references
|
||||
``
|
||||
|
||||
The same mechanism can for the observers in the integrate functions.
|
||||
|
||||
[endsect]
|
||||
|
@ -248,11 +248,16 @@ 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].
|
||||
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:
|
||||
|
||||
[stochastic_euler_ornstein_uhlenbeck_det]
|
||||
[stochastic_euler_ornstein_uhlenbeck_def]
|
||||
|
||||
In the stochastic part we have used the Mersenne twister for the random number generation and a Gaussian white noise generator `normal_distribution` with standard deviation ['__sigma]. Now, we can use the stochastic Euler stepper with the integrate functions:
|
||||
|
||||
[ornstein_uhlenbeck_main]
|
||||
|
||||
Note, how we have used the `make_pair` function for the generation of the system function.
|
||||
|
||||
examples, with integrate function
|
||||
|
||||
|
||||
|
||||
|
@ -116,14 +116,17 @@ struct streaming_observer
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main( int argc , char **argv )
|
||||
{
|
||||
using namespace std;
|
||||
using namespace boost::numeric::odeint;
|
||||
|
||||
//[ ornstein_uhlenbeck_main
|
||||
double dt = 0.1;
|
||||
state_type x = {{ 1.0 }};
|
||||
integrate_const( stochastic_euler< N >() , make_pair( ornstein_det() , ornstein_stoch( 1.0 ) ) , x , 0.0 , 10.0 , dt , streaming_observer() );
|
||||
|
||||
integrate_const( stochastic_euler< N >() , make_pair( ornstein_det() , ornstein_stoch( 1.0 ) ) ,
|
||||
x , 0.0 , 10.0 , dt , streaming_observer() );
|
||||
//]
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user