1 | /* |
2 | [auto_generated] |
3 | boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp |
4 | |
5 | [begin_description] |
6 | Implementation of the Runge Kutta Cash Karp 5(4) method. It uses the generic error stepper. |
7 | [end_description] |
8 | |
9 | Copyright 2011-2013 Mario Mulansky |
10 | Copyright 2011-2013 Karsten Ahnert |
11 | |
12 | Distributed under the Boost Software License, Version 1.0. |
13 | (See accompanying file LICENSE_1_0.txt or |
14 | copy at http://www.boost.org/LICENSE_1_0.txt) |
15 | */ |
16 | |
17 | |
18 | #ifndef BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED |
19 | #define BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED |
20 | |
21 | #include <boost/fusion/container/vector.hpp> |
22 | #include <boost/fusion/container/generation/make_vector.hpp> |
23 | |
24 | #include <boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp> |
25 | #include <boost/numeric/odeint/algebra/range_algebra.hpp> |
26 | #include <boost/numeric/odeint/algebra/default_operations.hpp> |
27 | #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> |
28 | #include <boost/numeric/odeint/algebra/operations_dispatcher.hpp> |
29 | |
30 | #include <boost/numeric/odeint/util/state_wrapper.hpp> |
31 | #include <boost/numeric/odeint/util/is_resizeable.hpp> |
32 | #include <boost/numeric/odeint/util/resizer.hpp> |
33 | |
34 | #include <boost/array.hpp> |
35 | |
36 | |
37 | |
38 | |
39 | namespace boost { |
40 | namespace numeric { |
41 | namespace odeint { |
42 | |
43 | |
44 | #ifndef DOXYGEN_SKIP |
45 | template< class Value = double > |
46 | struct rk54_ck_coefficients_a1 : boost::array< Value , 1 > |
47 | { |
48 | rk54_ck_coefficients_a1( void ) |
49 | { |
50 | (*this)[0] = static_cast< Value >( 1 )/static_cast< Value >( 5 ); |
51 | } |
52 | }; |
53 | |
54 | template< class Value = double > |
55 | struct rk54_ck_coefficients_a2 : boost::array< Value , 2 > |
56 | { |
57 | rk54_ck_coefficients_a2( void ) |
58 | { |
59 | (*this)[0] = static_cast<Value>( 3 )/static_cast<Value>( 40 ); |
60 | (*this)[1] = static_cast<Value>( 9 )/static_cast<Value>( 40 ); |
61 | } |
62 | }; |
63 | |
64 | |
65 | template< class Value = double > |
66 | struct rk54_ck_coefficients_a3 : boost::array< Value , 3 > |
67 | { |
68 | rk54_ck_coefficients_a3( void ) |
69 | { |
70 | (*this)[0] = static_cast<Value>( 3 )/static_cast<Value>( 10 ); |
71 | (*this)[1] = static_cast<Value>( -9 )/static_cast<Value>( 10 ); |
72 | (*this)[2] = static_cast<Value>( 6 )/static_cast<Value>( 5 ); |
73 | } |
74 | }; |
75 | |
76 | template< class Value = double > |
77 | struct rk54_ck_coefficients_a4 : boost::array< Value , 4 > |
78 | { |
79 | rk54_ck_coefficients_a4( void ) |
80 | { |
81 | (*this)[0] = static_cast<Value>( -11 )/static_cast<Value>( 54 ); |
82 | (*this)[1] = static_cast<Value>( 5 )/static_cast<Value>( 2 ); |
83 | (*this)[2] = static_cast<Value>( -70 )/static_cast<Value>( 27 ); |
84 | (*this)[3] = static_cast<Value>( 35 )/static_cast<Value>( 27 ); |
85 | } |
86 | }; |
87 | |
88 | template< class Value = double > |
89 | struct rk54_ck_coefficients_a5 : boost::array< Value , 5 > |
90 | { |
91 | rk54_ck_coefficients_a5( void ) |
92 | { |
93 | (*this)[0] = static_cast<Value>( 1631 )/static_cast<Value>( 55296 ); |
94 | (*this)[1] = static_cast<Value>( 175 )/static_cast<Value>( 512 ); |
95 | (*this)[2] = static_cast<Value>( 575 )/static_cast<Value>( 13824 ); |
96 | (*this)[3] = static_cast<Value>( 44275 )/static_cast<Value>( 110592 ); |
97 | (*this)[4] = static_cast<Value>( 253 )/static_cast<Value>( 4096 ); |
98 | } |
99 | }; |
100 | |
101 | template< class Value = double > |
102 | struct rk54_ck_coefficients_b : boost::array< Value , 6 > |
103 | { |
104 | rk54_ck_coefficients_b( void ) |
105 | { |
106 | (*this)[0] = static_cast<Value>( 37 )/static_cast<Value>( 378 ); |
107 | (*this)[1] = static_cast<Value>( 0 ); |
108 | (*this)[2] = static_cast<Value>( 250 )/static_cast<Value>( 621 ); |
109 | (*this)[3] = static_cast<Value>( 125 )/static_cast<Value>( 594 ); |
110 | (*this)[4] = static_cast<Value>( 0 ); |
111 | (*this)[5] = static_cast<Value>( 512 )/static_cast<Value>( 1771 ); |
112 | } |
113 | }; |
114 | |
115 | template< class Value = double > |
116 | struct rk54_ck_coefficients_db : boost::array< Value , 6 > |
117 | { |
118 | rk54_ck_coefficients_db( void ) |
119 | { |
120 | (*this)[0] = static_cast<Value>( 37 )/static_cast<Value>( 378 ) - static_cast<Value>( 2825 )/static_cast<Value>( 27648 ); |
121 | (*this)[1] = static_cast<Value>( 0 ); |
122 | (*this)[2] = static_cast<Value>( 250 )/static_cast<Value>( 621 ) - static_cast<Value>( 18575 )/static_cast<Value>( 48384 ); |
123 | (*this)[3] = static_cast<Value>( 125 )/static_cast<Value>( 594 ) - static_cast<Value>( 13525 )/static_cast<Value>( 55296 ); |
124 | (*this)[4] = static_cast<Value>( -277 )/static_cast<Value>( 14336 ); |
125 | (*this)[5] = static_cast<Value>( 512 )/static_cast<Value>( 1771 ) - static_cast<Value>( 1 )/static_cast<Value>( 4 ); |
126 | } |
127 | }; |
128 | |
129 | |
130 | template< class Value = double > |
131 | struct rk54_ck_coefficients_c : boost::array< Value , 6 > |
132 | { |
133 | rk54_ck_coefficients_c( void ) |
134 | { |
135 | (*this)[0] = static_cast<Value>(0); |
136 | (*this)[1] = static_cast<Value>( 1 )/static_cast<Value>( 5 ); |
137 | (*this)[2] = static_cast<Value>( 3 )/static_cast<Value>( 10 ); |
138 | (*this)[3] = static_cast<Value>( 3 )/static_cast<Value>( 5 ); |
139 | (*this)[4] = static_cast<Value>( 1 ); |
140 | (*this)[5] = static_cast<Value>( 7 )/static_cast<Value>( 8 ); |
141 | } |
142 | }; |
143 | #endif |
144 | |
145 | |
146 | template< |
147 | class State , |
148 | class Value = double , |
149 | class Deriv = State , |
150 | class Time = Value , |
151 | class Algebra = typename algebra_dispatcher< State >::algebra_type , |
152 | class Operations = typename operations_dispatcher< State >::operations_type , |
153 | class Resizer = initially_resizer |
154 | > |
155 | #ifndef DOXYGEN_SKIP |
156 | class runge_kutta_cash_karp54 : public explicit_error_generic_rk< 6 , 5 , 5 , 4 , |
157 | State , Value , Deriv , Time , Algebra , Operations , Resizer > |
158 | #else |
159 | class runge_kutta_cash_karp54 : public explicit_error_generic_rk |
160 | #endif |
161 | { |
162 | |
163 | public: |
164 | #ifndef DOXYGEN_SKIP |
165 | typedef explicit_error_generic_rk< 6 , 5 , 5 , 4 , State , Value , Deriv , Time , |
166 | Algebra , Operations , Resizer > stepper_base_type; |
167 | #endif |
168 | typedef typename stepper_base_type::state_type state_type; |
169 | typedef typename stepper_base_type::value_type value_type; |
170 | typedef typename stepper_base_type::deriv_type deriv_type; |
171 | typedef typename stepper_base_type::time_type time_type; |
172 | typedef typename stepper_base_type::algebra_type algebra_type; |
173 | typedef typename stepper_base_type::operations_type operations_type; |
174 | typedef typename stepper_base_type::resizer_type resizer_typ; |
175 | |
176 | #ifndef DOXYGEN_SKIP |
177 | typedef typename stepper_base_type::stepper_type stepper_type; |
178 | typedef typename stepper_base_type::wrapped_state_type wrapped_state_type; |
179 | typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type; |
180 | #endif |
181 | |
182 | |
183 | runge_kutta_cash_karp54( const algebra_type &algebra = algebra_type() ) : stepper_base_type( |
184 | boost::fusion::make_vector( rk54_ck_coefficients_a1<Value>() , |
185 | rk54_ck_coefficients_a2<Value>() , |
186 | rk54_ck_coefficients_a3<Value>() , |
187 | rk54_ck_coefficients_a4<Value>() , |
188 | rk54_ck_coefficients_a5<Value>() ) , |
189 | rk54_ck_coefficients_b<Value>() , rk54_ck_coefficients_db<Value>() , rk54_ck_coefficients_c<Value>() , |
190 | algebra ) |
191 | { } |
192 | }; |
193 | |
194 | |
195 | /********** DOXYGEN **********/ |
196 | |
197 | /** |
198 | * \class runge_kutta_cash_karp54 |
199 | * \brief The Runge-Kutta Cash-Karp method. |
200 | * |
201 | * The Runge-Kutta Cash-Karp method is one of the standard methods for |
202 | * solving ordinary differential equations, see |
203 | * <a href="http://en.wikipedia.org/wiki/Cash%E2%80%93Karp_methods">en.wikipedia.org/wiki/Cash-Karp_methods</a>. |
204 | * The method is explicit and fulfills the Error Stepper concept. Step size control |
205 | * is provided but continuous output is not available for this method. |
206 | * |
207 | * This class derives from explicit_error_stepper_base and inherits its interface via CRTP (current recurring template pattern). |
208 | * Furthermore, it derivs from explicit_error_generic_rk which is a generic Runge-Kutta algorithm with error estimation. |
209 | * For more details see explicit_error_stepper_base and explicit_error_generic_rk. |
210 | * |
211 | * \tparam State The state type. |
212 | * \tparam Value The value type. |
213 | * \tparam Deriv The type representing the time derivative of the state. |
214 | * \tparam Time The time representing the independent variable - the time. |
215 | * \tparam Algebra The algebra type. |
216 | * \tparam Operations The operations type. |
217 | * \tparam Resizer The resizer policy type. |
218 | */ |
219 | |
220 | |
221 | /** |
222 | * \fn runge_kutta_cash_karp54::runge_kutta_cash_karp54( const algebra_type &algebra ) |
223 | * \brief Constructs the runge_kutta_cash_karp54 class. This constructor can be used as a default |
224 | * constructor if the algebra has a default constructor. |
225 | * \param algebra A copy of algebra is made and stored inside explicit_stepper_base. |
226 | */ |
227 | } |
228 | } |
229 | } |
230 | |
231 | #endif // BOOST_NUMERIC_ODEINT_STEPPER_RUNGE_KUTTA_CASH_KARP54_HPP_INCLUDED |
232 | |