3 libs/numeric/odeint/test/adams_bashforth.cpp
6 This file tests the use of the adams bashforth stepper.
9 Copyright 2011-2012 Karsten Ahnert
10 Copyright 2011-2012 Mario Mulansky
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)
18 // disable checked iterator warning for msvc
20 #include <boost/config.hpp>
22 #pragma warning(disable:4996)
25 #define BOOST_TEST_MODULE odeint_adams_bashforth
29 #include <boost/array.hpp>
31 #include <boost/test/unit_test.hpp>
33 #include <boost/mpl/list.hpp>
34 #include <boost/mpl/size_t.hpp>
35 #include <boost/mpl/range_c.hpp>
38 #include <boost/numeric/odeint/stepper/adams_bashforth.hpp>
39 #include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
41 using namespace boost::unit_test
;
42 using namespace boost::numeric::odeint
;
44 typedef double value_type
;
48 template< class State
, class Deriv
, class Value
>
49 void operator()( const State
&_x
, Deriv
&_dxdt
, const Value
&dt
) const
51 const value_type sigma
= 10.0;
52 const value_type R
= 28.0;
53 const value_type b
= 8.0 / 3.0;
55 typename
boost::range_iterator
< const State
>::type x
= boost::begin( _x
);
56 typename
boost::range_iterator
< Deriv
>::type dxdt
= boost::begin( _dxdt
);
58 dxdt
[0] = sigma
* ( x
[1] - x
[0] );
59 dxdt
[1] = R
* x
[0] - x
[1] - x
[0] * x
[2];
60 dxdt
[2] = x
[0]*x
[1] - b
* x
[2];
64 template< class State
>
71 template< class System
, class StateIn
, class DerivIn
, class StateOut
>
72 void do_step_dxdt_impl( System system
, const StateIn
&in
, const DerivIn
&dxdt
, value_type t
, StateOut
&out
, value_type dt
)
74 m_stepper
.do_step( system
, in
, dxdt
, t
, out
, dt
);
78 template< class System
, class StateInOut
, class DerivIn
>
79 void do_step_dxdt_impl( System system
, StateInOut
&x
, const DerivIn
&dxdt
, value_type t
, value_type dt
)
81 m_stepper
.do_step( system
, x
, dxdt
, t
, dt
);
86 runge_kutta4
< State
> m_stepper
;
94 BOOST_AUTO_TEST_SUITE( adams_bashforth_test
)
96 BOOST_AUTO_TEST_CASE( test_adams_bashforth_coefficients
)
98 detail::adams_bashforth_coefficients
< value_type
, 1 > c1
;
99 detail::adams_bashforth_coefficients
< value_type
, 2 > c2
;
100 detail::adams_bashforth_coefficients
< value_type
, 3 > c3
;
101 detail::adams_bashforth_coefficients
< value_type
, 4 > c4
;
102 detail::adams_bashforth_coefficients
< value_type
, 5 > c5
;
103 detail::adams_bashforth_coefficients
< value_type
, 6 > c6
;
104 detail::adams_bashforth_coefficients
< value_type
, 7 > c7
;
105 detail::adams_bashforth_coefficients
< value_type
, 8 > c8
;
108 BOOST_AUTO_TEST_CASE( test_rotating_buffer
)
111 detail::rotating_buffer
< size_t , N
> buffer
;
112 for( size_t i
=0 ; i
<N
; ++i
) buffer
[i
] = i
;
114 for( size_t i
=0 ; i
<N
; ++i
)
115 BOOST_CHECK_EQUAL( buffer
[i
] , i
);
119 for( size_t i
=1 ; i
<N
; ++i
)
120 BOOST_CHECK_EQUAL( buffer
[i
] , i
- 1 );
121 BOOST_CHECK_EQUAL( buffer
[0] , size_t( N
-1 ) );
124 BOOST_AUTO_TEST_CASE( test_copying
)
126 typedef boost::array
< double , 1 > state_type
;
127 typedef adams_bashforth
< 2 , state_type
> stepper_type
;
130 s1
.step_storage()[0].m_v
[0] = 1.5;
131 s1
.step_storage()[1].m_v
[0] = 2.25;
133 stepper_type
s2( s1
);
134 BOOST_CHECK_CLOSE( s1
.step_storage()[0].m_v
[0] , s2
.step_storage()[0].m_v
[0] , 1.0e-14 );
135 BOOST_CHECK_CLOSE( s1
.step_storage()[1].m_v
[0] , s2
.step_storage()[1].m_v
[0] , 1.0e-14 );
136 BOOST_CHECK( ( &(s1
.step_storage()[0]) ) != ( &(s2
.step_storage()[0]) ) );
139 state_type
*p1
= &( s3
.step_storage()[0].m_v
) , *p2
= &( s3
.step_storage()[1].m_v
);
141 BOOST_CHECK( p1
== ( &( s3
.step_storage()[0].m_v
) ) );
142 BOOST_CHECK( p2
== ( &( s3
.step_storage()[1].m_v
) ) );
144 BOOST_CHECK_CLOSE( s1
.step_storage()[0].m_v
[0] , s3
.step_storage()[0].m_v
[0] , 1.0e-14 );
145 BOOST_CHECK_CLOSE( s1
.step_storage()[1].m_v
[0] , s3
.step_storage()[1].m_v
[0] , 1.0e-14 );
148 typedef boost::mpl::range_c
< size_t , 1 , 6 > vector_of_steps
;
150 BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps
, step_type
, vector_of_steps
)
152 const static size_t steps
= step_type::value
;
153 typedef boost::array
< value_type
, 3 > state_type
;
155 adams_bashforth
< steps
, state_type
> stepper
;
156 state_type x
= {{ 10.0 , 10.0 , 10.0 }};
157 const value_type dt
= 0.01;
160 stepper
.initialize( lorenz() , x
, t
, dt
);
161 BOOST_CHECK_CLOSE( t
, value_type( steps
- 1 ) * dt
, 1.0e-14 );
163 stepper
.do_step( lorenz() , x
, t
, dt
);
166 BOOST_AUTO_TEST_CASE( test_instantiation
)
168 typedef boost::array
< double , 3 > state_type
;
169 adams_bashforth
< 1 , state_type
> s1
;
170 adams_bashforth
< 2 , state_type
> s2
;
171 adams_bashforth
< 3 , state_type
> s3
;
172 adams_bashforth
< 4 , state_type
> s4
;
173 adams_bashforth
< 5 , state_type
> s5
;
174 adams_bashforth
< 6 , state_type
> s6
;
175 adams_bashforth
< 7 , state_type
> s7
;
176 adams_bashforth
< 8 , state_type
> s8
;
178 state_type x
= {{ 10.0 , 10.0 , 10.0 }};
179 value_type t
= 0.0 , dt
= 0.01;
180 s1
.do_step( lorenz() , x
, t
, dt
);
181 s2
.do_step( lorenz() , x
, t
, dt
);
182 s3
.do_step( lorenz() , x
, t
, dt
);
183 s4
.do_step( lorenz() , x
, t
, dt
);
184 s5
.do_step( lorenz() , x
, t
, dt
);
185 s6
.do_step( lorenz() , x
, t
, dt
);
186 // s7.do_step( lorenz() , x , t , dt );
187 // s8.do_step( lorenz() , x , t , dt );
190 BOOST_AUTO_TEST_CASE( test_auto_initialization
)
192 typedef boost::array
< double , 3 > state_type
;
193 state_type x
= {{ 10.0 , 10.0 , 10.0 }};
195 adams_bashforth
< 3 , state_type
, value_type
, state_type
, value_type
, range_algebra
, default_operations
,
196 initially_resizer
, rk4_decorator
< state_type
> > adams
;
198 adams
.initializing_stepper().do_count
= 0;
199 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
200 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 1 ) );
202 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
203 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
205 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
206 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
208 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
209 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
211 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
212 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
215 BOOST_AUTO_TEST_CASE( test_manual_initialization
)
217 typedef boost::array
< double , 3 > state_type
;
218 state_type x
= {{ 10.0 , 10.0 , 10.0 }};
220 adams_bashforth
< 3 , state_type
, value_type
, state_type
, value_type
, range_algebra
, default_operations
,
221 initially_resizer
, rk4_decorator
< state_type
> > adams
;
223 adams
.initializing_stepper().do_count
= 0;
224 double t
= 0.0 , dt
= 0.1;
225 adams
.initialize( lorenz() , x
, t
, dt
);
226 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
228 adams
.do_step( lorenz() , x
, 0.0 , x
, 0.1 );
229 BOOST_CHECK_EQUAL( adams
.initializing_stepper().do_count
, size_t( 2 ) );
232 BOOST_AUTO_TEST_SUITE_END()