integrate_times.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. [auto_generated]
  3. boost/numeric/odeint/integrate/detail/integrate_times.hpp
  4. [begin_description]
  5. Default integrate times implementation.
  6. [end_description]
  7. Copyright 2009-2012 Karsten Ahnert
  8. Copyright 2009-2012 Mario Mulansky
  9. Distributed under the Boost Software License, Version 1.0.
  10. (See accompanying file LICENSE_1_0.txt or
  11. copy at http://www.boost.org/LICENSE_1_0.txt)
  12. */
  13. #ifndef BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_TIMES_HPP_INCLUDED
  14. #define BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_TIMES_HPP_INCLUDED
  15. #include <stdexcept>
  16. #include <boost/config.hpp>
  17. #include <boost/numeric/odeint/util/unwrap_reference.hpp>
  18. #include <boost/numeric/odeint/stepper/controlled_step_result.hpp>
  19. #include <boost/numeric/odeint/util/detail/less_with_sign.hpp>
  20. namespace boost {
  21. namespace numeric {
  22. namespace odeint {
  23. namespace detail {
  24. /*
  25. * integrate_times for simple stepper
  26. */
  27. template< class Stepper , class System , class State , class TimeIterator , class Time , class Observer >
  28. size_t integrate_times(
  29. Stepper stepper , System system , State &start_state ,
  30. TimeIterator start_time , TimeIterator end_time , Time dt ,
  31. Observer observer , stepper_tag
  32. )
  33. {
  34. BOOST_USING_STD_MIN();
  35. typename odeint::unwrap_reference< Observer >::type &obs = observer;
  36. size_t steps = 0;
  37. Time current_dt = dt;
  38. while( true )
  39. {
  40. Time current_time = *start_time++;
  41. obs( start_state , current_time );
  42. if( start_time == end_time )
  43. break;
  44. while( less_with_sign( current_time , *start_time , current_dt ) )
  45. {
  46. current_dt = min BOOST_PREVENT_MACRO_SUBSTITUTION ( dt , *start_time - current_time );
  47. stepper.do_step( system , start_state , current_time , current_dt );
  48. current_time += current_dt;
  49. steps++;
  50. }
  51. }
  52. return steps;
  53. }
  54. /*
  55. * integrate_times for controlled stepper
  56. */
  57. template< class Stepper , class System , class State , class TimeIterator , class Time , class Observer >
  58. size_t integrate_times(
  59. Stepper stepper , System system , State &start_state ,
  60. TimeIterator start_time , TimeIterator end_time , Time dt ,
  61. Observer observer , controlled_stepper_tag
  62. )
  63. {
  64. BOOST_USING_STD_MIN();
  65. typename odeint::unwrap_reference< Observer >::type &obs = observer;
  66. const size_t max_attempts = 1000;
  67. const char *error_string = "Integrate adaptive : Maximal number of iterations reached. A step size could not be found.";
  68. size_t steps = 0;
  69. while( true )
  70. {
  71. size_t fail_steps = 0;
  72. Time current_time = *start_time++;
  73. obs( start_state , current_time );
  74. if( start_time == end_time )
  75. break;
  76. while( less_with_sign( current_time , *start_time , dt ) )
  77. {
  78. dt = min BOOST_PREVENT_MACRO_SUBSTITUTION ( dt , *start_time - current_time );
  79. if( stepper.try_step( system , start_state , current_time , dt ) == success )
  80. {
  81. ++steps;
  82. }
  83. else
  84. {
  85. ++fail_steps;
  86. }
  87. if( fail_steps == max_attempts ) throw std::overflow_error( error_string );
  88. }
  89. }
  90. return steps;
  91. }
  92. /*
  93. * integrate_times for dense output stepper
  94. */
  95. template< class Stepper , class System , class State , class TimeIterator , class Time , class Observer >
  96. size_t integrate_times(
  97. Stepper stepper , System system , State &start_state ,
  98. TimeIterator start_time , TimeIterator end_time , Time dt ,
  99. Observer observer , dense_output_stepper_tag
  100. )
  101. {
  102. typename odeint::unwrap_reference< Observer >::type &obs = observer;
  103. if( start_time == end_time )
  104. return 0;
  105. Time last_time_point = *(end_time-1);
  106. stepper.initialize( start_state , *start_time , dt );
  107. obs( start_state , *start_time++ );
  108. size_t count = 0;
  109. while( start_time != end_time )
  110. {
  111. while( ( start_time != end_time ) && less_eq_with_sign( *start_time , stepper.current_time() , stepper.current_time_step() ) )
  112. {
  113. stepper.calc_state( *start_time , start_state );
  114. obs( start_state , *start_time );
  115. start_time++;
  116. }
  117. // we have not reached the end, do another real step
  118. if( less_eq_with_sign( stepper.current_time() + stepper.current_time_step() ,
  119. last_time_point ,
  120. stepper.current_time_step() ) )
  121. {
  122. stepper.do_step( system );
  123. ++count;
  124. }
  125. else if( start_time != end_time )
  126. { // do the last step ending exactly on the end point
  127. stepper.initialize( stepper.current_state() , stepper.current_time() , last_time_point - stepper.current_time() );
  128. stepper.do_step( system );
  129. ++count;
  130. }
  131. }
  132. return count;
  133. }
  134. } // namespace detail
  135. } // namespace odeint
  136. } // namespace numeric
  137. } // namespace boost
  138. #endif // BOOST_NUMERIC_ODEINT_INTEGRATE_DETAIL_INTEGRATE_ADAPTIVE_HPP_INCLUDED