diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-04-08 03:09:47 +0000 |
---|---|---|
committer | <> | 2015-05-05 14:37:32 +0000 |
commit | f2541bb90af059680aa7036f315f052175999355 (patch) | |
tree | a5b214744b256f07e1dc2bd7273035a7808c659f /libs/numeric/odeint/test | |
parent | ed232fdd34968697a68783b3195b1da4226915b5 (diff) | |
download | boost-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_58_0.tar.bz2.HEADboost_1_58_0master
Diffstat (limited to 'libs/numeric/odeint/test')
17 files changed, 700 insertions, 30 deletions
diff --git a/libs/numeric/odeint/test/Jamfile.v2 b/libs/numeric/odeint/test/Jamfile.v2 index f89886624..efa35a578 100644 --- a/libs/numeric/odeint/test/Jamfile.v2 +++ b/libs/numeric/odeint/test/Jamfile.v2 @@ -6,18 +6,25 @@ # 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 - <library>/boost/test//boost_unit_test_framework <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 + # <cxxflags>-D_SCL_SECURE_NO_WARNINGS ; test-suite "odeint" @@ -74,12 +81,16 @@ test-suite "odeint" [ compile unwrap_boost_reference.cpp ] [ compile unwrap_reference.cpp : <cxxflags>-std=c++0x : unwrap_reference_C++11 ] [ compile-fail unwrap_reference.cpp : <cxxflags>-std=c++98 : unwrap_reference_C++98 ] - : <testing.launcher>valgrind + [ 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 ] diff --git a/libs/numeric/odeint/test/adams_bashforth.cpp b/libs/numeric/odeint/test/adams_bashforth.cpp index 91c2b8765..f7e5e2bf2 100644 --- a/libs/numeric/odeint/test/adams_bashforth.cpp +++ b/libs/numeric/odeint/test/adams_bashforth.cpp @@ -69,14 +69,14 @@ public: size_t do_count; template< class System , class StateIn , class DerivIn , class StateOut > - void do_step( System system , const StateIn &in , const DerivIn &dxdt , value_type t , StateOut &out , value_type dt ) + 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( System system , StateInOut &x , const DerivIn &dxdt , value_type t , value_type dt ) + 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; diff --git a/libs/numeric/odeint/test/bulirsch_stoer.cpp b/libs/numeric/odeint/test/bulirsch_stoer.cpp index 000121308..2c6a0c95a 100644 --- a/libs/numeric/odeint/test/bulirsch_stoer.cpp +++ b/libs/numeric/odeint/test/bulirsch_stoer.cpp @@ -131,7 +131,25 @@ BOOST_AUTO_TEST_CASE( test_bulirsch_stoer ) 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::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/libs/numeric/odeint/test/default_operations.cpp b/libs/numeric/odeint/test/default_operations.cpp index 2b6a7559f..a2634b7fe 100644 --- a/libs/numeric/odeint/test/default_operations.cpp +++ b/libs/numeric/odeint/test/default_operations.cpp @@ -229,12 +229,6 @@ 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; - typedef typename fix_type::time_2_type time_2_type; - typedef typename fix_type::time_3_type time_3_type; - typedef typename fix_type::time_4_type time_4_type; - typedef typename fix_type::time_5_type time_5_type; - typedef typename fix_type::time_6_type time_6_type; - typedef typename fix_type::time_7_type time_7_type; fix_type f; typedef default_operations::scale_sum2< value_type , time_type > Op; @@ -249,11 +243,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( scale_sum3_units_test , T , test_types ) 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; - typedef typename fix_type::time_3_type time_3_type; - typedef typename fix_type::time_4_type time_4_type; - typedef typename fix_type::time_5_type time_5_type; - typedef typename fix_type::time_6_type time_6_type; - typedef typename fix_type::time_7_type time_7_type; fix_type f; typedef default_operations::scale_sum3< value_type , time_type , time_2_type > Op; diff --git a/libs/numeric/odeint/test/dummy_odes.hpp b/libs/numeric/odeint/test/dummy_odes.hpp index 0797b276c..7a92363f6 100644 --- a/libs/numeric/odeint/test/dummy_odes.hpp +++ b/libs/numeric/odeint/test/dummy_odes.hpp @@ -55,6 +55,20 @@ struct constant_system_functor_fusion } }; +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 ) { diff --git a/libs/numeric/odeint/test/integrate_implicit.cpp b/libs/numeric/odeint/test/integrate_implicit.cpp index e1584c247..4bff200ae 100644 --- a/libs/numeric/odeint/test/integrate_implicit.cpp +++ b/libs/numeric/odeint/test/integrate_implicit.cpp @@ -106,7 +106,7 @@ struct perform_integrate_const_test 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>(floor(t_end/dt))+1 ); + 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 ) { diff --git a/libs/numeric/odeint/test/numeric/Jamfile.v2 b/libs/numeric/odeint/test/numeric/Jamfile.v2 index 9797900c3..1915a3259 100644 --- a/libs/numeric/odeint/test/numeric/Jamfile.v2 +++ b/libs/numeric/odeint/test/numeric/Jamfile.v2 @@ -28,5 +28,8 @@ test-suite "odeint" [ run rosenbrock.cpp ] [ run adams_bashforth.cpp ] [ run adams_bashforth_moulton.cpp ] + [ run abm_time_dependent.cpp ] + [ run order_quadrature_formula.cpp ] + [ run velocity_verlet.cpp ] : <testing.launcher>valgrind ; diff --git a/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp b/libs/numeric/odeint/test/numeric/abm_time_dependent.cpp new file mode 100644 index 000000000..019a17d6c --- /dev/null +++ b/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/libs/numeric/odeint/test/numeric/adams_bashforth.cpp b/libs/numeric/odeint/test/numeric/adams_bashforth.cpp index 3078f51ba..ca8a6cee9 100644 --- a/libs/numeric/odeint/test/numeric/adams_bashforth.cpp +++ b/libs/numeric/odeint/test/numeric/adams_bashforth.cpp @@ -1,7 +1,7 @@ /* Boost numeric test of the adams-bashforth steppers test file Copyright 2013 Karsten Ahnert - Copyright 2013 Mario Mulansky + Copyright 2013-2015 Mario Mulansky Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or @@ -34,7 +34,6 @@ 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 @@ -56,7 +55,6 @@ struct perform_adams_bashforth_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 }}; @@ -64,8 +62,7 @@ struct perform_adams_bashforth_test double t = 0.0; double dt = 0.2; // 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 ); + 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 @@ -79,14 +76,16 @@ struct perform_adams_bashforth_test // 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; + 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( boost::ref(init_stepper) , osc() , x1 , t , dt ); + 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 diff --git a/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp b/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp new file mode 100644 index 000000000..bdf2ae462 --- /dev/null +++ b/libs/numeric/odeint/test/numeric/order_quadrature_formula.cpp @@ -0,0 +1,191 @@ +/* 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/test/unit_test.hpp> + +#include <boost/mpl/vector.hpp> + +#include <boost/numeric/odeint.hpp> + +#include <boost/numeric/ublas/vector.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/libs/numeric/odeint/test/numeric/rosenbrock.cpp b/libs/numeric/odeint/test/numeric/rosenbrock.cpp index 0bb83650b..2b6a26788 100644 --- a/libs/numeric/odeint/test/numeric/rosenbrock.cpp +++ b/libs/numeric/odeint/test/numeric/rosenbrock.cpp @@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE( rosenbrock4_numeric_test ) double dt = 0.5; stepper.do_step( std::make_pair( sys() , jacobi() ) , x0 , 0.0 , x1 , dt ); - const double f = 2.0 * std::abs( sin(dt) - x1(0) ) / std::pow( dt , o ); + const double f = 2.0 * std::abs( std::sin(dt) - x1(0) ) / std::pow( dt , o ); std::cout << o << " , " << f << std::endl; @@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE( rosenbrock4_numeric_test ) { 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( sin(dt) - x1(0) ) , f*std::pow( dt , o ) ); + BOOST_CHECK_SMALL( std::abs( std::sin(dt) - x1(0) ) , f*std::pow( dt , o ) ); dt *= 0.5; } } diff --git a/libs/numeric/odeint/test/numeric/runge_kutta.cpp b/libs/numeric/odeint/test/numeric/runge_kutta.cpp index 7e149bf05..a71701bde 100644 --- a/libs/numeric/odeint/test/numeric/runge_kutta.cpp +++ b/libs/numeric/odeint/test/numeric/runge_kutta.cpp @@ -26,6 +26,7 @@ #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; @@ -142,7 +143,11 @@ 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 > + 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 ) @@ -156,7 +161,11 @@ 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 > + 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 ) diff --git a/libs/numeric/odeint/test/numeric/velocity_verlet.cpp b/libs/numeric/odeint/test/numeric/velocity_verlet.cpp new file mode 100644 index 000000000..5ac77807b --- /dev/null +++ b/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/libs/numeric/odeint/test/regression/Jamfile.v2 b/libs/numeric/odeint/test/regression/Jamfile.v2 new file mode 100644 index 000000000..e44b5354a --- /dev/null +++ b/libs/numeric/odeint/test/regression/Jamfile.v2 @@ -0,0 +1,29 @@ +# 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 : <cxxflags>-std=c++0x ] + : <testing.launcher>valgrind + ; diff --git a/libs/numeric/odeint/test/regression/regression_147.cpp b/libs/numeric/odeint/test/regression/regression_147.cpp new file mode 100644 index 000000000..7373782df --- /dev/null +++ b/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/libs/numeric/odeint/test/regression/regression_149.cpp b/libs/numeric/odeint/test/regression/regression_149.cpp new file mode 100644 index 000000000..a61082b30 --- /dev/null +++ b/libs/numeric/odeint/test/regression/regression_149.cpp @@ -0,0 +1,84 @@ +/* + + [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 ); + + auto iter = boost::find_if( + make_adaptive_time_range( stepper, rhs, x, 0.0, 1.0, 0.01 ), + []( const std::pair< const state_type &, double > &x ) + { return ( x.first[0] < 0.0 ); } ); + + 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/libs/numeric/odeint/test/std_array.cpp b/libs/numeric/odeint/test/std_array.cpp new file mode 100644 index 000000000..350a387a8 --- /dev/null +++ b/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() |