1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/*
libs/numeric/odeint/examples/stochastic_euler.hpp
Copyright 2012 Karsten Ahnert
Copyright 2012 Mario Mulansky
Stochastic euler stepper example and Ornstein-Uhlenbeck process
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or
copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#include <vector>
#include <iostream>
#include <boost/random.hpp>
#include <boost/array.hpp>
#include <boost/numeric/odeint.hpp>
/*
//[ stochastic_euler_class_definition
template< size_t N > class stochastic_euler
{
public:
typedef boost::array< double , N > state_type;
typedef boost::array< double , N > deriv_type;
typedef double value_type;
typedef double time_type;
typedef unsigned short order_type;
typedef boost::numeric::odeint::stepper_tag stepper_category;
static order_type order( void ) { return 1; }
// ...
};
//]
*/
/*
//[ stochastic_euler_do_step
template< size_t N > class stochastic_euler
{
public:
// ...
template< class System >
void do_step( System system , state_type &x , time_type t , time_type dt ) const
{
deriv_type det , stoch ;
system.first( x , det );
system.second( x , stoch );
for( size_t i=0 ; i<x.size() ; ++i )
x[i] += dt * det[i] + sqrt( dt ) * stoch[i];
}
};
//]
*/
//[ stochastic_euler_class
template< size_t N >
class stochastic_euler
{
public:
typedef boost::array< double , N > state_type;
typedef boost::array< double , N > deriv_type;
typedef double value_type;
typedef double time_type;
typedef unsigned short order_type;
typedef boost::numeric::odeint::stepper_tag stepper_category;
static order_type order( void ) { return 1; }
template< class System >
void do_step( System system , state_type &x , time_type t , time_type dt ) const
{
deriv_type det , stoch ;
system.first( x , det );
system.second( x , stoch );
for( size_t i=0 ; i<x.size() ; ++i )
x[i] += dt * det[i] + sqrt( dt ) * stoch[i];
}
};
//]
//[ stochastic_euler_ornstein_uhlenbeck_def
const static size_t N = 1;
typedef boost::array< double , N > state_type;
struct ornstein_det
{
void operator()( const state_type &x , state_type &dxdt ) const
{
dxdt[0] = -x[0];
}
};
struct ornstein_stoch
{
boost::mt19937 &m_rng;
boost::normal_distribution<> m_dist;
ornstein_stoch( boost::mt19937 &rng , double sigma ) : m_rng( rng ) , m_dist( 0.0 , sigma ) { }
void operator()( const state_type &x , state_type &dxdt )
{
dxdt[0] = m_dist( m_rng );
}
};
//]
struct streaming_observer
{
template< class State >
void operator()( const State &x , double t ) const
{
std::cout << t << "\t" << x[0] << "\n";
}
};
int main( int argc , char **argv )
{
using namespace std;
using namespace boost::numeric::odeint;
//[ ornstein_uhlenbeck_main
boost::mt19937 rng;
double dt = 0.1;
state_type x = {{ 1.0 }};
integrate_const( stochastic_euler< N >() , make_pair( ornstein_det() , ornstein_stoch( rng , 1.0 ) ),
x , 0.0 , 10.0 , dt , streaming_observer() );
//]
return 0;
}
|