diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/numeric/odeint/test | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/numeric/odeint/test')
75 files changed, 11992 insertions, 0 deletions
diff --git a/src/boost/libs/numeric/odeint/test/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/Jamfile.v2 new file mode 100644 index 00000000..68725822 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/Jamfile.v2 @@ -0,0 +1,103 @@ +# Copyright 2012-2013 Karsten Ahnert +# Copyright 2012-2013 Mario Mulansky +# Copyright 2013 Pascal Germroth +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# bring in rules for testing + +import testing ; + +# make sure you are using a new version of boost.build, otherwise the local +# odeint will not be included properly +# you can fix older boost.build versions by applying the patch provided in +# odeint's root, e.g.: +# cd ~/odeint-v2 +# sudo patch /usr/share/boost-build/build/toolset.jam toolset.jam.patch + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <define>BOOST_ALL_NO_LIB=1 + # use test library + <library>/boost//unit_test_framework + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + # <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run euler_stepper.cpp ] + [ run runge_kutta_concepts.cpp ] + [ run runge_kutta_error_concepts.cpp ] + [ run runge_kutta_controlled_concepts.cpp ] + [ run resizing.cpp ] + [ run default_operations.cpp ] + [ run range_algebra.cpp ] + [ run implicit_euler.cpp ] +# disable in clang + [ run fusion_algebra.cpp : : : <toolset>clang:<build>no ] + [ run stepper_with_units.cpp : : : <toolset>clang:<build>no ] + [ run stepper_copying.cpp ] + [ run stepper_with_ranges.cpp ] + [ run rosenbrock4.cpp ] + [ run rosenbrock4_mp.cpp ] + [ run is_pair.cpp ] + [ run adams_bashforth.cpp ] + [ run adams_moulton.cpp ] + [ run adams_bashforth_moulton.cpp ] + [ run controlled_adams_bashforth_moulton.cpp ] + [ run adaptive_adams_coefficients.cpp ] + [ run generic_stepper.cpp ] + [ run generic_error_stepper.cpp ] + [ run bulirsch_stoer.cpp ] + [ run integrate_times.cpp ] + [ run integrate_times.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_times_iterator ] + [ run integrate.cpp ] + [ run integrate.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_iterator ] + [ run integrate_implicit.cpp ] + [ run integrate_implicit.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrate_implicit_iterator ] + [ run generation.cpp ] + [ run trivial_state.cpp ] + [ run is_resizeable.cpp ] + [ run resize.cpp ] + [ run same_size.cpp ] + [ run split.cpp ] + [ run symplectic_steppers.cpp ] + [ run integrators_symplectic.cpp ] + [ run integrators_symplectic.cpp : : : <define>ODEINT_INTEGRATE_ITERATOR : integrators_symplectic_iterator ] + [ run velocity_verlet.cpp ] + [ run multi_array.cpp ] + [ compile algebra_dispatcher.cpp ] + [ run integrate_stepper_refs.cpp ] + [ run const_step_iterator.cpp ] + [ run const_step_time_iterator.cpp ] + [ run adaptive_iterator.cpp ] + [ run adaptive_time_iterator.cpp ] + [ run n_step_iterator.cpp ] + [ run n_step_time_iterator.cpp ] + [ run times_iterator.cpp ] + [ run times_time_iterator.cpp ] + [ run step_size_limitation.cpp ] + [ run integrate_overflow.cpp ] + [ compile unwrap_boost_reference.cpp ] + [ compile unwrap_reference.cpp : <cxxflags>-std=c++0x : unwrap_reference_C++11 ] + [ compile std_array.cpp : <cxxflags>-std=c++0x ] + : + <testing.launcher>valgrind + ; + +# also run numeric tests +build-project numeric ; + +build-project regression ; + +# test-suite "odeint-iterator_integrate" +# : +# [ run integrate.cpp : : : : integrate_iterator ] +# : <testing.launcher>valgrind +# <define>ODEINT_ITERATOR_INTEGRATE +# ; + diff --git a/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp b/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp new file mode 100644 index 00000000..7574346c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_bashforth.cpp @@ -0,0 +1,237 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_bashforth.cpp + + [begin_description] + This file tests the use of the adams bashforth stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adams_bashforth + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + + +#include <boost/numeric/odeint/stepper/adams_bashforth.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +template< class State > +class rk4_decorator +{ +public: + + size_t do_count; + + template< class System , class StateIn , class DerivIn , class StateOut > + void do_step_dxdt_impl( System system , const StateIn &in , const DerivIn &dxdt , value_type t , StateOut &out , value_type dt ) + { + m_stepper.do_step( system , in , dxdt , t , out , dt ); + ++do_count; + } + + template< class System , class StateInOut , class DerivIn > + void do_step_dxdt_impl( System system , StateInOut &x , const DerivIn &dxdt , value_type t , value_type dt ) + { + m_stepper.do_step( system , x , dxdt , t , dt ); + ++do_count; + } + + + runge_kutta4< State > m_stepper; + +private: + + +}; + + +BOOST_AUTO_TEST_SUITE( adams_bashforth_test ) + +BOOST_AUTO_TEST_CASE( test_adams_bashforth_coefficients ) +{ + detail::adams_bashforth_coefficients< value_type , 1 > c1; + detail::adams_bashforth_coefficients< value_type , 2 > c2; + detail::adams_bashforth_coefficients< value_type , 3 > c3; + detail::adams_bashforth_coefficients< value_type , 4 > c4; + detail::adams_bashforth_coefficients< value_type , 5 > c5; + detail::adams_bashforth_coefficients< value_type , 6 > c6; + detail::adams_bashforth_coefficients< value_type , 7 > c7; + detail::adams_bashforth_coefficients< value_type , 8 > c8; +} + +BOOST_AUTO_TEST_CASE( test_rotating_buffer ) +{ + const size_t N = 5; + detail::rotating_buffer< size_t , N > buffer; + for( size_t i=0 ; i<N ; ++i ) buffer[i] = i; + + for( size_t i=0 ; i<N ; ++i ) + BOOST_CHECK_EQUAL( buffer[i] , i ); + + buffer.rotate(); + + for( size_t i=1 ; i<N ; ++i ) + BOOST_CHECK_EQUAL( buffer[i] , i - 1 ); + BOOST_CHECK_EQUAL( buffer[0] , size_t( N-1 ) ); +} + +BOOST_AUTO_TEST_CASE( test_copying ) +{ + typedef boost::array< double , 1 > state_type; + typedef adams_bashforth< 2 , state_type > stepper_type; + + stepper_type s1; + s1.step_storage()[0].m_v[0] = 1.5; + s1.step_storage()[1].m_v[0] = 2.25; + + stepper_type s2( s1 ); + BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s2.step_storage()[0].m_v[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s2.step_storage()[1].m_v[0] , 1.0e-14 ); + BOOST_CHECK( ( &(s1.step_storage()[0]) ) != ( &(s2.step_storage()[0]) ) ); + + stepper_type s3; + state_type *p1 = &( s3.step_storage()[0].m_v ) , *p2 = &( s3.step_storage()[1].m_v ); + s3 = s1; + BOOST_CHECK( p1 == ( &( s3.step_storage()[0].m_v ) ) ); + BOOST_CHECK( p2 == ( &( s3.step_storage()[1].m_v ) ) ); + + BOOST_CHECK_CLOSE( s1.step_storage()[0].m_v[0] , s3.step_storage()[0].m_v[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( s1.step_storage()[1].m_v[0] , s3.step_storage()[1].m_v[0] , 1.0e-14 ); +} + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_bashforth< steps , state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + const value_type dt = 0.01; + value_type t = 0.0; + + stepper.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_CLOSE( t , value_type( steps - 1 ) * dt , 1.0e-14 ); + + stepper.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_bashforth< 1 , state_type > s1; + adams_bashforth< 2 , state_type > s2; + adams_bashforth< 3 , state_type > s3; + adams_bashforth< 4 , state_type > s4; + adams_bashforth< 5 , state_type > s5; + adams_bashforth< 6 , state_type > s6; + adams_bashforth< 7 , state_type > s7; + adams_bashforth< 8 , state_type > s8; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + value_type t = 0.0 , dt = 0.01; + s1.do_step( lorenz() , x , t , dt ); + s2.do_step( lorenz() , x , t , dt ); + s3.do_step( lorenz() , x , t , dt ); + s4.do_step( lorenz() , x , t , dt ); + s5.do_step( lorenz() , x , t , dt ); + s6.do_step( lorenz() , x , t , dt ); +// s7.do_step( lorenz() , x , t , dt ); +// s8.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_auto_initialization ) +{ + typedef boost::array< double , 3 > state_type; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + + adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations , + initially_resizer , rk4_decorator< state_type > > adams; + + adams.initializing_stepper().do_count = 0; + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 1 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.reset(); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 3 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 4 ) ); +} + +BOOST_AUTO_TEST_CASE( test_manual_initialization ) +{ + typedef boost::array< double , 3 > state_type; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + + adams_bashforth< 3 , state_type , value_type , state_type , value_type , range_algebra , default_operations , + initially_resizer , rk4_decorator< state_type > > adams; + + adams.initializing_stepper().do_count = 0; + double t = 0.0 , dt = 0.1; + adams.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); + + adams.do_step( lorenz() , x , 0.0 , x , 0.1 ); + BOOST_CHECK_EQUAL( adams.initializing_stepper().do_count , size_t( 2 ) ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp new file mode 100644 index 00000000..8e7688bb --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_bashforth_moulton.cpp @@ -0,0 +1,112 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_bashforth_moulton.cpp + + [begin_description] + This file tests the use of the Adams-Bashforth-Moulton. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_adams_bashforth_moulton + +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + +#include <boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +BOOST_AUTO_TEST_SUITE( adams_bashforth_moulton_test ) + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_bashforth_moulton< steps , state_type > stepper; + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + const value_type dt = 0.01; + value_type t = 0.0; + + stepper.initialize( lorenz() , x , t , dt ); + BOOST_CHECK_CLOSE( t , value_type( steps - 1 ) * dt , 1.0e-14 ); + + stepper.do_step( lorenz() , x , t , dt ); +} + + +BOOST_AUTO_TEST_CASE( test_copying ) +{ + typedef boost::array< double , 1 > state_type; + typedef adams_bashforth_moulton< 2 , state_type > stepper_type; + + stepper_type s1; + + stepper_type s2( s1 ); + + stepper_type s3; + s3 = s1; + } + + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_bashforth_moulton< 1 , state_type > s1; + adams_bashforth_moulton< 2 , state_type > s2; + adams_bashforth_moulton< 3 , state_type > s3; + adams_bashforth_moulton< 4 , state_type > s4; + adams_bashforth_moulton< 5 , state_type > s5; + adams_bashforth_moulton< 6 , state_type > s6; + adams_bashforth_moulton< 7 , state_type > s7; + adams_bashforth_moulton< 8 , state_type > s8; + + state_type x = {{ 10.0 , 10.0 , 10.0 }}; + value_type t = 0.0 , dt = 0.01; + s1.do_step( lorenz() , x , t , dt ); + s2.do_step( lorenz() , x , t , dt ); + s3.do_step( lorenz() , x , t , dt ); + s4.do_step( lorenz() , x , t , dt ); + s5.do_step( lorenz() , x , t , dt ); + s6.do_step( lorenz() , x , t , dt ); +// s7.do_step( lorenz() , x , t , dt ); +// s8.do_step( lorenz() , x , t , dt ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adams_moulton.cpp b/src/boost/libs/numeric/odeint/test/adams_moulton.cpp new file mode 100644 index 00000000..faccdda5 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adams_moulton.cpp @@ -0,0 +1,104 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adams_moulton.cpp + + [begin_description] + This file tests the use of the Adams-Moulton stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_adams_moulton + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + + +#include <boost/numeric/odeint/stepper/detail/adams_moulton_coefficients.hpp> +#include <boost/numeric/odeint/stepper/detail/rotating_buffer.hpp> +#include <boost/numeric/odeint/stepper/adams_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +struct lorenz +{ + template< class State , class Deriv , class Value > + void operator()( const State &_x , Deriv &_dxdt , const Value &dt ) const + { + const value_type sigma = 10.0; + const value_type R = 28.0; + const value_type b = 8.0 / 3.0; + + typename boost::range_iterator< const State >::type x = boost::begin( _x ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( _dxdt ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = x[0]*x[1] - b * x[2]; + } +}; + +BOOST_AUTO_TEST_SUITE( adams_moulton_test ) + +BOOST_AUTO_TEST_CASE( test_adams_moulton_coefficients ) +{ + detail::adams_moulton_coefficients< value_type , 1 > c1; + detail::adams_moulton_coefficients< value_type , 2 > c2; + detail::adams_moulton_coefficients< value_type , 3 > c3; + detail::adams_moulton_coefficients< value_type , 4 > c4; + detail::adams_moulton_coefficients< value_type , 5 > c5; + detail::adams_moulton_coefficients< value_type , 6 > c6; + detail::adams_moulton_coefficients< value_type , 7 > c7; + detail::adams_moulton_coefficients< value_type , 8 > c8; +} + +typedef boost::mpl::range_c< size_t , 1 , 6 > vector_of_steps; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_init_and_steps , step_type , vector_of_steps ) +{ + const static size_t steps = step_type::value; + typedef boost::array< value_type , 3 > state_type; + + adams_moulton< steps , state_type > stepper; +// state_type x = {{ 10.0 , 10.0 , 10.0 }}; +// const value_type dt = 0.01; +// value_type t = 0.0; + +// stepper.do_step( lorenz() , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + typedef boost::array< double , 3 > state_type; + adams_moulton< 1 , state_type > s1; + adams_moulton< 2 , state_type > s2; + adams_moulton< 3 , state_type > s3; + adams_moulton< 4 , state_type > s4; + adams_moulton< 5 , state_type > s5; + adams_moulton< 6 , state_type > s6; + adams_moulton< 7 , state_type > s7; + adams_moulton< 8 , state_type > s8; + +// state_type x = {{ 10.0 , 10.0 , 10.0 }}; +// value_type t = 0.0 , dt = 0.01; +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp b/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp new file mode 100644 index 00000000..362458f0 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_adams_coefficients.cpp @@ -0,0 +1,120 @@ +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adaptive_adams_coefficients + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp> + +#include <vector> + +#include <boost/mpl/list.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/range_c.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; + +BOOST_AUTO_TEST_SUITE( adaptive_adams_coefficients_test ) + +typedef boost::mpl::range_c< size_t , 2 , 10 > vector_of_steps; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_step, step_type, vector_of_steps ) +{ + const static size_t steps = step_type::value; + + typedef std::vector<double> deriv_type; + typedef double time_type; + + typedef detail::adaptive_adams_coefficients<steps, deriv_type, time_type> aac_type; + + std::vector<double> deriv; + deriv.push_back(-1); + + time_type t = 0.0; + time_type dt = 0.1; + + aac_type coeff; + for(size_t i=0; i<steps; ++i) + { + coeff.predict(t, dt); + coeff.do_step(deriv); + coeff.confirm(); + + t+= dt; + + if(coeff.m_eo < steps) + coeff.m_eo ++; + } + + std::vector<value_type> v(10); + v[0] = 1.0/1.0; + v[1] = 1.0/2.0; + v[2] = 5.0/12.0; + v[3] = 9.0/24.0; + v[4] = 251.0/720.0; + v[5] = 95.0/288.0; + v[6] = 19087.0/60480.0; + v[7] = 5257.0/17280.0; + v[8] = 5311869667636789.0/18014398509481984.0; + + for(size_t i=0; i<steps; ++i) + { + BOOST_CHECK_SMALL(coeff.beta[1][i] - 1.0, 1e-15); + + if(i == 0) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] + 1, 1e-15); + else if (i == steps-1 && steps%2 == 1) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] - 1, 1e-14); + else if (i == steps-1 && steps%2 == 0) + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0] + 1, 1e-14); + else + BOOST_CHECK_SMALL(coeff.phi[2][i].m_v[0], 1e-15); + + BOOST_CHECK_SMALL(coeff.g[i] - v[i], 1e-15); + } +} + +BOOST_AUTO_TEST_CASE( test_copy ) +{ + typedef std::vector<double> deriv_type; + typedef double time_type; + + typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; + aac_type c1; + + deriv_type deriv(1); + deriv[0] = 1.0; + + time_type t = 0.0; + time_type dt = 0.01; + + for(size_t i=0; i<3; ++i) + { + c1.predict(t, dt); + c1.do_step(deriv); + c1.confirm(); + + t+= dt; + + if(c1.m_eo < 3) + c1.m_eo ++; + } + + aac_type c2(c1); + BOOST_CHECK_EQUAL(c1.phi[0][0].m_v[0], c2.phi[0][0].m_v[0]); + BOOST_CHECK(&(c1.phi[0][0].m_v) != &(c2.phi[0][0].m_v)); + + aac_type c3; + deriv_type *p1 = &(c3.phi[0][0].m_v); + + c3 = c1; + BOOST_CHECK(p1 == (&(c3.phi[0][0].m_v))); + BOOST_CHECK_EQUAL(c1.phi[0][0].m_v[0], c3.phi[0][0].m_v[0]); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp b/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp new file mode 100644 index 00000000..8f3cfa74 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_iterator.cpp @@ -0,0 +1,346 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adaptive_iterator.cpp + + [begin_description] + This file tests the adaptive iterators. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_adaptive_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/adaptive_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + +BOOST_AUTO_TEST_SUITE( adaptive_iterator_test ) + +typedef mpl::vector< + dummy_controlled_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE( copy_controlled_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + iterator_type iter1( dummy_controlled_stepper() , empty_system() , x ); + iterator_type iter2( iter1 ); + + BOOST_CHECK_EQUAL( &( *iter1 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter2 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter1 ) , &( *iter2 ) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_EQUAL( &( *iter1 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter2 ) , &x ); + BOOST_CHECK_EQUAL( &( *iter1 ) , &( *iter2 ) ); + BOOST_CHECK( iter1.same( iter2 ) ); + +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + // fix by mario: do not dereference iterators at the end - made iter1 start iterator + iterator_type iter1( dummy_dense_output_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2( iter1 ); + + // fix by mario: iterator dereference now always gives internal state also for dense output, consistent with other iterator implementations + // changed: iterators with dense output stepper do not have an internal state now to avoid a copy + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator_with_reference_wrapper ) +{ + // bad use case, the same stepper is iterated twice + typedef adaptive_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + + state_type x = {{ 1.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1( boost::ref( stepper ) , empty_system() , x , 0.0 , 0.9 , 0.1 ); + iterator_type iter2( iter1 ); + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); + + ++iter1; + ++iter2; + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); // they point to the same stepper, there the times will be different +} + + + +BOOST_AUTO_TEST_CASE( assignment_controlled_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_controlled_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + // the iterators are indeed the same as this only checks the time values + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator ) +{ + typedef adaptive_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + + iter2 = iter1; + // fix by mario: iterator dereference now always gives internal state also for dense output, consistent with other iterator implementations + // changed: iterators with dense output stepper do not have an internal state now to avoid a copy + BOOST_CHECK_NE( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }}; + + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + + iter2 = iter1; + + BOOST_CHECK_EQUAL( & (*iter1) , & (*iter2) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( controlled_stepper_iterator_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE( controlled_stepper_range ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( controlled_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); +} + +BOOST_AUTO_TEST_CASE( controlled_stepper_range_with_reference_wrapper ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range_with_reference_wrapper ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef adaptive_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 2.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef adaptive_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_adaptive_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_adaptive_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_adaptive_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[4][0] , 2.0 , 1.0e-14 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp new file mode 100644 index 00000000..406a71c6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/adaptive_time_iterator.cpp @@ -0,0 +1,332 @@ +/* + [auto_generated] + libs/numeric/odeint/test/adaptive_time_iterator.cpp + + [begin_description] + This file tests the adaptive time iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_adaptive_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/adaptive_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + + + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( adaptive_time_iterator_test ) + +typedef mpl::vector< + dummy_controlled_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE( copy_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( copy_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_time_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE( assignment_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_controlled_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_controlled_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_controlled_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator ) +{ + typedef adaptive_time_iterator< dummy_dense_output_stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( dummy_dense_output_stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( dummy_dense_output_stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); + BOOST_CHECK_EQUAL( (iter1->first)[0] , (iter1->first)[0] ); +} + +BOOST_AUTO_TEST_CASE( assignment_dense_output_stepper_iterator_with_reference_wrapper ) +{ + typedef adaptive_time_iterator< boost::reference_wrapper< dummy_dense_output_stepper > , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + dummy_dense_output_stepper stepper; + iterator_type iter1 = iterator_type( boost::ref( stepper ) , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( boost::ref( stepper ) , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x2 ); + // same stepper instance -> same internal state + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_NE( &( iter1->first ) , &x1 ); + BOOST_CHECK_NE( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); +} + + +BOOST_AUTO_TEST_CASE( stepper_iterator_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( stepper_range ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + +BOOST_AUTO_TEST_CASE( stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_iterator_with_reference_wrapper_factory ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_adaptive_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_adaptive_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); +} + + + +BOOST_AUTO_TEST_CASE( stepper_range_with_reference_wrapper ) +{ + dummy_controlled_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-14 ); +} + +// just test if it compiles +BOOST_AUTO_TEST_CASE( dense_output_stepper_range_with_reference_wrapper ) +{ + dummy_dense_output_stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_adaptive_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); +} + + + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef adaptive_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 1.5 , 1.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef adaptive_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_adaptive_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_adaptive_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_adaptive_time_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 5 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].first[0] , 2.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[4].second , 0.35 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp b/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp new file mode 100644 index 00000000..66a292fd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/algebra_dispatcher.cpp @@ -0,0 +1,82 @@ +/* + [auto_generated] + libs/numeric/odeint/test/algebra_dispatcher.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_algebra_dispatcher + +#include <boost/numeric/odeint/config.hpp> +#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/array.hpp> +#include <boost/mpl/list.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( algebra_dispatcher_test ) + +BOOST_AUTO_TEST_CASE( range_algebra_with_vector ) +{ + typedef runge_kutta4< std::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , range_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( array_algebra_with_array ) +{ + typedef runge_kutta4< boost::array< double , 2 > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , array_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( range_algebra_with_array ) +{ + typedef runge_kutta4< boost::array< double , 2 > , double , boost::array< double , 2 > , double , range_algebra > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , range_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( fusion_algebra_with_fusion_vector ) +{ + typedef runge_kutta4< boost::fusion::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , fusion_algebra >::value )); +} + +BOOST_AUTO_TEST_CASE( fusion_algebra_with_fusion_vector2 ) +{ + typedef runge_kutta_fehlberg78< boost::fusion::vector< double > > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , fusion_algebra >::value )); +} + +typedef boost::mpl::list< float , double , long double , std::complex< double > , std::complex< float > > fp_types; +BOOST_AUTO_TEST_CASE_TEMPLATE( vector_space_algebra_with_floating_point , T , fp_types ) +{ + typedef runge_kutta_fehlberg78< T > stepper_type; + BOOST_STATIC_ASSERT(( boost::is_same< typename stepper_type::algebra_type , vector_space_algebra >::value )); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp b/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp new file mode 100644 index 00000000..7ff42757 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/boost_units_helpers.hpp @@ -0,0 +1,59 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_boost_units.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + + + +typedef double value_type; +typedef boost::units::quantity< boost::units::si::time , value_type > time_type; +typedef boost::units::quantity< boost::units::si::length , value_type > length_type; +typedef boost::units::quantity< boost::units::si::velocity , value_type > velocity_type; +typedef boost::units::quantity< boost::units::si::acceleration , value_type > acceleration_type; + + + +struct oscillator_mom_func_units +{ + template< class Coor , class MomDeriv > + void operator()( const Coor &q , MomDeriv &dp ) const + { + const boost::units::quantity< boost::units::si::frequency , value_type > omega = 1.0 * boost::units::si::hertz; + boost::fusion::at_c< 0 >( dp ) = - omega * omega * boost::fusion::at_c< 0 >( q ); + } +}; + +struct oscillator_coor_func_units +{ + template< class Mom , class CoorDeriv > + void operator()( const Mom &p , CoorDeriv &dq ) const + { + boost::fusion::at_c< 0 >( dq ) = boost::fusion::at_c< 0 >( p ); + } +}; + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_BOOST_UNITS_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp b/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp new file mode 100644 index 00000000..2c6a0c95 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/bulirsch_stoer.cpp @@ -0,0 +1,155 @@ +/* + [auto_generated] + libs/numeric/odeint/test/bulirsch_stoer.cpp + + [begin_description] + This file tests the Bulirsch-Stoer stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_bulirsch_stoer + +#include <utility> +#include <iostream> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::array< value_type , 3 > state_type; + +const double sigma = 10.0; +const double R = 28.0; +const double b = 8.0 / 3.0; + +struct lorenz +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +struct const_system +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = 1.0; + dxdt[1] = 1.0; + dxdt[2] = 1.0; + } +}; + +struct sin_system +{ + template< class State , class Deriv > + void operator()( const State &x , Deriv &dxdt , double t ) const + { + dxdt[0] = sin( x[0] ); + dxdt[1] = cos( x[1] ); + dxdt[2] = sin( x[2] ) + cos( x[2] ); + } +}; + +BOOST_AUTO_TEST_SUITE( bulirsch_stoer_test ) + +BOOST_AUTO_TEST_CASE( test_bulirsch_stoer ) +{ + typedef bulirsch_stoer< state_type > stepper_type; + stepper_type stepper( 1E-9 , 1E-9 , 1.0 , 0.0 ); + + state_type x; + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + + double dt = 0.1; + + //stepper.try_step( lorenz() , x , t , dt ); + + std::cout << "starting integration..." << std::endl; + + size_t steps = integrate_adaptive( stepper , lorenz() , x , 0.0 , 10.0 , dt ); + + std::cout << "required steps: " << steps << std::endl; + + bulirsch_stoer_dense_out< state_type > bs_do( 1E-9 , 1E-9 , 1.0 , 0.0 ); + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + double t = 0.0; + dt = 1E-1; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + std::cout << "one step successful, new time: " << bs_do.current_time() << " (" << t << ")" << std::endl; + + x = bs_do.current_state(); + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + bs_do.calc_state( bs_do.current_time()/3 , x ); + std::cout << "x( " << bs_do.current_time()/3 << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + std::cout << std::endl << "=======================================================================" << std::endl << std::endl; + + x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + t = 0.0; dt /= 3; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl; + + t = dt; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + + t = 2*dt; + bs_do.initialize( x , t , dt ); + bs_do.do_step( sin_system() ); + x = bs_do.current_state(); + + std::cout << "x( " << bs_do.current_time() << " ) = [ " << x[0] << " , " << x[1] << " , " << x[2] << " ]" << std::endl << std::endl << std::endl; +} + +BOOST_AUTO_TEST_CASE( test_bulirsch_stoer_adjust_size ) +{ + typedef bulirsch_stoer< state_type > stepper_type; + stepper_type stepper( 1E-9 , 1E-9 , 1.0 , 0.0 ); + + state_type x; x[0] = 10.0 ; x[1] = 10.0 ; x[2] = 5.0; + + stepper.adjust_size( x ); + + + double dt = 0.1; + + size_t steps = integrate_adaptive( stepper , lorenz() , x , 0.0 , 10.0 , dt ); + + std::cout << "required steps: " << steps << std::endl; +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/const_range.hpp b/src/boost/libs/numeric/odeint/test/const_range.hpp new file mode 100644 index 00000000..d646b1d8 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_range.hpp @@ -0,0 +1,50 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_range.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED + +#include <boost/mpl/copy.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/insert.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/range_c.hpp> +#include <boost/mpl/placeholders.hpp> + + +namespace mpl = boost::mpl; + + + +template< class N , class T > +struct const_range +{ + typedef typename mpl::copy< + mpl::range_c< typename N::value_type , 0 , N::value > , + mpl::inserter< + mpl::vector0<> , + mpl::insert< + mpl::_1 , + mpl::end< mpl::_1 > , + T + > + > + >::type type; +}; + +#endif // LIBS_NUMERIC_ODEINT_TEST_CONST_RANGE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp b/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp new file mode 100644 index 00000000..2d0ac9db --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_step_iterator.cpp @@ -0,0 +1,232 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_step_iterator.cpp + + [begin_description] + This file tests the const step iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_const_step_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/const_step_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( const_step_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.999 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 10 do_step calls so x should be 3.5 + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 2.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , 2.0 , 2.0 , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef const_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.3 , -0.05 , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_const_step_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_const_step_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_const_step_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp new file mode 100644 index 00000000..9227f5c0 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/const_step_time_iterator.cpp @@ -0,0 +1,218 @@ +/* + [auto_generated] + libs/numeric/odeint/test/const_step_time_iterator.cpp + + [begin_description] + This file tests the const step time iterator. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_const_step_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/const_step_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( const_step_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 1.0 , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 1.0 , 0.2 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_time_range( stepper , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_const_step_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + make_const_step_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_const_step_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 1.0 , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 1.5 , 1.0 , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , 2.0 , 2.0 , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef const_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_const_step_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + make_const_step_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_const_step_time_range( Stepper() , empty_system() , x , 0.0 , 0.35 , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp new file mode 100644 index 00000000..40d65720 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/controlled_adams_bashforth_moulton.cpp @@ -0,0 +1,56 @@ +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_controlled_adams_bashforth_moulton + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp> +#include <boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +struct const_sys +{ + template< class State , class Deriv , class Value > + void operator()( const State &x , Deriv &dxdt , const Value &dt ) const + { + dxdt[0] = 1; + } +}; + +typedef boost::array< double , 1 > state_type; +typedef double value_type; + +BOOST_AUTO_TEST_SUITE( controlled_adams_bashforth_moulton_test ) + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<1, state_type> > s1; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<2, state_type> > s2; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> > s3; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<4, state_type> > s4; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > s5; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<6, state_type> > s6; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<7, state_type> > s7; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<8, state_type> > s8; + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<9, state_type> > s9; + + state_type x = {{ 10.0 }}; + value_type t = 0.0 , dt = 0.01; + + s1.try_step(const_sys(), x, t, dt); + s2.try_step(const_sys(), x, t, dt); + s3.try_step(const_sys(), x, t, dt); + s4.try_step(const_sys(), x, t, dt); + s5.try_step(const_sys(), x, t, dt); + s6.try_step(const_sys(), x, t, dt); + s7.try_step(const_sys(), x, t, dt); + s8.try_step(const_sys(), x, t, dt); + s9.try_step(const_sys(), x, t, dt); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/default_operations.cpp b/src/boost/libs/numeric/odeint/test/default_operations.cpp new file mode 100644 index 00000000..a2634b7f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/default_operations.cpp @@ -0,0 +1,257 @@ +/* + [auto_generated] + libs/numeric/odeint/test/default_operations.cpp + + [begin_description] + This file tests default_operations. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#define BOOST_TEST_MODULE odeint_standard_operations + +#include <cmath> +#include <complex> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/mpl/list.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; +namespace mpl = boost::mpl; +using boost::numeric::odeint::default_operations; + + +template< class Value > struct internal_value_type { typedef Value type; }; +template< class T > struct internal_value_type< std::complex< T > > { typedef T type; }; + +template< class T > struct default_eps; +template<> struct default_eps< double > { static double def_eps( void ) { return 1.0e-10; } }; +template<> struct default_eps< float > { static float def_eps( void ) { return 1.0e-5; } }; + + +typedef units::unit< units::derived_dimension< units::time_base_dimension , 2 >::type , si::system > time_2; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 3 >::type , si::system > time_3; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 4 >::type , si::system > time_4; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 5 >::type , si::system > time_5; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 6 >::type , si::system > time_6; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 7 >::type , si::system > time_7; + +const time_2 second2 = si::second * si::second; +const time_3 second3 = second2 * si::second; +const time_4 second4 = second3 * si::second; +const time_5 second5 = second4 * si::second; +const time_6 second6 = second5 * si::second; +const time_7 second7 = second6 * si::second; + + + + +template< class Value , class Compare = typename internal_value_type< Value >::type > +struct double_fixture +{ + typedef Value value_type; + typedef Compare compare_type; + + double_fixture( const compare_type &eps_ = default_eps< compare_type >::def_eps() ) + : m_eps( eps_ ) , res( 0.0 ) , x1( 1.0 ) , x2( 2.0 ) , x3( 3.0 ) , x4( 4.0 ) , x5( 5.0 ) , x6( 6.0 ) , x7( 7.0 ) , x8( 8.0 ) + {} + + ~double_fixture( void ) + { + using std::abs; + BOOST_CHECK_SMALL( abs( x1 - value_type( 1.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x2 - value_type( 2.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x3 - value_type( 3.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x4 - value_type( 4.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x5 - value_type( 5.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x6 - value_type( 6.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( x7 - value_type( 7.0 ) ) , m_eps ); + } + + const compare_type m_eps; + value_type res; + value_type x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8; +}; + +template< class Value , class Compare = typename internal_value_type< Value >::type > +struct unit_fixture +{ + typedef Value value_type; + typedef Compare compare_type; + typedef units::quantity< si::length , value_type > length_type; + + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< time_2 , value_type > time_2_type; + typedef units::quantity< time_3 , value_type > time_3_type; + typedef units::quantity< time_4 , value_type > time_4_type; + typedef units::quantity< time_5 , value_type > time_5_type; + typedef units::quantity< time_6 , value_type > time_6_type; + typedef units::quantity< time_7 , value_type > time_7_type; + + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef units::quantity< si::acceleration , value_type > acceleration_type; + + unit_fixture( const compare_type &eps_ = default_eps< compare_type >::def_eps() ) + : m_eps( eps_ ) + , res( 0.0 * si::meter ) + , x( 1.0 * si::meter ) + , d1x( 2.0 * si::meter / si::second ) + , d2x( 3.0 * si::meter / si::second / si::second ) + {} + + ~unit_fixture( void ) + { + using std::abs; + BOOST_CHECK_SMALL( abs( x.value() - value_type( 1.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( d1x.value() - value_type( 2.0 ) ) , m_eps ); + BOOST_CHECK_SMALL( abs( d2x.value() - value_type( 3.0 ) ) , m_eps ); + } + + compare_type m_eps; + length_type res; + length_type x; + velocity_type d1x; + acceleration_type d2x; +}; + + +typedef mpl::list< float , double , std::complex< double > > test_types; + +BOOST_AUTO_TEST_SUITE( check_operations_test ) + +using std::abs; + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum2_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef typename default_operations::scale_sum2< T , T > Op; + Op op( 1.25 , 9.81 ); + op( f.res , f.x1 , f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 20.87 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum3_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum3< T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 ); + op( f.res , f.x1 , f.x2 , f.x3 ); + BOOST_CHECK_SMALL( abs( f.res - T( 23.48 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum4_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum4< T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 ); + BOOST_CHECK_SMALL( abs( f.res - T( 22.88 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum5_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum5< T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 ); + BOOST_CHECK_SMALL( abs( f.res - T( 6.38 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum6_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum6< T , T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 , 4.2 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 , f.x6 ); + BOOST_CHECK_SMALL( abs( f.res - T( 31.58 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum7_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::scale_sum7< T , T , T , T , T , T , T > Op; + Op op( 1.25 , 9.81 , 0.87 , -0.15 , -3.3 , 4.2 , -0.22 ); + op( f.res , f.x1 , f.x2 , f.x3 , f.x4 , f.x5 , f.x6 , f.x7 ); + BOOST_CHECK_SMALL( abs( f.res - T( 30.04 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( rel_error_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + f.res = -1.1; + typedef default_operations::rel_error< T > Op; + Op op( 0.1 , 0.2 , 0.15 , 0.12 ); + op( f.res , -f.x1 , -f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 6.17978 ) ) , typename fix_type::compare_type( 1.0e-4 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( maximum_test , T , test_types ) +{ + typedef double_fixture< T > fix_type; + fix_type f; + typedef default_operations::maximum< typename fix_type::compare_type > Op; + Op op; + f.res = op( f.x1 , f.x2 ); + BOOST_CHECK_SMALL( abs( f.res - T( 2.0 ) ) , f.m_eps ); +} + + + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum2_units_test , T , test_types ) +{ + typedef unit_fixture< T > fix_type; + typedef typename fix_type::value_type value_type; + typedef typename fix_type::time_type time_type; + + fix_type f; + typedef default_operations::scale_sum2< value_type , time_type > Op; + Op op( 1.0 , time_type( 1.0 * si::second ) ); + op( f.res , f.x , f.d1x ); + BOOST_CHECK_SMALL( abs( f.res.value() - T( 3.0 ) ) , f.m_eps ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum3_units_test , T , test_types ) +{ + typedef unit_fixture< T > fix_type; + typedef typename fix_type::value_type value_type; + typedef typename fix_type::time_type time_type; + typedef typename fix_type::time_2_type time_2_type; + + fix_type f; + typedef default_operations::scale_sum3< value_type , time_type , time_2_type > Op; + Op op( 1.0 , time_type( 1.0 * si::second ) , time_2_type( 1.0 * second2 ) ); + op( f.res , f.x , f.d1x , f.d2x ); + BOOST_CHECK_SMALL( abs( f.res.value() - T( 6.0 ) ) , f.m_eps ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp b/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp new file mode 100644 index 00000000..0c21013e --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/diagnostic_state_type.hpp @@ -0,0 +1,185 @@ +/* + [auto_generated] + libs/numeric/odeint/test/diagnostic_state_type.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED + +#include <boost/array.hpp> +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/numeric/odeint/util/same_size.hpp> +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/numeric/odeint/util/state_wrapper.hpp> + +template< size_t N > +struct counter +{ + static size_t& adjust_size_count( void ) + { + static size_t m_adjust_size_count; + return m_adjust_size_count; + } + + static size_t& construct_count( void ) + { + static size_t m_construct_count; + return m_construct_count; + } + + static size_t& copy_count( void ) + { + static size_t m_copy_count; + return m_copy_count; + } + + static size_t& destroy_count( void ) + { + static size_t m_destroy_count; + return m_destroy_count; + } + + + static void init_counter( void ) + { + counter< N >::adjust_size_count() = 0; + counter< N >::construct_count() = 0; + counter< N >::copy_count() = 0; + counter< N >::destroy_count() = 0; + } +}; + +template< size_t N > +class diagnostic_type : public boost::array< double , 1 > { }; + + +typedef diagnostic_type< 0 > diagnostic_state_type; +typedef diagnostic_type< 1 > diagnostic_deriv_type; +typedef diagnostic_type< 2 > diagnostic_state_type2; +typedef diagnostic_type< 3 > diagnostic_deriv_type2; + +typedef counter< 0 > counter_state; +typedef counter< 1 > counter_deriv; +typedef counter< 2 > counter_state2; +typedef counter< 3 > counter_deriv2; + + + +namespace boost { +namespace numeric { +namespace odeint { + + template< size_t N > + struct is_resizeable< diagnostic_type< N > > + { + typedef boost::true_type type; + const static bool value = type::value; + }; + + template< size_t N , size_t M > + struct same_size_impl< diagnostic_type< N > , diagnostic_type< M > > + { + static bool same_size( const diagnostic_type< N > &x1 , const diagnostic_type< M > &x2 ) + { + return false; + } + }; + + template< size_t N , class State1 > + struct same_size_impl< diagnostic_type< N > , State1 > + { + static bool same_size( const diagnostic_type< N > &x1 , const State1 &x2 ) + { + return false; + } + }; + + template< class State1 , size_t N > + struct same_size_impl< State1 , diagnostic_type< N > > + { + static bool same_size( const State1 &x1 , const diagnostic_type< N > &x2 ) + { + return false; + } + }; + + + + template< size_t N , class StateIn > + struct resize_impl< diagnostic_type< N > , StateIn > + { + static void resize( diagnostic_type< N > &x1 , const StateIn &x2 ) + { + counter< N >::adjust_size_count()++; + } + }; + + template< size_t N > + struct state_wrapper< diagnostic_type< N > > + { + typedef state_wrapper< diagnostic_type< N > > state_wrapper_type; + typedef diagnostic_type< N > state_type; + typedef double value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + counter< N >::construct_count()++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + counter< N >::construct_count()++; + counter< N >::copy_count()++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + counter< N >::construct_count()++; + counter< N >::copy_count()++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + counter< N >::copy_count()++; + return *this; + } + + ~state_wrapper() + { + counter< N >::destroy_count()++; + } + }; + + +} // namespace odeint +} // namespace numeric +} // namespace boost + +#define TEST_COUNTERS( c , s1 , s2 , s3 ,s4 ) \ + BOOST_CHECK_EQUAL( c::adjust_size_count() , size_t( s1 ) ); \ + BOOST_CHECK_EQUAL( c::construct_count() , size_t( s2 ) ); \ + BOOST_CHECK_EQUAL( c::copy_count() , size_t( s3 ) ); \ + BOOST_CHECK_EQUAL( c::destroy_count() , size_t( s4 ) ); + +#define TEST_COUNTERS_MSG( c , s1 , s2 , s3 ,s4 , msg ) \ + BOOST_CHECK_EQUAL( c::adjust_size_count() , size_t( s1 ) ); \ + BOOST_CHECK_EQUAL( c::construct_count() , size_t( s2 ) ); \ + BOOST_CHECK_EQUAL( c::copy_count() , size_t( s3 ) ); \ + BOOST_CHECK_EQUAL( c::destroy_count() , size_t( s4 ) ); + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DIAGNOSTIC_STATE_TYPE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_observers.hpp b/src/boost/libs/numeric/odeint/test/dummy_observers.hpp new file mode 100644 index 00000000..744c374f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_observers.hpp @@ -0,0 +1,41 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_observers.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED + + +namespace boost { +namespace numeric { +namespace odeint { + + +struct dummy_observer +{ + template< class State > + void operator()( const State &s ) const + { + } +}; + + +} // namespace odeint +} // namespace numeric +} // namespace boost + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_OBSERVERS_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_odes.hpp b/src/boost/libs/numeric/odeint/test/dummy_odes.hpp new file mode 100644 index 00000000..7a92363f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_odes.hpp @@ -0,0 +1,151 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_odes.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2012-2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED + +#include <boost/fusion/include/at_c.hpp> + + + + + + +/* + * rhs functors/functions for different state types + */ +struct constant_system_functor_standard +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + dxdt[0] = 1.0; + } +}; + +struct constant_system_functor_vector_space +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + dxdt = 1.0; + } +}; + +struct constant_system_functor_fusion +{ + template< class State , class Deriv , class Time > + void operator()( const State &x , Deriv &dxdt , const Time t ) const + { + boost::fusion::at_c< 0 >( dxdt ) = boost::fusion::at_c< 0 >( x ) / Time( 1.0 ); + } +}; + +struct lorenz +{ + template< typename State , typename Deriv , typename Time > + void operator()( const State& x , Deriv& dxdt , const Time& t ) const + { + const Time sigma = 10.0; + const Time R = 28.0; + const Time b = 8.0 / 3.0; + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; + } +}; + +template< class State , class Deriv , class Time > +void constant_system_standard( const State &x , Deriv &dxdt , const Time t ) +{ + dxdt[0] = 1.0; +} + +template< class State , class Deriv , class Time > +void constant_system_vector_space( const State &x , Deriv &dxdt , const Time t ) +{ + dxdt = 1.0; +} + +template< class State , class Deriv , class Time > +void constant_system_fusion( const State &x , Deriv &dxdt , const Time t ) +{ + boost::fusion::at_c< 0 >( dxdt ) = boost::fusion::at_c< 0 >( x ) / Time( 1.0 ); +} + + + + +/* + * rhs functors for symplectic steppers + */ +struct constant_mom_func +{ + template< class StateIn , class StateOut > + void operator()( const StateIn &q , StateOut &dp ) const + { + dp[0] = 1.0; + } +}; + +struct default_coor_func +{ + template< class StateIn , class StateOut > + void operator()( const StateIn &p , StateOut &dq ) const + { + dq[0] = p[0]; + } +}; + + + +struct constant_mom_func_vector_space_1d +{ + template< class T > + void operator()( const T &q , T &dp ) const + { + dp = 1.0; + } +}; + +struct default_coor_func_vector_space_1d +{ + template< class T > + void operator()( const T &p , T &dq ) const + { + dq = p; + } +}; + + + + + + + +struct empty_system +{ + template <class State > + void operator()( const State &x , State &dxdt , double t ) const + { + } +}; + + + + +#endif // LIBS_NUMERIC_ODEINT_TEST_DUMMY_ODES_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp b/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp new file mode 100644 index 00000000..5f8d749f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/dummy_steppers.hpp @@ -0,0 +1,122 @@ +/* + [auto_generated] + libs/numeric/odeint/test/dummy_steppers.hpp + + [begin_description] + Dummy steppers for several tests. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#ifndef BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED +#define BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED + +#include <boost/array.hpp> +#include <boost/numeric/odeint/stepper/stepper_categories.hpp> +#include <boost/numeric/odeint/stepper/controlled_step_result.hpp> + +namespace boost { +namespace numeric { +namespace odeint { + +struct dummy_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef unsigned short order_type; + typedef stepper_tag stepper_category; + + order_type order( void ) const { return 1; } + + template< class System > + void do_step( System sys , state_type &x , time_type t , time_type dt ) const + { + x[0] += 0.25; + } +}; + +struct dummy_dense_output_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef dense_output_stepper_tag stepper_category; + + void initialize( const state_type &x0 , time_type t0 , time_type dt0 ) + { + m_x = x0; + m_t = t0; + m_dt = dt0; + } + + template< class System > + std::pair< time_type , time_type > do_step( System sys ) + { + m_x[0] += 0.25; + m_t += m_dt; + return std::make_pair( m_t - m_dt , m_t ); + } + + void calc_state( time_type t_inter , state_type &x ) const + { + value_type theta = ( m_t - t_inter ) / m_dt; + x[0] = m_x[0] - 0.25 * theta; + + } + + const time_type& current_time( void ) const + { + return m_t; + } + + const state_type& current_state( void ) const + { + return m_x; + } + + const time_type& current_time_step( void ) const + { + return m_dt; + } + + state_type m_x; + time_type m_t; + time_type m_dt; +}; + + + +struct dummy_controlled_stepper +{ + typedef double value_type; + typedef value_type time_type; + typedef boost::array< value_type , 1 > state_type; + typedef state_type deriv_type; + typedef controlled_stepper_tag stepper_category; + + template< class Sys > + controlled_step_result try_step( Sys sys , state_type &x , time_type &t , time_type &dt ) const + { + x[0] += 0.25; + t += dt; + return success; + } +}; + + +} // odeint +} // numeric +} // boost + + +#endif // BOOST_LIBS_NUMERIC_ODEINT_TEST_DUMMY_STEPPER_HPP_INCLUDED diff --git a/src/boost/libs/numeric/odeint/test/euler_stepper.cpp b/src/boost/libs/numeric/odeint/test/euler_stepper.cpp new file mode 100644 index 00000000..a274de4b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/euler_stepper.cpp @@ -0,0 +1,105 @@ +/* + [auto_generated] + libs/numeric/odeint/test/euler_stepper.cpp + + [begin_description] + This file tests explicit Euler stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_explicit_euler + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/algebra/range_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +// test with own vector implementation + +class my_vec : public std::vector< double > { + +public: + + my_vec() : std::vector< double >() + { } + + my_vec( const my_vec &x ) : std::vector< double >( x ) + { } + + + my_vec( size_t dim ) + : std::vector< double >( dim ) + { } + +}; + +namespace boost { +namespace numeric { +namespace odeint { + +template<> +struct is_resizeable< my_vec > +{ + //struct type : public boost::true_type { }; + typedef boost::true_type type; + const static bool value = type::value; +}; +} } } + +typedef double value_type; +//typedef std::vector< value_type > state_type; +typedef my_vec state_type; + +/* use functors, because functions don't work with msvc 10, I guess this is a bug */ +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type t ) const + { + std::cout << "sys start " << dxdt.size() << std::endl; + dxdt[0] = x[0] + 2 * x[1]; + dxdt[1] = x[1]; + std::cout << "sys done" << std::endl; + } +}; + + +BOOST_AUTO_TEST_SUITE( explicit_euler_test ) + +BOOST_AUTO_TEST_CASE( test_euler ) +{ + range_algebra algebra; + euler< state_type > stepper( algebra ); + state_type x( 2 ); + x[0] = 0.0; x[1] = 1.0; + + std::cout << "initialized" << std::endl; + + const value_type eps = 1E-12; + const value_type dt = 0.1; + + stepper.do_step( sys() , x , 0.0 , dt ); + + using std::abs; + + // compare with analytic solution of above system + BOOST_CHECK_MESSAGE( abs( x[0] - 2.0*1.0*dt ) < eps , x[0] - 2.0*1.0*dt ); + BOOST_CHECK_MESSAGE( abs( x[1] - (1.0 + dt) ) < eps , x[1] - (1.0+dt) ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp b/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp new file mode 100644 index 00000000..cc63fa92 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/fusion_algebra.cpp @@ -0,0 +1,184 @@ +/* + [auto_generated] + libs/numeric/odeint/test/fusion_algebra.cpp + + [begin_description] + This file tests the Fusion algebra. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_fusion_algebra + +// using fusion vectors as state types requires increased macro variables +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + +#include <cmath> +#include <complex> +#include <utility> +#include <functional> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; +namespace fusion = boost::fusion; + +using boost::numeric::odeint::default_operations; +using boost::numeric::odeint::fusion_algebra; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + +const time_type dt = 0.1 * si::second; + + +struct fusion_fixture +{ + fusion_fixture( void ) + : res( 0.0 * si::meter , 0.0 * si::meter_per_second ) , + x( 1.0 * si::meter , 1.0 * si::meter_per_second ) , + k1( 1.0 * si::meter_per_second , 1.0 * si::meter_per_second_squared ) , + k2( 2.0 * si::meter_per_second , 2.0 * si::meter_per_second_squared ) , + k3( 3.0 * si::meter_per_second , 3.0 * si::meter_per_second_squared ) , + k4( 4.0 * si::meter_per_second , 4.0 * si::meter_per_second_squared ) , + k5( 5.0 * si::meter_per_second , 5.0 * si::meter_per_second_squared ) , + k6( 6.0 * si::meter_per_second , 6.0 * si::meter_per_second_squared ) { } + + ~fusion_fixture( void ) + { + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( x ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( x ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k1 ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k1 ).value() , 1.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k2 ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k2 ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k3 ).value() , 3.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k3 ).value() , 3.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k4 ).value() , 4.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k4 ).value() , 4.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k5 ).value() , 5.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k5 ).value() , 5.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( k6 ).value() , 6.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( k6 ).value() , 6.0 , 1.0e-10 ); + } + + state_type res , x; + deriv_type k1 , k2 , k3 , k4 , k5 , k6 ; +}; + + + +BOOST_AUTO_TEST_SUITE( fusion_algebra_test ) + +fusion_algebra algebra; + +BOOST_AUTO_TEST_CASE( for_each2 ) +{ + fusion_fixture f; + algebra.for_each2( f.res , f.k1 , + default_operations::scale_sum1< time_type >( dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 0.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 0.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each3 ) +{ + fusion_fixture f; + algebra.for_each3( f.res , f.x , f.k1 , + default_operations::scale_sum2< value_type , time_type >( 1.0 , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each4 ) +{ + fusion_fixture f; + algebra.for_each4( f.res , f.x , f.k1 , f.k2 , + default_operations::scale_sum3< value_type , time_type , time_type >( 1.0 , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.3 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.3 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each5 ) +{ + fusion_fixture f; + algebra.for_each5( f.res , f.x , f.k1 , f.k2 , f.k3 , + default_operations::scale_sum4< value_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 1.6 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 1.6 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each6 ) +{ + fusion_fixture f; + algebra.for_each6( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , + default_operations::scale_sum5< value_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 2.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each7 ) +{ + fusion_fixture f; + algebra.for_each7( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , + default_operations::scale_sum6< value_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 2.5 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 2.5 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each8 ) +{ + fusion_fixture f; + algebra.for_each8( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , + default_operations::scale_sum7< value_type , time_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt , dt ) ); + BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 3.1 , 1.0e-10 ); + BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 3.1 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE( for_each15 ) +{ + fusion_fixture f; + algebra.for_each15( f.res , f.x , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , f.k1 , f.k2 , f.k3 , f.k4 , f.k5 , f.k6 , f.k1 , + default_operations::scale_sum14< value_type , time_type , time_type , time_type , time_type , time_type , time_type , + time_type , time_type , time_type , time_type , time_type , time_type , time_type >( 1.0 , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt , dt ) ); + //BOOST_CHECK_CLOSE( fusion::at_c< 0 >( f.res ).value() , 3.1 , 1.0e-10 ); + //BOOST_CHECK_CLOSE( fusion::at_c< 1 >( f.res ).value() , 3.1 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE( norm_inf ) +{ + double nrm = algebra.norm_inf( fusion::make_vector( 1.0 , 2.0 , 3.0 ) ); + BOOST_CHECK_CLOSE( nrm , 3.0 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generation.cpp b/src/boost/libs/numeric/odeint/test/generation.cpp new file mode 100644 index 00000000..6432692d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generation.cpp @@ -0,0 +1,87 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generation.cpp + + [begin_description] + This file tests the generation functions. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_generation + +#include <vector> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> + +using namespace boost::numeric::odeint; + +template< class Stepper1 , class Stepper2 > +void check_stepper_type( const Stepper1 &s1 , const Stepper2 &s2 ) +{ + BOOST_STATIC_ASSERT(( boost::is_same< Stepper1 , Stepper2 >::value )); +} + +BOOST_AUTO_TEST_SUITE( generation_test ) + +typedef std::vector< double > state_type; + +typedef runge_kutta_cash_karp54< state_type > rk54_type; +typedef runge_kutta_cash_karp54_classic< state_type > rk54_classic_type; +typedef runge_kutta_dopri5< state_type > dopri5_type; +typedef runge_kutta_fehlberg78< state_type > fehlberg78_type; +typedef rosenbrock4< double > rosenbrock4_type; + + +BOOST_AUTO_TEST_CASE( test_generation_dopri5 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , dopri5_type() ) , controlled_runge_kutta< dopri5_type >() ); + check_stepper_type( make_controlled< dopri5_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< dopri5_type >() ); + + check_stepper_type( make_dense_output( 1.0e-6 , 1.0e-10 , dopri5_type() ) , dense_output_runge_kutta< controlled_runge_kutta< dopri5_type > >() ); + check_stepper_type( make_dense_output< dopri5_type >( 1.0e-6 , 1.0e-10 ) , dense_output_runge_kutta< controlled_runge_kutta< dopri5_type > >() ); +} + +BOOST_AUTO_TEST_CASE( test_generation_cash_karp54 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rk54_type() ) , controlled_runge_kutta< rk54_type >() ); + check_stepper_type( make_controlled< rk54_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< rk54_type >() ); +} + +BOOST_AUTO_TEST_CASE( test_generation_cash_karp54_classic ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rk54_classic_type() ) , controlled_runge_kutta< rk54_classic_type >() ); + check_stepper_type( make_controlled< rk54_classic_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< rk54_classic_type >() ); +} + + +BOOST_AUTO_TEST_CASE( test_generation_fehlberg78 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , fehlberg78_type() ) , controlled_runge_kutta< fehlberg78_type >() ); + check_stepper_type( make_controlled< fehlberg78_type >( 1.0e-6 , 1.0e-10 ) , controlled_runge_kutta< fehlberg78_type >() ); +} + + +BOOST_AUTO_TEST_CASE( test_generation_rosenbrock4 ) +{ + check_stepper_type( make_controlled( 1.0e-6 , 1.0e-10 , rosenbrock4_type() ) , rosenbrock4_controller< rosenbrock4_type >() ); + check_stepper_type( make_controlled< rosenbrock4_type >( 1.0e-6 , 1.0e-10 ) , rosenbrock4_controller< rosenbrock4_type >() ); + + check_stepper_type( make_dense_output( 1.0e-6 , 1.0e-10 , rosenbrock4_type() ) , rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4_type > >() ); + check_stepper_type( make_dense_output< rosenbrock4_type >( 1.0e-6 , 1.0e-10 ) , rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4_type > >() ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp b/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp new file mode 100644 index 00000000..0b18da89 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generic_error_stepper.cpp @@ -0,0 +1,111 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generic_error_stepper.cpp + + [begin_description] + This file tests the generic error stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_generic_error_stepper + +#include <iostream> +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/explicit_error_generic_rk.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> + +#include <boost/array.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace fusion = boost::fusion; + +typedef double value_type; +typedef boost::array< value_type , 2 > state_type; + +void sys( const state_type &x , state_type &dxdt , const value_type &t ) +{ + dxdt[ 0 ] = x[ 0 ] + 2 * x[ 1 ]; + dxdt[ 1 ] = x[ 1 ]; +} + +typedef explicit_error_generic_rk< 6 , 5 , 4 , 5 , state_type> error_rk_generic_type; + +const boost::array< double , 1 > a1 = {{ 0.2 }}; +const boost::array< double , 2 > a2 = {{ 3.0/40.0 , 9.0/40 }}; +const boost::array< double , 3 > a3 = {{ 0.3 , -0.9 , 1.2 }}; +const boost::array< double , 4 > a4 = {{ -11.0/54.0 , 2.5 , -70.0/27.0 , 35.0/27.0 }}; +const boost::array< double , 5 > a5 = {{ 1631.0/55296.0 , 175.0/512.0 , 575.0/13824.0 , 44275.0/110592.0 , 253.0/4096.0 }}; + +const error_rk_generic_type::coef_a_type a = fusion::make_vector( a1 , a2 , a3 , a4 , a5 ); +const error_rk_generic_type::coef_b_type b = {{ 37.0/378.0 , 0.0 , 250.0/621.0 , 125.0/594.0 , 0.0 , 512.0/1771.0 }}; +const error_rk_generic_type::coef_b_type b2 = {{ b[0]-2825.0/27648.0 , b[1]-0.0 , b[2]-18575.0/48384.0 , b[3]-13525.0/55296.0 , b[4]-277.0/14336.0 , b[5]-0.25 }}; +const error_rk_generic_type::coef_c_type c = {{ 0.0 , 0.2 , 0.3 , 0.6 , 1.0 , 7.0/8 }}; + +typedef runge_kutta_cash_karp54< state_type > error_rk54_ck_generic_type; +typedef runge_kutta_cash_karp54_classic< state_type > rk54_ck_type; + +BOOST_AUTO_TEST_SUITE( generic_error_stepper_test ) + +BOOST_AUTO_TEST_CASE( test_generic_error_stepper ) +{ + //simultaneously test copying + error_rk_generic_type rk_generic_( a , b , b2 , c ); + error_rk_generic_type rk_generic = rk_generic_; + + error_rk54_ck_generic_type rk54_ck_generic_; + error_rk54_ck_generic_type rk54_ck_generic = rk54_ck_generic_; + + //std::cout << stepper; + + rk54_ck_type rk54_ck_; + rk54_ck_type rk54_ck = rk54_ck_; + + typedef error_rk_generic_type::state_type state_type; + typedef error_rk_generic_type::value_type stepper_value_type; + typedef error_rk_generic_type::deriv_type deriv_type; + typedef error_rk_generic_type::time_type time_type; + + state_type x = {{ 0.0 , 1.0 }}; + state_type y = x; + state_type z = x; + state_type x_err , y_err , z_err; + + rk_generic.do_step( sys , x , 0.0 , 0.1 , x_err ); + + rk54_ck_generic.do_step( sys , y , 0.0 , 0.1 , y_err); + + rk54_ck.do_step( sys , z , 0.0 , 0.1 , z_err ); + + BOOST_CHECK_NE( 0.0 , x[0] ); + BOOST_CHECK_NE( 1.0 , x[1] ); + BOOST_CHECK_NE( 0.0 , x_err[0] ); + BOOST_CHECK_NE( 0.0 , x_err[1] ); + // compare with analytic solution of above system + BOOST_CHECK_EQUAL( x[0] , y[0] ); + BOOST_CHECK_EQUAL( x[1] , y[1] ); + BOOST_CHECK_EQUAL( x[0] , z[0] ); + BOOST_CHECK_EQUAL( x[1] , z[1] ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/generic_stepper.cpp b/src/boost/libs/numeric/odeint/test/generic_stepper.cpp new file mode 100644 index 00000000..e2c18272 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/generic_stepper.cpp @@ -0,0 +1,104 @@ +/* + [auto_generated] + libs/numeric/odeint/test/generic_stepper.cpp + + [begin_description] + This file tests the generic stepper. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_generic_stepper + +#include <iostream> +#include <utility> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/explicit_generic_rk.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> + +#include <boost/array.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace fusion = boost::fusion; + +typedef double value_type; +typedef boost::array< value_type , 2 > state_type; + +void sys( const state_type &x , state_type &dxdt , const value_type &t ) +{ + dxdt[ 0 ] = x[ 0 ] + 2 * x[ 1 ]; + dxdt[ 1 ] = x[ 1 ]; +} + +typedef explicit_generic_rk< 4 , 4 , state_type> rk_generic_type; +typedef runge_kutta4< state_type > rk4_generic_type; + +const boost::array< double , 1 > a1 = {{ 0.5 }}; +const boost::array< double , 2 > a2 = {{ 0.0 , 0.5 }}; +const boost::array< double , 3 > a3 = {{ 0.0 , 0.0 , 1.0 }}; + +const rk_generic_type::coef_a_type a = fusion::make_vector( a1 , a2 , a3 ); +const rk_generic_type::coef_b_type b = {{ 1.0/6 , 1.0/3 , 1.0/3 , 1.0/6 }}; +const rk_generic_type::coef_c_type c = {{ 0.0 , 0.5 , 0.5 , 1.0 }}; + +typedef runge_kutta4_classic< state_type > rk4_type; + +BOOST_AUTO_TEST_SUITE( generic_stepper_test ) + +BOOST_AUTO_TEST_CASE( test_generic_stepper ) +{ + //simultaneously test copying + rk_generic_type rk_generic_( a , b , c ); + rk_generic_type rk_generic = rk_generic_; + + rk4_generic_type rk4_generic_; + rk4_generic_type rk4_generic = rk4_generic_; + + //std::cout << stepper; + + rk4_type rk4_; + rk4_type rk4 = rk4_; + + typedef rk_generic_type::state_type state_type; + typedef rk_generic_type::value_type stepper_value_type; + typedef rk_generic_type::deriv_type deriv_type; + typedef rk_generic_type::time_type time_type; + + state_type x = {{ 0.0 , 1.0 }}; + state_type y = x; + state_type z = x; + + rk_generic.do_step( sys , x , 0.0 , 0.1 ); + + rk4_generic.do_step( sys , y , 0.0 , 0.1 ); + + rk4.do_step( sys , z , 0.0 , 0.1 ); + + BOOST_CHECK_NE( 0.0 , x[0] ); + BOOST_CHECK_NE( 1.0 , x[1] ); + // compare with analytic solution of above system + BOOST_CHECK_EQUAL( x[0] , y[0] ); + BOOST_CHECK_EQUAL( x[1] , y[1] ); + BOOST_CHECK_EQUAL( x[0] , z[0] ); + BOOST_CHECK_EQUAL( x[1] , z[1] ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/implicit_euler.cpp b/src/boost/libs/numeric/odeint/test/implicit_euler.cpp new file mode 100644 index 00000000..575c896a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/implicit_euler.cpp @@ -0,0 +1,86 @@ +/* + [auto_generated] + libs/numeric/odeint/test/implicit_euler.cpp + + [begin_description] + This file tests the implicit Euler stepper. + [end_description] + + Copyright 2010-2011 Mario Mulansky + Copyright 2010-2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_implicit_euler + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> + +#include <boost/numeric/odeint/stepper/implicit_euler.hpp> +//#include <boost/numeric/odeint/util/ublas_resize.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +/* use functors, because functions don't work with msvc 10, I guess this is a bug */ +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type t ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + } +}; + +BOOST_AUTO_TEST_SUITE( implicit_euler_test ) + +BOOST_AUTO_TEST_CASE( test_euler ) +{ + implicit_euler< value_type > stepper; + state_type x( 2 ); + x(0) = 0.0; x(1) = 1.0; + + value_type eps = 1E-12; + + /* make_pair doesn't work with function pointers on msvc 10 */ + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 ); + + using std::abs; + + // compare with analytic solution of above system + BOOST_CHECK_MESSAGE( abs( x(0) - 20.0/81.0 ) < eps , x(0) - 20.0/81.0 ); + BOOST_CHECK_MESSAGE( abs( x(1) - 10.0/9.0 ) < eps , x(0) - 10.0/9.0 ); + +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate.cpp b/src/boost/libs/numeric/odeint/test/integrate.cpp new file mode 100644 index 00000000..07d4617f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate.cpp @@ -0,0 +1,299 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate.cpp + + [begin_description] + This file tests the integrate function and its variants. + [end_description] + + Copyright 2011-2012 Mario Mulansky + Copyright 2011-2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_functions + +#include <boost/type_traits.hpp> + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +// nearly everything from odeint is used in these tests +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp> +#endif +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/modified_midpoint.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> + +#include <boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp> +#include <boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp> + +#include <boost/numeric/odeint/util/detail/less_with_sign.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + + +typedef double value_type; +typedef std::vector< value_type > state_type; + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + state_type& m_x; + + push_back_time( std::vector< double > × , state_type &x ) + : m_times( times ) , m_x( x ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + boost::numeric::odeint::copy( x , m_x ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()( const value_type t_end , const value_type dt ) + { + // std::cout << "Testing integrate_const with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + size_t steps = integrate_const( Stepper() , lorenz , x , 0.0 , t_end , + dt , push_back_time( times , x_end ) ); + + std::cout.precision(16); + std::cout << t_end << " (" << dt << "), " << steps << " , " << times.size() << " , " << 10.0+dt*steps << "=" << x_end[0] << std::endl; + + std::cout << static_cast<int>(floor(t_end/dt)) << " , " << t_end/dt << std::endl; + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , static_cast<int>(floor(t_end/dt))+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + //std::cout << i << " , " << times[i] << " , " << static_cast< value_type >(i)*dt << std::endl; + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2E-16 ); + } + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + times[times.size()-1]) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 + //BOOST_CHECK_EQUAL( x[1] , x_end[1] ); + //BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()( const value_type t_end = 10.0 , const value_type dt = 0.03 ) + { + // std::cout << "Testing integrate_adaptive with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + size_t steps = integrate_adaptive( Stepper() , lorenz , x , 0.0 , t_end , + dt , push_back_time( times , x_end ) ); + + // std::cout << t_end << " , " << steps << " , " << times.size() << " , " << dt << " , " << 10.0+t_end << "=" << x_end[0] << std::endl; + + BOOST_CHECK_EQUAL( times.size() , steps+1 ); + + BOOST_CHECK_SMALL( times[0] - 0.0 , 2E-16 ); + BOOST_CHECK_SMALL( times[times.size()-1] - t_end , times.size() * 2E-16 ); + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + t_end) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()( const int n = 10 , const int dn=1 , const value_type dt = 0.03 ) + { + // std::cout << "Testing integrate_times with " << typeid( Stepper ).name() << std::endl; + + state_type x( 3 ) , x_end( 3 ); + x[0] = x[1] = x[2] = 10.0; + + std::vector< double > times; + + std::vector< double > obs_times( abs(n) ); + for( int i=0 ; boost::numeric::odeint::detail::less_with_sign( static_cast<double>(i) , + static_cast<double>(obs_times.size()) , + dt ) ; i+=dn ) + { + obs_times[i] = i; + } + // simple stepper + integrate_times( Stepper() , lorenz , x , obs_times.begin() , obs_times.end() , + dt , push_back_time( times , x_end ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , abs(n) ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + 1.0*times[times.size()-1]) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()( const int n = 200 , const value_type dt = 0.01 ) + { + // std::cout << "Testing integrate_n_steps with " << typeid( Stepper ).name() << ". "; + // std::cout << "dt=" << dt << std::endl; + + state_type x( 3 ) , x_end( 3 ); + x[0] = x[1] = x[2] = 10.0; + + std::vector< double > times; + + // simple stepper + value_type end_time = integrate_n_steps( Stepper() , lorenz , x , 0.0 , dt , n , push_back_time( times , x_end ) ); + + BOOST_CHECK_SMALL( end_time - n*dt , 2E-16 ); + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , n+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL(times[i] - static_cast< value_type >(i) * dt, 2E-16); + } + // check first, trivial, component + BOOST_CHECK_SMALL( (10.0 + end_time) - x_end[0] , 1E-6 ); // precision of steppers: 1E-6 +// BOOST_CHECK_EQUAL( x[1] , x_end[1] ); +// BOOST_CHECK_EQUAL( x[2] , x_end[2] ); + + } +}; + + + +class stepper_methods : public mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + controlled_runge_kutta< runge_kutta_cash_karp54< state_type > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type > > , + controlled_runge_kutta< runge_kutta_fehlberg78< state_type > > , + bulirsch_stoer< state_type > , + dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >, + adaptive_adams_bashforth_moulton<3, state_type>, + adaptive_adams_bashforth_moulton<5, state_type>, + adaptive_adams_bashforth_moulton<7, state_type>, + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> >, + controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > + //bulirsch_stoer_dense_out< state_type > +> { }; + + + +BOOST_AUTO_TEST_SUITE( integrate_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + perform_integrate_const_test< Stepper > tester; + tester( 1.005 , 0.01 ); + tester( 1.0 , 0.01 ); + tester( 1.1 , 0.01 ); + tester( -1.005 , -0.01 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + perform_integrate_adaptive_test< Stepper > tester; + tester( 1.005 , 0.01 ); + tester( 1.0 , 0.01 ); + tester( 1.1 , 0.01 ); + tester( -1.005 , -0.01 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + perform_integrate_times_test< Stepper > tester; + tester(); + //tester( -10 , -0.01 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, stepper_methods ) +{ + if(!boost::is_same<Stepper, controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<3, state_type> > >::value && + !boost::is_same<Stepper, controlled_adams_bashforth_moulton<adaptive_adams_bashforth_moulton<5, state_type> > >::value) + { + perform_integrate_n_steps_test< Stepper > tester; + tester(); + tester( 200 , 0.01 ); + tester( 200 , 0.01 ); + tester( 200 , 0.01 ); + tester( 200 , -0.01 ); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp b/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp new file mode 100644 index 00000000..4bff200a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_implicit.cpp @@ -0,0 +1,233 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_implicit.cpp + + [begin_description] + This file tests the integrate function and its variants with the implicit steppers. + [end_description] + + Copyright 2011 Mario Mulansky + Copyright 2011-2013 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_integrate_functions_implicit + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_n_steps.hpp> +#endif +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace ublas = boost::numeric::ublas; + +typedef double value_type; +typedef ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + const value_type dt = 0.03; + const value_type t_end = 10.0; + + std::vector< value_type > times; + + integrate_const( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , t_end , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , static_cast<int>(std::floor(t_end/dt))+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + { + //std::cout << i << std::endl; + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2.0e-16 ); + } + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + const value_type dt = 0.03; + const value_type t_end = 10.0; + + std::vector< value_type > times; + + size_t steps = integrate_adaptive( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , t_end , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( times.size() , steps+1 ); + + BOOST_CHECK_SMALL( times[0] - 0.0 , 2.0e-16 ); + BOOST_CHECK_SMALL( times[times.size()-1] - t_end , times.size() * 3.0e-16 ); + } +}; + + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + + const value_type dt = 0.03; + + std::vector< double > times; + + // simple stepper + integrate_times( Stepper() , std::make_pair( sys() , jacobi() ) , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , 10 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()( void ) + { + state_type x( 2 , 1.0 ); + + const value_type dt = 0.03; + const int n = 200; + + std::vector< double > times; + + // simple stepper + value_type end_time = integrate_n_steps( Stepper() , std::make_pair( sys() , jacobi() ) , x , 0.0 , dt , n , push_back_time( times ) ); + + BOOST_CHECK_SMALL( end_time - n*dt , 3.0e-16 ); + BOOST_CHECK_EQUAL( static_cast<int>(times.size()) , n+1 ); + + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast< value_type >(i)*dt , (i+1) * 2.0e-16 ); + } +}; + + + +class stepper_methods : public mpl::vector< + rosenbrock4< value_type > , + rosenbrock4_controller< rosenbrock4< value_type > > , + rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > +> { }; + + + +BOOST_AUTO_TEST_SUITE( integrate_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + perform_integrate_const_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + perform_integrate_adaptive_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + perform_integrate_times_test< Stepper > tester; + tester(); +} + + +class simple_stepper_methods : public mpl::vector< + rosenbrock4< value_type > +> { }; + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, simple_stepper_methods ) +{ + perform_integrate_n_steps_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp b/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp new file mode 100644 index 00000000..0dba4046 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_overflow.cpp @@ -0,0 +1,200 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_overflow.cpp + + [begin_description] + This file tests the overflow exception of the integrate functions. + [end_description] + + Copyright 2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_overflow + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/numeric/odeint.hpp> + + +using namespace boost::numeric::odeint; + + +typedef double value_type; +typedef std::vector< value_type > state_type; + +// the famous lorenz system as usual +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +typedef runge_kutta_dopri5<state_type> stepper_type; +typedef runge_kutta_cash_karp54<state_type> cash_karp_type; + + +BOOST_AUTO_TEST_SUITE( integrate_overflow ) + +BOOST_AUTO_TEST_CASE( test_integrate_const ) +{ + state_type x(3, 5.0); + std::vector<double> times; + + // check the function signatures with normal stepper + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0); + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer()); + // no exceptions expected for normal steppers + integrate_const(stepper_type(), lorenz, x, 0.0, 10.0, 1.0, null_observer(), max_step_checker(10)); + + + // check exceptions for controlled stepper + integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_const(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 10.0, 1.0); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_const(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 10.0, 1.0, push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_CASE( test_integrate_n_steps ) +{ + state_type x(3, 5.0); + std::vector<double> times; + + // check the function signatures with normal stepper + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10); + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer()); + // no exceptions expected for normal steppers + integrate_n_steps(stepper_type(), lorenz, x, 0.0, 1.0, 10, null_observer(), max_step_checker(10)); + + + // check exceptions for controlled stepper + integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_n_steps(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10); + integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, 0.0, 1.0, 10, push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_n_steps(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + 0.0, 1.0, 10, push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_CASE( test_integrate_times ) +{ + state_type x(3, 5.0); + std::vector<double> times; + boost::counting_iterator<int> t0(0); + boost::counting_iterator<int> t1(10); + + // check the function signatures with normal stepper + integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // no exceptions expected for big enough step size + integrate_times(stepper_type(), lorenz, x, t0, t1, 1.0 , push_back_time(times), max_step_checker(10)); + // if dt*max_steps < observer time difference we expect an exception + BOOST_CHECK_THROW(integrate_times(stepper_type(), lorenz, x, t0, t1, 0.01, push_back_time(times), + max_step_checker(10)), + std::runtime_error); + + // check exceptions for controlled stepper + // no exception if no checker is provided + integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<stepper_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check cash karp controlled stepper + // no exception if no checker is provided + integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_controlled<cash_karp_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); + + // check exceptions for dense output stepper + integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, t0, t1, 1.0 , + push_back_time(times)); + // very small error terms -> standard overflow threshold of 500 should fire an exception + BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-15, 1E-15), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker()), + std::runtime_error); + // small threshold of 10 -> larger error still gives an exception + BOOST_CHECK_THROW(integrate_times(make_dense_output<stepper_type>(1E-5, 1E-5), lorenz, x, + t0, t1, 1.0 , push_back_time(times), max_step_checker(10)), + std::runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp b/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp new file mode 100644 index 00000000..5d6d34c9 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_stepper_refs.cpp @@ -0,0 +1,271 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_stepper_refs.cpp + + [begin_description] + Tests the integrate functions with boost::ref( stepper) + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_integrate_stepper_refs + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/noncopyable.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_n_steps.hpp> +#include <boost/numeric/odeint/stepper/controlled_step_result.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; +typedef std::vector< value_type > state_type; + +// minimal non-copyable basic stepper +template< +class State +> +class simple_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef stepper_tag stepper_category; + + template< class System > + void do_step( System system , state_type &in , time_type t , time_type dt ) + { + // empty + + } +}; + +// minimal non-copyable controlled stepper +template< +class State +> +class controlled_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef controlled_stepper_tag stepper_category; + + template< class System > + controlled_step_result try_step( System system , state_type &in , time_type &t , time_type &dt ) + { + std::cout << "dense out stepper: " << t << " , " << dt << std::endl; + t += dt; + return success; + } +}; + +// minimal non-copyable dense_output stepper +template< +class State +> +class dense_out_stepper_nc : boost::noncopyable +{ +public : + typedef State state_type; + typedef double value_type; + typedef state_type deriv_type; + typedef double time_type; + typedef size_t order_type; + typedef dense_output_stepper_tag stepper_category; + + void initialize( const state_type &x0 , const time_type t0 , const time_type dt0 ) + { + m_x = x0; + m_t = t0; + m_dt = dt0; + std::cout << "initialize: " << m_t << " , " << m_dt << std::endl; + } + + template< class System > + void do_step( System system ) + { + std::cout << "dense out stepper: " << m_t << " , " << m_dt << std::endl; + m_t += m_dt; + } + + void calc_state( const time_type t_inter , state_type &x ) + { + x = m_x; + } + + const state_type& current_state() const + { return m_x; } + + time_type current_time() const + { return m_t; } + + time_type current_time_step() const + { return m_dt; } + + +private : + time_type m_t; + time_type m_dt; + state_type m_x; +}; + + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + //const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + // first component trivial + dxdt[0] = 1.0; //sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + state_type& m_x; + + push_back_time( std::vector< double > × , state_type &x ) + : m_times( times ) , m_x( x ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + boost::numeric::odeint::copy( x , m_x ); + } +}; + +template< class Stepper > +struct perform_integrate_const_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_const( boost::ref(stepper) , lorenz , x , 0.0 , 1.0 , + 0.1, push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_adaptive_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_adaptive( boost::ref(stepper) , lorenz , x , 0.0 , 1.0 , + 0.1, push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_n_steps_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_n_steps( boost::ref(stepper) , lorenz , x , 0.0 , 0.1 , + 10 , push_back_time( times , x_end ) ); + } +}; + +template< class Stepper > +struct perform_integrate_times_test +{ + void operator()() + { + state_type x( 3 , 10.0 ) , x_end( 3 ); + + std::vector< value_type > times; + + Stepper stepper; + + integrate_times( boost::ref(stepper) , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , 0.1 , + push_back_time( times , x_end ) ); + } +}; + +class stepper_methods : public mpl::vector< + simple_stepper_nc< state_type > , + controlled_stepper_nc< state_type >, + dense_out_stepper_nc< state_type > > { }; + +BOOST_AUTO_TEST_SUITE( integrate_stepper_refs ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate const" << std::endl; + perform_integrate_const_test< Stepper > tester; + tester(); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate adaptive" << std::endl; + perform_integrate_adaptive_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate n steps" << std::endl; + perform_integrate_n_steps_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_methods ) +{ + std::cout << "integrate times" << std::endl; + perform_integrate_times_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrate_times.cpp b/src/boost/libs/numeric/odeint/test/integrate_times.cpp new file mode 100644 index 00000000..2837f09e --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrate_times.cpp @@ -0,0 +1,247 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrate_times.cpp + + [begin_description] + This file tests the integrate_times function and its variants. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_integrate_times + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/ref.hpp> +#include <boost/iterator/counting_iterator.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_times.hpp> +#include <boost/numeric/odeint/iterator/integrate/integrate_adaptive.hpp> +#endif +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef std::vector< value_type > state_type; + + +void lorenz( const state_type &x , state_type &dxdt , const value_type t ) +{ + BOOST_CHECK( t >= 0.0 ); + + const value_type sigma( 10.0 ); + const value_type R( 28.0 ); + const value_type b( value_type( 8.0 ) / value_type( 3.0 ) ); + + dxdt[0] = sigma * ( x[1] - x[0] ); + dxdt[1] = R * x[0] - x[1] - x[0] * x[2]; + dxdt[2] = -b * x[2] + x[0] * x[1]; +} + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + void operator()( const state_type &x , double t ) + { + m_times.push_back( t ); + } +}; + +BOOST_AUTO_TEST_SUITE( integrate_times_test ) + +BOOST_AUTO_TEST_CASE( test_integrate_times ) +{ + + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + + const value_type dt = 0.03; + + std::vector< double > times; + + std::cout << "test rk4 stepper" << std::endl; + + // simple stepper + integrate_times( runge_kutta4< state_type >() , lorenz , x , boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test dopri5 stepper" << std::endl; + + // controlled stepper + integrate_times( controlled_runge_kutta< runge_kutta_dopri5< state_type > >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test BS stepper" << std::endl; + + //another controlled stepper + integrate_times( bulirsch_stoer< state_type >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + std::cout << "test dense_out stepper" << std::endl; + + // dense output stepper + integrate_times( dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >() , + lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + + std::cout << "test BS_do stepper" << std::endl; + + integrate_times( bulirsch_stoer_dense_out< state_type >() , lorenz , x , + boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + +} + + +BOOST_AUTO_TEST_CASE( test_integrate_times_ranges ) +{ + + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + + const value_type dt = 0.03; + + std::vector< double > times; + + // simple stepper + integrate_times( runge_kutta4< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + // controlled stepper + integrate_times( controlled_runge_kutta< runge_kutta_dopri5< state_type > >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + //another controlled stepper + integrate_times( bulirsch_stoer< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + times.clear(); + + + // dense output stepper + integrate_times( bulirsch_stoer_dense_out< state_type >() , lorenz , x , + std::make_pair( boost::counting_iterator<int>(0) , boost::counting_iterator<int>(10) ) , + dt , push_back_time( times ) ); + + for( int i=0 ; i<10 ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_EQUAL( times[i] , static_cast<double>(i) ); + +} + +BOOST_AUTO_TEST_CASE( test_integrate_times_overshoot ) +{ + state_type x( 3 ); + x[0] = x[1] = x[2] = 10.0; + double dt = -0.1; + + std::vector<double> times( 10 ); + for( int i=0 ; i<10 ; ++i ) + times[i] = 1.0-i*1.0/9.0; + + std::cout << "test rk4 stepper" << std::endl; + // simple stepper + std::vector<double> obs_times; + int steps = integrate_times( runge_kutta4< state_type >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); +// different behavior for the iterator based integrate implementaton +#ifndef ODEINT_INTEGRATE_ITERATOR + BOOST_CHECK_EQUAL( steps , 18 ); // we really need 18 steps because dt and + // the difference of the observation times + // are so out of sync +#else + // iterator based implementation can only return the number of iteration steps + BOOST_CHECK_EQUAL( steps , 9 ); +#endif + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); + + std::cout << "test rk_ck stepper" << std::endl; + // controlled stepper + obs_times.clear(); + integrate_times( controlled_runge_kutta< runge_kutta_cash_karp54< state_type > >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); + + std::cout << "test dopri5 stepper" << std::endl; + // controlled stepper + obs_times.clear(); + integrate_times( dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >() , lorenz , x , + times.begin() , times.end() , + dt , push_back_time( obs_times ) ); + for( int i=0 ; i<10 ; ++i ) + BOOST_CHECK_EQUAL( times[i] , obs_times[i] ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp b/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp new file mode 100644 index 00000000..2c286195 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/integrators_symplectic.cpp @@ -0,0 +1,74 @@ +/* + [auto_generated] + libs/numeric/odeint/test/integrators_symplectic.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_iterators_symplectic + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 +#define FUSION_MAX_VECTOR_SIZE 15 + +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#ifndef ODEINT_INTEGRATE_ITERATOR +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#else +#include <boost/numeric/odeint/iterator/integrate/integrate_const.hpp> +#endif +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +typedef std::vector<double> container_type; + +struct harm_osc { + void operator()( const container_type &q , container_type &dpdt ) + { + dpdt[0] = -q[0]; + } +}; + +class complete_steppers : public mpl::vector< + symplectic_euler< container_type > + , symplectic_rkn_sb3a_mclachlan< container_type > + , symplectic_rkn_sb3a_m4_mclachlan< container_type > + > {}; + +BOOST_AUTO_TEST_SUITE( symplectic_steppers_test ) + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_integrate_const , Stepper , complete_steppers ) +{ + container_type q( 1 , 1.0 ) , p( 1 , 0.0 ); + size_t steps = integrate_const( Stepper() , harm_osc() , + std::make_pair( boost::ref(q) , boost::ref(p) ) , + 0.0 , 1.0 , 0.1 ); + BOOST_CHECK( steps == 10 ); + BOOST_CHECK_CLOSE( q[0] , std::cos(1.0) , 100*std::pow( 0.1 , Stepper::order_value ) ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/is_pair.cpp b/src/boost/libs/numeric/odeint/test/is_pair.cpp new file mode 100644 index 00000000..bf3bc35b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/is_pair.cpp @@ -0,0 +1,49 @@ +/* + [auto_generated] + libs/numeric/odeint/test/is_pair.cpp + + [begin_description] + This file tests the is_pair meta-function. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +#define BOOST_TEST_MODULE odeint_is_pair + +#include <utility> + +#include <boost/test/unit_test.hpp> +#include <boost/static_assert.hpp> + +#include <boost/numeric/odeint/util/is_pair.hpp> + +using namespace boost::numeric::odeint; + + + +BOOST_AUTO_TEST_SUITE( is_pair_test ) + +BOOST_AUTO_TEST_CASE( test_is_pair ) +{ + typedef std::pair< int , int > type1; + typedef std::pair< int& , int > type2; + typedef std::pair< int , int& > type3; + typedef std::pair< int& , int& > type4; + typedef std::pair< const int , int > type5; + typedef std::pair< const int& , int > type6; + + BOOST_STATIC_ASSERT(( is_pair< type1 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type2 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type3 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type4 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type5 >::value )); + BOOST_STATIC_ASSERT(( is_pair< type6 >::value )); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/is_resizeable.cpp b/src/boost/libs/numeric/odeint/test/is_resizeable.cpp new file mode 100644 index 00000000..cb8e9c1c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/is_resizeable.cpp @@ -0,0 +1,116 @@ +/* + [auto_generated] + libs/numeric/odeint/test/is_resizeable.cpp + + [begin_description] + This file tests is_resizeable meta-function of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_is_resizeable + +#include <vector> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +template< typename T > struct my_seq1 {}; +template< typename T > struct my_seq2 {}; + +namespace boost { namespace fusion { namespace traits { + + template< typename T > struct is_sequence< my_seq1< T > > : boost::true_type {}; + template< typename T > struct is_sequence< my_seq2< T > > : boost::true_type {}; +} } } // boost::fusion::traits + +namespace boost { namespace numeric { namespace odeint { + + template< typename T > + struct is_resizeable< my_seq2< T > > : boost::true_type {}; + +} } } // boost::numeric::odeint + + + +BOOST_AUTO_TEST_CASE( test_vector ) +{ + BOOST_CHECK( is_resizeable< std::vector< int > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_double ) +{ + BOOST_CHECK( !( is_resizeable< double >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_vector ) +{ + typedef boost::fusion::vector< std::vector< double > , std::vector< double > > state_type; + BOOST_CHECK( is_resizeable< state_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_double ) +{ + typedef boost::fusion::vector< double , double > state_type; + BOOST_CHECK( !( is_resizeable< state_type >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed1 ) +{ + typedef boost::fusion::vector< double , std::vector< double > > state_type; + BOOST_CHECK( is_resizeable< state_type >::value); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed2 ) +{ + typedef boost::fusion::vector< std::vector< double > , double > state_type; + BOOST_CHECK( is_resizeable< state_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_quantity_sequence ) +{ + namespace units = boost::units; + namespace si = boost::units::si; + + typedef double value_type; + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< si::length , value_type > length_type; + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef boost::fusion::vector< length_type , velocity_type > state_type; + + BOOST_CHECK( !( is_resizeable< state_type >::value ) ); +} + +BOOST_AUTO_TEST_CASE( test_my_seq1 ) +{ + BOOST_CHECK( !is_resizeable< my_seq1< double > >::value ); +} + +BOOST_AUTO_TEST_CASE( test_my_seq2 ) +{ + BOOST_CHECK( is_resizeable< my_seq2< double > >::value ); +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/multi_array.cpp b/src/boost/libs/numeric/odeint/test/multi_array.cpp new file mode 100644 index 00000000..67b7f964 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/multi_array.cpp @@ -0,0 +1,211 @@ +/* + [auto_generated] + libs/numeric/odeint/test/multi_array.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_multi_array + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/algebra/multi_array_algebra.hpp> +#include <boost/numeric/odeint/util/multi_array_adaption.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::multi_array< double , 1 > vector_type; +typedef boost::multi_array< double , 2 > matrix_type; +typedef boost::multi_array< double , 3 > tensor_type; + + +BOOST_AUTO_TEST_SUITE( multi_array_test ) + +BOOST_AUTO_TEST_CASE( test_resizeable ) +{ + BOOST_CHECK( is_resizeable< vector_type >::value ); + BOOST_CHECK( is_resizeable< matrix_type >::value ); + BOOST_CHECK( is_resizeable< tensor_type >::value ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector1 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[12] ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector2 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[13] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector3 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,11)] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector4 ) +{ + vector_type v1( boost::extents[12] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,10)] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_vector5 ) +{ + vector_type v1( boost::extents[vector_type::extent_range(-1,10)] ); + vector_type v2( boost::extents[vector_type::extent_range(-1,10)] ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + + + +BOOST_AUTO_TEST_CASE( test_same_size_matrix1 ) +{ + matrix_type m1( boost::extents[12][4] ); + matrix_type m2( boost::extents[12][4] ); + BOOST_CHECK( same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix2 ) +{ + matrix_type m1( boost::extents[12][4] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix3 ) +{ + matrix_type m1( boost::extents[12][matrix_type::extent_range(-1,2)] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_matrix4 ) +{ + matrix_type m1( boost::extents[12][matrix_type::extent_range(-1,1)] ); + matrix_type m2( boost::extents[12][3] ); + BOOST_CHECK( !same_size( m1 , m2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_tensor1 ) +{ + tensor_type t1( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + tensor_type t2( boost::extents[ tensor_type::extent_range( 2 , 13 ) ] + [ tensor_type::extent_range( -1 , 5 ) ] + [ tensor_type::extent_range( 1 , 4 ) ] ); + BOOST_CHECK( !same_size( t1 , t2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_same_size_tensor2 ) +{ + tensor_type t1( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + tensor_type t2( boost::extents[ tensor_type::extent_range( -2 , 9 ) ] + [ tensor_type::extent_range( 5 , 11 ) ] + [ tensor_type::extent_range( -1 , 2 ) ] ); + BOOST_CHECK( same_size( t1 , t2 ) ); +} + + +// Tests for tensor_type + +BOOST_AUTO_TEST_CASE( test_resize_vector1 ) +{ + vector_type v1( boost::extents[4] ); + vector_type v2; + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_resize_vector2 ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2; + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_resize_vector3 ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2( boost::extents[ vector_type::extent_range( 2 , 9 ) ] ); + BOOST_CHECK( !same_size( v1 , v2 ) ); + resize( v2 , v1 ); + BOOST_CHECK( same_size( v1 , v2 ) ); +} + +struct mult4 +{ + void operator()( double &a , double const &b ) const + { + a = b * 4.0; + } +}; + +BOOST_AUTO_TEST_CASE( test_for_each2_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -2 , 9 ) ] ); + vector_type v2( boost::extents[ vector_type::extent_range( 2 , 13 ) ] ); + for( int i=-2 ; i<9 ; ++i ) + v1[i] = i * 2; + multi_array_algebra::for_each2( v2 , v1 , mult4() ); + for( int i=2 ; i<13 ; ++i ) + BOOST_CHECK_EQUAL( v2[i] , v1[i-4]*4.0 ); +} + +struct vector_ode +{ + const static size_t n = 128; + void operator()( const vector_type &x , vector_type &dxdt , double t ) const + { + dxdt[-1] = x[n] - 2.0 * x[-1] + x[0]; + for( size_t i=0 ; i<n ; ++i ) + dxdt[i] = x[i-1] - 2.0 * x[i] + x[i+1]; + dxdt[n] = x[-1] - 2.0 * x[n] + x[n-1]; + } +}; + + +BOOST_AUTO_TEST_CASE( test_rk4_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -1 , vector_ode::n+1 ) ] ); + integrate_const( runge_kutta4< vector_type >() , vector_ode() , v1 , 0.0 , 1.0 , 0.01 ); +} + +BOOST_AUTO_TEST_CASE( test_dopri5_vector ) +{ + vector_type v1( boost::extents[ vector_type::extent_range( -1 , vector_ode::n+1 ) ] ); + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , runge_kutta_dopri5< vector_type >() ) , vector_ode() , v1 , 0.0 , 1.0 , 0.01 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp b/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp new file mode 100644 index 00000000..bebcf6da --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/n_step_iterator.cpp @@ -0,0 +1,225 @@ +/* + [auto_generated] + libs/numeric/odeint/test/n_step_iterator.cpp + + [begin_description] + This file tests the n-step iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_n_step_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/n_step_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( n_step_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 0.2 , 10 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 10 do_step calls so x should be 3.5 + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_range( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 2.5 , 0.1 , 0 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( last1 == last2 ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef n_step_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , 0.3 , -0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_n_step_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + make_n_step_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_n_step_range( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-14 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp new file mode 100644 index 00000000..fbce8676 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/n_step_time_iterator.cpp @@ -0,0 +1,213 @@ +/* + [auto_generated] + libs/numeric/odeint/test/n_step_time_iterator.cpp + + [begin_description] + This file tests the n-step time iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_n_step_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/n_step_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_SUITE( n_step_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &( iter2->first ) ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , 0.0 , 0.1 , 10 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , 0.0 , 0.2 , 10 ); + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &( iter1->first ) , &x1 ); + BOOST_CHECK_EQUAL( &( iter2->first ) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_time_iterator_begin( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_time_iterator_end( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_time_range( stepper , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_n_step_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + make_n_step_time_iterator_end( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_n_step_time_range( boost::ref( stepper ) , boost::ref( system ) , x , 0.0 , 0.1 , 10 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 3.5 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , 0.0 , 0.1 , 0 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( last1 == last2 ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef n_step_time_iterator< Stepper , empty_system , state_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_n_step_time_iterator_begin( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + make_n_step_time_iterator_end( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_n_step_time_range( Stepper() , empty_system() , x , 0.0 , 0.1 , 3 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[0].second , 0.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].second , 0.1 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].second , 0.2 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].second , 0.3 , 1.0e-13 ); + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 new file mode 100644 index 00000000..a4643f6a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/Jamfile.v2 @@ -0,0 +1,36 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# bring in rules for testing + + +import testing ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>../../include + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + +# <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run runge_kutta.cpp ] + [ run symplectic.cpp ] + [ run rosenbrock.cpp ] + [ run adams_bashforth.cpp ] + [ run adams_bashforth_moulton.cpp ] + [ run adaptive_adams_bashforth_moulton.cpp ] + [ run abm_time_dependent.cpp ] + [ run order_quadrature_formula.cpp ] + [ run velocity_verlet.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp b/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp new file mode 100644 index 00000000..019a17d6 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp @@ -0,0 +1,85 @@ +/* Boost numeric test of the adams-bashforth-moulton steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef value_type state_type; + + +// simple time-dependent rhs, analytic solution x = 0.5*t^2 +struct simple_rhs +{ + void operator()( const state_type& x , state_type &dxdt , const double t ) const + { + dxdt = t; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_abm_time_dependent_test ) + + +/* generic test for all adams bashforth moulton steppers */ +template< class Stepper > +struct perform_abm_time_dependent_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = 0.0; + state_type x1 = x0; + double t = 0.0; + double dt = 0.1; + const int steps = 10; + + integrate_n_steps( boost::ref(stepper) , simple_rhs(), x1 , t , dt , steps ); + BOOST_CHECK_LT( std::abs( 0.5 - x1 ) , std::pow( dt , o ) ); + } +}; + +typedef mpl::vector< + adams_bashforth_moulton< 2 , state_type > , + adams_bashforth_moulton< 3 , state_type > , + adams_bashforth_moulton< 4 , state_type > , + adams_bashforth_moulton< 5 , state_type > , + adams_bashforth_moulton< 6 , state_type > , + adams_bashforth_moulton< 7 , state_type > , + adams_bashforth_moulton< 8 , state_type > + > adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( abm_time_dependent_test , Stepper, adams_bashforth_moulton_steppers ) +{ + perform_abm_time_dependent_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp new file mode 100644 index 00000000..ca8a6cee --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth.cpp @@ -0,0 +1,117 @@ +/* Boost numeric test of the adams-bashforth steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adams_bashforth_test ) + + +/* generic test for all adams bashforth steppers */ +template< class Stepper > +struct perform_adams_bashforth_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.2; + // initialization, does a number of steps already to fill internal buffer, t is increased + stepper.initialize( osc() , x1 , t , dt ); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // do a number of steps to fill the buffer with results from adams bashforth + for( size_t n=0 ; n < stepper.steps ; ++n ) + { + stepper.do_step( osc() , x1 , t , dt ); + t += dt; + } + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " + << Stepper::initializing_stepper_type::order_value+1 << " , " + << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adams_bashforth< 2 , state_type > , + adams_bashforth< 3 , state_type > , + adams_bashforth< 4 , state_type > , + adams_bashforth< 5 , state_type > , + adams_bashforth< 6 , state_type > , + adams_bashforth< 7 , state_type > , + adams_bashforth< 8 , state_type > + > adams_bashforth_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_test , Stepper, adams_bashforth_steppers ) +{ + perform_adams_bashforth_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp new file mode 100644 index 00000000..dea57182 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adams_bashforth_moulton.cpp @@ -0,0 +1,119 @@ +/* Boost numeric test of the adams-bashforth-moulton steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; +typedef runge_kutta_fehlberg78<state_type> initializing_stepper; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adams_bashforth_moulton_test ) + + +/* generic test for all adams bashforth moulton steppers */ +template< class Stepper > +struct perform_adams_bashforth_moulton_test +{ + void operator()( void ) + { + Stepper stepper; + initializing_stepper init_stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.25; + // initialization, does a number of steps already to fill internal buffer, t is increased + // we use the rk78 as initializing stepper + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + // do a number of steps to fill the buffer with results from adams bashforth + for( size_t n=0 ; n < stepper.steps ; ++n ) + { + stepper.do_step( osc() , x1 , t , dt ); + t += dt; + } + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( boost::ref(init_stepper) , osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth-moulton step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adams_bashforth_moulton< 1 , state_type > , + adams_bashforth_moulton< 2 , state_type > , + adams_bashforth_moulton< 3 , state_type > , + adams_bashforth_moulton< 4 , state_type > , + adams_bashforth_moulton< 5 , state_type > , + adams_bashforth_moulton< 6 , state_type > , + adams_bashforth_moulton< 7 , state_type > , + adams_bashforth_moulton< 8 , state_type > + > adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_moulton_test , Stepper, adams_bashforth_moulton_steppers ) +{ + perform_adams_bashforth_moulton_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp b/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp new file mode 100644 index 00000000..0932dd1d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/adaptive_adams_bashforth_moulton.cpp @@ -0,0 +1,113 @@ +/* Boost numeric test of the adams-bashforth steppers test file + + Copyright 2013 Karsten Ahnert + Copyright 2013-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adaptive_adams_bashforth_moulton + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; +typedef runge_kutta_fehlberg78<state_type> initializing_stepper; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_adaptive_adams_bashforth_moulton_test ) + + +/* generic test for all adams bashforth steppers */ +template< class Stepper > +struct perform_adaptive_adams_bashforth_moulton_test +{ + void operator()( void ) + { + Stepper stepper; + initializing_stepper init_stepper; + + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 = x0; + double t = 0.0; + double dt = 0.25; + // initialization, does a number of steps to self-start the stepper with a small stepsize + stepper.initialize( init_stepper, osc() , x1 , t , dt); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + // only examine the error of the adams-bashforth step, not the initialization + const double f = 2.0 * std::abs( A*sin(t+dt+phi) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x1 = x0; + t = 0.0; + stepper.initialize( init_stepper, osc() , x1 , t , dt ); + A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + phi = std::asin(x1[0]/A) - t; + // now we do the actual step + stepper.do_step( osc() , x1 , t , dt ); + stepper.reset(); + // only examine the error of the adams-bashforth step, not the initialization + std::cout << "Testing dt=" << dt << " , " << std::abs( A*sin(t+dt+phi) - x1[0] ) << std::endl; + BOOST_CHECK_LT( std::abs( A*sin(t+dt+phi) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + +typedef mpl::vector< + adaptive_adams_bashforth_moulton< 2 , state_type > , + adaptive_adams_bashforth_moulton< 3 , state_type > , + adaptive_adams_bashforth_moulton< 4 , state_type > , + adaptive_adams_bashforth_moulton< 5 , state_type > , + adaptive_adams_bashforth_moulton< 6 , state_type > , + adaptive_adams_bashforth_moulton< 7 , state_type > + > adaptive_adams_bashforth_moulton_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adaptive_adams_bashforth_moulton_test , Stepper, adaptive_adams_bashforth_moulton_steppers ) +{ + perform_adaptive_adams_bashforth_moulton_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp b/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp new file mode 100644 index 00000000..cefab4da --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp @@ -0,0 +1,195 @@ +/* Boost numeric test for orders of quadrature formulas test file + + Copyright 2015 Gregor de Cillia + Copyright 2015 Mario Mulansky <mario.mulansky@gmx.net> + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> + +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE order_quadrature_formula + +#include <iostream> +#include <cmath> + +#include "boost/format.hpp" + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +#include <boost/numeric/ublas/vector.hpp> + +#include <boost/format.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; +typedef value_type time_type; +typedef value_type state_type; + +BOOST_AUTO_TEST_SUITE( order_of_convergence_test ) + +/* defines the simple monomial f(t) = (p+1) * t^p.*/ +struct monomial +{ + int power; + + monomial(int p = 0) : power( p ){}; + + void operator()( const state_type &x , state_type &dxdt , const time_type t ) + { + dxdt = ( 1.0 + power ) * pow( t, power ); + } +}; + + +/* generic test for all steppers that support integrate_const */ +template< class Stepper > +struct stepper_order_test +{ + void operator()( int steps = 1 ) + { + const int estimated_order = estimate_order( steps ); + const int defined_order = Stepper::order_value; + + std::cout << boost::format( "%-20i%-20i\n" ) + % estimated_order % defined_order; + + BOOST_REQUIRE_EQUAL( estimated_order, defined_order ); + } + + /* + the order of the stepper is estimated by trying to solve the ODE + x'(t) = (p+1) * t^p + until the errors are too big to be justified by finite precision. + the first value p for which the problem is *not* solved within the + finite precision tolerance is the estimate for the order of the scheme. + */ + int estimate_order( int steps ) + { + const double dt = 1.0/steps; + const double tolerance = steps*1E-15; + int p; + for( p = 0; true; p++ ) + { + // begin with x'(t) = t^0 = 1 + // => x (t) = t + // then use x'(t) = 2*t^1 + // => x (t) = t^2 + // ... + state_type x = 0.0; + + double t = integrate_n_steps( Stepper(), monomial( p ), x, 0.0, dt, + steps ); + if( fabs( x - pow( t, ( 1.0 + p ) ) ) > tolerance ) + break; + } + // the smallest power p for which the test failed is the estimated order, + // as the solution for this power is x(t) = t^{p+1} + return p; + } +}; + + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > + > runge_kutta_steppers; + +typedef mpl::vector< + adams_bashforth< 2, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 3, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 4, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 5, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 6, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 7, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > >, + adams_bashforth< 8, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, runge_kutta_fehlberg78< state_type > > + > ab_steppers; + + +typedef mpl::vector< + adams_bashforth_moulton< 2, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 3, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 4, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 5, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 6, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 7, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > >, + adams_bashforth_moulton< 8, state_type, double, state_type, double, + vector_space_algebra, default_operations, + initially_resizer, + runge_kutta_fehlberg78< state_type > > + > abm_steppers; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_test , Stepper, runge_kutta_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(10); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_test , Stepper, ab_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(16); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( adams_bashforth_moultion_test , Stepper, abm_steppers ) +{ + stepper_order_test< Stepper > tester; + tester(16); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp b/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp new file mode 100644 index 00000000..2b6a2678 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/rosenbrock.cpp @@ -0,0 +1,89 @@ +/* Boost numeric test of the rosenbrock4 stepper test file + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_rosenbrock + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 1 ); + dxdt( 1 ) = -x( 0 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 0; + jacobi( 0 , 1 ) = 1; + jacobi( 1 , 0 ) = -1; + jacobi( 1 , 1 ) = 0; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + + +BOOST_AUTO_TEST_SUITE( numeric_rosenbrock4 ) + +BOOST_AUTO_TEST_CASE( rosenbrock4_numeric_test ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + const int o = stepper.order()+1; + + state_type x0( 2 ) , x1( 2 ); + x0(0) = 0.0; x0(1) = 1.0; + + double dt = 0.5; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x0 , 0.0 , x1 , dt ); + const double f = 2.0 * std::abs( std::sin(dt) - x1(0) ) / std::pow( dt , o ); + + std::cout << o << " , " << f << std::endl; + + while( f*std::pow( dt , o ) > 1E-16 ) + { + stepper.do_step( std::make_pair( sys() , jacobi() ) , x0 , 0.0 , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_SMALL( std::abs( std::sin(dt) - x1(0) ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp b/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp new file mode 100644 index 00000000..a71701bd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/runge_kutta.cpp @@ -0,0 +1,177 @@ +/* Boost numeric test of the runge kutta steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_runge_kutta + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/stepper/extrapolation_stepper.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 2 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x , state_type &dxdt , const double t ) const + { + dxdt[0] = x[1]; + dxdt[1] = -x[0]; + } +}; + +/* reset dispatcher */ +template< class StepperCategory > +struct resetter +{ + template< class Stepper > + static void reset( Stepper &stepper ) { } +}; + +template< > +struct resetter< explicit_error_stepper_fsal_tag > +{ + template< class Stepper > + static void reset( Stepper &stepper ) + { stepper.reset(); } +}; + + +BOOST_AUTO_TEST_SUITE( numeric_runge_kutta_test ) + + +/* generic test for all runge kutta steppers */ +template< class Stepper > +struct perform_runge_kutta_test +{ + void operator()( void ) + { + + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , x0 , t , x1 , dt ); + const double f = 2.0 * std::abs( sin(dt) - x1[0] ) / std::pow( dt , o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + // reset stepper which require resetting (fsal steppers) + resetter< typename Stepper::stepper_category >::reset( stepper ); + + stepper.do_step( osc() , x0 , t , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_LT( std::abs( sin(dt) - x1[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +/* generic error test for all runge kutta steppers */ +template< class Stepper > +struct perform_runge_kutta_error_test +{ + void operator()( void ) + { + Stepper stepper; + const int o = stepper.error_order()+1; //order of the error is order of approximation + 1 + + const state_type x0 = {{ 0.0 , 1.0 }}; + state_type x1 , x_err; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , x0 , t , x1 , dt , x_err ); + const double f = 2.0 * std::abs( x_err[0] ) / std::pow( dt , o ); + + std::cout << o << " , " << f << " , " << x0[0] << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + // reset stepper which require resetting (fsal steppers) + resetter< typename Stepper::stepper_category >::reset( stepper ); + + stepper.do_step( osc() , x0 , t , x1 , dt , x_err ); + std::cout << "Testing dt=" << dt << ": " << x_err[1] << std::endl; + BOOST_CHECK_SMALL( std::abs( x_err[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + extrapolation_stepper< 4, state_type > , + extrapolation_stepper< 6, state_type > , + extrapolation_stepper< 8, state_type > , + extrapolation_stepper< 10, state_type > + > runge_kutta_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_test , Stepper, runge_kutta_steppers ) +{ + perform_runge_kutta_test< Stepper > tester; + tester(); +} + + +typedef mpl::vector< + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + extrapolation_stepper< 4, state_type > , + extrapolation_stepper< 6, state_type > , + extrapolation_stepper< 8, state_type > , + extrapolation_stepper< 10, state_type > + > runge_kutta_error_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_error_test , Stepper, runge_kutta_error_steppers ) +{ + perform_runge_kutta_error_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp b/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp new file mode 100644 index 00000000..6d3f75b1 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/symplectic.cpp @@ -0,0 +1,95 @@ +/* Boost numeric test of the symplectic steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_symplectic + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double ,1 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &q , state_type &dpdt ) const + { + dpdt[0] = -q[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( numeric_symplectic_test ) + + +/* generic test for all symplectic steppers */ +template< class Stepper > +struct perform_symplectic_test +{ + void operator()( void ) + { + + Stepper stepper; + const int o = stepper.order()+1; //order of the error is order of approximation + 1 + + const state_type q0 = {{ 0.0 }}; + const state_type p0 = {{ 1.0 }}; + state_type q1,p1; + std::pair< state_type , state_type >x1( q1 , p1 ); + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt ); + const double f = 2.0 * std::abs( sin(dt) - x1.first[0] ) / std::pow( dt , o ); + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + stepper.do_step( osc() , std::make_pair( q0 , p0 ) , t , x1 , dt ); + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_SMALL( std::abs( sin(dt) - x1.first[0] ) , f*std::pow( dt , o ) ); + dt *= 0.5; + } + } +}; + + +typedef mpl::vector< + symplectic_euler< state_type > , + symplectic_rkn_sb3a_mclachlan< state_type > + > symplectic_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( symplectic_test , Stepper, symplectic_steppers ) +{ + perform_symplectic_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp b/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp new file mode 100644 index 00000000..5ac77807 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/numeric/velocity_verlet.cpp @@ -0,0 +1,93 @@ +/* Boost numeric test of the runge kutta steppers test file + + Copyright 2012 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_runge_kutta + +#include <iostream> +#include <cmath> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double value_type; + +typedef boost::array< double , 1 > state_type; + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc +{ + void operator()( const state_type &x, const state_type &v, state_type &a, + const double t ) const + { + a[0] = -x[0]; + } +}; + +BOOST_AUTO_TEST_SUITE( velocity_verlet_test ) + +BOOST_AUTO_TEST_CASE( numeric_velocity_verlet_test ) +{ + + velocity_verlet<state_type> stepper; + const int steps = 10; + // order of the error is order of approximation + 1 + const int o = stepper.order() + 1; + + const state_type x0 = {{ 0.0 }}; + const state_type v0 = {{ 1.0 }}; + state_type x = x0; + state_type v = v0; + const double t = 0.0; + /* do a first step with dt=0.1 to get an estimate on the prefactor of the error dx = f * dt^(order+1) */ + double dt = 0.5; + for ( int step = 0; step < steps; ++step ) + { + stepper.do_step( + osc(), std::make_pair( boost::ref( x ), boost::ref( v ) ), t, dt ); + } + const double f = steps * std::abs( sin( steps * dt ) - x[0] ) / + std::pow( dt, o ); // upper bound + + std::cout << o << " , " << f << std::endl; + + /* as long as we have errors above machine precision */ + while( f*std::pow( dt , o ) > 1E-16 ) + { + x = x0; + v = v0; + stepper.reset(); + for ( int step = 0; step < steps; ++step ) + { + stepper.do_step( osc() , std::make_pair(boost::ref(x), boost::ref(v)) , t , dt ); + } + std::cout << "Testing dt=" << dt << std::endl; + BOOST_CHECK_LT( std::abs( sin( steps * dt ) - x[0] ), + f * std::pow( dt, o ) ); + dt *= 0.5; + } +}; + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp b/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp new file mode 100644 index 00000000..10c0c84e --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/prepare_stepper_testing.hpp @@ -0,0 +1,74 @@ +/* + [auto_generated] + libs/numeric/odeint/test/prepare_stepper_testing.hpp + + [begin_description] + This file defines some helper functions for the stepper tests. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef PREPARE_STEPPER_TESTING_HPP_ +#define PREPARE_STEPPER_TESTING_HPP_ + +#include <boost/array.hpp> +#include <vector> +#include <complex> + +#include <boost/fusion/sequence.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/algebra/array_algebra.hpp> +#include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp> + +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +using namespace boost::numeric::odeint; + +/* the state types that will be tested */ +typedef std::vector< double > vector_type; +typedef std::vector< std::complex<double> > complex_vector_type; +typedef double vector_space_type; +typedef boost::array< double , 1 > array_type; +typedef boost::array< std::complex<double> , 1 > complex_array_type; + +typedef boost::multiprecision::cpp_dec_float_50 mp_type; +typedef boost::array< mp_type , 1 > mp_array_type; + +typedef mpl::vector< vector_type , complex_vector_type , vector_space_type , + array_type , complex_array_type , mp_type , mp_array_type + >::type container_types; + +namespace boost { namespace numeric { namespace odeint { + + // mp_type forms a vector space + template<> + struct algebra_dispatcher< mp_type > + { + typedef vector_space_algebra algebra_type; + }; + + // add norm computation + template<> + struct vector_space_norm_inf< mp_type > + { + typedef mp_type result_type; + mp_type operator()( mp_type x ) const + { + using std::abs; + return abs(x); + } + }; + +} } } + +#endif /* PREPARE_STEPPER_TESTING_HPP_ */ diff --git a/src/boost/libs/numeric/odeint/test/range_algebra.cpp b/src/boost/libs/numeric/odeint/test/range_algebra.cpp new file mode 100644 index 00000000..d80e9519 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/range_algebra.cpp @@ -0,0 +1,143 @@ +/* + [auto_generated] + libs/numeric/odeint/test/check_operations.cpp + + [begin_description] + This file tests interaction between the algebras and the operations. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_standard_algebra + +#include <cmath> +#include <complex> +#include <utility> +#include <functional> +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/numeric/odeint/algebra/default_operations.hpp> +#include <boost/numeric/odeint/algebra/range_algebra.hpp> +#include <boost/numeric/odeint/algebra/array_algebra.hpp> + +#include <boost/mpl/list.hpp> + +namespace units = boost::units; +namespace si = boost::units::si; + +using boost::numeric::odeint::default_operations; +using boost::numeric::odeint::range_algebra; +using boost::numeric::odeint::array_algebra; + + +BOOST_AUTO_TEST_SUITE( standard_algebra_test ) + +typedef boost::mpl::list< range_algebra , array_algebra > algebra_types; +range_algebra algebra; + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each2 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }}; + algebra.for_each2( x1 , x2 , default_operations::scale_sum1<>( 1.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 2.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 2.0 , 1.0e-10 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each3 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }}; + algebra.for_each3( x1 , x2 , x3 , default_operations::scale_sum2<>( 1.0 , 2.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 8.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 8.0 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each4 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }}; + algebra.for_each4( x1 , x2 , x3 , x4 , default_operations::scale_sum3<>( 1.0 , 2.0 , 3.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 20.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 20.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each5 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }}; + algebra.for_each5( x1 , x2 , x3 , x4 , x5 , default_operations::scale_sum4<>( 1.0 , 2.0 , 3.0 , 4.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 40.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 40.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each6 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }}; + algebra.for_each6( x1 , x2 , x3 , x4 , x5 , x6 ,default_operations::scale_sum5<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 70.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 70.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each7 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }} , x7 = {{ 7.0 , 7.0 }}; + algebra.for_each7( x1 , x2 , x3 , x4 , x5 , x6 , x7 , default_operations::scale_sum6<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 112.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 112.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( for_each8 , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x1 = {{ 1.0 , 1.0 }} , x2 = {{ 2.0 , 2.0 }} , x3 = {{ 3.0 , 3.0 }} , x4 = {{ 4.0 , 4.0 }} , x5 = {{ 5.0 , 5.0 }} , x6 = {{ 6.0 , 6.0 }} , x7 = {{ 7.0 , 7.0 }} , x8 = {{ 8.0 , 8.0 }}; + algebra.for_each8( x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , default_operations::scale_sum7<>( 1.0 , 2.0 , 3.0 , 4.0 , 5.0 , 6.0 , 7.0 ) ); + BOOST_CHECK_CLOSE( x1[0] , 168.0 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1] , 168.0 , 1.0e-10 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( norm_inf , algebra_type , algebra_types ) +{ + algebra_type algebra; + boost::array< double , 2 > x = {{ 1.25 , 2.25 }}; + double nrm = algebra.norm_inf( x ); + BOOST_CHECK_CLOSE( nrm , 2.25 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x[0] , 1.25 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x[1] , 2.25 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_CASE( for_each2_with_units ) +{ + range_algebra algebra; + typedef units::quantity< si::time , double > time_type; + typedef units::quantity< si::length , double > length_type; + typedef units::quantity< si::velocity , double > velocity_type; + boost::array< length_type , 2 > x1 = {{ 1.0 * si::meter , 1.0 * si::meter }}; + boost::array< velocity_type , 2 > x2 = {{ 2.0 * si::meter / si::seconds , 2.0 * si::meter / si::seconds }}; + algebra.for_each2( x1 , x2 , default_operations::scale_sum1< time_type >( 0.1 * si::second ) ); + BOOST_CHECK_CLOSE( x1[0].value() , 0.2 , 1.0e-10 ); + BOOST_CHECK_CLOSE( x1[1].value() , 0.2 , 1.0e-10 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 b/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 new file mode 100644 index 00000000..bb085f46 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/Jamfile.v2 @@ -0,0 +1,31 @@ +# Copyright 2012 Karsten Ahnert +# Copyright 2012 Mario Mulansky +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# bring in rules for testing + + +import testing ; + +use-project boost : $(BOOST_ROOT) ; + +project + : requirements + <library>/boost/test//boost_unit_test_framework + <define>BOOST_ALL_NO_LIB=1 + <include>../../include + <link>static + <toolset>clang:<cxxflags>-Wno-unused-variable + +# <cxxflags>-D_SCL_SECURE_NO_WARNINGS + ; + +test-suite "odeint" + : + [ run regression_147.cpp ] + [ compile regression_149.cpp ] + [ run regression_168.cpp ] + [ run regression_189.cpp ] + : <testing.launcher>valgrind + ; diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp new file mode 100644 index 00000000..7373782d --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_147.cpp @@ -0,0 +1,88 @@ +/* + + [begin_description] + Test case for issue 147 + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef double state_type; + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ + dxdt = 1; +} + + +template<class Stepper, class InitStepper> +struct perform_init_test +{ + void operator()( void ) + { + double t = 0; + const double dt = 0.1; + + state_type x = 0; + + Stepper stepper; + InitStepper init_stepper; + stepper.initialize( init_stepper, rhs, x, t, dt ); + + // ab-stepper needs order-1 init steps: t and x should be (order-1)*dt + BOOST_CHECK_CLOSE( t , (stepper.order()-1)*dt , 1E-16 ); + BOOST_CHECK_CLOSE( x, ( stepper.order() - 1 ) * dt, 2E-14 ); + } +}; + +typedef mpl::vector< + euler< state_type > , + modified_midpoint< state_type > , + runge_kutta4< state_type > , + runge_kutta4_classic< state_type > , + runge_kutta_cash_karp54_classic< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > + > runge_kutta_steppers; + + +BOOST_AUTO_TEST_SUITE( regression_147_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( init_test , InitStepper, + runge_kutta_steppers ) +{ + perform_init_test< adams_bashforth<4, state_type>, InitStepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp new file mode 100644 index 00000000..2790d683 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_149.cpp @@ -0,0 +1,93 @@ +/* + + [begin_description] + Test case for issue 149: + Error C2582 with msvc-10 when using iterator-based integration + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/range/algorithm/find_if.hpp> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +typedef std::vector<double> state_type; + +void rhs( const state_type &x , state_type &dxdt , const double t ) +{ +} + + +template<class Stepper> +struct perform_test +{ + void operator()( void ) + { + bulirsch_stoer< state_type > stepper( 1e-9, 0.0, 0.0, 0.0 ); + state_type x( 3, 10.0 ); + + print( boost::find_if( + make_adaptive_time_range( stepper, rhs, x, 0.0, 1.0, 0.01 ), + pred ) ); + + } + + static bool pred( const std::pair< const state_type &, double > &x ) + { + return ( x.first[0] < 0.0 ); + } + + template<class Iterator> + void print( Iterator iter ) + { + std::cout << iter->second << "\t" << iter->first[0] << "\t" + << iter->first[1] << "\t" << iter->first[2] << "\n"; + } +}; + +typedef mpl::vector< + euler< state_type > , + runge_kutta4< state_type > , + runge_kutta_cash_karp54< state_type > , + runge_kutta_dopri5< state_type > , + runge_kutta_fehlberg78< state_type > , + bulirsch_stoer< state_type > + > steppers; + + +BOOST_AUTO_TEST_SUITE( regression_147_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( regression_147_test , Stepper, + steppers ) +{ + perform_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp new file mode 100644 index 00000000..8349261a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_168.cpp @@ -0,0 +1,90 @@ +/* + + [begin_description] + Test case for issue 149: + Error C2582 with msvc-10 when using iterator-based integration + [end_description] + + Copyright 2011-2015 Karsten Ahnert + Copyright 2011-2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +// disable checked iterator warning for msvc + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_regression_147 + +#include <utility> +#include <iostream> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/range/algorithm/find_if.hpp> + +#include <boost/numeric/odeint.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef units::quantity< si::time , double > time_type; +typedef units::quantity< si::length , double > length_type; +typedef units::quantity< si::velocity , double > velocity_type; +typedef units::quantity< si::acceleration , double > acceleration_type; +typedef units::quantity< si::frequency , double > frequency_type; + +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + + +struct oscillator +{ + frequency_type m_omega; + + oscillator( const frequency_type &omega = 1.0 * si::hertz ) : m_omega( omega ) { } + + void operator()( const state_type &x , deriv_type &dxdt , time_type t ) const + { + fusion::at_c< 0 >( dxdt ) = fusion::at_c< 1 >( x ); + fusion::at_c< 1 >( dxdt ) = - m_omega * m_omega * fusion::at_c< 0 >( x ); + } +}; + + +BOOST_AUTO_TEST_CASE( regression_168 ) +{ + typedef runge_kutta_dopri5< state_type , double , deriv_type , time_type > stepper_type; + + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + integrate_const( make_dense_output( 1.0e-6 , 1.0e-6 , stepper_type() ) , oscillator( 2.0 * si::hertz ) , + x , 0.0 * si::second , 100.0 * si::second , 0.1 * si::second); +}
\ No newline at end of file diff --git a/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp b/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp new file mode 100644 index 00000000..54530072 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/regression/regression_189.cpp @@ -0,0 +1,72 @@ +/* + + [begin_description] + Test case for issue 189: + Controlled Rosenbrock stepper fails to increase step size + [end_description] + + Copyright 2016 Karsten Ahnert + Copyright 2016 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_regression_189 + +#include <boost/numeric/odeint.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/operator.hpp> + +using namespace boost::numeric::odeint; +namespace phoenix = boost::phoenix; + +typedef boost::numeric::ublas::vector< double > vector_type; +typedef boost::numeric::ublas::matrix< double > matrix_type; + +struct stiff_system +{ + void operator()( const vector_type &x , vector_type &dxdt , double /* t */ ) + { + dxdt[ 0 ] = -101.0 * x[ 0 ] - 100.0 * x[ 1 ]; + dxdt[ 1 ] = x[ 0 ]; + } +}; + +struct stiff_system_jacobi +{ + void operator()( const vector_type & /* x */ , matrix_type &J , const double & /* t */ , vector_type &dfdt ) + { + J( 0 , 0 ) = -101.0; + J( 0 , 1 ) = -100.0; + J( 1 , 0 ) = 1.0; + J( 1 , 1 ) = 0.0; + dfdt[0] = 0.0; + dfdt[1] = 0.0; + } +}; + + +BOOST_AUTO_TEST_CASE( regression_189 ) +{ + vector_type x( 2 , 1.0 ); + + size_t num_of_steps = integrate_const( make_dense_output< rosenbrock4< double > >( 1.0e-6 , 1.0e-6 ) , + std::make_pair( stiff_system() , stiff_system_jacobi() ) , + x , 0.0 , 50.0 , 0.01 , + std::cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + // regression: number of steps should be 74 + size_t num_of_steps_expected = 74; + BOOST_CHECK_EQUAL( num_of_steps , num_of_steps_expected ); + + vector_type x2( 2 , 1.0 ); + + size_t num_of_steps2 = integrate_const( make_dense_output< runge_kutta_dopri5< vector_type > >( 1.0e-6 , 1.0e-6 ) , + stiff_system() , x2 , 0.0 , 50.0 , 0.01 , + std::cout << phoenix::arg_names::arg2 << " " << phoenix::arg_names::arg1[0] << "\n" ); + num_of_steps_expected = 1531; + BOOST_CHECK_EQUAL( num_of_steps2 , num_of_steps_expected ); +} diff --git a/src/boost/libs/numeric/odeint/test/resize.cpp b/src/boost/libs/numeric/odeint/test/resize.cpp new file mode 100644 index 00000000..db40f4bf --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resize.cpp @@ -0,0 +1,98 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resize.cpp + + [begin_description] + This file tests the resize function of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_resize + +#include <vector> +#include <cmath> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +BOOST_AUTO_TEST_CASE( test_vector ) +{ + std::vector< double > x1( 10 ); + std::vector< double > x2; + resize( x2 , x1 ); + BOOST_CHECK( x2.size() == 10 ); +} + + +BOOST_AUTO_TEST_CASE( test_fusion_vector_of_vector ) +{ + typedef boost::fusion::vector< std::vector< double > , std::vector< double > > state_type; + state_type x1; + boost::fusion::at_c< 0 >( x1 ).resize( 10 ); + boost::fusion::at_c< 1 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 0 >( x2 ).size() == 10 ); + BOOST_CHECK( boost::fusion::at_c< 1 >( x2 ).size() == 10 ); +} + + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed1 ) +{ + typedef boost::fusion::vector< std::vector< double > , double > state_type; + state_type x1; + boost::fusion::at_c< 0 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 0 >( x2 ).size() == 10 ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_vector_mixed2 ) +{ + typedef boost::fusion::vector< double , std::vector< double > , double > state_type; + state_type x1; + boost::fusion::at_c< 1 >( x1 ).resize( 10 ); + state_type x2; + resize( x2 , x1 ); + BOOST_CHECK( boost::fusion::at_c< 1 >( x2 ).size() == 10 ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_quantity_sequence ) +{ + namespace units = boost::units; + namespace si = boost::units::si; + + typedef double value_type; + typedef units::quantity< si::time , value_type > time_type; + typedef units::quantity< si::length , value_type > length_type; + typedef units::quantity< si::velocity , value_type > velocity_type; + typedef boost::fusion::vector< length_type , velocity_type > state_type; + + state_type x1 , x2; + resize( x2 , x1 ); +} diff --git a/src/boost/libs/numeric/odeint/test/resizing.cpp b/src/boost/libs/numeric/odeint/test/resizing.cpp new file mode 100644 index 00000000..75179519 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resizing.cpp @@ -0,0 +1,110 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resizing.cpp + + [begin_description] + This file tests the resizing mechanism of odeint. + [end_description] + + Copyright 2010-2012 Karsten Ahnert + Copyright 2010-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_resize + +#include <vector> +#include <cmath> + +#include <boost/array.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/integral_constant.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +#include <boost/numeric/odeint/util/resizer.hpp> +#include <boost/numeric/odeint/util/is_resizeable.hpp> + +#include "resizing_test_state_type.hpp" + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + + + + + + +void constant_system( const test_array_type &x , test_array_type &dxdt , double t ) { dxdt[0] = 1.0; } + + +BOOST_AUTO_TEST_SUITE( check_resize_test ) + + +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > euler_manual_type; +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > euler_initially_type; +typedef euler< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > euler_always_type; + +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > rk4_manual_type; +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > rk4_initially_type; +typedef runge_kutta4_classic< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > rk4_always_type; + + +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , never_resizer > rk4_gen_manual_type; +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , initially_resizer > rk4_gen_initially_type; +typedef runge_kutta4< test_array_type , double , test_array_type , double , range_algebra , default_operations , always_resizer > rk4_gen_always_type; + + +typedef mpl::vector< + mpl::vector< euler_manual_type , mpl::int_<1> , mpl::int_<0> > , + mpl::vector< euler_initially_type , mpl::int_<1> , mpl::int_<1> > , + mpl::vector< euler_always_type , mpl::int_<1> , mpl::int_<3> > , + mpl::vector< rk4_manual_type , mpl::int_<5> , mpl::int_<0> > , + mpl::vector< rk4_initially_type , mpl::int_<5> , mpl::int_<1> > , + mpl::vector< rk4_always_type , mpl::int_<5> , mpl::int_<3> > , + mpl::vector< rk4_gen_manual_type , mpl::int_<5> , mpl::int_<0> > , + mpl::vector< rk4_gen_initially_type , mpl::int_<5> , mpl::int_<1> > , + mpl::vector< rk4_gen_always_type , mpl::int_<5> , mpl::int_<3> > + >::type resize_check_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_resize , T, resize_check_types ) +{ + typedef typename mpl::at< T , mpl::int_< 0 > >::type stepper_type; + const size_t resize_calls = mpl::at< T , mpl::int_< 1 > >::type::value; + const size_t multiplicity = mpl::at< T , mpl::int_< 2 > >::type::value; + adjust_size_count = 0; + + stepper_type stepper; + test_array_type x; + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + stepper.do_step( constant_system , x , 0.0 , 0.1 ); + + BOOST_TEST_MESSAGE( "adjust_size_count : " << adjust_size_count ); + BOOST_CHECK_MESSAGE( adjust_size_count == resize_calls * multiplicity , "adjust_size_count : " << adjust_size_count << " expected: " << resize_calls * multiplicity ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp b/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp new file mode 100644 index 00000000..af55937a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/resizing_test_state_type.hpp @@ -0,0 +1,69 @@ +/* + [auto_generated] + libs/numeric/odeint/test/resizing_test_state_type.hpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + + +#ifndef LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED +#define LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED + +#include <boost/numeric/odeint/util/is_resizeable.hpp> +#include <boost/numeric/odeint/util/resize.hpp> +#include <boost/numeric/odeint/util/same_size.hpp> + +#include <boost/array.hpp> + + + +// Mario: velocity verlet tests need arrays of size 2 +// some ugly detailed dependency, maybe this can be improved? +class test_array_type : public boost::array< double , 2 > { }; + +size_t adjust_size_count; + +namespace boost { +namespace numeric { +namespace odeint { + + template<> + struct is_resizeable< test_array_type > + { + typedef boost::true_type type; + const static bool value = type::value; + }; + + template<> + struct same_size_impl< test_array_type , test_array_type > + { + static bool same_size( const test_array_type &x1 , const test_array_type &x2 ) + { + return false; + } + }; + + template<> + struct resize_impl< test_array_type , test_array_type > + { + static void resize( test_array_type &x1 , const test_array_type &x2 ) + { + adjust_size_count++; + } + }; + +} // namespace odeint +} // namespace numeric +} // namespace boost + + +#endif // LIBS_NUMERIC_ODEINT_TEST_RESIZING_TEST_STATE_TYPE_HPP_DEFINED diff --git a/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp b/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp new file mode 100644 index 00000000..0b7bea4b --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/rosenbrock4.cpp @@ -0,0 +1,173 @@ +/* + [auto_generated] + libs/numeric/odeint/test/rosenbrock4.cpp + + [begin_description] + This file tests the Rosenbrock 4 stepper and its controller and dense output stepper. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_rosenbrock4 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +BOOST_AUTO_TEST_SUITE( rosenbrock4_test ) + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_stepper ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ) , xerr( 2 ); + x(0) = 0.0; x(1) = 1.0; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 , xerr ); + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , 0.0 , 0.1 ); + +// using std::abs; +// value_type eps = 1E-12; +// +// // compare with analytic solution of above system +// BOOST_CHECK_SMALL( abs( x(0) - 20.0/81.0 ) , eps ); +// BOOST_CHECK_SMALL( abs( x(1) - 10.0/9.0 ) , eps ); + +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_controller ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + + value_type t = 0.0 , dt = 0.01; + stepper.try_step( std::make_pair( sys() , jacobi() ) , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output ) +{ + typedef rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > stepper_type; + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); +} + +class rosenbrock4_controller_max_dt_adaptable : public rosenbrock4_controller< rosenbrock4< value_type > > +{ + public: + void set_max_dt(value_type max_dt) + { + m_max_dt = max_dt; + } +}; + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output_ref ) +{ + typedef rosenbrock4_dense_output< boost::reference_wrapper< rosenbrock4_controller_max_dt_adaptable > > stepper_type; + rosenbrock4_controller_max_dt_adaptable c_stepper; + stepper_type stepper( boost::ref( c_stepper ) ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); + + // adapt the maximal step size to a small value (smaller than the step size) and make a step + const double max_dt = 1e-8; + c_stepper.set_max_dt(max_dt); + stepper.do_step( std::make_pair( sys() , jacobi() ) ); + // check if the step was done with the requested maximal step size + BOOST_CHECK_CLOSE(max_dt, stepper.current_time_step(), 1e-14); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_copy_dense_output ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + typedef rosenbrock4_dense_output< controlled_stepper_type > stepper_type; + + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + stepper_type stepper2( stepper ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp b/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp new file mode 100644 index 00000000..dc295c47 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/rosenbrock4_mp.cpp @@ -0,0 +1,143 @@ +/* + [auto_generated] + libs/numeric/odeint/test/rosenbrock4.cpp + + [begin_description] + This file tests the Rosenbrock 4 stepper and its controller and dense output stepper. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_rosenbrock4 + +#include <utility> +#include <iostream> + +#include <boost/test/unit_test.hpp> +#include <boost/multiprecision/cpp_dec_float.hpp> + +#include <boost/numeric/odeint/stepper/rosenbrock4.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_controller.hpp> +#include <boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp> + +#include <boost/numeric/ublas/vector.hpp> +#include <boost/numeric/ublas/matrix.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef boost::multiprecision::cpp_dec_float_50 value_type; +typedef boost::numeric::ublas::vector< value_type > state_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +struct sys +{ + void operator()( const state_type &x , state_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 0 ) + 2 * x( 1 ); + dxdt( 1 ) = x( 1 ); + } +}; + +struct jacobi +{ + void operator()( const state_type &x , matrix_type &jacobi , const value_type &t , state_type &dfdt ) const + { + jacobi( 0 , 0 ) = 1; + jacobi( 0 , 1 ) = 2; + jacobi( 1 , 0 ) = 0; + jacobi( 1 , 1 ) = 1; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + +BOOST_AUTO_TEST_SUITE( rosenbrock4_test ) + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_stepper ) +{ + typedef rosenbrock4< value_type > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ) , xerr( 2 ); + x(0) = 0.0; x(1) = 1.0; + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , + static_cast<value_type>(0.0) , static_cast<value_type>(0.1) , xerr ); + + stepper.do_step( std::make_pair( sys() , jacobi() ) , x , + static_cast<value_type>(0.0) , static_cast<value_type>(0.1) ); + +// using std::abs; +// value_type eps = 1E-12; +// +// // compare with analytic solution of above system +// BOOST_CHECK_SMALL( abs( x(0) - 20.0/81.0 ) , eps ); +// BOOST_CHECK_SMALL( abs( x(1) - 10.0/9.0 ) , eps ); + +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_controller ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > stepper_type; + stepper_type stepper; + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + + value_type t = 0.0 , dt = 0.01; + stepper.try_step( std::make_pair( sys() , jacobi() ) , x , t , dt ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output ) +{ + typedef rosenbrock4_dense_output< rosenbrock4_controller< rosenbrock4< value_type > > > stepper_type; + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + + typedef stepper_type::state_type state_type; + typedef stepper_type::value_type stepper_value_type; + typedef stepper_type::deriv_type deriv_type; + typedef stepper_type::time_type time_type; + state_type x( 2 ); + x( 0 ) = 0.0 ; x(1) = 1.0; + stepper.initialize( x , 0.0 , 0.1 ); + std::pair< value_type , value_type > tr = stepper.do_step( std::make_pair( sys() , jacobi() ) ); + stepper.calc_state( 0.5 * ( tr.first + tr.second ) , x ); +} + +BOOST_AUTO_TEST_CASE( test_rosenbrock4_copy_dense_output ) +{ + typedef rosenbrock4_controller< rosenbrock4< value_type > > controlled_stepper_type; + typedef rosenbrock4_dense_output< controlled_stepper_type > stepper_type; + + controlled_stepper_type c_stepper; + stepper_type stepper( c_stepper ); + stepper_type stepper2( stepper ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp new file mode 100644 index 00000000..42235dea --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_concepts.cpp @@ -0,0 +1,217 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Runge-Kutta steppers. It's one of the main tests + of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/modified_midpoint.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> + +#include <boost/numeric/odeint/algebra/detail/extract_value_type.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.2; + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::time_type time_type; + + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) ); +} + +// default case is used for vector space types like plain double +template< class Stepper , typename T > +struct perform_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + Stepper stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_vector_space< vector_space_type , vector_space_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class Stepper , typename T > +struct perform_stepper_test< Stepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , static_cast<T>(2.0) ); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_standard< vector_type , vector_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x[0] << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +template< class Stepper , typename T > +struct perform_stepper_test< Stepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x; + x[0] = static_cast<T>(2.0); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_stepper_concept( stepper , constant_system_standard< array_type , array_type , typename Stepper::time_type > , x ); +#else + check_stepper_concept( stepper , boost::cref( sys ) , x ); +#endif + check_stepper_concept( stepper , boost::cref( sys ) , x ); + std::cout << x[0] << " ?= " << result << std::endl; + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +// split stepper methods to ensure the final vector has less than 30(?) elements +// (stepper_methods*container_types) < 30(?) +template< class State > class stepper_methods1 : public mpl::vector< + euler< State , typename detail::extract_value_type<State>::type > , + modified_midpoint< State , typename detail::extract_value_type<State>::type > , + runge_kutta4< State , typename detail::extract_value_type<State>::type > , + runge_kutta4_classic< State , typename detail::extract_value_type<State>::type > + > { }; + +template< class State > class stepper_methods2 : public mpl::vector< + runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > , + runge_kutta_cash_karp54< State , typename detail::extract_value_type<State>::type > , + runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > , + runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > + > { }; + + + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + stepper_methods1< mpl::_2 > + > + > +>::type stepper_combinations1; + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + stepper_methods2< mpl::_2 > + > + > +>::type stepper_combinations2; + + +BOOST_AUTO_TEST_SUITE( runge_kutta_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test1 , Stepper, stepper_combinations1 ) +{ + perform_stepper_test< Stepper , typename Stepper::deriv_type > tester; + tester(); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test2 , Stepper, stepper_combinations2 ) +{ + perform_stepper_test< Stepper , typename Stepper::deriv_type > tester; + tester(); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp new file mode 100644 index 00000000..7f70cc53 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp @@ -0,0 +1,212 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_controlled_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Controlled Runge-Kutta steppers. + It's one of the main tests of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_controlled_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.2; // two steps + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_controlled_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + //typedef typename stepper_type::order_type order_type; controlled_error_stepper don't necessarily have a order (burlish-stoer) + typedef typename stepper_type::time_type time_type; + + time_type t = 0.0 , dt = 0.1; + controlled_step_result step_result = stepper.try_step( system , x , t , dt ); + + BOOST_CHECK_MESSAGE( step_result == success , "step result: " << step_result ); // error = 0 for constant system -> step size is always too small +} + + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename ControlledStepper::time_type > + , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test< ControlledStepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , 2.0 ); + ControlledStepper controlled_stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + + check_controlled_stepper_concept( controlled_stepper , + constant_system_standard< vector_type , vector_type , typename ControlledStepper::time_type > , + x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class ControlledStepper > +struct perform_controlled_stepper_test< ControlledStepper , vector_space_type > +{ + void operator()( void ) const + { + using std::abs; + vector_space_type x; + x = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename ControlledStepper::time_type > + , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x - result )) < eps ); + } +}; + +template< class ControlledStepper , typename T > +struct perform_controlled_stepper_test< ControlledStepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x; + x[0] = 2.0; + ControlledStepper controlled_stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_controlled_stepper_concept( controlled_stepper , constant_system_standard< array_type , array_type , typename ControlledStepper::time_type > , x ); +#else + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); +#endif + check_controlled_stepper_concept( controlled_stepper , boost::cref( sys ) , x ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class State > class controlled_stepper_methods : public mpl::vector< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > > , + controlled_runge_kutta< runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > > , + controlled_runge_kutta< runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > > , + bulirsch_stoer< State , typename detail::extract_value_type<State>::type > + > { }; + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + controlled_stepper_methods< mpl::_2 > + > + > + >::type all_controlled_stepper_methods; + + + + +BOOST_AUTO_TEST_SUITE( controlled_runge_kutta_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , ControlledStepper , all_controlled_stepper_methods ) +{ + perform_controlled_stepper_test< ControlledStepper , typename ControlledStepper::state_type > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp b/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp new file mode 100644 index 00000000..06980772 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/runge_kutta_error_concepts.cpp @@ -0,0 +1,182 @@ +/* + [auto_generated] + libs/numeric/odeint/test/runge_kutta_error_concepts.cpp + + [begin_description] + This file tests the Stepper concepts of odeint with all Runge-Kutta Error steppers. + It's one of the main tests of odeint. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_runge_kutta_error_concepts + +#include <vector> +#include <cmath> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/array.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/ref.hpp> +#include <boost/bind.hpp> +#include <boost/utility.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/for_each.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> + +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> + +#include "prepare_stepper_testing.hpp" +#include "dummy_odes.hpp" + +using std::vector; + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; + +const double result = 2.4; // four steps total... + +const double eps = 1.0e-14; + +template< class Stepper , class System > +void check_error_stepper_concept( Stepper &stepper , System system , typename Stepper::state_type &x , typename Stepper::state_type &xerr ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::deriv_type container_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::time_type time_type; + + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) ); + stepper.do_step( system , x , static_cast<time_type>(0.0) , static_cast<time_type>(0.1) , xerr ); +} + +// default case is used for vector space types like plain double +template< class Stepper , typename T > +struct perform_error_stepper_test +{ + typedef T vector_space_type; + void operator()( void ) const + { + using std::abs; + vector_space_type x , xerr; + x = 2.0; + Stepper stepper; + constant_system_functor_vector_space sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , + constant_system_vector_space< vector_space_type , vector_space_type , typename Stepper::time_type > , + x , + xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + + BOOST_CHECK_MESSAGE( (abs( x - result )) < eps , x ); + } +}; + +template< class Stepper , typename T > +struct perform_error_stepper_test< Stepper , std::vector<T> > +{ + typedef std::vector<T> vector_type; + void operator()( void ) + { + using std::abs; + vector_type x( 1 , 2.0 ) , xerr( 1 ); + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , constant_system_standard< vector_type , vector_type , typename Stepper::time_type > , x , xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + + +template< class Stepper , typename T > +struct perform_error_stepper_test< Stepper , boost::array<T,1> > +{ + typedef boost::array<T,1> array_type; + void operator()( void ) + { + using std::abs; + array_type x , xerr; + x[0] = 2.0; + Stepper stepper; + constant_system_functor_standard sys; +#ifndef _MSC_VER + // dont run this for MSVC due to compiler bug 697006 + check_error_stepper_concept( stepper , constant_system_standard< array_type , array_type , typename Stepper::time_type > , x , xerr ); +#else + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); +#endif + check_error_stepper_concept( stepper , boost::cref( sys ) , x , xerr ); + BOOST_CHECK( (abs( x[0] - result )) < eps ); + } +}; + +template< class State > class error_stepper_methods : public mpl::vector< + runge_kutta_cash_karp54_classic< State , typename detail::extract_value_type<State>::type > , + runge_kutta_cash_karp54< State , typename detail::extract_value_type<State>::type > , + runge_kutta_dopri5< State , typename detail::extract_value_type<State>::type > , + runge_kutta_fehlberg78< State , typename detail::extract_value_type<State>::type > + > { }; + + +typedef mpl::copy +< + container_types , + mpl::inserter + < + mpl::vector0<> , + mpl::insert_range + < + mpl::_1 , + mpl::end< mpl::_1 > , + error_stepper_methods< mpl::_2 > + > + > + >::type all_error_stepper_methods; + + +BOOST_AUTO_TEST_SUITE( runge_kutta_error_concept_test ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( error_stepper_test , Stepper , all_error_stepper_methods ) +{ + perform_error_stepper_test< Stepper , typename Stepper::state_type > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/same_size.cpp b/src/boost/libs/numeric/odeint/test/same_size.cpp new file mode 100644 index 00000000..09a04c19 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/same_size.cpp @@ -0,0 +1,65 @@ +/* + [auto_generated] + libs/numeric/odeint/test/same_size.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_dummy + +#include <boost/test/unit_test.hpp> + +#include <boost/numeric/odeint/util/same_size.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + + +BOOST_AUTO_TEST_SUITE( same_size_test ) + +BOOST_AUTO_TEST_CASE( test_vector_true ) +{ + std::vector< double > v1( 10 ) , v2( 10 ); + BOOST_CHECK_EQUAL( true , same_size( v1 , v2 ) ); +} + + +BOOST_AUTO_TEST_CASE( test_vector_false ) +{ + std::vector< double > v1( 10 ) , v2( 20 ); + BOOST_CHECK_EQUAL( false , same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_true ) +{ + boost::fusion::vector< double , std::vector< double > > v1 , v2; + boost::fusion::at_c< 1 >( v1 ).resize( 10 ); + boost::fusion::at_c< 1 >( v2 ).resize( 10 ); + BOOST_CHECK_EQUAL( true , same_size( v1 , v2 ) ); +} + +BOOST_AUTO_TEST_CASE( test_fusion_false ) +{ + boost::fusion::vector< double , std::vector< double > > v1 , v2; + boost::fusion::at_c< 1 >( v1 ).resize( 10 ); + boost::fusion::at_c< 1 >( v2 ).resize( 20 ); + BOOST_CHECK_EQUAL( false , same_size( v1 , v2 ) ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/split.cpp b/src/boost/libs/numeric/odeint/test/split.cpp new file mode 100644 index 00000000..b8f056be --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/split.cpp @@ -0,0 +1,68 @@ +/* + [auto_generated] + libs/numeric/odeint/test/split.cpp + + [begin_description] + Test the range split. + [end_description] + + Copyright 2013 Karsten Ahnert + Copyright 2013 Mario Mulansky + Copyright 2013 Pascal Germroth + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_split + +#include <iostream> + +#include <boost/test/unit_test.hpp> +#include <boost/numeric/odeint/util/split_adaptor.hpp> +#include <boost/range/irange.hpp> + +template<class T> +inline void dump_range(const T &r) { + std::cout << '['; + std::copy(boost::begin(r), boost::end(r), std::ostream_iterator< + typename std::iterator_traits< + typename boost::range_iterator<const T>::type + >::value_type >(std::cout, " ") ); + std::cout << ']'; +} + +template<class A, class B> +inline void check_equal_range(const A a, const B b) { + BOOST_CHECK_EQUAL_COLLECTIONS( boost::begin(a), boost::end(a), boost::begin(b), boost::end(b) ); +} + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint::detail; +using namespace boost; + +BOOST_AUTO_TEST_CASE( test_eleven ) +{ + // 0 1 2 3 | 4 5 6 7 | 8 9 10 11 + check_equal_range( irange(0, 12) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 12) | split(1, 3), irange(4, 8) ); + check_equal_range( irange(0, 12) | split(2, 3), irange(8, 12) ); +} + +BOOST_AUTO_TEST_CASE( test_ten ) +{ + // 0 1 2 3 | 4 5 6 7 | 8 9 10 + check_equal_range( irange(0, 11) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 11) | split(1, 3), irange(4, 8) ); + check_equal_range( irange(0, 11) | split(2, 3), irange(8, 11) ); +} + +BOOST_AUTO_TEST_CASE( test_nine ) +{ + // 0 1 2 3 | 4 5 6 | 7 8 9 + check_equal_range( irange(0, 10) | split(0, 3), irange(0, 4) ); + check_equal_range( irange(0, 10) | split(1, 3), irange(4, 7) ); + check_equal_range( irange(0, 10) | split(2, 3), irange(7, 10) ); +} diff --git a/src/boost/libs/numeric/odeint/test/std_array.cpp b/src/boost/libs/numeric/odeint/test/std_array.cpp new file mode 100644 index 00000000..350a387a --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/std_array.cpp @@ -0,0 +1,57 @@ +/* + [auto_generated] + test/std_array.cpp + + [begin_description] + Checks if odeint compiles fine with the std::array using the array algebra + [end_description] + + Copyright 2009-2014 Karsten Ahnert + Copyright 2009-2014 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_std_array + +#include <array> +#include <boost/numeric/odeint.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +typedef std::array<double, 3> state_type; + +void rhs(const state_type &x, state_type &dxdt, const double t) +{ +} + +BOOST_AUTO_TEST_SUITE( unwrap_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + state_type x = {0.0, 0.0, 0.0}; + + typedef boost::numeric::odeint::runge_kutta4<state_type> stepper_type; +// check if array algebra is selected, but only if odeint detects c++11 +#ifdef BOOST_NUMERIC_ODEINT_CXX11 + BOOST_STATIC_ASSERT(( boost::is_same< stepper_type::algebra_type , + boost::numeric::odeint::array_algebra >::value )); +#endif + stepper_type stepper1; + stepper1.do_step(rhs, x, 0.0, 0.1); + + boost::numeric::odeint::runge_kutta4< + state_type, double, state_type, double, + boost::numeric::odeint::array_algebra > stepper; + stepper.do_step(rhs, x, 0.0, 0.1); + +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp b/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp new file mode 100644 index 00000000..2d8e4725 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/step_size_limitation.cpp @@ -0,0 +1,268 @@ +/* + [auto_generated] + libs/numeric/odeint/test/step_size_limitation.cpp + + [begin_description] + Tests the step size limitation functionality + [end_description] + + Copyright 2015 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_integrate_times + +#include <boost/test/unit_test.hpp> + +#include <utility> +#include <iostream> +#include <vector> + +#include <boost/numeric/odeint.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +typedef double value_type; +typedef std::vector< value_type > state_type; + +/*********************************************** + * first part of the tests: explicit methods + *********************************************** + */ + +void damped_osc( const state_type &x , state_type &dxdt , const value_type t ) +{ + const value_type gam( 0.1); + + dxdt[0] = x[1]; + dxdt[1] = -x[0] - gam*x[1]; +} + + +struct push_back_time +{ + std::vector< double >& m_times; + + push_back_time( std::vector< double > × ) + : m_times( times ) { } + + template<typename State> + void operator()( const State &x , double t ) + { + m_times.push_back( t ); + } +}; + +BOOST_AUTO_TEST_SUITE( step_size_limitation_test ) + +BOOST_AUTO_TEST_CASE( test_step_adjuster ) +{ + // first use adjuster without step size limitation + default_step_adjuster<double, double> step_adjuster; + const double dt = 0.1; + double dt_new = step_adjuster.decrease_step(dt, 1.5, 2); + BOOST_CHECK(dt_new < dt*2.0/3.0); + + dt_new = step_adjuster.increase_step(dt, 0.8, 1); + // for errors > 0.5 no increase is performed + BOOST_CHECK(dt_new == dt); + + dt_new = step_adjuster.increase_step(dt, 0.4, 1); + // smaller errors should lead to step size increase + std::cout << dt_new << std::endl; + BOOST_CHECK(dt_new > dt); + + + // now test with step size limitation max_dt = 0.1 + default_step_adjuster<double, double> + limited_adjuster(dt); + + dt_new = limited_adjuster.decrease_step(dt, 1.5, 2); + // decreasing works as before + BOOST_CHECK(dt_new < dt*2.0/3.0); + + dt_new = limited_adjuster.decrease_step(2*dt, 1.1, 2); + // decreasing a large step size should give max_dt + BOOST_CHECK(dt_new == dt); + + dt_new = limited_adjuster.increase_step(dt, 0.8, 1); + // for errors > 0.5 no increase is performed, still valid + BOOST_CHECK(dt_new == dt); + + dt_new = limited_adjuster.increase_step(dt, 0.4, 1); + // but even for smaller errors, we should at most get 0.1 + BOOST_CHECK_EQUAL(dt_new, dt); + + dt_new = limited_adjuster.increase_step(0.9*dt, 0.1, 1); + std::cout << dt_new << std::endl; + // check that we don't increase beyond max_dt + BOOST_CHECK(dt_new == dt); +} + + +template<class Stepper> +void test_explicit_stepper(Stepper stepper, const double max_dt) +{ + state_type x( 2 ); + x[0] = x[1] = 10.0; + const size_t steps = 100; + + std::vector<double> times; + + integrate_adaptive(stepper, damped_osc, x, 0.0, steps*max_dt, max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); + + // this should also work when we provide some bigger initial dt + integrate_adaptive(stepper, damped_osc, x, 0.0, steps*max_dt, 10*max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); +} + + +BOOST_AUTO_TEST_CASE( test_controlled ) +{ + const double max_dt = 0.01; + + test_explicit_stepper(make_controlled(1E-2, 1E-2, max_dt, + runge_kutta_dopri5<state_type>()), + max_dt); + test_explicit_stepper(make_controlled(1E-2, 1E-2, -max_dt, + runge_kutta_dopri5<state_type>()), + -max_dt); + + test_explicit_stepper(make_controlled(1E-2, 1E-2, max_dt, + runge_kutta_cash_karp54<state_type>()), + max_dt); + test_explicit_stepper(make_controlled(1E-2, 1E-2, -max_dt, + runge_kutta_cash_karp54<state_type>()), + -max_dt); + + test_explicit_stepper(bulirsch_stoer<state_type>(1E-2, 1E-2, 1.0, 1.0, max_dt), + max_dt); + test_explicit_stepper(bulirsch_stoer<state_type>(1E-2, 1E-2, 1.0, 1.0, -max_dt), + -max_dt); +} + + +BOOST_AUTO_TEST_CASE( test_dense_out ) +{ + const double max_dt = 0.01; + test_explicit_stepper(make_dense_output(1E-2, 1E-2, max_dt, + runge_kutta_dopri5<state_type>()), + max_dt); + test_explicit_stepper(make_dense_output(1E-2, 1E-2, -max_dt, + runge_kutta_dopri5<state_type>()), + -max_dt); + + test_explicit_stepper(bulirsch_stoer_dense_out<state_type>(1E-2, 1E-2, 1, 1, max_dt), + max_dt); + + test_explicit_stepper(bulirsch_stoer_dense_out<state_type>(1E-2, 1E-2, 1, 1, -max_dt), + -max_dt); +} + + +/*********************************************** + * second part of the tests: implicit Rosenbrock + *********************************************** + */ + +typedef boost::numeric::ublas::vector< value_type > vector_type; +typedef boost::numeric::ublas::matrix< value_type > matrix_type; + + +// harmonic oscillator, analytic solution x[0] = sin( t ) +struct osc_rhs +{ + void operator()( const vector_type &x , vector_type &dxdt , const value_type &t ) const + { + dxdt( 0 ) = x( 1 ); + dxdt( 1 ) = -x( 0 ); + } +}; + +struct osc_jacobi +{ + void operator()( const vector_type &x , matrix_type &jacobi , const value_type &t , vector_type &dfdt ) const + { + jacobi( 0 , 0 ) = 0; + jacobi( 0 , 1 ) = 1; + jacobi( 1 , 0 ) = -1; + jacobi( 1 , 1 ) = 0; + dfdt( 0 ) = 0.0; + dfdt( 1 ) = 0.0; + } +}; + + +template<class Stepper> +void test_rosenbrock_stepper(Stepper stepper, const double max_dt) +{ + vector_type x( 2 ); + x(0) = x(1) = 10.0; + const size_t steps = 100; + + std::vector<double> times; + + integrate_adaptive(stepper, + std::make_pair(osc_rhs(), osc_jacobi()), + x, 0.0, steps*max_dt, max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); + + // this should also work when we provide some bigger initial dt + integrate_adaptive(stepper, + std::make_pair(osc_rhs(), osc_jacobi()), + x, 0.0, steps*max_dt, 10*max_dt, push_back_time(times)); + + BOOST_CHECK_EQUAL(times.size(), steps+1); + // check that dt remains at exactly max_dt + for( size_t i=0 ; i<times.size() ; ++i ) + // check if observer was called at times 0,1,2,... + BOOST_CHECK_SMALL( times[i] - static_cast<double>(i)*max_dt , 1E-15); + times.clear(); +} + + +BOOST_AUTO_TEST_CASE( test_controlled_rosenbrock ) +{ + const double max_dt = 0.01; + + test_rosenbrock_stepper(make_controlled(1E-2, 1E-2, max_dt, rosenbrock4<value_type>()), + max_dt); + test_rosenbrock_stepper(make_controlled(1E-2, 1E-2, -max_dt, rosenbrock4<value_type>()), + -max_dt); +} + + +BOOST_AUTO_TEST_CASE( test_dense_out_rosenbrock ) +{ + const double max_dt = 0.01; + + test_rosenbrock_stepper(make_dense_output(1E-2, 1E-2, max_dt, rosenbrock4<value_type>()), + max_dt); + test_rosenbrock_stepper(make_dense_output(1E-2, 1E-2, -max_dt, rosenbrock4<value_type>()), + -max_dt); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/stepper_copying.cpp b/src/boost/libs/numeric/odeint/test/stepper_copying.cpp new file mode 100644 index 00000000..c29e4de1 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_copying.cpp @@ -0,0 +1,856 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_copying.cpp + + [begin_description] + This file tests the copying of the steppers. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) +*/ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC +#pragma warning(disable:4996) +#endif + + +#define BOOST_TEST_MODULE odeint_stepper_copying + +#include <boost/test/unit_test.hpp> +#include <boost/type_traits/integral_constant.hpp> + +//#include <boost/numeric/odeint/util/construct.hpp> +//#include <boost/numeric/odeint/util/destruct.hpp> +#include <boost/numeric/odeint/util/copy.hpp> + +#include <boost/numeric/odeint/util/state_wrapper.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +template< class T , size_t Dim > +class test_array +{ +public: + + const static size_t dim = Dim; + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + + value_type& operator[]( size_t i ) + { + return m_data[i]; + } + + const value_type& operator[]( size_t i ) const + { + return m_data[i]; + } + + iterator begin( void ) + { + return m_data; + } + + iterator end( void ) + { + return m_data + dim; + } + + const_iterator begin( void ) const + { + return m_data; + } + + const_iterator end( void ) const + { + return m_data + dim; + } + + +private: + + value_type m_data[dim]; +}; + +template< class T , size_t Dim > +class test_array2 : public test_array< T , Dim > +{ +}; + + + +/* + * Explicit testing if copying was successful is difficult, + * hence we only test if the number of copy operations is right. + * + * Otherwise one has to prepare the states. + */ + +size_t construct_count = 0; +size_t construct2_count = 0; +size_t destruct_count = 0; +size_t destruct2_count = 0; +size_t copy_count = 0; +size_t copy2_count = 0; + +void reset_counter( void ) +{ + construct_count = 0; + construct2_count = 0; + destruct_count = 0; + destruct2_count = 0; + copy_count = 0; + copy2_count = 0; +} + + +namespace boost { namespace numeric { namespace odeint { + +//provide the state_wrapper + template< class T , size_t Dim > + struct state_wrapper< test_array< T , Dim > > + { + typedef state_wrapper< test_array< T , Dim > > state_wrapper_type; + typedef test_array< T , Dim > state_type; + typedef T value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + construct_count++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + construct_count++; + copy_count++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + construct_count++; + copy_count++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + copy_count++; + return *this; + } + + ~state_wrapper() + { + destruct_count++; + } + }; + +//provide the state_wrapper + template< class T , size_t Dim > + struct state_wrapper< test_array2< T , Dim > > + { + typedef state_wrapper< test_array2< T , Dim > > state_wrapper_type; + typedef test_array2< T , Dim > state_type; + typedef T value_type; + + state_type m_v; + + state_wrapper() : m_v() + { + construct2_count++; + } + + state_wrapper( const state_type &v ) : m_v( v ) + { + construct2_count++; + copy2_count++; + } + + state_wrapper( const state_wrapper_type &x ) : m_v( x.m_v ) + { + construct2_count++; + copy2_count++; + } + + state_wrapper_type& operator=( const state_wrapper_type &x ) + { + copy2_count++; + return *this; + } + + ~state_wrapper() + { + destruct2_count++; + } + }; + + + } } } + + + +typedef test_array< double , 3 > state_type; +typedef test_array2< double , 3 > deriv_type; +typedef boost::numeric::odeint::euler< state_type , double , deriv_type > euler_type; +typedef boost::numeric::odeint::runge_kutta4_classic< state_type , double , deriv_type > rk4_type; +typedef boost::numeric::odeint::runge_kutta4< state_type , double , deriv_type > rk4_generic_type; +typedef boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type , double , deriv_type > rk54_type; +typedef boost::numeric::odeint::runge_kutta_cash_karp54< state_type , double , deriv_type > rk54_generic_type; +typedef boost::numeric::odeint::runge_kutta_dopri5< state_type , double , deriv_type > dopri5_type; +typedef boost::numeric::odeint::controlled_runge_kutta< rk54_type > controlled_rk54_type; +typedef boost::numeric::odeint::controlled_runge_kutta< rk54_generic_type > controlled_rk54_generic_type; +typedef boost::numeric::odeint::controlled_runge_kutta< dopri5_type > controlled_dopri5_type; +typedef boost::numeric::odeint::dense_output_runge_kutta< euler_type > dense_output_euler_type; +typedef boost::numeric::odeint::dense_output_runge_kutta< controlled_dopri5_type > dense_output_dopri5_type; + +#define CHECK_COUNTERS( c1 , c2 , c3 , c4 , c5 , c6 ) \ + BOOST_CHECK_EQUAL( construct_count , size_t( c1 ) ); \ + BOOST_CHECK_EQUAL( construct2_count , size_t( c2 ) ); \ + BOOST_CHECK_EQUAL( destruct_count , size_t( c3 ) ); \ + BOOST_CHECK_EQUAL( destruct2_count , size_t( c4) ); \ + BOOST_CHECK_EQUAL( copy_count , size_t( c5 ) ) ; \ + BOOST_CHECK_EQUAL( copy2_count, size_t( c6 ) ) + +BOOST_AUTO_TEST_SUITE( stepper_copying ) + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_construct ) +{ + reset_counter(); + { + euler_type euler; + } + CHECK_COUNTERS( 0 , 1 , 0 , 1 , 0 , 0 ); +} + + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * + * Copying + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_copy_construct ) +{ + reset_counter(); + { + euler_type euler; + euler_type euler2( euler ); + } + CHECK_COUNTERS( 0 , 1 + 1 , 0 , 1 + 1 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * + * Copying + * 1 deriv_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_euler_assign ) +{ + reset_counter(); + { + euler_type euler; + euler_type euler2; + euler2 = euler; + } + CHECK_COUNTERS( 0 , 2 , 0 , 2 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_rk4 + * 1 state_type in explicit_rk4 + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_construct ) +{ + reset_counter(); + { + rk4_type rk4; + } + CHECK_COUNTERS( 1 , 4 , 1 , 4 , 0 , 0 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_copy_construct ) +{ + reset_counter(); + { + rk4_type rk4; + rk4_type rk4_2( rk4 ); + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_assign ) +{ + reset_counter(); + { + rk4_type rk4; + rk4_type rk4_2; + rk4 = rk4_2; + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + + +/* + * Construct + Destruct + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_rk4 + * 1 state_type in explicit_rk4 + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_construct ) +{ + reset_counter(); + { + rk4_generic_type rk4; + } + CHECK_COUNTERS( 1 , 4 , 1 , 4 , 0 , 0 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_copy_construct ) +{ + reset_counter(); + { + rk4_generic_type rk4; + rk4_generic_type rk4_2( rk4 ); + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 * 1 deriv_type in explicit_stepper_base + * 2 * 3 deriv_type in explicit_rk4 + * 2 * 1 state_type in explicit_rk4 + * + * Copying + * 1 deriv_type in explicit_stepper_base + * 3 deriv_type in explicit_stepper_base + * 1 state_type in explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( explicit_rk4_generic_assign ) +{ + reset_counter(); + { + rk4_generic_type rk4; + rk4_generic_type rk4_2; + rk4 = rk4_2; + } + CHECK_COUNTERS( 2 , 8 , 2 , 8 , 1 , 4 ); +} + +/* + * Construct + Destruct + * 2 explicit_rk54_ck: + * 2 * 1 deriv_type in explicit_error_stepper_base + * 2 * 5 deriv_type in explicit_error_rk54_ck + * 2 * 1 state_type in explicit_error_rk4 + * 1 controlled_stepper: + * 1 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_construct ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + } + CHECK_COUNTERS( 4 , 13 , 4 , 13 , 1 , 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_rk54_ck: + * 3 * 1 deriv_type in explicit_error_stepper_base + * 3 * 5 deriv_type in explicit_error_rk54_ck + * 3 * 1 state_type in explicit_error_rk4 + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_copy_construct ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + controlled_rk54_type stepper2( stepper ); + } + CHECK_COUNTERS( 7 , 20 , 7 , 20 , 4 , 13 ); +} + +/* + * Construct + Destruct + * 4 explicit_rk54_ck: + * 4 * 1 deriv_type in explicit_error_stepper_base + * 4 * 5 deriv_type in explicit_error_rk54_ck + * 4 * 1 state_type in explicit_error_rk4 + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_rk54_ck: + * 2 * 1 deriv_type from explicit_error_stepper_base + * 2 * 5 deriv_type from explicit_error_rk54_ck + * 2 * 1 state_type from explicit_error_rk54_ck + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck + * 1 state_type from explicit_error_rk54_ck + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_assign ) +{ + reset_counter(); + { + controlled_rk54_type stepper; + controlled_rk54_type stepper2; + stepper2 = stepper; + } + CHECK_COUNTERS( 8 , 26 , 8 , 26 , 5 , 19 ); +} + + + +/* + * Construct + Destruct + * 2 explicit_rk54_ck_generic: + * 2 * 1 deriv_type in explicit_error_stepper_base + * 2 * 5 deriv_type in explicit_error_rk54_ck_generic + * 2 * 1 state_type in explicit_error_rk54_ck_generic + * 1 controlled_stepper: + * 1 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck_generic: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_construct ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + } + CHECK_COUNTERS( 4 , 13 , 4 , 13 , 1 , 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_rk54_ck_generic: + * 3 * 1 deriv_type in explicit_error_stepper_base + * 3 * 5 deriv_type in explicit_error_rk54_ck_generic + * 3 * 1 state_type in explicit_error_rk4_generic + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_rk54_ck_generic: + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_copy_construct ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + controlled_rk54_generic_type stepper2( stepper ); + } + CHECK_COUNTERS( 7 , 20 , 7 , 20 , 4 , 13 ); +} + +/* + * Construct + Destruct + * 4 explicit_rk54_ck_generic: + * 4 * 1 deriv_type in explicit_error_stepper_base + * 4 * 5 deriv_type in explicit_error_rk54_ck_generic + * 4 * 1 state_type in explicit_error_rk4_generic + * 2 controlled_stepper: + * 2 * 1 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_rk54_ck_generic: + * 2 * 1 deriv_type from explicit_error_stepper_base + * 2 * 5 deriv_type from explicit_error_rk54_ck_generic + * 2 * 1 state_type from explicit_error_rk54_ck_generic + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 5 deriv_type from explicit_error_rk54_ck_generic + * 1 state_type from explicit_error_rk54_ck_generic + * 1 deriv_type from controlled_error_stepper + * 2 state_type from controlled_error_stepper + */ +BOOST_AUTO_TEST_CASE( controlled_rk54_generic_assign ) +{ + reset_counter(); + { + controlled_rk54_generic_type stepper; + controlled_rk54_generic_type stepper2; + stepper2 = stepper; + } + CHECK_COUNTERS( 8 , 26 , 8 , 26 , 5 , 19 ); +} + + +/* + * Construct + Destruct + * 2 explicit_error_dopri5: + * 2 * 1 deriv_type in explicit_error_stepper_base_fsal + * 2 * 6 deriv_type in explicit_error_dopri5 + * 2 * 1 state_type in explicit_error_dopri5 + * 1 controlled_error_stepper (fsal): + * 2 deriv_type + * 2 state_type + * + * Copying + * 1 copy process of explicit_dopri5: + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + */ + +BOOST_AUTO_TEST_CASE( controlled_dopri5_construct ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + } + CHECK_COUNTERS( 2 * 1 + 2 , 2 * (6+1) + 2 , 2 * 1 + 2 , 2 * (6+1) + 2 , 1 , 1 + 6 ); +} + + +/* + * Construct + Destruct + * 3 explicit_error_dopri5: + * 3 * 1 deriv_type in explicit_error_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 deriv_type + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_error_dopri5: + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_error_dopri5 + * 1 state_type from explicit_error_error_dopri5 + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base_fsal + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + * 2 deriv_type from controlled_error_stepper (fsal) + * 2 state_type from controlled_error_stepper (fsal) + */ +BOOST_AUTO_TEST_CASE( controlled_dopri5_copy_construct ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + controlled_dopri5_type dopri5_2( dopri5 ); + } + CHECK_COUNTERS( 3 * 1 + 2 * 2 , 3 * (6+1) + 2 * 2 , 3 * 1 + 2 * 2 , 3 * (6+1) + 2 * 2 , 1 + 1 + 2 , 1 + 6 + 1 + 6 + 2 ); +} + +/* + * Construct + Destruct + * 4 explicit_error_dopri5: + * 4 * 1 deriv_type in explicit_error_stepper_base_fsal + * 4 * 6 deriv_type in explicit_error_dopri5 + * 4 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 deriv_type + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_error_dopri5: + * 2 * 1 deriv_type from explicit_error_stepper_base_fsal + * 2 * 6 deriv_type from explicit_error_dopri5 + * 2 * 1 state_type from explicit_error_dopri5 + * + * 1 process of copying controlled_error_stepper + * 1 deriv_type from explicit_error_stepper_base + * 6 deriv_type from explicit_error_dopri5 + * 1 state_type from explicit_error_dopri5 + * 2 deriv_type from controlled_error_stepper (fsal) + * 2 state_type from controlled_error_stepper (fsal) + */ +BOOST_AUTO_TEST_CASE( controlled_dopri5_assign ) +{ + reset_counter(); + { + controlled_dopri5_type dopri5; + controlled_dopri5_type dopri5_2; + dopri5_2 = dopri5; + } + CHECK_COUNTERS( 4 * 1 + 2 * 2 , 4 * (1+6) + 2 * 2 , 4 * 1 + 2 * 2 , 4 * (1+6) + 2 * 2 , 2 * 1 + 1 + 2 , 2 * (6+1) + 1 + 6 + 2 ); +} + + +/* + * Construct + Destruct + * 2 explicit_euler: + * 2 * 1 deriv_type in explicit_stepper_base + * 1 dense_output_explicit: + * 2 state_type + * + * Copying + * 1 copy process of explicit_euler: + * 1 deriv_type from explicit_stepper_base + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_construct ) +{ + reset_counter(); + { + dense_output_euler_type euler; + } + CHECK_COUNTERS( 2 , 2 * 1 , 2 , 2 * 1 , 0 , 1 ); +} + +/* + * Construct + Destruct + * 3 explicit_euler: + * 3 * 1 deriv_type in explicit_stepper_base + * 2 dense_output_explicit: + * 2 * 2 state_type + * + * Copying + * 1 copy process of explicit_euler: + * 1 deriv_type from explicit_stepper_base + * + * 1 process of copying + * 1 deriv_type from explicit_stepper_base + * 2 state_type from dense_output_explicit + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_copy_construct ) +{ + reset_counter(); + { + dense_output_euler_type euler; + dense_output_euler_type euler2( euler ); + } + CHECK_COUNTERS( 2 * 2 , 3 * 1 , 2 * 2 , 3 * 1 , 2 , 1 + 1 ); +} + +/* + * Construct + Destruct + * 4 explicit_euler: + * 4 * 1 deriv_type in explicit_stepper_base + * 2 dense_output_explicit: + * 2 * 2 state_type + * + * Copying + * 2 copy process of explicit_euler: + * 2 * 1 deriv_type from explicit_stepper_base + * + * 1 process of copying dense_ouput_explicit + * 1 deriv_type from explicit_stepper_base + * 2 state_type from dense_output_explicit + */ +BOOST_AUTO_TEST_CASE( dense_output_euler_assign ) +{ + reset_counter(); + { + dense_output_euler_type euler; + dense_output_euler_type euler2; + euler2 = euler; + } + CHECK_COUNTERS( 2 * 2 , 4 * 1 , 2 * 2 , 4 * 1 , 2 , 2 * 1 + 1 ); +} + +/* + * Construct + Destruct + * 3 dense_output_dopri5: + * 3 * 1 deriv_type in explicit_error_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 controlled_error_stepper (fsal): + * 2 * 2 state_type + * 2 * 2 deriv_type + * 1 dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + * + * Copying + * 2 copy process of explicit_error_dopri5: + * 2 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 2 * 6 deriv_type in explicit_error_dopri5 + * 2 * 1 state_type in explicit_error_dopri5 + * 1 copy process of dense_output_controlled (fsal) + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_construct ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + } + CHECK_COUNTERS( 3*1 + 2*2 + 2 , 3*(1+6) + 2*2 + 2 , 3*1 + 2*2 + 2 , 3*(1+6) + 2*2 + 2 , 2*1 + 2 , 2*(1+6) + 2 ); +} + +/* + * Construct + Destruct + * 4 dense_output_dopri5: + * 4 * 1 deriv_type in explicit_error_stepper_base_fsal + * 4 * 5 deriv_type in explicit_error_dopri5 + * 4 * 1 state_type in explicit_error_dopri5 + * 3 controlled_error_stepper (fsal): + * 3 * 2 state_type + * 3 * 2 deriv_type + * 2 dense_output_controlled_explicit: + * 2 * 2 state_type + * 2 * 2 deriv_type + * + * Copying + * 3 copy process of explicit_error_dopri5: + * 3 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 3 * 6 deriv_type in explicit_error_dopri5 + * 3 * 1 state_type in explicit_error_dopri5 + * 2 copy process of controlled_error_stepper (fsal): + * 2 * 2 state_type + * 2 * 2 deriv_type + * 1 copy process of dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_copy_construct ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + dense_output_dopri5_type dopri5_2( dopri5 ); + } + CHECK_COUNTERS( 4*1 + 3*2 + 2*2 , 4*(1+6) + 3*2 + 2*2 , 4*1 + 3*2 + 2*2 , 4*(1+6) + 3*2 + 2*2 , 3*1 + 2*2 + 1*2 , 3*(6+1) + 2*2 + 2 ); +} + +/* + * Construct + Destruct + * 6 dense_output_dopri5: + * 6 * 1 deriv_type in explicit_error_stepper_base_fsal + * 6 * 6 deriv_type in explicit_error_dopri5 + * 6 * 1 state_type in explicit_error_dopri5 + * 4 controlled_error_stepper (fsal): + * 4 * 2 state_type + * 4 * 2 deriv_type + * 2 dense_output_controlled_explicit: + * 2 * 2 state_type + * 2 * 2 deriv_type + * + * Copying + * 5 copy process of explicit_error_dopri5: + * 5 * 1 deriv_type from explicit_erro_stepper_base_fsal + * 5 * 6 deriv_type in explicit_error_dopri5 + * 5 * 1 state_type in explicit_error_dopri5 + * 3 copy process of controlled_error_stepper (fsal): + * 3 * 2 state_type + * 3 * 2 deriv_type + * 1 copy process of dense_output_controlled_explicit: + * 2 state_type + * 2 deriv_type + */ +BOOST_AUTO_TEST_CASE( dense_output_dopri5_assign ) +{ + reset_counter(); + { + dense_output_dopri5_type dopri5; + dense_output_dopri5_type dopri5_2; + dopri5_2 = dopri5; + } + CHECK_COUNTERS( 6*1 + 4*2 + 2*2 , 6*(6+1) + 4*2 + 2*2 , 6*1 + 4*2 + 2*2 , 6*(6+1) + 4*2 + 2*2 , 5*1 + 3*2 + 2 , 5*(6+1) + 3*2 + 2 ); +} + + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp b/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp new file mode 100644 index 00000000..59f007f2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_with_ranges.cpp @@ -0,0 +1,292 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_with_ranges.cpp + + [begin_description] + This file tests if the steppers play well with Boost.Range. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_stepper_with_ranges + +#include <boost/test/unit_test.hpp> + +#include <vector> +#include <utility> +#include <iostream> + +#include <boost/array.hpp> +#include <boost/range.hpp> +#include <boost/ref.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> + +typedef std::vector< double > state_type; +typedef boost::array< double , 3 > state_type2; + +/* explicitly force range algebra for this array! */ +namespace boost { namespace numeric { namespace odeint { + +template<> +struct algebra_dispatcher< state_type2 > +{ typedef range_algebra algebra_type; }; + +} } } + + +/* + * The two systems are needed, since for steppers with more than + * one internal step it is difficult to calculate the exact result + * + * system1 is suited for euler + */ +struct system1 +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = x[0]; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< const State >::type x = boost::begin( x_ ); + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = x[0]; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + +/* + * system2 is suited for all steppers, it allows you to calculate the result analytically. + */ +struct system2 +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ , double t ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + + +/* + * Useful for Hamiltonian systems + */ +struct ham_sys +{ + template< class State , class Deriv > + void operator()( const State &x_ , Deriv &dxdt_ ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } + + template< class State , class Deriv > + void operator()( const State &x_ , const Deriv &dxdt_ ) + { + typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ ); + dxdt[0] = 1.0; + dxdt[1] = 2.0; + dxdt[2] = 3.0; + } +}; + + +struct vector_fixture +{ + const static size_t dim = 6; + boost::array< double , dim > in; + boost::array< double , dim > q; + boost::array< double , dim > p; + state_type err; + + vector_fixture( void ) + : in() , err( 3 ) + { + for( size_t i=0 ; i<dim ; ++i ) + { + in[ i ] = q[i] = p[i] = double( i ); + } + for( size_t i=0 ; i<3 ; ++i ) + { + err[i] = double( i ) * 10.0; + } + } + + ~vector_fixture( void ) + { + } +}; + +#define CHECK_VALUES( x , x0 , x1 , x2 , x3 , x4 , x5 ) \ + BOOST_CHECK_CLOSE( x[0] , x0 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[1] , x1 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[2] , x2 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[3] , x3 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[4] , x4 , 1.0e-8 ); \ + BOOST_CHECK_CLOSE( x[5] , x5 , 1.0e-8 ) + + + +BOOST_AUTO_TEST_SUITE( stepper_with_ranges ) + +BOOST_AUTO_TEST_CASE( explicit_euler_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::euler< state_type > euler; + euler.do_step( system1() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + + +BOOST_AUTO_TEST_CASE( explicit_error_k54_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > rk54; + rk54.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( explicit_error_k54_with_range_v5 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > rk54; + rk54.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 , f.err ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( runge_kutta_dopri5_with_range_v1 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_dopri5< state_type > dopri5; + dopri5.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( runge_kutta_dopri5_with_range_v5 ) +{ + vector_fixture f; + boost::numeric::odeint::runge_kutta_dopri5< state_type > dopri5; + dopri5.do_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , 0.1 , 0.1 , f.err ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( controlled_error_stepper_rk54 ) +{ + double t = 0.0 , dt = 0.1; + vector_fixture f; + boost::numeric::odeint::controlled_runge_kutta< boost::numeric::odeint::runge_kutta_cash_karp54_classic< state_type > > stepper; + stepper.try_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , t , dt ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( controlled_error_stepper_dopri5 ) +{ + double t = 0.0 , dt = 0.1; + vector_fixture f; + boost::numeric::odeint::controlled_runge_kutta< boost::numeric::odeint::runge_kutta_dopri5< state_type > > stepper; + stepper.try_step( system2() , std::make_pair( f.in.begin() + 1 , f.in.begin() + 4 ) , t , dt ); + CHECK_VALUES( f.in , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); +} + + +BOOST_AUTO_TEST_CASE( symplectic_euler_coor_func ) +{ + vector_fixture f; + boost::numeric::odeint::symplectic_euler< state_type > euler; + euler.do_step( ham_sys() , + std::make_pair( f.q.begin() + 1 , f.q.begin() + 4 ) , + std::make_pair( f.p.begin() + 3 , f.p.begin() + 6 ) , + 0.0 , 0.1 ); + CHECK_VALUES( f.q , 0.0 , 1.3 , 2.4 , 3.5 , 4.0 , 5.0 ); + CHECK_VALUES( f.p , 0.0 , 1.0 , 2.0 , 3.1 , 4.2 , 5.3 ); +} + +BOOST_AUTO_TEST_CASE( symplectic_euler_coor_and_mom_func ) +{ + vector_fixture f; + boost::numeric::odeint::symplectic_euler< state_type > euler; + euler.do_step( std::make_pair( ham_sys() , ham_sys() ) , + std::make_pair( f.q.begin() + 1 , f.q.begin() + 4 ) , + std::make_pair( f.p.begin() + 3 , f.p.begin() + 6 ) , + 0.0 , 0.1 ); + CHECK_VALUES( f.q , 0.0 , 1.1 , 2.2 , 3.3 , 4.0 , 5.0 ); + CHECK_VALUES( f.p , 0.0 , 1.0 , 2.0 , 3.1 , 4.2 , 5.3 ); +} + + +BOOST_AUTO_TEST_CASE( dense_output_euler_with_ranges ) +{ + using namespace boost::numeric::odeint; + vector_fixture f; + dense_output_runge_kutta< euler< state_type > > stepper; + stepper.initialize( std::make_pair( f.in.begin() + 1, f.in.begin() + 4 ) , 0.0 , 0.1 ); + stepper.do_step( system1() ); + stepper.calc_state( 0.05 , std::make_pair( f.in.begin() + 1 ,f.in.begin() +4 ) ); + CHECK_VALUES( f.in , 0.0 , 1.05 , 2.1 , 3.15 , 4.0 , 5.0 ); +} + +BOOST_AUTO_TEST_CASE( dense_output_dopri5_with_ranges ) +{ + using namespace boost::numeric::odeint; + vector_fixture f; + dense_output_runge_kutta< + controlled_runge_kutta< + runge_kutta_dopri5< state_type > + > > stepper; + stepper.initialize( std::make_pair( f.in.begin() + 1, f.in.begin() + 4 ) , 0.0 , 0.1 ); + stepper.do_step( system2() ); + stepper.calc_state( 0.05 , std::make_pair( f.in.begin() + 1 ,f.in.begin() +4 ) ); + CHECK_VALUES( f.in , 0.0 , 1.05 , 2.1 , 3.15 , 4.0 , 5.0 ); +} + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp b/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp new file mode 100644 index 00000000..3e3a6450 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/stepper_with_units.cpp @@ -0,0 +1,328 @@ +/* + [auto_generated] + libs/numeric/odeint/test/stepper_with_units.cpp + + [begin_description] + This file tests if the steppers play well with Boost.Units. + [end_description] + + Copyright 2011-2012 Karsten Ahnert + Copyright 2011-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_stepper_with_units + +// the runge-kutta 78 stepper invoked with boost units requires increased fusion macro variables! +// note that by default the rk78 + units test case is disabled as it requires enormous memory when compiling (5 GB) +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + + +#include <boost/numeric/odeint/config.hpp> + +#include <boost/test/unit_test.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/container.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54_classic.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_fehlberg78.hpp> +#include <boost/numeric/odeint/stepper/controlled_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer.hpp> +#include <boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra_dispatcher.hpp> + + +using namespace boost::numeric::odeint; +using namespace boost::unit_test; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , velocity_type > state_type; +typedef fusion::vector< velocity_type , acceleration_type > deriv_type; + +void oscillator( const state_type &x , deriv_type &dxdt , time_type t ) +{ + const units::quantity< si::frequency , value_type > omega = 1.0 * si::hertz; + fusion::at_c< 0 >( dxdt ) = fusion::at_c< 1 >( x ); + fusion::at_c< 1 >( dxdt ) = - omega * omega * fusion::at_c< 0 >( x ); +} + +template< class Stepper > +void check_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.do_step( oscillator , x , t , dt ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt ); + + // test call method four + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , x , dt ); +} + +template< class Stepper > +void check_fsal_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.do_step( oscillator , x , t , dt ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dxdt , dt ); +} + +template< class Stepper > +void check_error_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , xerr; + + // test call method one + stepper.do_step( oscillator , x , t , dt , xerr ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt , xerr ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt , xerr ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dt , xerr ); +} + +template< class Stepper > +void check_fsal_error_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + typedef typename stepper_type::order_type order_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + + const time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , xerr; + + // test call method one + stepper.do_step( oscillator , x , t , dt , xerr ); + + // test call method two + stepper.do_step( oscillator , x , t , x , dt , xerr ); + + // test call method three + deriv_type dxdt; + oscillator( x , dxdt , t ); + stepper.do_step( oscillator , x , dxdt , t , dt , xerr ); + + // test call method four + stepper.do_step( oscillator , x , dxdt , t , x , dxdt , dt , xerr ); +} + +template< class Stepper > +void check_controlled_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; + + time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ); + + // test call method one + stepper.try_step( oscillator , x , t , dt ); +} + + +template< class Stepper > +void check_dense_output_stepper( Stepper &stepper ) +{ + typedef Stepper stepper_type; + typedef typename stepper_type::state_type state_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::deriv_type deriv_type; + typedef typename stepper_type::time_type time_type; +// typedef typename stepper_type::order_type order_type; + + time_type t( 0.0 * si::second ); + time_type dt( 0.1 * si::second ); + state_type x( 1.0 * si::meter , 0.0 * si::meter_per_second ) , x2; + + stepper.initialize( x , t , dt ); + stepper.do_step( oscillator ); + stepper.calc_state( dt / 2.0 , x2 ); +} + + + + + + +class stepper_types : public mpl::vector +< + euler< state_type , value_type , deriv_type , time_type >, + runge_kutta4< state_type , value_type , deriv_type , time_type > , + runge_kutta4_classic< state_type , value_type , deriv_type , time_type > , + runge_kutta_cash_karp54< state_type , value_type , deriv_type , time_type >, + runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > + // don't run rk78 test - gcc requires > 5GB RAM to compile this + //, runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > + > { }; + +class fsal_stepper_types : public mpl::vector +< + runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > + > { }; + +class error_stepper_types : public mpl::vector +< + runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > + //, runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > + > { }; + +class fsal_error_stepper_types : public mpl::vector +< + runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > + > { }; + +class controlled_stepper_types : public mpl::vector +< + controlled_runge_kutta< runge_kutta_cash_karp54_classic< state_type , value_type , deriv_type , time_type > > , + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > > + , bulirsch_stoer< state_type , value_type , deriv_type , time_type > + // rk78 with units needs up to 3GB memory to compile - disable testing... + //, controlled_runge_kutta< runge_kutta_fehlberg78< state_type , value_type , deriv_type , time_type > > + > { }; + +class dense_output_stepper_types : public mpl::vector +< + dense_output_runge_kutta< euler< state_type , value_type , deriv_type , time_type > > , + dense_output_runge_kutta< + controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , deriv_type , time_type > > > + //, bulirsch_stoer_dense_out< state_type , value_type , deriv_type , time_type > + > { }; + + + + +BOOST_AUTO_TEST_SUITE( stepper_with_units ) + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_test , Stepper , stepper_types ) +{ + Stepper stepper; + check_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( fsl_stepper_test , Stepper , fsal_stepper_types ) +{ + Stepper stepper; + check_fsal_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( error_stepper_test , Stepper , error_stepper_types ) +{ + Stepper stepper; + check_error_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( fsal_error_stepper_test , Stepper , fsal_error_stepper_types ) +{ + Stepper stepper; + check_fsal_error_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , Stepper , controlled_stepper_types ) +{ + Stepper stepper; + check_controlled_stepper( stepper ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( dense_ouput_test , Stepper , dense_output_stepper_types ) +{ + Stepper stepper; + check_dense_output_stepper( stepper ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp b/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp new file mode 100644 index 00000000..498983bd --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/symplectic_steppers.cpp @@ -0,0 +1,391 @@ +/* + [auto_generated] + libs/numeric/odeint/test/symplectic_steppers.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2012 Karsten Ahnert + Copyright 2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_symplectic_steppers + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 +#define FUSION_MAX_VECTOR_SIZE 15 + + +#include <boost/test/unit_test.hpp> + +#include <boost/array.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/zip_view.hpp> +#include <boost/mpl/vector_c.hpp> +#include <boost/mpl/insert_range.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/copy.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/inserter.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/fusion/container/vector.hpp> +#include <boost/fusion/include/make_vector.hpp> + +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> +#include <boost/numeric/odeint/stepper/symplectic_euler.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_mclachlan.hpp> +#include <boost/numeric/odeint/stepper/symplectic_rkn_sb3a_m4_mclachlan.hpp> +#include <boost/numeric/odeint/integrate/integrate_const.hpp> + +#include "diagnostic_state_type.hpp" +#include "const_range.hpp" +#include "dummy_odes.hpp" +#include "boost_units_helpers.hpp" + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +class custom_range_algebra : public range_algebra { }; +class custom_default_operations : public default_operations { }; + + +template< class Coor , class Mom , class Value , class CoorDeriv , class MomDeriv , class Time , + class Algebra , class Operations , class Resizer > +class complete_steppers : public mpl::vector< + symplectic_euler< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + , symplectic_rkn_sb3a_mclachlan< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + , symplectic_rkn_sb3a_m4_mclachlan< Coor , Mom , Value , CoorDeriv , MomDeriv , Time , + Algebra , Operations , Resizer > + > {}; + +template< class Resizer > +class vector_steppers : public complete_steppers< + diagnostic_state_type , diagnostic_state_type2 , double , + diagnostic_deriv_type , diagnostic_deriv_type2 , double , + custom_range_algebra , custom_default_operations , Resizer + > { }; + + +typedef mpl::vector< initially_resizer , always_resizer , never_resizer > resizers; +typedef mpl::vector_c< int , 1 , 3 , 0 > resizer_multiplicities ; + + +typedef mpl::copy< + resizers , + mpl::inserter< + mpl::vector0<> , + mpl::insert_range< + mpl::_1 , + mpl::end< mpl::_1 > , + vector_steppers< mpl::_2 > + > + > + >::type all_stepper_methods; + + +typedef mpl::size< vector_steppers< initially_resizer > >::type num_steppers; +typedef mpl::copy< + resizer_multiplicities , + mpl::inserter< + mpl::vector0<> , + mpl::insert_range< + mpl::_1 , + mpl::end< mpl::_1 > , + const_range< num_steppers , mpl::_2 > + > + > + >::type all_multiplicities; + + + + + + + +BOOST_AUTO_TEST_SUITE( symplectic_steppers_test ) + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_assoc_types , Stepper , vector_steppers< initially_resizer > ) +{ + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::coor_type , diagnostic_state_type >::value ) , + "Coordinate type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::momentum_type , diagnostic_state_type2 >::value ) , + "Momentum type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::coor_deriv_type , diagnostic_deriv_type >::value ) , + "Coordinate deriv type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::momentum_deriv_type , diagnostic_deriv_type2 >::value ) , + "Momentum deriv type" ); + + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::state_type , std::pair< diagnostic_state_type , diagnostic_state_type2 > >::value ) , + "State type" ); + BOOST_STATIC_ASSERT_MSG( + ( boost::is_same< typename Stepper::deriv_type , std::pair< diagnostic_deriv_type , diagnostic_deriv_type2 > >::value ) , + "Deriv type" ); + + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::value_type , double >::value ) , "Value type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::time_type , double >::value ) , "Time type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::algebra_type , custom_range_algebra >::value ) , "Algebra type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::operations_type , custom_default_operations >::value ) , "Operations type" ); + + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::resizer_type , initially_resizer >::value ) , "Resizer type" ); + BOOST_STATIC_ASSERT_MSG( ( boost::is_same< typename Stepper::stepper_category , stepper_tag >::value ) , "Stepper category" ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_adjust_size , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + diagnostic_state_type x; + stepper.adjust_size( x ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_deriv , 1 , 1 , 0 , 1 ); + TEST_COUNTERS( counter_deriv2 , 1 , 1 , 0 , 1 ); +} + + +typedef mpl::zip_view< mpl::vector< all_stepper_methods , all_multiplicities > >::type zipped_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_resizing , Stepper , zipped_steppers ) +{ + typedef typename mpl::at_c< Stepper , 0 >::type stepper_type; + const size_t multiplicity = mpl::at_c< Stepper , 1 >::type::value; + + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + stepper_type stepper; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x; + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + // dqdt is not needed when called with mom func only, so no resizing + // TEST_COUNTERS( counter_deriv , multiplicity , 1 , 0 , 1 ); + TEST_COUNTERS( counter_deriv2 , multiplicity , 1 , 0 , 1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_copying1 , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + Stepper stepper2( stepper ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_deriv , 0 , 2 , 1 , 2 ); + TEST_COUNTERS( counter_deriv2 , 0 , 2 , 1 , 2 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_copying2 , Stepper , vector_steppers< initially_resizer > ) +{ + counter_state::init_counter(); + counter_deriv::init_counter(); + counter_state2::init_counter(); + counter_deriv2::init_counter(); + + { + Stepper stepper; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x; + stepper.do_step( constant_mom_func() , x , 0.0 , 0.1 ); + Stepper stepper2( stepper ); + } + + TEST_COUNTERS( counter_state , 0 , 0 , 0 , 0 ); + TEST_COUNTERS( counter_state2 , 0 , 0 , 0 , 0 ); + // dqdt is not needed when called with mom func only, so no resizing + //TEST_COUNTERS( counter_deriv , 1 , 2 , 1 , 2 ); + TEST_COUNTERS( counter_deriv2 , 1 , 2 , 1 , 2 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v1 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x1 , x2 , x3 , x4; + x1.first[0] = 1.0; + x1.second[0] = 2.0; + x2 = x3 = x4 = x1; + diagnostic_state_type x5_coor , x5_mom; + x5_coor[0] = x1.first[0]; + x5_mom[0] = x1.second[0]; + + s.do_step( constant_mom_func() , x1 , 0.0 , 0.1 ); + + s.do_step( std::make_pair( default_coor_func() , constant_mom_func() ) , x2 , 0.0 , 0.1 ); + + default_coor_func cf; + constant_mom_func mf; + s.do_step( std::make_pair( boost::ref( cf ) , boost::ref( mf ) ) , x3 , 0.0 , 0.1 ); + + std::pair< default_coor_func , constant_mom_func > pf; + s.do_step( boost::ref( pf ) , x4 , 0.0 , 0.1 ); + + s.do_step( constant_mom_func() , std::make_pair( boost::ref( x5_coor ) , boost::ref( x5_mom ) ) , 0.0 , 0.1 ); + + // checking for absolute values is not possible here, since the steppers are to different + BOOST_CHECK_CLOSE( x1.first[0] , x2.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x2.first[0] , x3.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x3.first[0] , x4.first[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x4.first[0] , x5_coor[0] , 1.0e-14 ); + + BOOST_CHECK_CLOSE( x1.second[0] , x2.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x2.second[0] , x3.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x3.second[0] , x4.second[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x4.second[0] , x5_mom[0] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_range , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + diagnostic_state_type q , p ; + q[0] = 1.0; + p[0] = 2.0; + + std::vector< double > x; + x.push_back( 1.0 ); + x.push_back( 2.0 ); + s.do_step( constant_mom_func() , + std::make_pair( x.begin() , x.begin() + 1 ) , + std::make_pair( x.begin() + 1 , x.begin() + 2 ) , + 0.0 , 0.1 ); + + s.do_step( constant_mom_func() , q , p , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( q[0] , x[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( p[0] , x[1] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v2 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + diagnostic_state_type q , p ; + q[0] = 1.0; + p[0] = 2.0; + diagnostic_state_type q2 = q , p2 = p; + + + s.do_step( constant_mom_func() , q , p , 0.0 , 0.1 ); + s.do_step( constant_mom_func() , std::make_pair( boost::ref( q2 ) , boost::ref( p2 ) ) , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( q[0] , q2[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( p[0] , p2[0] , 1.0e-14 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step_v3 , Stepper , vector_steppers< initially_resizer > ) +{ + Stepper s; + std::pair< diagnostic_state_type , diagnostic_state_type2 > x_in , x_out; + x_in.first[0] = 1.0; + x_in.second[0] = 2.0; + diagnostic_state_type q2 , p2; + q2[0] = x_in.first[0]; + p2[0] = x_in.second[0]; + + + s.do_step( constant_mom_func() , x_in , 0.0 , x_out , 0.1 ); + s.do_step( constant_mom_func() , std::make_pair( boost::ref( q2 ) , boost::ref( p2 ) ) , 0.0 , 0.1 ); + + BOOST_CHECK_CLOSE( x_in.first[0] , 1.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_in.second[0] , 2.0 , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_out.first[0] , q2[0] , 1.0e-14 ); + BOOST_CHECK_CLOSE( x_out.second[0] , p2[0] , 1.0e-14 ); +} + + +typedef double vector_space; +typedef complete_steppers< vector_space , vector_space , double , + vector_space , vector_space , double , + vector_space_algebra , default_operations , initially_resizer > vector_space_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_with_vector_space_algebra , Stepper , vector_space_steppers ) +{ + Stepper s; + std::pair< vector_space , vector_space > x; + s.do_step( constant_mom_func_vector_space_1d() , x , 0.0 , 0.1 ); + + s.do_step( std::make_pair( default_coor_func_vector_space_1d() , constant_mom_func_vector_space_1d() ) , x , 0.0 , 0.1 ); +} + + +typedef boost::fusion::vector< length_type > coor_type; +typedef boost::fusion::vector< velocity_type > mom_type; +typedef boost::fusion::vector< acceleration_type > acc_type; +typedef complete_steppers< coor_type , mom_type , double , + mom_type , acc_type , time_type, + fusion_algebra , default_operations , initially_resizer > boost_unit_steppers; +BOOST_AUTO_TEST_CASE_TEMPLATE( test_with_boost_units , Stepper , boost_unit_steppers ) +{ + namespace fusion = boost::fusion; + namespace si = boost::units::si; + Stepper s; + + coor_type q = fusion::make_vector( 1.0 * si::meter ); + mom_type p = fusion::make_vector( 2.0 * si::meter_per_second ); + time_type t = 0.0 * si::second; + time_type dt = 0.1 * si::second; + + coor_type q1 = q , q2 = q; + mom_type p1 = p , p2 = p; + + s.do_step( oscillator_mom_func_units() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , t , dt ); + + s.do_step( std::make_pair( oscillator_coor_func_units() , oscillator_mom_func_units() ) , + std::make_pair( boost::ref( q1 ) , boost::ref( p1 ) ) , t , dt ); + + s.do_step( oscillator_mom_func_units() , q2 , p2 , t , dt ); + + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( q ).value() ) , ( fusion::at_c< 0 >( q1 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( q1 ).value() ) , ( fusion::at_c< 0 >( q2 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( p ).value() ) , ( fusion::at_c< 0 >( p1 ).value() ) , 1.0e-14 ); + BOOST_CHECK_CLOSE( ( fusion::at_c< 0 >( p1 ).value() ) , ( fusion::at_c< 0 >( p2 ).value() ) , 1.0e-14 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/times_iterator.cpp b/src/boost/libs/numeric/odeint/test/times_iterator.cpp new file mode 100644 index 00000000..552d5af7 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/times_iterator.cpp @@ -0,0 +1,237 @@ +/* + [auto_generated] + libs/numeric/odeint/test/times_iterator.cpp + + [begin_description] + This file tests the n-step iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_times_iterator + +#include <iterator> +#include <algorithm> +#include <vector> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/times_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; + + +BOOST_AUTO_TEST_SUITE( times_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + +boost::array<double,4> times = {{ 0.0 , 0.1, 0.2, 0.3 }}; +typedef boost::array<double,4>::iterator time_iterator_type; + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &(*iter2) ); + BOOST_CHECK_EQUAL( &(*iter1) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + std::cout << "assignment" << std::endl; + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type> iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , times.begin() , times.end() , 0.2 ); + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(*iter1) , &x1 ); + BOOST_CHECK_EQUAL( &(*iter2) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + std::cout << "factory" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_iterator_begin( stepper , boost::ref( system ) , x , times.begin(), times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 3 do_step calls so x should be 1.75 + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + std::cout << "range" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_range( stepper , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_range( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end(), 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + std::cout << "transitivity1" << std::endl; + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , times.end() , times.end() , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , times.end()-1 , times.end() , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type> stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + stepper_iterator first( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef times_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::array<double,4> neg_times = {{ 0.0 , -0.1, -0.2, -0.3 }}; + stepper_iterator first( Stepper() , empty_system() , x , neg_times.begin() , neg_times.end() , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + std::copy( make_times_iterator_begin( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + make_times_iterator_end<time_iterator_type>( Stepper() , empty_system() , x ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + std::vector< state_type > res; + boost::range::copy( make_times_range( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + std::back_insert_iterator< std::vector< state_type > >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0][0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1][0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2][0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3][0] , 1.75 , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp b/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp new file mode 100644 index 00000000..274f8a62 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/times_time_iterator.cpp @@ -0,0 +1,250 @@ +/* + [auto_generated] + libs/numeric/odeint/test/times_time_iterator.cpp + + [begin_description] + This file tests the times iterator. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2009-2013 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_times_time_iterator + +#include <iterator> +#include <algorithm> +#include <vector> +#include <iostream> + +#include <boost/numeric/odeint/config.hpp> +#include <boost/array.hpp> +#include <boost/range/algorithm/for_each.hpp> +#include <boost/range/algorithm/copy.hpp> +#include <boost/mpl/vector.hpp> + +#include <boost/test/unit_test.hpp> +#include <boost/test/floating_point_comparison.hpp> + +#include <boost/numeric/odeint/iterator/times_time_iterator.hpp> +#include "dummy_steppers.hpp" +#include "dummy_odes.hpp" +#include "dummy_observers.hpp" + +namespace mpl = boost::mpl; +using namespace boost::numeric::odeint; + +typedef dummy_stepper::state_type state_type; +typedef dummy_stepper::value_type value_type; +typedef dummy_stepper::time_type time_type; + +BOOST_AUTO_TEST_SUITE( times_time_iterator_test ) + +typedef mpl::vector< + dummy_stepper + , dummy_dense_output_stepper + > dummy_steppers; + +boost::array<double,4> times = {{ 0.0 , 0.1, 0.2, 0.3 }}; +typedef boost::array<double,4>::iterator time_iterator_type; +typedef std::vector< std::pair< state_type , time_type > > result_vector; + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_stepper_iterator , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > iterator_type; + state_type x = {{ 1.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iter1; + BOOST_CHECK_EQUAL( &(iter1->first) , &(iter2->first) ); + BOOST_CHECK_EQUAL( &(iter1->first) , &x ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( assignment_stepper_iterator , Stepper , dummy_steppers ) +{ + std::cout << "assignment" << std::endl; + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type> iterator_type; + state_type x1 = {{ 1.0 }} , x2 = {{ 2.0 }}; + iterator_type iter1 = iterator_type( Stepper() , empty_system() , x1 , times.begin() , times.end() , 0.1 ); + iterator_type iter2 = iterator_type( Stepper() , empty_system() , x2 , times.begin() , times.end() , 0.2 ); + BOOST_CHECK_EQUAL( &(iter1->first) , &x1 ); + BOOST_CHECK_EQUAL( &(iter2->first) , &x2 ); + BOOST_CHECK( !iter1.same( iter2 ) ); + iter2 = iter1; + BOOST_CHECK_EQUAL( &(iter1->first) , &x1 ); + BOOST_CHECK_EQUAL( &(iter2->first) , &x1 ); + BOOST_CHECK( iter1.same( iter2 ) ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_factory , Stepper , dummy_steppers ) +{ + std::cout << "factory" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_time_iterator_begin( stepper , boost::ref( system ) , x , times.begin(), times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( stepper , boost::ref( system ) , x ) , + dummy_observer() ); + + // dummy_steppers just add 0.25 at each step, the above for_each leads to 3 do_step calls so x should be 1.75 + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range , Stepper , dummy_steppers ) +{ + std::cout << "range" << std::endl; + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_time_range( stepper , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_iterator_with_reference_wrapper_factory , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + std::for_each( + make_times_time_iterator_begin( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( boost::ref( stepper ) , boost::ref( system ) , x ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( stepper_range_with_reference_wrapper , Stepper , dummy_steppers ) +{ + Stepper stepper; + empty_system system; + state_type x = {{ 1.0 }}; + + boost::for_each( make_times_time_range( boost::ref( stepper ) , boost::ref( system ) , x , times.begin() , times.end(), 0.1 ) , + dummy_observer() ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + + +BOOST_AUTO_TEST_CASE_TEMPLATE( transitivity1 , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + std::cout << "transitivity1" << std::endl; + state_type x = {{ 1.0 }}; + stepper_iterator first1( Stepper() , empty_system() , x , times.end() , times.end() , 0.1 ); + stepper_iterator last1( Stepper() , empty_system() , x ); + stepper_iterator last2( Stepper() , empty_system() , x ); + + BOOST_CHECK( first1 == last1 ); + BOOST_CHECK( first1 == last2 ); + BOOST_CHECK( last1 == last2 ); + + first1 = stepper_iterator( Stepper() , empty_system() , x , times.end()-1 , times.end() , 0.1 ); + last1 = stepper_iterator( Stepper() , empty_system() , x ); + BOOST_CHECK( first1 != last1 ); + BOOST_CHECK( ++first1 == last1 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type> stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + stepper_iterator first( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); // the iterator should not iterate over the end +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_negative_time_step , Stepper , dummy_steppers ) +{ + typedef times_time_iterator< Stepper , empty_system , state_type , time_iterator_type > stepper_iterator; + state_type x = {{ 1.0 }}; + result_vector res; + boost::array<double,4> neg_times = {{ 0.0 , -0.1, -0.2, -0.3 }}; + stepper_iterator first( Stepper() , empty_system() , x , neg_times.begin() , neg_times.end() , -0.1 ); + stepper_iterator last( Stepper() , empty_system() , x ); + + std::copy( first , last , std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , neg_times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + std::copy( make_times_time_iterator_begin( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + make_times_time_iterator_end<time_iterator_type>( Stepper() , empty_system() , x ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE( copy_algorithm_with_range_factory , Stepper , dummy_steppers ) +{ + state_type x = {{ 1.0 }}; + result_vector res; + boost::range::copy( make_times_time_range( Stepper() , empty_system() , x , times.begin() , times.end() , 0.1 ) , + std::back_insert_iterator< result_vector >( res ) ); + + BOOST_CHECK_EQUAL( res.size() , size_t( 4 ) ); + BOOST_CHECK_CLOSE( res[0].first[0] , 1.0 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[1].first[0] , 1.25 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[2].first[0] , 1.5 , 1.0e-13 ); + BOOST_CHECK_CLOSE( res[3].first[0] , 1.75 , 1.0e-13 ); + + for( size_t n=0 ; n<4 ; ++n ) + BOOST_CHECK_CLOSE( res[n].second , times[n] , 1.0e-13 ); + + BOOST_CHECK_CLOSE( x[0] , 1.75 , 1.0e-13 ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/trivial_state.cpp b/src/boost/libs/numeric/odeint/test/trivial_state.cpp new file mode 100644 index 00000000..9976db7f --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/trivial_state.cpp @@ -0,0 +1,109 @@ +/* + [auto_generated] + libs/numeric/odeint/test/trivial_state.cpp + + [begin_description] + This file tests if the steppers can integrate the trivial state consisting of a single double. + [end_description] + + Copyright 2012-2013 Mario Mulansky + Copyright 2012 Karsten Ahnert + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <limits> + +// disable checked iterator warning for msvc +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_trivial_state + +#include <boost/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/at.hpp> + +#include <boost/numeric/odeint/stepper/euler.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta4.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp> +#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp> +#include <boost/numeric/odeint/stepper/generation.hpp> +#include <boost/numeric/odeint/integrate/integrate_adaptive.hpp> +#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp> + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +namespace mpl = boost::mpl; + +struct constant_system +{ + template< typename T > + void operator()( const T &x , T &dxdt , const T t ) const + { dxdt = 1.0; } +}; + + +BOOST_AUTO_TEST_SUITE( trivial_state_test ) + +/* test different do_step methods of simple steppers */ + +typedef mpl::vector< + euler< double > , + runge_kutta4< double > , + // with floats all four parameters have to be given explicitly to override default double + euler< float , float , float , float > , + runge_kutta4< float , float , float , float > + >::type stepper_types; + + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_do_step , T, stepper_types ) +{ + typedef T stepper_type; + stepper_type stepper; + typename stepper_type::state_type x = 0.0; + typename stepper_type::time_type t = 0.0; + typename stepper_type::time_type dt = 0.1; + stepper.do_step( constant_system() , x , t , dt ); + BOOST_CHECK_CLOSE( x , 0.1 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); + + // this overload is not allowed if the types of dxdt and dt are the same + // deriv_type dxdt = 1.0; + // stepper.do_step( constant_system , x , dxdt , t , dt ); + + typename stepper_type::state_type x_out; + stepper.do_step( constant_system() , x , t , x_out , dt ); + BOOST_CHECK_CLOSE( x , 0.1 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); + BOOST_CHECK_CLOSE( x_out , 0.2 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); +} + + +/* test integrate_adaptive with controlled steppers */ + +typedef mpl::vector< + runge_kutta_cash_karp54< double > , + runge_kutta_dopri5< double > , + // with floats all four parameters have to be given explicitly to override default double + runge_kutta_cash_karp54< float , float , float , float > , + runge_kutta_dopri5< float , float , float , float > + > error_stepper_types; + +BOOST_AUTO_TEST_CASE_TEMPLATE( test_integrate , T , error_stepper_types ) +{ + typedef T stepper_type; + typename stepper_type::state_type x = 0.0; + typename stepper_type::time_type t0 = 0.0; + typename stepper_type::time_type t1 = 1.0; + typename stepper_type::time_type dt = 0.1; + integrate_adaptive( make_controlled< stepper_type >( 1e-6 , 1e-6 ) , constant_system() , x , t0 , t1 , dt ); + BOOST_CHECK_CLOSE( x , 1.0 , 100*std::numeric_limits< typename stepper_type::state_type >::epsilon() ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp b/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp new file mode 100644 index 00000000..4106fdf2 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/unwrap_boost_reference.cpp @@ -0,0 +1,40 @@ +/* + [auto_generated] + libs/numeric/odeint/test/unwrap_boost_reference.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#define BOOST_TEST_MODULE odeint_unwrap_boost_reference + +#include <boost/numeric/odeint/util/unwrap_reference.hpp> +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +template< typename T > +void func( T t ) +{ + typedef typename boost::numeric::odeint::unwrap_reference< T >::type type; +} + +BOOST_AUTO_TEST_SUITE( unwrap_boost_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + int a; + func( boost::ref( a ) ); + func( a ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp b/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp new file mode 100644 index 00000000..7337ddd3 --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/unwrap_reference.cpp @@ -0,0 +1,42 @@ +/* + [auto_generated] + libs/numeric/odeint/test/unwrap_reference.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + + +#define BOOST_TEST_MODULE odeint_unwrap_reference + +#include <boost/numeric/odeint/util/unwrap_reference.hpp> + +#include <boost/test/unit_test.hpp> + +using namespace boost::unit_test; + +template< typename T > +void func( T t ) +{ + typedef typename boost::numeric::odeint::unwrap_reference< T >::type type; +} + +BOOST_AUTO_TEST_SUITE( unwrap_reference_test ) + +BOOST_AUTO_TEST_CASE( test_case ) +{ + int a; + func( std::ref( a ) ); + func( a ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp b/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp new file mode 100644 index 00000000..93a2e97c --- /dev/null +++ b/src/boost/libs/numeric/odeint/test/velocity_verlet.cpp @@ -0,0 +1,298 @@ +/* + [auto_generated] + libs/numeric/odeint/test/velocity_verlet.cpp + + [begin_description] + tba. + [end_description] + + Copyright 2009-2012 Karsten Ahnert + Copyright 2009-2012 Mario Mulansky + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or + copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#include <boost/config.hpp> +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_velocity_verlet + +#define BOOST_FUSION_INVOKE_MAX_ARITY 15 +#define BOOST_RESULT_OF_NUM_ARGS 15 + +#include <boost/numeric/odeint/config.hpp> + +#include "resizing_test_state_type.hpp" + +#include <boost/numeric/odeint/stepper/velocity_verlet.hpp> +#include <boost/numeric/odeint/algebra/fusion_algebra.hpp> + +#include <boost/array.hpp> +#include <boost/test/unit_test.hpp> + +#include <boost/units/systems/si/length.hpp> +#include <boost/units/systems/si/time.hpp> +#include <boost/units/systems/si/velocity.hpp> +#include <boost/units/systems/si/acceleration.hpp> +#include <boost/units/systems/si/io.hpp> + +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/vector20.hpp> +#include <boost/fusion/container.hpp> + +namespace fusion = boost::fusion; +namespace units = boost::units; +namespace si = boost::units::si; + +typedef double value_type; +typedef units::quantity< si::time , value_type > time_type; +typedef units::unit< units::derived_dimension< units::time_base_dimension , 2 >::type , si::system > time_2; +typedef units::quantity< time_2 , value_type > time_2_type; +typedef units::quantity< si::length , value_type > length_type; +typedef units::quantity< si::velocity , value_type > velocity_type; +typedef units::quantity< si::acceleration , value_type > acceleration_type; +typedef fusion::vector< length_type , length_type > coor_vector; +typedef fusion::vector< velocity_type , velocity_type > velocity_vector; +typedef fusion::vector< acceleration_type , acceleration_type > accelartion_vector; + + + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +size_t ode_call_count; + +struct velocity_verlet_fixture +{ + velocity_verlet_fixture( void ) { ode_call_count = 0; adjust_size_count = 0; } +}; + +struct ode +{ + template< class CoorIn , class MomentumIn , class AccelerationOut , class Time > + void operator()( const CoorIn &q , const MomentumIn &p , AccelerationOut &a , Time t ) const + { + a[0] = -q[0] - p[0]; + a[1] = -q[1] - p[1]; + ++ode_call_count; + } +}; + +struct ode_units +{ + void operator()( coor_vector const &q , velocity_vector const &p , accelartion_vector &a , time_type t ) const + { + const units::quantity< si::frequency , value_type > omega = 1.0 * si::hertz; + const units::quantity< si::frequency , value_type > friction = 0.001 * si::hertz; + fusion::at_c< 0 >( a ) = omega * omega * fusion::at_c< 0 >( q ) - friction * fusion::at_c< 0 >( p ); + fusion::at_c< 1 >( a ) = omega * omega * fusion::at_c< 1 >( q ) - friction * fusion::at_c< 0 >( p ); + ++ode_call_count; + } +}; + +template< class Q , class P > +void init_state( Q &q , P &p ) +{ + q[0] = 1.0 ; q[1] = 0.5; + p[0] = 2.0 ; p[1] = -1.0; +} + +typedef boost::array< double , 2 > array_type; +typedef std::vector< double > vector_type; + +typedef velocity_verlet< array_type > array_stepper; +typedef velocity_verlet< vector_type > vector_stepper; + +template< typename Resizer > +struct get_resizer_test_stepper +{ + typedef velocity_verlet< test_array_type , test_array_type , double , test_array_type , + double , double , range_algebra , default_operations , Resizer > type; +}; + + + + + +BOOST_AUTO_TEST_SUITE( velocity_verlet_test ) + +BOOST_FIXTURE_TEST_CASE( test_with_array_ref , velocity_verlet_fixture ) +{ + array_stepper stepper; + array_type q , p ; + init_state( q , p ); + stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_array_pair , velocity_verlet_fixture ) +{ + array_stepper stepper; + std::pair< array_type , array_type > xxx; + init_state( xxx.first , xxx.second ); + stepper.do_step( ode() , xxx , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_vector_ref , velocity_verlet_fixture ) +{ + vector_stepper stepper; + vector_type q( 2 ) , p( 2 ); + init_state( q , p ); + stepper.do_step( ode() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_vector_pair , velocity_verlet_fixture ) +{ + vector_stepper stepper; + std::pair< vector_type , vector_type > x; + x.first.resize( 2 ) ; x.second.resize( 2 ); + init_state( x.first , x.second ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initial_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_always_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< always_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) ); // attention: one more system call, since the size of the state has been changed +} + +BOOST_FIXTURE_TEST_CASE( test_with_never_resizer , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< never_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_reset , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); + stepper.reset(); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 3 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 5 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initialize1 , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + test_array_type ain; + ode()( x.first , x.second , ain , 0.0 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 0 ) ); + stepper.initialize( ain ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_initialize2 , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.initialize( ode() , x.first , x.second , 0.0 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 1 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_FIXTURE_TEST_CASE( test_adjust_size , velocity_verlet_fixture ) +{ + typedef get_resizer_test_stepper< initially_resizer >::type stepper_type; + std::pair< test_array_type , test_array_type > x; + init_state( x.first , x.second ); + stepper_type stepper; + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 2 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.adjust_size( x.first ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); + stepper.do_step( ode() , x , 0.0 , 0.01 ); + BOOST_CHECK_EQUAL( adjust_size_count , size_t( 4 ) ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 4 ) ); +} + +BOOST_FIXTURE_TEST_CASE( test_with_unit_pair , velocity_verlet_fixture ) +{ + typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector , + time_type , time_2_type , fusion_algebra , default_operations > stepper_type; + + std::pair< coor_vector , velocity_vector > x; + fusion::at_c< 0 >( x.first ) = 1.0 * si::meter; + fusion::at_c< 1 >( x.first ) = 0.5 * si::meter; + fusion::at_c< 0 >( x.second ) = 2.0 * si::meter_per_second; + fusion::at_c< 1 >( x.second ) = -1.0 * si::meter_per_second; + stepper_type stepper; + stepper.do_step( ode_units() , x , 0.0 * si::second , 0.01 * si::second ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_FIXTURE_TEST_CASE( test_with_unit_ref , velocity_verlet_fixture ) +{ + typedef velocity_verlet< coor_vector , velocity_vector , value_type , accelartion_vector , + time_type , time_2_type , fusion_algebra , default_operations > stepper_type; + + coor_vector q; + velocity_vector p; + fusion::at_c< 0 >( q ) = 1.0 * si::meter; + fusion::at_c< 1 >( q ) = 0.5 * si::meter; + fusion::at_c< 0 >( p ) = 2.0 * si::meter_per_second; + fusion::at_c< 1 >( p ) = -1.0 * si::meter_per_second; + stepper_type stepper; + stepper.do_step( ode_units() , std::make_pair( boost::ref( q ) , boost::ref( p ) ) , 0.0 * si::second , 0.01 * si::second ); + BOOST_CHECK_EQUAL( ode_call_count , size_t( 2 ) ); +} + + +BOOST_AUTO_TEST_SUITE_END() |