documentation: steppers and boost_ref

This commit is contained in:
Karsten Ahnert 2012-04-02 20:27:51 +02:00
parent b40639d8c0
commit 83c55a4632
8 changed files with 157 additions and 16 deletions

View File

@ -1912,9 +1912,9 @@
</p>
<p>
where <span class="emphasis"><em>&#958;</em></span> is Gaussian white noise with zero mean and
a standard deviation <span class="emphasis"><em>&#963;</em></span>. <span class="emphasis"><em>f(x)</em></span> is
said to be the deterministic part while <span class="emphasis"><em>g(x) &#958;</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>&#963;(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) &#958;</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 + &#958;</em></span>
</p>
<p>
where &#958; is Gaussian white noise with standard deviation <span class="emphasis"><em>&#963;</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">&lt;</span> <span class="keyword">double</span> <span class="special">,</span> <span class="identifier">N</span> <span class="special">&gt;</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">&amp;</span><span class="identifier">x</span> <span class="special">,</span> <span class="identifier">state_type</span> <span class="special">&amp;</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">&lt;&gt;</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">&amp;</span><span class="identifier">x</span> <span class="special">,</span> <span class="identifier">state_type</span> <span class="special">&amp;</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>&#963;</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">&lt;</span> <span class="identifier">N</span> <span class="special">&gt;()</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>

View File

@ -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 &#169; 2009-2011 Karsten Ahnert

View File

@ -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 &#169; 2009-2011 Karsten Ahnert

View File

@ -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>

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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;
}