stochastic_euler.cpp 3.2 KB

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