const_step_iterator.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * const_step_iterator.cpp
  3. *
  4. * Copyright 2012-2013 Karsten Ahnert
  5. * Copyright 2013 Mario Mulansky
  6. *
  7. * Distributed under the Boost Software License, Version 1.0.
  8. * (See accompanying file LICENSE_1_0.txt or
  9. * copy at http://www.boost.org/LICENSE_1_0.txt)
  10. *
  11. * several examples for using iterators
  12. */
  13. #include <iostream>
  14. #include <iterator>
  15. #include <utility>
  16. #include <algorithm>
  17. #include <array>
  18. #include <cassert>
  19. #include <boost/range/algorithm.hpp>
  20. #include <boost/range/adaptor/filtered.hpp>
  21. #include <boost/range/numeric.hpp>
  22. #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
  23. #include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp>
  24. #include <boost/numeric/odeint/stepper/generation.hpp>
  25. #include <boost/numeric/odeint/iterator/const_step_iterator.hpp>
  26. #include <boost/numeric/odeint/iterator/const_step_time_iterator.hpp>
  27. #define tab "\t"
  28. using namespace std;
  29. using namespace boost::numeric::odeint;
  30. const double sigma = 10.0;
  31. const double R = 28.0;
  32. const double b = 8.0 / 3.0;
  33. struct lorenz
  34. {
  35. template< class State , class Deriv >
  36. void operator()( const State &x , Deriv &dxdt , double t ) const
  37. {
  38. dxdt[0] = sigma * ( x[1] - x[0] );
  39. dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
  40. dxdt[2] = -b * x[2] + x[0] * x[1];
  41. }
  42. };
  43. int main( int argc , char **argv )
  44. {
  45. typedef std::array< double , 3 > state_type;
  46. // std::for_each
  47. {
  48. runge_kutta4< state_type > stepper;
  49. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  50. std::for_each( make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  51. make_const_step_time_iterator_end( stepper , lorenz() , x ) ,
  52. []( const std::pair< const state_type&, double > &x ) {
  53. std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
  54. }
  55. // std::copy_if
  56. {
  57. std::vector< state_type > res;
  58. runge_kutta4< state_type > stepper;
  59. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  60. std::copy_if( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  61. make_const_step_iterator_end( stepper , lorenz() , x ) ,
  62. std::back_inserter( res ) ,
  63. []( const state_type& x ) {
  64. return ( x[0] > 0.0 ) ? true : false; } );
  65. for( size_t i=0 ; i<res.size() ; ++i )
  66. cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n";
  67. }
  68. // std::accumulate
  69. {
  70. //[ const_step_iterator_accumulate
  71. runge_kutta4< state_type > stepper;
  72. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  73. double res = std::accumulate( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  74. make_const_step_iterator_end( stepper , lorenz() , x ) ,
  75. 0.0 ,
  76. []( double sum , const state_type &x ) {
  77. return sum + x[0]; } );
  78. cout << res << endl;
  79. //]
  80. }
  81. // std::transform
  82. {
  83. runge_kutta4< state_type > stepper;
  84. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  85. vector< double > weights;
  86. std::transform( make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  87. make_const_step_iterator_end( stepper , lorenz() , x ) ,
  88. back_inserter( weights ) ,
  89. []( const state_type &x ) {
  90. return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } );
  91. for( size_t i=0 ; i<weights.size() ; ++i )
  92. cout << weights[i] << "\n";
  93. }
  94. // std::transform with time_iterator
  95. {
  96. runge_kutta4< state_type > stepper;
  97. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  98. vector< double > weights;
  99. std::transform( make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  100. make_const_step_time_iterator_end( stepper , lorenz() , x ) ,
  101. back_inserter( weights ) ,
  102. []( const std::pair< const state_type &, double > &x ) {
  103. return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } );
  104. for( size_t i=0 ; i<weights.size() ; ++i )
  105. cout << weights[i] << "\n";
  106. }
  107. // /*
  108. // * Boost.Range versions
  109. // */
  110. // boost::range::for_each
  111. {
  112. runge_kutta4< state_type > stepper;
  113. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  114. boost::range::for_each( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  115. []( const state_type &x ) {
  116. std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } );
  117. }
  118. // boost::range::for_each with time iterator
  119. {
  120. runge_kutta4< state_type > stepper;
  121. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  122. boost::range::for_each( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  123. []( const std::pair< const state_type& , double > &x ) {
  124. std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
  125. }
  126. // boost::range::copy with filtered adaptor (simulating std::copy_if)
  127. {
  128. std::vector< state_type > res;
  129. runge_kutta4< state_type > stepper;
  130. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  131. boost::range::copy( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) |
  132. boost::adaptors::filtered( [] ( const state_type &x ) { return ( x[0] > 0.0 ); } ) ,
  133. std::back_inserter( res ) );
  134. for( size_t i=0 ; i<res.size() ; ++i )
  135. cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n";
  136. }
  137. // boost::range::accumulate
  138. {
  139. //[const_step_iterator_accumulate_range
  140. runge_kutta4< state_type > stepper;
  141. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  142. double res = boost::accumulate( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 ,
  143. []( double sum , const state_type &x ) {
  144. return sum + x[0]; } );
  145. cout << res << endl;
  146. //]
  147. }
  148. // boost::range::accumulate with time iterator
  149. {
  150. //[const_step_time_iterator_accumulate_range
  151. runge_kutta4< state_type > stepper;
  152. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  153. double res = boost::accumulate( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 ,
  154. []( double sum , const std::pair< const state_type &, double > &x ) {
  155. return sum + x.first[0]; } );
  156. cout << res << endl;
  157. //]
  158. }
  159. // boost::range::transform
  160. {
  161. runge_kutta4< state_type > stepper;
  162. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  163. vector< double > weights;
  164. boost::transform( make_const_step_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) ,
  165. []( const state_type &x ) {
  166. return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } );
  167. for( size_t i=0 ; i<weights.size() ; ++i )
  168. cout << weights[i] << "\n";
  169. }
  170. // boost::range::find with time iterator
  171. {
  172. runge_kutta4< state_type > stepper;
  173. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  174. auto iter = boost::find_if( make_const_step_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  175. []( const std::pair< const state_type & , double > &x ) {
  176. return ( x.first[0] < 0.0 ); } );
  177. cout << iter->second << "\t" << iter->first[0] << "\t" << iter->first[1] << "\t" << iter->first[2] << "\n";
  178. }
  179. /*
  180. * Boost.Range versions for dense output steppers
  181. */
  182. // boost::range::for_each
  183. {
  184. runge_kutta_dopri5< state_type > stepper;
  185. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  186. boost::range::for_each( make_const_step_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  187. []( const state_type &x ) {
  188. std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } );
  189. }
  190. // boost::range::for_each with time iterator
  191. {
  192. runge_kutta_dopri5< state_type > stepper;
  193. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  194. boost::range::for_each( make_const_step_time_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
  195. []( const std::pair< const state_type& , double > &x ) {
  196. std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
  197. }
  198. /*
  199. * Pure iterators
  200. */
  201. {
  202. runge_kutta4< state_type > stepper;
  203. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  204. auto first = make_const_step_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 );
  205. auto last = make_const_step_iterator_end( stepper , lorenz() , x );
  206. while( first != last )
  207. {
  208. assert( last != first );
  209. cout << (*first)[0] << tab << (*first)[1] << tab << (*first)[2] << "\n";
  210. ++first;
  211. }
  212. }
  213. {
  214. runge_kutta4< state_type > stepper;
  215. state_type x = {{ 10.0 , 10.0 , 10.0 }};
  216. auto first = make_const_step_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 );
  217. auto last = make_const_step_time_iterator_end( stepper , lorenz() , x );
  218. while( first != last )
  219. {
  220. assert( last != first );
  221. cout << first->second << tab << first->first[0] << tab << first->first[1] << tab << first->first[2] << "\n";
  222. ++first;
  223. }
  224. }
  225. return 0;
  226. }