File indexing completed on 2025-01-18 09:42:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_CLASSIC_HPP_INCLUDED
0021
0022
0023 #include <boost/numeric/odeint/util/bind.hpp>
0024
0025 #include <boost/numeric/odeint/stepper/base/explicit_error_stepper_base.hpp>
0026 #include <boost/numeric/odeint/algebra/range_algebra.hpp>
0027 #include <boost/numeric/odeint/algebra/default_operations.hpp>
0028 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0029 #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp>
0030 #include <boost/numeric/odeint/stepper/stepper_categories.hpp>
0031 #include <boost/numeric/odeint/util/state_wrapper.hpp>
0032 #include <boost/numeric/odeint/util/is_resizeable.hpp>
0033 #include <boost/numeric/odeint/util/resizer.hpp>
0034
0035 namespace boost {
0036 namespace numeric {
0037 namespace odeint {
0038
0039
0040
0041
0042 template<
0043 class State ,
0044 class Value = double ,
0045 class Deriv = State ,
0046 class Time = Value ,
0047 class Algebra = typename algebra_dispatcher< State >::algebra_type ,
0048 class Operations = typename operations_dispatcher< State >::operations_type ,
0049 class Resizer = initially_resizer
0050 >
0051 #ifndef DOXYGEN_SKIP
0052 class runge_kutta_cash_karp54_classic
0053 : public explicit_error_stepper_base<
0054 runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
0055 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer >
0056 #else
0057 class runge_kutta_cash_karp54_classic : public explicit_error_stepper_base
0058 #endif
0059 {
0060
0061
0062 public :
0063
0064 #ifndef DOXYGEN_SKIP
0065 typedef explicit_error_stepper_base<
0066 runge_kutta_cash_karp54_classic< State , Value , Deriv , Time , Algebra , Operations , Resizer > ,
0067 5 , 5 , 4 , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_base_type;
0068 #else
0069 typedef explicit_error_stepper_base< runge_kutta_cash_karp54_classic< ... > , ... > stepper_base_type;
0070 #endif
0071
0072 typedef typename stepper_base_type::state_type state_type;
0073 typedef typename stepper_base_type::value_type value_type;
0074 typedef typename stepper_base_type::deriv_type deriv_type;
0075 typedef typename stepper_base_type::time_type time_type;
0076 typedef typename stepper_base_type::algebra_type algebra_type;
0077 typedef typename stepper_base_type::operations_type operations_type;
0078 typedef typename stepper_base_type::resizer_type resizer_type;
0079
0080 #ifndef DOXYGEN_SKIP
0081 typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
0082 typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
0083 typedef typename stepper_base_type::stepper_type stepper_type;
0084 #endif
0085
0086
0087 runge_kutta_cash_karp54_classic( const algebra_type &algebra = algebra_type() ) : stepper_base_type( algebra )
0088 { }
0089
0090
0091
0092 template< class System , class StateIn , class DerivIn , class StateOut , class Err >
0093 void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt , Err &xerr )
0094 {
0095 const value_type c1 = static_cast<value_type> ( 37 ) / static_cast<value_type>( 378 );
0096 const value_type c3 = static_cast<value_type> ( 250 ) / static_cast<value_type>( 621 );
0097 const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 594 );
0098 const value_type c6 = static_cast<value_type> ( 512 ) / static_cast<value_type>( 1771 );
0099
0100 const value_type dc1 = c1 - static_cast<value_type> ( 2825 ) / static_cast<value_type>( 27648 );
0101 const value_type dc3 = c3 - static_cast<value_type> ( 18575 ) / static_cast<value_type>( 48384 );
0102 const value_type dc4 = c4 - static_cast<value_type> ( 13525 ) / static_cast<value_type>( 55296 );
0103 const value_type dc5 = static_cast<value_type> ( -277 ) / static_cast<value_type>( 14336 );
0104 const value_type dc6 = c6 - static_cast<value_type> ( 1 ) / static_cast<value_type> ( 4 );
0105
0106 do_step_impl( system , in , dxdt , t , out , dt );
0107
0108
0109 stepper_base_type::m_algebra.for_each6( xerr , dxdt , m_k3.m_v , m_k4.m_v , m_k5.m_v , m_k6.m_v ,
0110 typename operations_type::template scale_sum5< time_type , time_type , time_type , time_type , time_type >( dt*dc1 , dt*dc3 , dt*dc4 , dt*dc5 , dt*dc6 ));
0111
0112 }
0113
0114
0115
0116 template< class System , class StateIn , class DerivIn , class StateOut >
0117 void do_step_impl( System system , const StateIn &in , const DerivIn &dxdt , time_type t , StateOut &out , time_type dt )
0118 {
0119 const value_type a2 = static_cast<value_type> ( 1 ) / static_cast<value_type> ( 5 );
0120 const value_type a3 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
0121 const value_type a4 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 5 );
0122 const value_type a5 = static_cast<value_type> ( 1 );
0123 const value_type a6 = static_cast<value_type> ( 7 ) / static_cast<value_type> ( 8 );
0124
0125 const value_type b21 = static_cast<value_type> ( 1 ) / static_cast<value_type> ( 5 );
0126 const value_type b31 = static_cast<value_type> ( 3 ) / static_cast<value_type>( 40 );
0127 const value_type b32 = static_cast<value_type> ( 9 ) / static_cast<value_type>( 40 );
0128 const value_type b41 = static_cast<value_type> ( 3 ) / static_cast<value_type> ( 10 );
0129 const value_type b42 = static_cast<value_type> ( -9 ) / static_cast<value_type> ( 10 );
0130 const value_type b43 = static_cast<value_type> ( 6 ) / static_cast<value_type> ( 5 );
0131 const value_type b51 = static_cast<value_type> ( -11 ) / static_cast<value_type>( 54 );
0132 const value_type b52 = static_cast<value_type> ( 5 ) / static_cast<value_type> ( 2 );
0133 const value_type b53 = static_cast<value_type> ( -70 ) / static_cast<value_type>( 27 );
0134 const value_type b54 = static_cast<value_type> ( 35 ) / static_cast<value_type>( 27 );
0135 const value_type b61 = static_cast<value_type> ( 1631 ) / static_cast<value_type>( 55296 );
0136 const value_type b62 = static_cast<value_type> ( 175 ) / static_cast<value_type>( 512 );
0137 const value_type b63 = static_cast<value_type> ( 575 ) / static_cast<value_type>( 13824 );
0138 const value_type b64 = static_cast<value_type> ( 44275 ) / static_cast<value_type>( 110592 );
0139 const value_type b65 = static_cast<value_type> ( 253 ) / static_cast<value_type>( 4096 );
0140
0141 const value_type c1 = static_cast<value_type> ( 37 ) / static_cast<value_type>( 378 );
0142 const value_type c3 = static_cast<value_type> ( 250 ) / static_cast<value_type>( 621 );
0143 const value_type c4 = static_cast<value_type> ( 125 ) / static_cast<value_type>( 594 );
0144 const value_type c6 = static_cast<value_type> ( 512 ) / static_cast<value_type>( 1771 );
0145
0146 typename odeint::unwrap_reference< System >::type &sys = system;
0147
0148 m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl<StateIn> , detail::ref( *this ) , detail::_1 ) );
0149
0150
0151 stepper_base_type::m_algebra.for_each3( m_x_tmp.m_v , in , dxdt ,
0152 typename operations_type::template scale_sum2< value_type , time_type >( 1.0 , dt*b21 ) );
0153
0154 sys( m_x_tmp.m_v , m_k2.m_v , t + dt*a2 );
0155
0156 stepper_base_type::m_algebra.for_each4( m_x_tmp.m_v , in , dxdt , m_k2.m_v ,
0157 typename operations_type::template scale_sum3< value_type , time_type , time_type >( 1.0 , dt*b31 , dt*b32 ));
0158
0159 sys( m_x_tmp.m_v , m_k3.m_v , t + dt*a3 );
0160
0161 stepper_base_type::m_algebra.for_each5( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v ,
0162 typename operations_type::template scale_sum4< value_type , time_type , time_type , time_type >( 1.0 , dt*b41 , dt*b42 , dt*b43 ));
0163
0164 sys( m_x_tmp.m_v, m_k4.m_v , t + dt*a4 );
0165 stepper_base_type::m_algebra.for_each6( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v , m_k4.m_v ,
0166 typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b51 , dt*b52 , dt*b53 , dt*b54 ));
0167
0168 sys( m_x_tmp.m_v , m_k5.m_v , t + dt*a5 );
0169 stepper_base_type::m_algebra.for_each7( m_x_tmp.m_v , in , dxdt , m_k2.m_v , m_k3.m_v , m_k4.m_v , m_k5.m_v ,
0170 typename operations_type::template scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt*b61 , dt*b62 , dt*b63 , dt*b64 , dt*b65 ));
0171
0172 sys( m_x_tmp.m_v , m_k6.m_v , t + dt*a6 );
0173 stepper_base_type::m_algebra.for_each6( out , in , dxdt , m_k3.m_v , m_k4.m_v , m_k6.m_v ,
0174 typename operations_type::template scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt*c1 , dt*c3 , dt*c4 , dt*c6 ));
0175
0176 }
0177
0178
0179
0180
0181
0182 template< class StateIn >
0183 void adjust_size( const StateIn &x )
0184 {
0185 resize_impl( x );
0186 stepper_base_type::adjust_size( x );
0187 }
0188
0189 private:
0190
0191 template< class StateIn >
0192 bool resize_impl( const StateIn &x )
0193 {
0194 bool resized = false;
0195 resized |= adjust_size_by_resizeability( m_x_tmp , x , typename is_resizeable<state_type>::type() );
0196 resized |= adjust_size_by_resizeability( m_k2 , x , typename is_resizeable<deriv_type>::type() );
0197 resized |= adjust_size_by_resizeability( m_k3 , x , typename is_resizeable<deriv_type>::type() );
0198 resized |= adjust_size_by_resizeability( m_k4 , x , typename is_resizeable<deriv_type>::type() );
0199 resized |= adjust_size_by_resizeability( m_k5 , x , typename is_resizeable<deriv_type>::type() );
0200 resized |= adjust_size_by_resizeability( m_k6 , x , typename is_resizeable<deriv_type>::type() );
0201 return resized;
0202 }
0203
0204
0205 wrapped_state_type m_x_tmp;
0206 wrapped_deriv_type m_k2, m_k3, m_k4, m_k5, m_k6;
0207 resizer_type m_resizer;
0208
0209 };
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282 }
0283 }
0284 }
0285
0286
0287
0288
0289 #endif