From 1eefa78c96a0f103407e956d513cf2387f5899fa Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Wed, 9 Dec 2015 12:09:39 +0100 Subject: [PATCH 01/65] Bugfix for #144 also in const version Issue #144 has been fixed some time ago, but only for the non-const ref do_step interface. This fixes also the const ref interface implementation. --- .../boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp index 2f7cc4c6..c41f572a 100644 --- a/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp @@ -175,7 +175,7 @@ private: { m_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_impl< StateInOut > , detail::ref( *this ) , detail::_1 ) ); m_adams_bashforth.do_step( system , in , t , m_x.m_v , dt ); - m_adams_moulton.do_step( system , in , m_x.m_v , t , out , dt , m_adams_bashforth.step_storage() ); + m_adams_moulton.do_step( system , in , m_x.m_v , t+dt , out , dt , m_adams_bashforth.step_storage() ); } else { From 9d02efbff2ecbe658db6a6d3375e0e7ab80685f7 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Wed, 9 Dec 2015 12:51:50 +0100 Subject: [PATCH 02/65] added reset to adams bashforth moulton The ABM stepper was missing reset functionality, see #182 --- .../odeint/stepper/adams_bashforth_moulton.hpp | 11 +++++++++++ test/adams_bashforth.cpp | 7 ++++++- test/adams_bashforth_moulton.cpp | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp index c41f572a..f3edce19 100644 --- a/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adams_bashforth_moulton.hpp @@ -150,6 +150,12 @@ public : } + void reset(void) + { + m_adams_bashforth.reset(); + } + + private: @@ -293,6 +299,11 @@ private: * \param dt The step size. */ + /** + * \fn adams_bashforth_moulton::reset( void ) + * \brief Resets the internal buffers of the stepper. + */ + } // odeint } // numeric diff --git a/test/adams_bashforth.cpp b/test/adams_bashforth.cpp index f7e5e2bf..7574346c 100644 --- a/test/adams_bashforth.cpp +++ b/test/adams_bashforth.cpp @@ -208,8 +208,13 @@ BOOST_AUTO_TEST_CASE( test_auto_initialization ) 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( 2 ) ); + 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 ) diff --git a/test/adams_bashforth_moulton.cpp b/test/adams_bashforth_moulton.cpp index c821ac79..8e7688bb 100644 --- a/test/adams_bashforth_moulton.cpp +++ b/test/adams_bashforth_moulton.cpp @@ -104,8 +104,8 @@ BOOST_AUTO_TEST_CASE( test_instantiation ) 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 ); +// s7.do_step( lorenz() , x , t , dt ); +// s8.do_step( lorenz() , x , t , dt ); } From a569bdc0c5afc07b3dd4ed55fa31e185b4c49008 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Thu, 10 Dec 2015 17:18:09 +0100 Subject: [PATCH 03/65] fixing #183 --- include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp index 4b908333..2c612799 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -282,7 +282,7 @@ public: { m_current_k_opt = min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast(m_k_max-1) , static_cast(m_current_k_opt)+1 ); new_h = h_opt[k]; - new_h *= m_cost[m_current_k_opt]/m_cost[k]; + new_h *= static_cast(m_cost[m_current_k_opt])/static_cast(m_cost[k]); } else new_h = h_opt[m_current_k_opt]; break; From eb2804b2819a1dbb569b83efe03d4db529984a1f Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Thu, 10 Dec 2015 17:22:44 +0100 Subject: [PATCH 04/65] resetting optimal order when resetting BS stepper addressing #184, simple fix is to also reset m_current_k_opt and therefore make sure the loop doesnt overshoot. --- .../numeric/odeint/stepper/bulirsch_stoer.hpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp index 2c612799..4f5bcda7 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -117,16 +117,8 @@ public: const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); m_coeff[i][k] = 1.0 / ( r*r - static_cast< value_type >( 1.0 ) ); // coefficients for extrapolation } - - // crude estimate of optimal order - - m_current_k_opt = 4; - /* no calculation because log10 might not exist for value_type! - const value_type logfact( -log10( max BOOST_PREVENT_MACRO_SUBSTITUTION( eps_rel , static_cast< value_type >(1.0E-12) ) ) * 0.6 + 0.5 ); - m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast( 1 ) , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast( m_k_max-1 ) , logfact )); - */ } - + reset(); } @@ -344,6 +336,12 @@ public: { m_first = true; m_last_step_rejected = false; + // crude estimate of optimal order + m_current_k_opt = 4; + /* no calculation because log10 might not exist for value_type! + const value_type logfact( -log10( max BOOST_PREVENT_MACRO_SUBSTITUTION( eps_rel , static_cast< value_type >(1.0E-12) ) ) * 0.6 + 0.5 ); + m_current_k_opt = max BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast( 1 ) , min BOOST_PREVENT_MACRO_SUBSTITUTION( static_cast( m_k_max-1 ) , logfact )); + */ } From cc8c9772ac7894f5170ca69bf3e748a9f22885d5 Mon Sep 17 00:00:00 2001 From: Martin Langer Date: Fri, 18 Dec 2015 15:32:48 +0100 Subject: [PATCH 05/65] table for precomputed facmin in bulirsch_stoer --- include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp index 4f5bcda7..7a97960d 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -98,6 +98,7 @@ public: m_interval_sequence( m_k_max+1 ) , m_coeff( m_k_max+1 ) , m_cost( m_k_max+1 ) , + m_facmin_table( m_k_max+1 ) , m_table( m_k_max ) , STEPFAC1( 0.65 ) , STEPFAC2( 0.94 ) , STEPFAC3( 0.02 ) , STEPFAC4( 4.0 ) , KFAC1( 0.8 ) , KFAC2( 0.9 ) { @@ -112,6 +113,7 @@ public: else m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; m_coeff[i].resize(i); + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , 1.0 / static_cast< value_type > ( 2*i+1 ) ); for( size_t k = 0 ; k < i ; ++k ) { const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); @@ -415,7 +417,7 @@ private: BOOST_USING_STD_MAX(); using std::pow; value_type expo( 1.0/(2*k+1) ); - value_type facmin = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , expo ); + value_type facmin = m_facmin_table[k]; value_type fac; if (error == 0.0) fac=1.0/facmin; @@ -504,6 +506,7 @@ private: int_vector m_interval_sequence; // stores the successive interval counts value_matrix m_coeff; int_vector m_cost; // costs for interval count + value_vector m_facmin_table // for precomputed facmin to save pow calls state_table_type m_table; // sequence of states for extrapolation From 607bb768ba8b0c2a019990a092a42544a9ee57ba Mon Sep 17 00:00:00 2001 From: Martin Langer Date: Fri, 18 Dec 2015 15:40:53 +0100 Subject: [PATCH 06/65] table for precomputed facmin in bulirsch_stoer_dense_out --- .../numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index d876ca3d..ff448cc2 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -110,6 +110,7 @@ public: m_interval_sequence( m_k_max+1 ) , m_coeff( m_k_max+1 ) , m_cost( m_k_max+1 ) , + m_facmin_table( m_k_max+1 ) , m_table( m_k_max ) , m_mp_states( m_k_max+1 ) , m_derivs( m_k_max+1 ) , @@ -129,6 +130,7 @@ public: else m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; m_coeff[i].resize(i); + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , 1.0 / static_cast< value_type > ( 2*i+1 ) ); for( size_t k = 0 ; k < i ; ++k ) { const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); @@ -429,7 +431,7 @@ private: using std::pow; value_type expo = static_cast(1)/(m_interval_sequence[k-1]); - value_type facmin = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , expo ); + value_type facmin = m_facmin_table[k]; value_type fac; if (error == 0.0) fac = static_cast(1)/facmin; @@ -692,6 +694,7 @@ private: int_vector m_interval_sequence; // stores the successive interval counts value_matrix m_coeff; int_vector m_cost; // costs for interval count + value_vector m_facmin_table // for precomputed facmin to save pow calls state_vector_type m_table; // sequence of states for extrapolation From 61a74d2bfc915ed76bd6cdb5b188e9d2967c70e1 Mon Sep 17 00:00:00 2001 From: Martin Langer Date: Fri, 18 Dec 2015 16:14:48 +0100 Subject: [PATCH 07/65] fixed missing semicolon --- include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp | 2 +- .../boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp index 7a97960d..aad52e0c 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -506,7 +506,7 @@ private: int_vector m_interval_sequence; // stores the successive interval counts value_matrix m_coeff; int_vector m_cost; // costs for interval count - value_vector m_facmin_table // for precomputed facmin to save pow calls + value_vector m_facmin_table; // for precomputed facmin to save pow calls state_table_type m_table; // sequence of states for extrapolation diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index ff448cc2..44d4c06c 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -694,7 +694,7 @@ private: int_vector m_interval_sequence; // stores the successive interval counts value_matrix m_coeff; int_vector m_cost; // costs for interval count - value_vector m_facmin_table // for precomputed facmin to save pow calls + value_vector m_facmin_table; // for precomputed facmin to save pow calls state_vector_type m_table; // sequence of states for extrapolation From 0f943fbf8b303a8083876bb1fba677d4c4677417 Mon Sep 17 00:00:00 2001 From: Martin Langer Date: Sun, 27 Dec 2015 22:42:33 +0100 Subject: [PATCH 08/65] fixed wrong precomputation in BS dense stepper --- .../boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index 44d4c06c..5f5d5e3d 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -130,7 +130,7 @@ public: else m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; m_coeff[i].resize(i); - m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , 1.0 / static_cast< value_type > ( 2*i+1 ) ); + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast(1)/(m_interval_sequence[i-1]) ); for( size_t k = 0 ; k < i ; ++k ) { const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); From a625f532b158fc4aa853467c9b6d2d0c9d0dd3b2 Mon Sep 17 00:00:00 2001 From: Martin Langer Date: Mon, 28 Dec 2015 12:04:39 +0100 Subject: [PATCH 09/65] corrected rushed fix --- .../numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index 5f5d5e3d..6b26a8c4 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -126,11 +126,16 @@ public: m_interval_sequence[i] = 2 + 4*i; // 2 6 10 14 ... m_derivs[i].resize( m_interval_sequence[i] ); if( i == 0 ) + { m_cost[i] = m_interval_sequence[i]; + m_facmin_table[0] = 1; // never to be used + } else + { + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast(1)/(m_interval_sequence[i-1]) ); m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; + } m_coeff[i].resize(i); - m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast(1)/(m_interval_sequence[i-1]) ); for( size_t k = 0 ; k < i ; ++k ) { const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); From cc9b1963e734b017930d6740732f0fa4216a5b16 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Mon, 28 Dec 2015 15:26:00 +0100 Subject: [PATCH 10/65] BS stepper: correct exponents for optimal h Becoming suspicious by the difference of the exponents used for computing the new step size in the BS and BS denseout stepper (see 0f943fbf8b303a8083876bb1fba677d4c4677417) I checked again the Hairer book and I'm now convinced there was a mistake in our implementation and both steppers should use 1/(2*k+1) as exponent. The background is the this exponent represents the order of the error of the k-th iteration, and this order is always 2k+1, independent of the interval_sequence. This error is computed from the difference of the k-th and k-1 - th iteration, which have the orders 2k+2 2k respectively, which means the computed error has order 2k+1. --- include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp | 2 +- .../numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp index aad52e0c..02c37492 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer.hpp @@ -113,7 +113,7 @@ public: else m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; m_coeff[i].resize(i); - m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , 1.0 / static_cast< value_type > ( 2*i+1 ) ); + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast< value_type >(1) / static_cast< value_type >( 2*i+1 ) ); for( size_t k = 0 ; k < i ; ++k ) { const value_type r = static_cast< value_type >( m_interval_sequence[i] ) / static_cast< value_type >( m_interval_sequence[k] ); diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index 6b26a8c4..6a1eed15 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -128,13 +128,11 @@ public: if( i == 0 ) { m_cost[i] = m_interval_sequence[i]; - m_facmin_table[0] = 1; // never to be used - } - else + } else { - m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast(1)/(m_interval_sequence[i-1]) ); m_cost[i] = m_cost[i-1] + m_interval_sequence[i]; } + m_facmin_table[i] = pow BOOST_PREVENT_MACRO_SUBSTITUTION( STEPFAC3 , static_cast< value_type >(1) / static_cast< value_type >( 2*i+1 ) ); m_coeff[i].resize(i); for( size_t k = 0 ; k < i ; ++k ) { From 31c29dd9486c78d1ec4c0eac7b95e7d34a21362e Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Tue, 19 Jan 2016 15:37:50 +0100 Subject: [PATCH 11/65] fixes #189 A bug introduced with the recent max_dt facility prevented the rosenbrock controller to increase step size in most cases (if max_dt=0). This is fixed now, and a regression test case has been added. --- .../odeint/stepper/rosenbrock4_controller.hpp | 2 + test/regression/Jamfile.v2 | 1 + test/regression/regression_189.cpp | 71 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 test/regression/regression_189.cpp diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp index 0e5edd32..61d6e511 100644 --- a/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp +++ b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp @@ -163,6 +163,8 @@ public: if( m_max_dt != static_cast(0) ) { dt = detail::min_abs(m_max_dt, dt_new); + } else { + dt = dt_new; } m_last_rejected = false; return success; diff --git a/test/regression/Jamfile.v2 b/test/regression/Jamfile.v2 index 25bbf0c1..4f64698b 100644 --- a/test/regression/Jamfile.v2 +++ b/test/regression/Jamfile.v2 @@ -26,5 +26,6 @@ test-suite "odeint" [ run regression_147.cpp ] [ compile regression_149.cpp : -std=c++0x ] [ run regression_168.cpp ] + [ run regression_189.cpp ] : valgrind ; diff --git a/test/regression/regression_189.cpp b/test/regression/regression_189.cpp new file mode 100644 index 00000000..dbd88ac8 --- /dev/null +++ b/test/regression/regression_189.cpp @@ -0,0 +1,71 @@ +/* + + [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 + +#include +#include +#include + +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 + BOOST_CHECK_EQUAL( num_of_steps , 74 ); + + 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" ); + + BOOST_CHECK_EQUAL( num_of_steps2 , 1531 ); +} From b816e93fcfd099fdd33e9f3caa6dc5d57b83f8d7 Mon Sep 17 00:00:00 2001 From: Karsten Ahnert Date: Fri, 1 Apr 2016 21:39:42 +0200 Subject: [PATCH 12/65] fixing #12107 --- include/boost/numeric/odeint/integrate/integrate_n_steps.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp b/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp index 7f3a49bd..5cc8aa0e 100644 --- a/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp +++ b/include/boost/numeric/odeint/integrate/integrate_n_steps.hpp @@ -23,6 +23,7 @@ #include #include #include +#include namespace boost { namespace numeric { From f1255a83196d1b69b1b81d7eec9b77d9281682cd Mon Sep 17 00:00:00 2001 From: Tim Keitt Date: Thu, 26 Jan 2017 12:05:53 -0600 Subject: [PATCH 13/65] Fix unused variable warning --- include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp index 8ae627fe..aac2b02d 100644 --- a/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp @@ -143,7 +143,7 @@ public: error = max BOOST_PREVENT_MACRO_SUBSTITUTION ( static_cast( pow( static_cast(5.0) , -static_cast(stepper_order) ) ) , error); - time_type dt_old = dt; + // time_type dt_old = dt; unused variable warning //error too small - increase dt and keep the evolution and limit scaling factor to 5.0 dt *= static_cast(9)/static_cast(10) * pow(error, static_cast(-1) / stepper_order); From 850fa824ebff9e94a2c1420768cc31ad003ecc32 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Thu, 26 Jan 2017 21:48:39 -0800 Subject: [PATCH 14/65] Add no-unused-local-typedef to Jenkins build This adds the flag -Wno-unused-local-typedef to the global build options on Jenkins to shorten the log file for the clang build when building Boost. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d97c457..0dc65c01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ addons: env: - CXXSTD="" - - CXXSTD="cxxflags='-std=c++0x'" + - CXXSTD="-std=c++0x" # For now disable gcc on osx as g++4.8 is not yet available matrix: @@ -45,4 +45,4 @@ before_install: - $CC --version script: - - $BOOST_ROOT/b2 toolset=$CC $CXXSTD \ No newline at end of file + - $BOOST_ROOT/b2 toolset=$CC cxxflags='-Wno-unused-local-typedef $CXXSTD' \ No newline at end of file From 5d3b01395546ea55068007a60373eadb88cba69d Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 12:40:31 -0700 Subject: [PATCH 15/65] Update Boost on Travis, fix bug with boost 1.63 --- .travis.yml | 11 ++++------- test/numeric/order_quadrature_formula.cpp | 2 ++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0dc65c01..85f94940 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,14 +28,11 @@ matrix: compiler: gcc before_install: -# 1.55: http://sourceforge.net/projects/boost/files/boost/1.55.0/boost_1_55_0.tar.bz2/download -# 1.57: http://sourceforge.net/projects/boost/files/boost/1.57.0/boost_1_57_0.tar.bz2/download # 1.58: http://downloads.sourceforge.net/project/boost/boost/1.58.0/boost_1_58_0.tar.bz2\?r\=\&ts\=1435589970\&use_mirror\=garr - - wget http://downloads.sourceforge.net/project/boost/boost/1.58.0/boost_1_58_0.tar.bz2\?r\=\&ts\=1435589970\&use_mirror\=garr -O /tmp/boost.tar.bz2 +# 1.63: https://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2/download?use_mirror=superb-dca2 + - wget https://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2/download?use_mirror=superb-dca2 -O /tmp/boost.tar.bz2 - tar jxf /tmp/boost.tar.bz2 - - mv boost_1_58_0 $PWD/boost-trunk -# patch the boost build system - not neccessary with 1.58 anymore -# - patch $PWD/boost-trunk/tools/build/v2/build/toolset.jam toolset.jam.patch + - mv boost_1_63_0 $PWD/boost-trunk - export BOOST_ROOT="$PWD/boost-trunk" - cd $BOOST_ROOT @@ -45,4 +42,4 @@ before_install: - $CC --version script: - - $BOOST_ROOT/b2 toolset=$CC cxxflags='-Wno-unused-local-typedef $CXXSTD' \ No newline at end of file + - $BOOST_ROOT/b2 toolset=$CC cxxflags='$CXXSTD' \ No newline at end of file diff --git a/test/numeric/order_quadrature_formula.cpp b/test/numeric/order_quadrature_formula.cpp index bdf2ae46..923183ff 100644 --- a/test/numeric/order_quadrature_formula.cpp +++ b/test/numeric/order_quadrature_formula.cpp @@ -20,6 +20,8 @@ #include #include +#include "boost/format.hpp" + #include #include From dd54cbf031c9b52a88be4602ea7e632eff68bf82 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 12:51:53 -0700 Subject: [PATCH 16/65] Fix Badge in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 735afd52..23e4f88b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/headmyshoulder/odeint-v2/trend.png)](https://bitdeli.com/free "Bitdeli Badge") +[![Build Status](https://travis-ci.org/headmyshoulder/odeint-v2.svg?branch=master)](https://travis-ci.org/headmyshoulder/odeint-v2) odeint is a highly flexible library for solving ordinary differential equations. From a452f6e8167379528b25880a1029cfcdeb458bbb Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 13:07:10 -0700 Subject: [PATCH 17/65] Fix `abs` warnings and clang compiler warning flag --- Jamroot | 2 +- test/runge_kutta_concepts.cpp | 1 + test/runge_kutta_controlled_concepts.cpp | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Jamroot b/Jamroot index 6476f9a9..03ad4f0a 100644 --- a/Jamroot +++ b/Jamroot @@ -15,7 +15,7 @@ project : requirements include&&$(BOOST_ROOT) gcc:"-Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unknown-pragmas -Wno-unused-local-typedefs" - clang:"-Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedefs" + clang:"-Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedef" intel:"-ipo" ; diff --git a/test/runge_kutta_concepts.cpp b/test/runge_kutta_concepts.cpp index a16b04fd..42235dea 100644 --- a/test/runge_kutta_concepts.cpp +++ b/test/runge_kutta_concepts.cpp @@ -88,6 +88,7 @@ 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; diff --git a/test/runge_kutta_controlled_concepts.cpp b/test/runge_kutta_controlled_concepts.cpp index 2132b092..7f70cc53 100644 --- a/test/runge_kutta_controlled_concepts.cpp +++ b/test/runge_kutta_controlled_concepts.cpp @@ -87,6 +87,7 @@ 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; @@ -134,6 +135,7 @@ 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; From ff3fd556cba6153fcca28759db5237b65020fa25 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 13:27:57 -0700 Subject: [PATCH 18/65] Fix compiler warnings, activate parallel CI build --- .travis.yml | 2 +- Jamroot | 2 +- test/regression/regression_189.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85f94940..598074c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,4 +42,4 @@ before_install: - $CC --version script: - - $BOOST_ROOT/b2 toolset=$CC cxxflags='$CXXSTD' \ No newline at end of file + - $BOOST_ROOT/b2 toolset=$CC cxxflags='$CXXSTD' -j4 \ No newline at end of file diff --git a/Jamroot b/Jamroot index 03ad4f0a..9b22377b 100644 --- a/Jamroot +++ b/Jamroot @@ -15,7 +15,7 @@ project : requirements include&&$(BOOST_ROOT) gcc:"-Wall -Wno-unused-parameter -Wno-unused-variable -Wno-unknown-pragmas -Wno-unused-local-typedefs" - clang:"-Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedef" + clang:"-Wall -Wextra -Wno-unknown-warning-option -Wno-unused-function -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedef" intel:"-ipo" ; diff --git a/test/regression/regression_189.cpp b/test/regression/regression_189.cpp index dbd88ac8..54530072 100644 --- a/test/regression/regression_189.cpp +++ b/test/regression/regression_189.cpp @@ -59,13 +59,14 @@ BOOST_AUTO_TEST_CASE( regression_189 ) 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 - BOOST_CHECK_EQUAL( num_of_steps , 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" ); - - BOOST_CHECK_EQUAL( num_of_steps2 , 1531 ); + num_of_steps_expected = 1531; + BOOST_CHECK_EQUAL( num_of_steps2 , num_of_steps_expected ); } From 53d15cc83a09e2ba57ea3420b1c637c4e8b1c611 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 13:46:30 -0700 Subject: [PATCH 19/65] Use 2 cores on Travis, not 4 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 598074c8..7d723fb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,8 @@ before_install: - ./bootstrap.sh - cd $TRAVIS_BUILD_DIR - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$CC" = "gcc" ]; then export CC=gcc-4.8; fi + - echo "Toolset: ${CC}" - $CC --version script: - - $BOOST_ROOT/b2 toolset=$CC cxxflags='$CXXSTD' -j4 \ No newline at end of file + - $BOOST_ROOT/b2 toolset=$CC cxxflags='$CXXSTD' -j2 \ No newline at end of file From 3a83fdbd8f312ba62e0097fc762e9492904bbfd3 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 13:51:50 -0700 Subject: [PATCH 20/65] Fix travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7d723fb6..df24254b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ before_install: - ./bootstrap.sh - cd $TRAVIS_BUILD_DIR - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$CC" = "gcc" ]; then export CC=gcc-4.8; fi - - echo "Toolset: ${CC}" + - echo "Toolset: $CC" - $CC --version script: From f0469a2fb6d707d184fb07cc072aa179d0b31579 Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sun, 7 May 2017 13:57:31 -0700 Subject: [PATCH 21/65] Fix travis config 2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index df24254b..118d3c0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ before_install: - ./bootstrap.sh - cd $TRAVIS_BUILD_DIR - if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$CC" = "gcc" ]; then export CC=gcc-4.8; fi - - echo "Toolset: $CC" + - echo $CC - $CC --version script: From 491df811e327e6d121839b44d14bbefe09904780 Mon Sep 17 00:00:00 2001 From: Denis Demidov Date: Wed, 10 May 2017 11:35:07 +0300 Subject: [PATCH 22/65] Provide algebra dispatcher for boost::multi_array Fixes #205 --- .../odeint/algebra/multi_array_algebra.hpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp b/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp index 0bc476e6..f0ae30e4 100644 --- a/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp +++ b/include/boost/numeric/odeint/algebra/multi_array_algebra.hpp @@ -19,6 +19,8 @@ #define BOOST_NUMERIC_ODEINT_ALGEBRA_MULTI_ARRAY_ALGEBRA_HPP_DEFINED +#include + #include #include #include @@ -121,7 +123,7 @@ struct multi_array_algebra { detail::for_each15( s1.data() , s1.data() + s1.num_elements() , s2.data() , s3.data() , s4.data() , s5.data() , s6.data() , s7.data() , s8.data() , s9.data() , s10.data() , s11.data() , s12.data() , s13.data() , s14.data() , s15.data() , op ); } - + template< typename S > static typename norm_result_type::type norm_inf( const S &s ) { @@ -129,15 +131,11 @@ struct multi_array_algebra } }; -// template< class T , size_t N > -// struct algebra_dispatcher< boost::array< T , N > > -// { -// typedef array_algebra algebra_type; -// }; - - - - +template< class T , size_t N > +struct algebra_dispatcher< boost::multi_array< T , N > > +{ + typedef multi_array_algebra algebra_type; +}; } // namespace odeint From 6a00e946f71ee6b2b4d8e1d5a8137b9ffd8159ac Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 23 May 2017 09:29:37 +0200 Subject: [PATCH 23/65] Initial commit from Bitbucket to Github --- .../stepper/adaptive_adams_bashforth.hpp | 131 +++++++++++++ .../odeint/stepper/adaptive_adams_moulton.hpp | 79 ++++++++ .../controlled_adams_bashforth_moulton.hpp | 178 ++++++++++++++++++ .../detail/adaptive_adams_coefficients.hpp | 134 +++++++++++++ .../stepper/detail/pid_step_adjuster.hpp | 73 +++++++ .../odeint/stepper/detail/polynomial.hpp | 137 ++++++++++++++ 6 files changed, 732 insertions(+) create mode 100644 include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp create mode 100644 include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp create mode 100644 include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp create mode 100644 include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp create mode 100644 include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp create mode 100644 include/boost/numeric/odeint/stepper/detail/polynomial.hpp diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp new file mode 100644 index 00000000..fdbaeedb --- /dev/null +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -0,0 +1,131 @@ +#ifndef STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED +#define STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED + +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +namespace boost { +namespace numeric { +namespace odeint { + +template< +size_t Steps, +class State, +class Value, +class Deriv = State, +class Time = Value, +class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< State >::operations_type , +class Resizer = initially_resizer +> +class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operations > +{ + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order = steps; + + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + typedef stepper_tag stepper_category; + + typedef detail::adaptive_adams_coefficients coeff_type; + + typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; + + adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) + :algebra_stepper_base_type( algebra ) , + m_dxdt_resizer(), m_xnew_resizer() + {}; + + template + void do_step(System system, state_type & inOut, time_type t, time_type dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, m_xnew, dt); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; + + template + void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + system(in, m_dxdt.m_v, t); + m_coeff.step(m_dxdt.m_v, t); + m_coeff.confirm(); + + do_step_impl(m_coeff, in, t, out, dt); + }; + + void do_step_impl(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type dt) + { + coeff.poly.reset(); + out = in; + + // integrating + for(size_t i=0; i0) + { + coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); + } + + time_type c = coeff.poly.evaluate_integrated(dt); + coeff.m_c[i] = c; + + // predict next state + this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, typename Operations::template scale_sum2(1.0, c)); + } + }; + + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; + + resizer_type m_dxdt_resizer; + resizer_type m_xnew_resizer; + + coeff_type m_coeff; + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp new file mode 100644 index 00000000..063ba325 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -0,0 +1,79 @@ +#ifndef STEPPER_ADAMS_MOULTON_HPP_INCLUDED +#define STEPPER_ADAMS_MOULTON_HPP_INCLUDED + +// helper class for controlled_adams_bashforth_moulton + +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace numeric { +namespace odeint { + +template< +size_t Steps, +class State, +class Value, +class Deriv = State, +class Time = Value, +class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< State >::operations_type , +class Resizer = initially_resizer +> +class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations > +{ + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order = steps + 1; + + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + + typedef state_wrapper wrapped_state_type; + + typedef detail::adaptive_adams_coefficients coeff_type; + + typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; + + adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ), m_coeff() + {}; + + void do_step(coeff_type & coeff, const state_type & in, + time_type t, state_type & out, time_type &dt) + { + coeff.poly.add_root(0); + out = in; + + // integrating + for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); + } + // std::cout << std::endl; + }; + + private: + coeff_type m_coeff; +}; + +} +} +} + +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp new file mode 100644 index 00000000..9a57a053 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -0,0 +1,178 @@ +#ifndef STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +namespace boost { +namespace numeric { +namespace odeint { + + + +template< +size_t Steps, +class State, +class Value, +class Deriv = State, +class Time = Value, +class StepAdjuster = detail::pid_step_adjuster, +class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< State >::operations_type , +class Resizer = initially_resizer +> +class controlled_adams_bashforth_moulton +{ + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order = steps; + + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef StepAdjuster step_adjuster_type; + typedef Resizer resizer_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + + typedef detail::adaptive_adams_coefficients coeff_type; + + typedef detail::rotating_buffer error_storage_type; + + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, StepAdjuster, Algebra, Operations, Resizer > stepper_type; + + typedef explicit_controlled_stepper_tag stepper_category; + + controlled_adams_bashforth_moulton() + :m_aab(), m_aam(m_aab.algebra()), m_coeff(), + m_xerr_resizer(), m_dxdt_resizer(), m_xnew_resizer(), + m_step_adjuster() + {}; + + controlled_adams_bashforth_moulton(const algebra_type &algebra) + :m_aab(algebra), m_aam(m_aab.algebra()), m_coeff(), + m_xerr_resizer(), m_dxdt_resizer(), m_xnew_resizer(), + m_step_adjuster() + {}; + + template + controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); + + if(res == success) + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + + return res; + }; + + template + controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + if(m_coeff.m_effective_order == 1) + { + system(in, m_dxdt.m_v, t); + + m_coeff.step(m_dxdt.m_v, t); + m_coeff.confirm(); + } + // predict + m_aab.do_step_impl(m_coeff, in, t, out, dt); + + // evaluate + system(out, m_dxdt.m_v, t + dt); + m_coeff.step(m_dxdt.m_v, t + dt); + + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + boost::numeric::odeint::copy( out, m_xerr.m_v); + + // correct + m_aam.do_step(m_coeff, in, t, out, dt); + m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(1.0, -1.0)); + + double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); + + if(ratio >= 0.9) + { + // evaluate + system(out, m_dxdt.m_v, t+dt); + m_coeff.step(m_dxdt.m_v, t+dt); + m_coeff.confirm(); + + t += dt; + dt *= ratio; + + return success; + } + else + { + dt *= ratio; + return fail; + } + }; + + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; + + aab_type m_aab; + aam_type m_aam; + + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; + + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; + wrapped_state_type m_xerr; + + coeff_type m_coeff; + + step_adjuster_type m_step_adjuster; +}; + +}}} + +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp new file mode 100644 index 00000000..ef2da350 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -0,0 +1,134 @@ +#ifndef ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED +#define ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost { +namespace numeric { +namespace odeint { +namespace detail { + +template< +size_t Steps, +class Deriv, +class Time, +class Algebra = typename algebra_dispatcher< Deriv >::algebra_type, +class Operations = typename operations_dispatcher< Deriv >::operations_type , +class Resizer = initially_resizer +> +struct adaptive_adams_coefficients +{ + public: + static const size_t steps = Steps; + + typedef Deriv deriv_type; + typedef Time time_type; + typedef state_wrapper wrapped_deriv_type; + typedef detail::rotating_buffer step_storage_type; // +1 for moulton + typedef detail::rotating_buffer time_storage_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + + typedef Resizer resizer_type; + + typedef adaptive_adams_coefficients aac_type; + typedef detail::Polynomial poly_type; + + adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) + :m_algebra(algebra), m_effective_order(1), poly(), m_resizer() + {}; + + // maybe step/tentative step are the better options + void step(const deriv_type &deriv, const time_type &t) + { + m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); + + m_tts[0] = t; + m_tss[0][0].m_v = deriv; + + for(size_t i=1; i(1/dt, -1/dt)); + } + }; + void confirm() + { + for(size_t i=0; i m_ss; + time_storage_type m_ts; + + std::array m_tss; + time_storage_type m_tts; + + size_t m_effective_order; + + private: + template< class StateType > + bool resize_tss_impl( const StateType &x ) + { + bool resized( false ); + for( size_t i=0 ; i::type() ); + + m_tts[i] = 0; + } + return resized; + }; + + resizer_type m_resizer; + algebra_type m_algebra; +}; + +} +} +} +} + +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp new file mode 100644 index 00000000..54354927 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -0,0 +1,73 @@ +#ifndef PID_STEP_ADJUSTER_HPP_INCLUDED +#define PID_STEP_ADJUSTER_HPP_INCLUDED + +#include + +#include + +namespace boost{ +namespace numeric{ +namespace odeint{ +namespace detail{ +template +struct pid_step_adjuster +{ + public: + typedef State state_type; + typedef Time time_type; + typedef rotating_buffer error_storage_type; + + pid_step_adjuster(time_type dtmax = 0.5) + :m_error_storage(), m_dtmax(dtmax), init(0) + {}; + + double adjust_stepsize(const state_type &err, const time_type &dt) + { + // basic controller + m_error_storage[0] = err; + + if(init < order-1) + { + ++init; + m_error_storage.rotate(); + return 1.0; + } + + double theta = 1.0/tol; + double ratio = 100; + double r; + + for(size_t i=0; i= m_dtmax) + { + ratio = m_dtmax / dt; + } + + if(ratio > 0.9) + { + m_error_storage.rotate(); + } + + return ratio; + }; + + private: + time_type m_dtmax; + error_storage_type m_error_storage; + size_t init; +}; + +} +} +} +} +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp new file mode 100644 index 00000000..e4e66b80 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp @@ -0,0 +1,137 @@ +#ifndef POLYNOMIAL_HPP_INCLUDED +#define POLYNOMIAL_HPP_INCLUDED + +#include +#include + +namespace boost { +namespace numeric { +namespace odeint { +namespace detail{ + +template< +size_t order, +class Time +> +class Polynomial +{ + public: + typedef Time time_type; + + Polynomial() + :m_coeff{0} + { + // start with 'constant' polynomial + m_coeff[order-1] = 1; + }; + + Polynomial(std::array coeff) + { + m_coeff = coeff; + }; + + Polynomial integrate() + { + std::array coeff_int; + coeff_int[order] = 0; + + for(size_t i=0; i polyInt(coeff_int); + return polyInt; + }; + + time_type evaluate(const time_type &t) + { + // fma: x*y+z + res = m_coeff[0]; + for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); + res = ((i >= order)?0:m_coeff[i]/(order-i)) + res * t; + } + + return res; + } + + void add_root(const time_type &root) + { + for(size_t j=0; j from_roots(time_type * roots, unsigned short num_roots) + { + time_type coeff[order] = {0}; + coeff[order-1] = 1; + + for(size_t i=0; i poly(coeff); + return poly; + }; + private: + // first element is highest order + std::array m_coeff; + time_type res; +}; +}}}} + +#endif \ No newline at end of file From 518f2186ca42881640a5e976f0ca333a6af40e05 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 24 May 2017 16:31:16 +0200 Subject: [PATCH 24/65] unittests --- test/Jamfile.v2 | 4 ++ test/adaptive_adams_bashforth.cpp | 44 +++++++++++++++ test/adaptive_adams_coefficients.cpp | 52 ++++++++++++++++++ test/controlled_adams_bashforth_moulton.cpp | 22 ++++++++ test/integrate.cpp | 6 ++- test/polynomial.cpp | 60 +++++++++++++++++++++ 6 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 test/adaptive_adams_bashforth.cpp create mode 100644 test/adaptive_adams_coefficients.cpp create mode 100644 test/controlled_adams_bashforth_moulton.cpp create mode 100644 test/polynomial.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 502ee419..a67b0054 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -48,6 +48,10 @@ test-suite "odeint" [ run adams_bashforth.cpp ] [ run adams_moulton.cpp ] [ run adams_bashforth_moulton.cpp ] + [ run adaptive_adams_bashforth.cpp ] + [ run controlled_adams_bashforth_moulton.cpp ] + [ run adaptive_adams_coefficients.cpp ] + [ run polynomial.cpp ] [ run generic_stepper.cpp ] [ run generic_error_stepper.cpp ] [ run bulirsch_stoer.cpp ] diff --git a/test/adaptive_adams_bashforth.cpp b/test/adaptive_adams_bashforth.cpp new file mode 100644 index 00000000..c0ef16c1 --- /dev/null +++ b/test/adaptive_adams_bashforth.cpp @@ -0,0 +1,44 @@ +#include +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adaptive_adams_bashforth + +#include + +#include + +#include + +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; + } +}; + +BOOST_AUTO_TEST_SUITE( adaptive_adams_bashforth_test ) + +BOOST_AUTO_TEST_CASE( test_const_int ) +{ + typedef double time_type; + typedef std::vector state_type; + + typedef adaptive_adams_bashforth<3, state_type, time_type> aab_type; + + state_type x0; + x0.push_back(0); + time_type t0 = 0.0; + time_type dt = 0.1; + + aab_type aab; + aab.do_step(const_sys(), x0, t0, dt); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp new file mode 100644 index 00000000..8183b5cc --- /dev/null +++ b/test/adaptive_adams_coefficients.cpp @@ -0,0 +1,52 @@ +#include +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_adaptive_adams_coefficients + +#include + +#include + +#include + +#include +#include +#include + +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 deriv_type; + typedef double time_type; + + typedef detail::adaptive_adams_coefficients aac; + + std::vector deriv; + deriv.push_back(-1); + + aac coeff; + for(size_t i=0; i +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_controlled_adams_bashforth_moulton + +#include + +#include + +using namespace boost::unit_test; +using namespace boost::numeric::odeint; + +BOOST_AUTO_TEST_SUITE( controlled_adams_bashforth_moulton_test ) + +BOOST_AUTO_TEST_CASE( test_init ) +{ + +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/integrate.cpp b/test/integrate.cpp index a90e8b37..d07c231c 100644 --- a/test/integrate.cpp +++ b/test/integrate.cpp @@ -54,6 +54,8 @@ #include #include +#include + #include using namespace boost::unit_test; @@ -237,7 +239,9 @@ class stepper_methods : public mpl::vector< 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 > > > + dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >, + controlled_adams_bashforth_moulton<3, state_type, value_type>, + controlled_adams_bashforth_moulton<5, state_type, value_type> //bulirsch_stoer_dense_out< state_type > > { }; diff --git a/test/polynomial.cpp b/test/polynomial.cpp new file mode 100644 index 00000000..2b1c356a --- /dev/null +++ b/test/polynomial.cpp @@ -0,0 +1,60 @@ +#include +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE odeint_polynomial + +#include + +#include + +using namespace boost::unit_test; +using namespace boost::numeric::odeint::detail; + +BOOST_AUTO_TEST_SUITE( polynomial_test ) + +BOOST_AUTO_TEST_CASE( test_init ) +{ + Polynomial<3, double> p1; + + boost::array coeff = {0, 1, 2}; + Polynomial<3, double> p2(coeff); +} +BOOST_AUTO_TEST_CASE( test_add_roots ) +{ + Polynomial<3, double> poly; + poly.add_root(1); + + poly.add_root(0); +} +BOOST_AUTO_TEST_CASE( test_copy ) +{ + +} +BOOST_AUTO_TEST_CASE( test_remove ) +{ + +} +BOOST_AUTO_TEST_CASE( test_integrate ) +{ + +} +BOOST_AUTO_TEST_CASE( test_evaluate ) +{ + boost::array c1 = {2, 1, 0}; + Polynomial<3, double> p1(c1); + + BOOST_CHECK_EQUAL(p1.evaluate(0), 0); + BOOST_CHECK_EQUAL(p1.evaluate(1), 3); + BOOST_CHECK_EQUAL(p1.evaluate(2), 10); + + boost::array c2 = {0.001, 10, 0, 3, 1}; + Polynomial<5, double> p2(c2); + + BOOST_CHECK_CLOSE(p2.evaluate(0), 1, 0.001); + BOOST_CHECK_CLOSE(p2.evaluate(0.001), 1.003, 0.001); + BOOST_CHECK_CLOSE(p2.evaluate(1.001), 14.034, 0.001); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 233ebc57924fda35fb7294c589201093f7b0ef22 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 24 May 2017 16:31:40 +0200 Subject: [PATCH 25/65] changes to files to fix warnings --- include/boost/numeric/odeint.hpp | 3 + include/boost/numeric/odeint.hpp~ | 86 +++++++++++++++++++ .../stepper/adaptive_adams_bashforth.hpp | 5 +- .../odeint/stepper/adaptive_adams_moulton.hpp | 2 +- .../controlled_adams_bashforth_moulton.hpp | 14 +-- .../detail/adaptive_adams_coefficients.hpp | 10 ++- .../stepper/detail/pid_step_adjuster.hpp | 2 +- .../odeint/stepper/detail/polynomial.hpp | 15 ++-- 8 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 include/boost/numeric/odeint.hpp~ diff --git a/include/boost/numeric/odeint.hpp b/include/boost/numeric/odeint.hpp index e0100899..032ad65a 100644 --- a/include/boost/numeric/odeint.hpp +++ b/include/boost/numeric/odeint.hpp @@ -51,6 +51,9 @@ #include +#include +#include + #include #include #include diff --git a/include/boost/numeric/odeint.hpp~ b/include/boost/numeric/odeint.hpp~ new file mode 100644 index 00000000..19b527c9 --- /dev/null +++ b/include/boost/numeric/odeint.hpp~ @@ -0,0 +1,86 @@ +/* + [auto_generated] + boost/numeric/odeint.hpp + + [begin_description] + Forward include for odeint. Includes nearly everything. + [end_description] + + Copyright 2009-2013 Karsten Ahnert + Copyright 2010-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 BOOST_NUMERIC_ODEINT_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_HPP_INCLUDED + +#include +#include + +// start with ublas wrapper because we need its specializations before including state_wrapper.hpp +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#ifndef __CUDACC__ +/* Bulirsch Stoer with Dense Output does not compile with nvcc + * because of the binomial library used there which relies on unsupported SSE functions + */ +#include +#endif + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +/* + * Including this algebra slows down the compilation time + */ +// #include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + + +#endif // BOOST_NUMERIC_ODEINT_HPP_INCLUDED diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index fdbaeedb..b5353840 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -10,6 +10,7 @@ #include +#include #include #include @@ -25,7 +26,7 @@ namespace odeint { template< size_t Steps, class State, -class Value, +class Value = double, class Deriv = State, class Time = Value, class Algebra = typename algebra_dispatcher< State >::algebra_type, @@ -67,7 +68,7 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation { m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, m_xnew, dt); + do_step(system, inOut, t, m_xnew.m_v, dt); boost::numeric::odeint::copy( m_xnew.m_v , inOut); }; diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp index 063ba325..410f4c7e 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -19,7 +19,7 @@ namespace odeint { template< size_t Steps, class State, -class Value, +class Value = double, class Deriv = State, class Time = Value, class Algebra = typename algebra_dispatcher< State >::algebra_type, diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 9a57a053..706fc881 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -30,7 +30,7 @@ namespace odeint { template< size_t Steps, class State, -class Value, +class Value = double, class Deriv = State, class Time = Value, class StepAdjuster = detail::pid_step_adjuster, @@ -69,15 +69,15 @@ class controlled_adams_bashforth_moulton typedef explicit_controlled_stepper_tag stepper_category; controlled_adams_bashforth_moulton() - :m_aab(), m_aam(m_aab.algebra()), m_coeff(), - m_xerr_resizer(), m_dxdt_resizer(), m_xnew_resizer(), - m_step_adjuster() + :m_aab(), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff(), m_step_adjuster() {}; controlled_adams_bashforth_moulton(const algebra_type &algebra) - :m_aab(algebra), m_aam(m_aab.algebra()), m_coeff(), - m_xerr_resizer(), m_dxdt_resizer(), m_xnew_resizer(), - m_step_adjuster() + :m_aab(algebra), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff(), m_step_adjuster() {}; template diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index ef2da350..a2244dc3 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -12,8 +12,10 @@ #include #include +#include + #include -#include +#include namespace boost { namespace numeric { @@ -48,7 +50,7 @@ struct adaptive_adams_coefficients typedef detail::Polynomial poly_type; adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) - :m_algebra(algebra), m_effective_order(1), poly(), m_resizer() + :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) {}; // maybe step/tentative step are the better options @@ -99,10 +101,10 @@ struct adaptive_adams_coefficients poly_type poly; time_storage_type m_c; - std::array m_ss; + boost::array m_ss; time_storage_type m_ts; - std::array m_tss; + boost::array m_tss; time_storage_type m_tts; size_t m_effective_order; diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 54354927..5d7ddd28 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -18,7 +18,7 @@ struct pid_step_adjuster typedef rotating_buffer error_storage_type; pid_step_adjuster(time_type dtmax = 0.5) - :m_error_storage(), m_dtmax(dtmax), init(0) + :m_dtmax(dtmax), m_error_storage(), init(0) {}; double adjust_stepsize(const state_type &err, const time_type &dt) diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp index e4e66b80..0d4ef7a1 100644 --- a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp +++ b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp @@ -2,7 +2,7 @@ #define POLYNOMIAL_HPP_INCLUDED #include -#include +#include namespace boost { namespace numeric { @@ -19,20 +19,21 @@ class Polynomial typedef Time time_type; Polynomial() - :m_coeff{0} { + for(size_t i = 0; i coeff) + Polynomial(boost::array coeff) { m_coeff = coeff; }; Polynomial integrate() { - std::array coeff_int; + boost::array coeff_int; coeff_int[order] = 0; for(size_t i=0; i m_coeff; + boost::array m_coeff; time_type res; }; }}}} From ac90a029cef0135ab1241b027be781d1fa317632 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 25 May 2017 16:39:57 +0200 Subject: [PATCH 26/65] completed testcases --- test/adaptive_adams_bashforth.cpp | 23 ++++++-- test/adaptive_adams_coefficients.cpp | 31 ++++++++++- test/controlled_adams_bashforth_moulton.cpp | 61 ++++++++++++++++++++- test/integrate.cpp | 2 + 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/test/adaptive_adams_bashforth.cpp b/test/adaptive_adams_bashforth.cpp index c0ef16c1..36e0001f 100644 --- a/test/adaptive_adams_bashforth.cpp +++ b/test/adaptive_adams_bashforth.cpp @@ -25,20 +25,35 @@ struct const_sys BOOST_AUTO_TEST_SUITE( adaptive_adams_bashforth_test ) -BOOST_AUTO_TEST_CASE( test_const_int ) +BOOST_AUTO_TEST_CASE( test_instantiation ) { typedef double time_type; typedef std::vector state_type; - typedef adaptive_adams_bashforth<3, state_type, time_type> aab_type; + adaptive_adams_bashforth<1, state_type> s1; + adaptive_adams_bashforth<2, state_type> s2; + adaptive_adams_bashforth<3, state_type> s3; + adaptive_adams_bashforth<4, state_type> s4; + adaptive_adams_bashforth<5, state_type> s5; + adaptive_adams_bashforth<6, state_type> s6; + adaptive_adams_bashforth<7, state_type> s7; + adaptive_adams_bashforth<8, state_type> s8; + adaptive_adams_bashforth<9, state_type> s9; state_type x0; x0.push_back(0); time_type t0 = 0.0; time_type dt = 0.1; - aab_type aab; - aab.do_step(const_sys(), x0, t0, dt); + s1.do_step(const_sys(), x0, t0, dt); + s2.do_step(const_sys(), x0, t0, dt); + s3.do_step(const_sys(), x0, t0, dt); + s4.do_step(const_sys(), x0, t0, dt); + s5.do_step(const_sys(), x0, t0, dt); + s6.do_step(const_sys(), x0, t0, dt); + s7.do_step(const_sys(), x0, t0, dt); + s8.do_step(const_sys(), x0, t0, dt); + s9.do_step(const_sys(), x0, t0, dt); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp index 8183b5cc..4ef194dd 100644 --- a/test/adaptive_adams_coefficients.cpp +++ b/test/adaptive_adams_coefficients.cpp @@ -30,12 +30,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_step, step_type, vector_of_steps ) typedef std::vector deriv_type; typedef double time_type; - typedef detail::adaptive_adams_coefficients aac; + typedef detail::adaptive_adams_coefficients aac_type; std::vector deriv; deriv.push_back(-1); - aac coeff; + aac_type coeff; for(size_t i=0; i 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; + + c1.step(deriv, 0.0); + c1.confirm(); + c1.step(deriv, 1.0); + c1.confirm(); + c1.step(deriv, 2.0); + c1.confirm(); + + aac_type c2(c1); + BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); + BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); + + aac_type c3; + c3 = c1; + BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); +} + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/controlled_adams_bashforth_moulton.cpp b/test/controlled_adams_bashforth_moulton.cpp index 3900b92c..215902fc 100644 --- a/test/controlled_adams_bashforth_moulton.cpp +++ b/test/controlled_adams_bashforth_moulton.cpp @@ -12,11 +12,68 @@ 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_init ) +BOOST_AUTO_TEST_CASE( test_copy ) { - + controlled_adams_bashforth_moulton<3, state_type> s1; + + state_type deriv = {{1.0}}; + s1.coeff().step(deriv, 0.0); + s1.coeff().confirm(); + s1.coeff().step(deriv, 1.0); + s1.coeff().confirm(); + s1.coeff().step(deriv, 2.0); + s1.coeff().confirm(); + + controlled_adams_bashforth_moulton<3, state_type> s2(s1); + BOOST_CHECK_CLOSE(s2.coeff().m_ss[0][0].m_v[0], s1.coeff().m_ss[0][0].m_v[0], 1e-14); + BOOST_CHECK_CLOSE(s2.coeff().m_ss[1][0].m_v[0], s1.coeff().m_ss[1][0].m_v[0], 1e-14); + BOOST_CHECK((&(s2.coeff().m_ss[0]) != &(s1.coeff().m_ss[0]))); + + controlled_adams_bashforth_moulton<3, state_type> s3; + s3 = s1; + + BOOST_CHECK_CLOSE(s3.coeff().m_ss[0][0].m_v[0], s1.coeff().m_ss[0][0].m_v[0], 1e-14); + BOOST_CHECK_CLOSE(s3.coeff().m_ss[1][0].m_v[0], s1.coeff().m_ss[1][0].m_v[0], 1e-14); +} + +BOOST_AUTO_TEST_CASE( test_instantiation ) +{ + controlled_adams_bashforth_moulton<1, state_type> s1; + controlled_adams_bashforth_moulton<2, state_type> s2; + controlled_adams_bashforth_moulton<3, state_type> s3; + controlled_adams_bashforth_moulton<4, state_type> s4; + controlled_adams_bashforth_moulton<5, state_type> s5; + controlled_adams_bashforth_moulton<6, state_type> s6; + controlled_adams_bashforth_moulton<7, state_type> s7; + controlled_adams_bashforth_moulton<8, state_type> s8; + controlled_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/test/integrate.cpp b/test/integrate.cpp index d07c231c..2f8b7459 100644 --- a/test/integrate.cpp +++ b/test/integrate.cpp @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -240,6 +241,7 @@ class stepper_methods : public mpl::vector< 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<3, state_type>, controlled_adams_bashforth_moulton<3, state_type, value_type>, controlled_adams_bashforth_moulton<5, state_type, value_type> //bulirsch_stoer_dense_out< state_type > From 8e2b3c2550b532efd3763cb9a52ed2bdcddeb4aa Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 25 May 2017 16:40:31 +0200 Subject: [PATCH 27/65] fixed minor things in stepper --- .../stepper/controlled_adams_bashforth_moulton.hpp | 10 ++++++++++ .../stepper/detail/adaptive_adams_coefficients.hpp | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 706fc881..6b5ecf3a 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -140,6 +140,16 @@ class controlled_adams_bashforth_moulton } }; + const coeff_type& coeff() const + { + return m_coeff; + }; + + coeff_type& coeff() + { + return m_coeff; + }; + private: template< class StateType > bool resize_dxdt_impl( const StateType &x ) diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index a2244dc3..b1f21424 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -53,7 +53,6 @@ struct adaptive_adams_coefficients :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) {}; - // maybe step/tentative step are the better options void step(const deriv_type &deriv, const time_type &t) { m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); From 2f098f7d86683ecc684e501431e6cb93ce0753ad Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 25 May 2017 18:45:38 +0200 Subject: [PATCH 28/65] removed tmp-file --- include/boost/numeric/odeint.hpp~ | 86 ------------------------------- 1 file changed, 86 deletions(-) delete mode 100644 include/boost/numeric/odeint.hpp~ diff --git a/include/boost/numeric/odeint.hpp~ b/include/boost/numeric/odeint.hpp~ deleted file mode 100644 index 19b527c9..00000000 --- a/include/boost/numeric/odeint.hpp~ +++ /dev/null @@ -1,86 +0,0 @@ -/* - [auto_generated] - boost/numeric/odeint.hpp - - [begin_description] - Forward include for odeint. Includes nearly everything. - [end_description] - - Copyright 2009-2013 Karsten Ahnert - Copyright 2010-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 BOOST_NUMERIC_ODEINT_HPP_INCLUDED -#define BOOST_NUMERIC_ODEINT_HPP_INCLUDED - -#include -#include - -// start with ublas wrapper because we need its specializations before including state_wrapper.hpp -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#ifndef __CUDACC__ -/* Bulirsch Stoer with Dense Output does not compile with nvcc - * because of the binomial library used there which relies on unsupported SSE functions - */ -#include -#endif - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -/* - * Including this algebra slows down the compilation time - */ -// #include - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - - -#endif // BOOST_NUMERIC_ODEINT_HPP_INCLUDED From fa769dd236e9145b9cef1431119701b6667d6743 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 19 Jun 2017 10:04:37 +0200 Subject: [PATCH 29/65] Fixed small bug and added more functionality to the controller --- .../stepper/adaptive_adams_bashforth.hpp | 5 +- .../odeint/stepper/adaptive_adams_moulton.hpp | 2 +- .../controlled_adams_bashforth_moulton.hpp | 26 ++-- .../detail/adaptive_adams_coefficients.hpp | 2 +- .../stepper/detail/pid_step_adjuster.hpp | 64 +++++++--- .../detail/pid_step_adjuster_coefficients.hpp | 112 ++++++++++++++++++ 6 files changed, 179 insertions(+), 32 deletions(-) create mode 100644 include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index b5353840..304ec225 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -54,7 +54,7 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation typedef state_wrapper wrapped_deriv_type; typedef stepper_tag stepper_category; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; @@ -75,6 +75,7 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation template void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) { + std::cout << "aa1" << std::endl; m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); system(in, m_dxdt.m_v, t); @@ -129,4 +130,4 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation } } -#endif \ No newline at end of file +#endif diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp index 410f4c7e..b9dc8221 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -45,7 +45,7 @@ class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations typedef state_wrapper wrapped_state_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 6b5ecf3a..e75bff7c 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -33,10 +33,10 @@ class State, class Value = double, class Deriv = State, class Time = Value, -class StepAdjuster = detail::pid_step_adjuster, class Algebra = typename algebra_dispatcher< State >::algebra_type, class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer +class Resizer = initially_resizer, +class StepAdjuster = detail::pid_step_adjuster > class controlled_adams_bashforth_moulton { @@ -58,13 +58,13 @@ class controlled_adams_bashforth_moulton typedef state_wrapper wrapped_state_type; typedef state_wrapper wrapped_deriv_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef detail::rotating_buffer error_storage_type; - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, StepAdjuster, Algebra, Operations, Resizer > stepper_type; + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer, StepAdjuster > stepper_type; typedef explicit_controlled_stepper_tag stepper_category; @@ -97,6 +97,8 @@ class controlled_adams_bashforth_moulton controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) { m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + // std::cout << "T: " << t << std::endl; if(m_coeff.m_effective_order == 1) { @@ -107,6 +109,7 @@ class controlled_adams_bashforth_moulton } // predict m_aab.do_step_impl(m_coeff, in, t, out, dt); + // std::cout << "Pred: " << out[0] << std::endl; // evaluate system(out, m_dxdt.m_v, t + dt); @@ -115,12 +118,17 @@ class controlled_adams_bashforth_moulton m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); boost::numeric::odeint::copy( out, m_xerr.m_v); - // correct + // // correct m_aam.do_step(m_coeff, in, t, out, dt); - m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(1.0, -1.0)); + m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(-1.0, 1.0)); + + // std::cout << "Corr: " << out[0] << std::endl; + // std::cout << "Err: " << m_xerr.m_v[0] << std::endl; double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); + // std::cout << "Ratio: " << ratio << std::endl; + if(ratio >= 0.9) { // evaluate @@ -185,4 +193,4 @@ class controlled_adams_bashforth_moulton }}} -#endif \ No newline at end of file +#endif diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index b1f21424..64031a59 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -132,4 +132,4 @@ struct adaptive_adams_coefficients } } -#endif \ No newline at end of file +#endif diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 5d7ddd28..66a85951 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -2,6 +2,7 @@ #define PID_STEP_ADJUSTER_HPP_INCLUDED #include +#include #include @@ -9,65 +10,90 @@ namespace boost{ namespace numeric{ namespace odeint{ namespace detail{ -template + +template struct pid_step_adjuster { public: typedef State state_type; typedef Time time_type; - typedef rotating_buffer error_storage_type; - pid_step_adjuster(time_type dtmax = 0.5) - :m_dtmax(dtmax), m_error_storage(), init(0) + typedef rotating_buffer error_storage_type; + typedef rotating_buffer time_storage_type; + typedef pid_step_adjuster_coefficients coeff_type; + + pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) + :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_tol(tol), m_failed(0), m_init(0) {}; double adjust_stepsize(const state_type &err, const time_type &dt) { // basic controller m_error_storage[0] = err; + m_time_storage[0] = dt; - if(init < order-1) - { - ++init; - m_error_storage.rotate(); - return 1.0; - } - - double theta = 1.0/tol; double ratio = 100; double r; for(size_t i=0; i= 2) + { + r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(Steps + 1)) * + pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(Steps + 1)) * + pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(Steps + 1)) * + pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(Steps + 1))* + pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(Steps + 1)); + } + else + { + r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(Steps + 1)); // purely integrating controller for startup + } + if(r= m_dtmax) { ratio = m_dtmax / dt; } - if(ratio > 0.9) + if(ratio >= 0.9) { m_error_storage.rotate(); + m_time_storage.rotate(); + + ++m_init; } - + else + { + m_init = 0; + m_failed ++; + //std::cout << m_failed << std::endl; + } + return ratio; }; private: time_type m_dtmax; error_storage_type m_error_storage; - size_t init; + time_storage_type m_time_storage; + + size_t m_init; + double m_tol; + + size_t m_failed; + + coeff_type m_coeff; }; } } } } -#endif \ No newline at end of file +#endif diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp new file mode 100644 index 00000000..ba6198db --- /dev/null +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -0,0 +1,112 @@ +#ifndef PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED +#define PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED + +#include + +namespace boost{ +namespace numeric{ +namespace odeint{ +namespace detail{ + +enum adjuster_type{ + BASIC = 1, + H0211 = 2, + H211b = 3, + H211PI = 4, + H0312 = 5, + H312b = 6, + H312PID = 7, + H0321 = 8, + H321 = 9 +}; + +template +class pid_step_adjuster_coefficients; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1, 0, 0, 0, 0}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/2, 1.0/2, 0, 1.0/2, 0}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/5, 2.0/5, 0, 1.0/5, 0}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/6, 2.0/6, 0, 0, 0}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/4, 2.0/2, 1.0/4, 3.0/4, 1.0/4}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/6, 2.0/6, 1.0/6, 3.0/6, 1.0/6}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/18, 2.0/9, 1.0/18, 0, 0}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({5.0/4, 1.0/2, -3.0/4, -1.0/4, -3.0/4}) + {} +}; + +template<> +class pid_step_adjuster_coefficients : public boost::array +{ +public: + pid_step_adjuster_coefficients() + : boost::array({1.0/3, 1.0/18, -5.0/18, -5.0/6, -1.0/6}) + {} +}; + +} +} +} +} + +#endif \ No newline at end of file From ca966c2736eef8386797739cb7bdf8d2a4cf69d1 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 19 Jun 2017 10:41:38 +0200 Subject: [PATCH 30/65] compiles without c++11 --- .../stepper/detail/pid_step_adjuster.hpp | 2 +- .../detail/pid_step_adjuster_coefficients.hpp | 128 +++++++++++++----- 2 files changed, 92 insertions(+), 38 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 66a85951..5ab69059 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -11,7 +11,7 @@ namespace numeric{ namespace odeint{ namespace detail{ -template +template struct pid_step_adjuster { public: diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp index ba6198db..2cd7ce03 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -9,99 +9,153 @@ namespace odeint{ namespace detail{ enum adjuster_type{ - BASIC = 1, - H0211 = 2, - H211b = 3, - H211PI = 4, - H0312 = 5, - H312b = 6, - H312PID = 7, - H0321 = 8, - H321 = 9 + BASIC, + H0211, + H211b, + H211PI, + H0312, + H312b, + H312PID, + H0321, + H321 }; -template +template class pid_step_adjuster_coefficients; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1, 0, 0, 0, 0}) - {} + : boost::array() + { + (*this)[0] = 1; + (*this)[1] = 0; + (*this)[2] = 0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/2, 1.0/2, 0, 1.0/2, 0}) - {} + : boost::array() + { + (*this)[0] = 1.0/2.0; + (*this)[1] = 1.0/2.0; + (*this)[2] = 0; + (*this)[3] = 1.0/2.0; + (*this)[4] = 0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/5, 2.0/5, 0, 1.0/5, 0}) - {} + : boost::array() + { + (*this)[0] = 1.0/5.0; + (*this)[1] = 2.0/5.0; + (*this)[2] = 0; + (*this)[3] = 1.0/5.0; + (*this)[4] = 0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/6, 2.0/6, 0, 0, 0}) - {} + : boost::array() + { + (*this)[0] = 1.0/6.0; + (*this)[1] = 2.0/6.0; + (*this)[2] = 0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/4, 2.0/2, 1.0/4, 3.0/4, 1.0/4}) - {} + : boost::array() + { + (*this)[0] = 1.0/4.0; + (*this)[1] = 2.0/2.0; + (*this)[2] = 1.0/4.0; + (*this)[3] = 3.0/4.0; + (*this)[4] = 1.0/4.0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/6, 2.0/6, 1.0/6, 3.0/6, 1.0/6}) - {} + : boost::array() + { + (*this)[0] = 1.0/6.0; + (*this)[1] = 2.0/6.0; + (*this)[2] = 1.0/6.0; + (*this)[3] = 3.0/6.0; + (*this)[4] = 1.0/6.0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/18, 2.0/9, 1.0/18, 0, 0}) - {} + : boost::array() + { + (*this)[0] = 1.0/18.0; + (*this)[1] = 2.0/9.0; + (*this)[2] = 1.0/18.0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({5.0/4, 1.0/2, -3.0/4, -1.0/4, -3.0/4}) - {} + : boost::array() + { + (*this)[0] = 5.0/4.0; + (*this)[1] = 1.0/2.0; + (*this)[2] = -3.0/4.0; + (*this)[3] = -1.0/4.0; + (*this)[4] = -3.0/4.0; + } }; template<> -class pid_step_adjuster_coefficients : public boost::array +class pid_step_adjuster_coefficients : public boost::array { public: pid_step_adjuster_coefficients() - : boost::array({1.0/3, 1.0/18, -5.0/18, -5.0/6, -1.0/6}) - {} + : boost::array() + { + (*this)[0] = 1.0/3.0; + (*this)[1] = 1.0/18.0; + (*this)[2] = -5.0/18.0; + (*this)[3] = -5.0/16.0; + (*this)[4] = -1.0/6.0; + } }; } From 28b01caee73539246f25df89f6705a67dd6f5520 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 19 Jun 2017 16:13:58 +0200 Subject: [PATCH 31/65] minor naming changes --- .../detail/adaptive_adams_coefficients.hpp | 25 +++++++++++++++++++ .../stepper/detail/pid_step_adjuster.hpp | 2 +- .../odeint/stepper/detail/polynomial.hpp | 22 ++++++++-------- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 64031a59..57ec2d1a 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -53,6 +53,31 @@ struct adaptive_adams_coefficients :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) {}; + /*aac_type &operator=(const aac_type & rhs) + { + this->poly = rhs.poly; + this->m_c = rhs.m_c; + // this->m_ss = rhs.m_ss; + + for(size_t i=0; im_ss[i][j] = rhs.m_ss[i][j]; + } + } + + this->m_ts = rhs.m_ts; + this->m_tss = rhs.m_tss; + this->m_tts = rhs.m_tts; + this->m_effective_order = rhs.m_effective_order; + + this->m_algebra = rhs.m_algebra; + this->m_resizer = rhs.m_resizer; + + return *this; + }*/ + void step(const deriv_type &deriv, const time_type &t) { m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 5ab69059..36621740 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -23,7 +23,7 @@ struct pid_step_adjuster typedef pid_step_adjuster_coefficients coeff_type; pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_tol(tol), m_failed(0), m_init(0) + :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol), m_failed(0) {}; double adjust_stepsize(const state_type &err, const time_type &dt) diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp index 0d4ef7a1..e8d25ad8 100644 --- a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp +++ b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp @@ -17,6 +17,7 @@ class Polynomial { public: typedef Time time_type; + typedef Polynomial poly_type; Polynomial() { @@ -49,26 +50,26 @@ class Polynomial time_type evaluate(const time_type &t) { // fma: x*y+z - res = m_coeff[0]; + m_res = m_coeff[0]; for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); - res = ((i >= order)?0:m_coeff[i]/(order-i)) + res * t; + // m_res = fma(m_res, t, ((i >= order)?0:m_coeff[i]/(order-i))); + m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; } - return res; + return m_res; } void add_root(const time_type &root) @@ -130,10 +131,11 @@ class Polynomial Polynomial poly(coeff); return poly; }; - private: + // first element is highest order boost::array m_coeff; - time_type res; + private: + time_type m_res; }; }}}} From 5fe4175a61db316747ab53697202df7f0704d841 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 19 Jun 2017 16:28:29 +0200 Subject: [PATCH 32/65] removed print used in debugging --- .../boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index 304ec225..0b6fa9f4 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -75,7 +75,6 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation template void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) { - std::cout << "aa1" << std::endl; m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); system(in, m_dxdt.m_v, t); From 16801429c9ab7e0cc1c147919c7b965ad0cff956 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 20 Jun 2017 17:04:15 +0200 Subject: [PATCH 33/65] modifications to stepper to allow make_controlled --- include/boost/numeric/odeint.hpp | 1 + .../stepper/adaptive_adams_bashforth.hpp | 24 ++- .../adaptive_adams_bashforth_moulton.hpp | 199 ++++++++++++++++++ .../odeint/stepper/adaptive_adams_moulton.hpp | 18 +- .../controlled_adams_bashforth_moulton.hpp | 160 +++++--------- .../controlled_adams_bashforth_moulton_v2.hpp | 196 +++++++++++++++++ .../detail/adaptive_adams_coefficients.hpp | 6 + .../numeric/odeint/stepper/generation.hpp | 1 + ...ion_controlled_adams_bashforth_moulton.hpp | 45 ++++ 9 files changed, 528 insertions(+), 122 deletions(-) create mode 100644 include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp create mode 100644 include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp create mode 100644 include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp diff --git a/include/boost/numeric/odeint.hpp b/include/boost/numeric/odeint.hpp index 032ad65a..d577b6a4 100644 --- a/include/boost/numeric/odeint.hpp +++ b/include/boost/numeric/odeint.hpp @@ -52,6 +52,7 @@ #include #include +#include #include #include diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index 0b6fa9f4..1b8821bd 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -38,7 +38,7 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation public: static const size_t steps = Steps; typedef unsigned short order_type; - static const order_type order = steps; + static const order_type order_value = steps; typedef State state_type; typedef Value value_type; @@ -54,7 +54,7 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation typedef state_wrapper wrapped_deriv_type; typedef stepper_tag stepper_category; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; @@ -63,6 +63,11 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation m_dxdt_resizer(), m_xnew_resizer() {}; + order_type order() const + { + return order_value; + }; + template void do_step(System system, state_type & inOut, time_type t, time_type dt) { @@ -105,6 +110,21 @@ class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operation } }; + const coeff_type& coeff() const + { + return m_coeff; + }; + + coeff_type& coeff() + { + return m_coeff; + }; + + void reset() + { + m_coeff.reset(); + }; + private: template< class StateType > bool resize_dxdt_impl( const StateType &x ) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp new file mode 100644 index 00000000..2497ffa6 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -0,0 +1,199 @@ +#ifndef STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace boost { +namespace numeric { +namespace odeint { + + + +template< +size_t Steps, +class State, +class Value = double, +class Deriv = State, +class Time = Value, +class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< State >::operations_type , +class Resizer = initially_resizer +> +class adaptive_adams_bashforth_moulton +{ + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; + + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + + typedef detail::adaptive_adams_coefficients coeff_type; + + typedef detail::rotating_buffer error_storage_type; + + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; + + typedef error_stepper_tag stepper_category; + + adaptive_adams_bashforth_moulton() + :m_aab(), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff() + {}; + + adaptive_adams_bashforth_moulton(const algebra_type &algebra) + :m_aab(algebra), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff() + {}; + + order_type order() + { + return order_value + 1; + } + + order_type stepper_order() + { + return order_value + 1; + } + + order_type error_order() + { + return order_value; + } + + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, dt, m_xerr.m_v); + }; + + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, in, t, out, dt, m_xerr.m_v); + }; + + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, m_xnew.m_v, dt, xerr); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; + + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + do_step_impl(system, m_coeff, in, t, out, dt, xerr); + + system(out, m_dxdt.m_v, t+dt); + m_coeff.step(m_dxdt.m_v, t+dt); + m_coeff.confirm(); + }; + + template + void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + if(coeff.m_effective_order == 1) + { + system(in, m_dxdt.m_v, t); + + coeff.step(m_dxdt.m_v, t); + coeff.confirm(); + } + // predict + m_aab.do_step_impl(coeff, in, t, out, dt); + + // evaluate + system(out, m_dxdt.m_v, t + dt); + coeff.step(m_dxdt.m_v, t + dt); + + boost::numeric::odeint::copy( out, xerr); + + // correct + m_aam.do_step(coeff, in, t, out, dt); + + // Error calculation + m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); + }; + + const coeff_type& coeff() const + { + return m_coeff; + }; + + coeff_type& coeff() + { + return m_coeff; + }; + + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; + + aab_type m_aab; + aam_type m_aam; + + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; + + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; + wrapped_state_type m_xerr; + + coeff_type m_coeff; +}; + +}}} + +#endif diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp index b9dc8221..88693b7f 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -31,28 +31,30 @@ class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations public: static const size_t steps = Steps; typedef unsigned short order_type; - static const order_type order = steps + 1; + static const order_type order_value = steps + 1; typedef State state_type; typedef Value value_type; typedef Deriv deriv_type; typedef Time time_type; - typedef Resizer resizer_type; typedef Algebra algebra_type; typedef Operations operations_type; typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef state_wrapper wrapped_state_type; - - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ), m_coeff() + :algebra_stepper_base_type( algebra ) {}; + order_type order() const + { + return order_value; + }; + void do_step(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type &dt) { @@ -65,11 +67,7 @@ class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations time_type c = ((i!=coeff.m_effective_order-1)?coeff.m_c[i]:coeff.poly.evaluate_integrated(dt)); this->m_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); } - // std::cout << std::endl; }; - - private: - coeff_type m_coeff; }; } diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index e75bff7c..905f3010 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -1,89 +1,65 @@ #ifndef STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #define STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED -#include -#include -#include +#include +#include + +#include #include -#include - -#include -#include #include #include - -#include -#include - -#include #include -#include - -namespace boost { -namespace numeric { +namespace boost{ +namespace numeric{ namespace odeint { - - +// template< +// class ErrorStepper, +// class ErrorChecker, +// class StepAdjuster, +// class Resizer +// > template< -size_t Steps, -class State, -class Value = double, -class Deriv = State, -class Time = Value, -class Algebra = typename algebra_dispatcher< State >::algebra_type, -class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer, -class StepAdjuster = detail::pid_step_adjuster +class ErrorStepper, +class StepAdjuster = detail::pid_step_adjuster, +class Resizer = initially_resizer > class controlled_adams_bashforth_moulton { public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order = steps; + typedef ErrorStepper 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 State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef StepAdjuster step_adjuster_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; + // typedef ErrorChecker error_checker_type; + typedef StepAdjuster step_adjuster_type; + typedef controlled_stepper_tag stepper_category; - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; + typedef typename stepper_type::wrapped_state_type wrapped_state_type; + typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef controlled_adams_bashforth_moulton controlled_stepper_type; - typedef detail::rotating_buffer error_storage_type; - - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer, StepAdjuster > stepper_type; - - typedef explicit_controlled_stepper_tag stepper_category; - - controlled_adams_bashforth_moulton() - :m_aab(), m_aam(m_aab.algebra()), + controlled_adams_bashforth_moulton( + step_adjuster_type step_adjuster = step_adjuster_type() + ) + :m_stepper(), m_coeff(m_stepper.coeff()), m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff(), m_step_adjuster() - {}; - - controlled_adams_bashforth_moulton(const algebra_type &algebra) - :m_aab(algebra), m_aam(m_aab.algebra()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff(), m_step_adjuster() + m_step_adjuster(step_adjuster) {}; template controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); @@ -96,42 +72,15 @@ class controlled_adams_bashforth_moulton template controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - // std::cout << "T: " << t << std::endl; - - if(m_coeff.m_effective_order == 1) - { - system(in, m_dxdt.m_v, t); - - m_coeff.step(m_dxdt.m_v, t); - m_coeff.confirm(); - } - // predict - m_aab.do_step_impl(m_coeff, in, t, out, dt); - // std::cout << "Pred: " << out[0] << std::endl; - - // evaluate - system(out, m_dxdt.m_v, t + dt); - m_coeff.step(m_dxdt.m_v, t + dt); - - m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - boost::numeric::odeint::copy( out, m_xerr.m_v); - - // // correct - m_aam.do_step(m_coeff, in, t, out, dt); - m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(-1.0, 1.0)); - - // std::cout << "Corr: " << out[0] << std::endl; - // std::cout << "Err: " << m_xerr.m_v[0] << std::endl; + m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); - // std::cout << "Ratio: " << ratio << std::endl; - if(ratio >= 0.9) { - // evaluate + m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + system(out, m_dxdt.m_v, t+dt); m_coeff.step(m_dxdt.m_v, t+dt); m_coeff.confirm(); @@ -148,16 +97,6 @@ class controlled_adams_bashforth_moulton } }; - const coeff_type& coeff() const - { - return m_coeff; - }; - - coeff_type& coeff() - { - return m_coeff; - }; - private: template< class StateType > bool resize_dxdt_impl( const StateType &x ) @@ -167,7 +106,7 @@ class controlled_adams_bashforth_moulton template< class StateType > bool resize_xerr_impl( const StateType &x ) { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); }; template< class StateType > bool resize_xnew_impl( const StateType &x ) @@ -175,22 +114,23 @@ class controlled_adams_bashforth_moulton return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); }; - aab_type m_aab; - aam_type m_aam; + stepper_type m_stepper; + typename stepper_type::coeff_type &m_coeff; + + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xerr; + wrapped_state_type m_xnew; resizer_type m_dxdt_resizer; resizer_type m_xerr_resizer; resizer_type m_xnew_resizer; - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xnew; - wrapped_state_type m_xerr; - - coeff_type m_coeff; - + // error_checker_type m_error_checker; step_adjuster_type m_step_adjuster; }; -}}} +} +} +} -#endif +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp new file mode 100644 index 00000000..e75bff7c --- /dev/null +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp @@ -0,0 +1,196 @@ +#ifndef STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +namespace boost { +namespace numeric { +namespace odeint { + + + +template< +size_t Steps, +class State, +class Value = double, +class Deriv = State, +class Time = Value, +class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< State >::operations_type , +class Resizer = initially_resizer, +class StepAdjuster = detail::pid_step_adjuster +> +class controlled_adams_bashforth_moulton +{ + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order = steps; + + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef StepAdjuster step_adjuster_type; + typedef Resizer resizer_type; + + typedef Algebra algebra_type; + typedef Operations operations_type; + + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + + typedef detail::adaptive_adams_coefficients coeff_type; + + typedef detail::rotating_buffer error_storage_type; + + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer, StepAdjuster > stepper_type; + + typedef explicit_controlled_stepper_tag stepper_category; + + controlled_adams_bashforth_moulton() + :m_aab(), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff(), m_step_adjuster() + {}; + + controlled_adams_bashforth_moulton(const algebra_type &algebra) + :m_aab(algebra), m_aam(m_aab.algebra()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff(), m_step_adjuster() + {}; + + template + controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); + + if(res == success) + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + + return res; + }; + + template + controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + // std::cout << "T: " << t << std::endl; + + if(m_coeff.m_effective_order == 1) + { + system(in, m_dxdt.m_v, t); + + m_coeff.step(m_dxdt.m_v, t); + m_coeff.confirm(); + } + // predict + m_aab.do_step_impl(m_coeff, in, t, out, dt); + // std::cout << "Pred: " << out[0] << std::endl; + + // evaluate + system(out, m_dxdt.m_v, t + dt); + m_coeff.step(m_dxdt.m_v, t + dt); + + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + boost::numeric::odeint::copy( out, m_xerr.m_v); + + // // correct + m_aam.do_step(m_coeff, in, t, out, dt); + m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(-1.0, 1.0)); + + // std::cout << "Corr: " << out[0] << std::endl; + // std::cout << "Err: " << m_xerr.m_v[0] << std::endl; + + double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); + + // std::cout << "Ratio: " << ratio << std::endl; + + if(ratio >= 0.9) + { + // evaluate + system(out, m_dxdt.m_v, t+dt); + m_coeff.step(m_dxdt.m_v, t+dt); + m_coeff.confirm(); + + t += dt; + dt *= ratio; + + return success; + } + else + { + dt *= ratio; + return fail; + } + }; + + const coeff_type& coeff() const + { + return m_coeff; + }; + + coeff_type& coeff() + { + return m_coeff; + }; + + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; + + aab_type m_aab; + aam_type m_aam; + + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; + + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; + wrapped_state_type m_xerr; + + coeff_type m_coeff; + + step_adjuster_type m_step_adjuster; +}; + +}}} + +#endif diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 57ec2d1a..b58fb7e5 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -108,6 +108,12 @@ struct adaptive_adams_coefficients } }; + void reset() + { + poly.reset(); + m_effective_order = 1; + }; + void pretty_print() { for(size_t k=0; k<2; ++k) diff --git a/include/boost/numeric/odeint/stepper/generation.hpp b/include/boost/numeric/odeint/stepper/generation.hpp index 90ad2b9a..a051d13b 100644 --- a/include/boost/numeric/odeint/stepper/generation.hpp +++ b/include/boost/numeric/odeint/stepper/generation.hpp @@ -29,6 +29,7 @@ #include #include +#include #include diff --git a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp new file mode 100644 index 00000000..c3db2a15 --- /dev/null +++ b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp @@ -0,0 +1,45 @@ +#ifndef GENERATION_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define GENERATION_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED + +#include +#include +#include + +namespace boost { +namespace numeric { +namespace odeint { + +template< size_t Steps, class State , class Value , class Deriv , class Time , class Algebra , class Operations , class Resizer > +struct get_controller< adaptive_adams_bashforth_moulton< Steps, State , Value , Deriv , Time , Algebra , Operations , Resizer > > +{ + typedef adaptive_adams_bashforth_moulton stepper_type; + typedef controlled_adams_bashforth_moulton< stepper_type > type; +}; + +// controller factory for controlled_adams_bashforth_moulton +template< class Stepper > +struct controller_factory< Stepper , controlled_adams_bashforth_moulton< Stepper > > +{ + typedef Stepper stepper_type; + typedef controlled_adams_bashforth_moulton< stepper_type > controller_type; + typedef typename controller_type::step_adjuster_type step_adjuster_type; + typedef typename stepper_type::value_type value_type; + typedef typename stepper_type::value_type time_type; + + controller_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper ) + { + return controller_type( step_adjuster_type(rel_error)); + } + + controller_type operator()( value_type abs_error , value_type rel_error , + time_type max_dt, const stepper_type &stepper ) + { + return controller_type( step_adjuster_type(rel_error, max_dt)); + } +}; + +} +} +} + +#endif \ No newline at end of file From b29586d9d3ddf6a6aec7f68907a27c68990e8273 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 21 Jun 2017 18:13:25 +0200 Subject: [PATCH 34/65] implemented adaptive adams bashforth moulton to enable make_controlled --- .../adaptive_adams_bashforth_moulton.hpp | 17 +- .../controlled_adams_bashforth_moulton.hpp | 31 +-- .../controlled_adams_bashforth_moulton_v2.hpp | 196 ------------------ .../stepper/detail/pid_step_adjuster.hpp | 42 ++-- ...ion_controlled_adams_bashforth_moulton.hpp | 4 +- 5 files changed, 42 insertions(+), 248 deletions(-) delete mode 100644 include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 2497ffa6..cd90db78 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -1,6 +1,7 @@ #ifndef STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #define STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#include #include #include #include @@ -34,7 +35,7 @@ class Algebra = typename algebra_dispatcher< State >::algebra_type, class Operations = typename operations_dispatcher< State >::operations_type , class Resizer = initially_resizer > -class adaptive_adams_bashforth_moulton +class adaptive_adams_bashforth_moulton: public algebra_stepper_base< Algebra , Operations > { public: static const size_t steps = Steps; @@ -49,6 +50,7 @@ class adaptive_adams_bashforth_moulton typedef Algebra algebra_type; typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; typedef state_wrapper wrapped_state_type; typedef state_wrapper wrapped_deriv_type; @@ -63,14 +65,8 @@ class adaptive_adams_bashforth_moulton typedef error_stepper_tag stepper_category; - adaptive_adams_bashforth_moulton() - :m_aab(), m_aam(m_aab.algebra()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff() - {}; - - adaptive_adams_bashforth_moulton(const algebra_type &algebra) - :m_aab(algebra), m_aam(m_aab.algebra()), + adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), m_coeff() {}; @@ -163,6 +159,8 @@ class adaptive_adams_bashforth_moulton return m_coeff; }; + wrapped_deriv_type m_dxdt; + private: template< class StateType > bool resize_dxdt_impl( const StateType &x ) @@ -187,7 +185,6 @@ class adaptive_adams_bashforth_moulton resizer_type m_xerr_resizer; resizer_type m_xnew_resizer; - wrapped_deriv_type m_dxdt; wrapped_state_type m_xnew; wrapped_state_type m_xerr; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 905f3010..2002d5d4 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -15,15 +15,12 @@ namespace boost{ namespace numeric{ namespace odeint { -// template< -// class ErrorStepper, -// class ErrorChecker, -// class StepAdjuster, -// class Resizer -// > template< class ErrorStepper, -class StepAdjuster = detail::pid_step_adjuster, +class StepAdjuster = detail::pid_step_adjuster, class Resizer = initially_resizer > class controlled_adams_bashforth_moulton @@ -39,7 +36,6 @@ class controlled_adams_bashforth_moulton typedef typename stepper_type::operations_type operations_type; typedef Resizer resizer_type; - // typedef ErrorChecker error_checker_type; typedef StepAdjuster step_adjuster_type; typedef controlled_stepper_tag stepper_category; @@ -48,9 +44,7 @@ class controlled_adams_bashforth_moulton typedef controlled_adams_bashforth_moulton controlled_stepper_type; - controlled_adams_bashforth_moulton( - step_adjuster_type step_adjuster = step_adjuster_type() - ) + controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) :m_stepper(), m_coeff(m_stepper.coeff()), m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), m_step_adjuster(step_adjuster) @@ -75,24 +69,22 @@ class controlled_adams_bashforth_moulton m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); - double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); + time_type dtPrev = dt; + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); - if(ratio >= 0.9) + if(dt / dtPrev >= 0.9) { m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - system(out, m_dxdt.m_v, t+dt); - m_coeff.step(m_dxdt.m_v, t+dt); + system(out, m_dxdt.m_v, t+dtPrev); + m_coeff.step(m_dxdt.m_v, t+dtPrev); m_coeff.confirm(); - t += dt; - dt *= ratio; - + t += dtPrev; return success; } else { - dt *= ratio; return fail; } }; @@ -125,7 +117,6 @@ class controlled_adams_bashforth_moulton resizer_type m_xerr_resizer; resizer_type m_xnew_resizer; - // error_checker_type m_error_checker; step_adjuster_type m_step_adjuster; }; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp deleted file mode 100644 index e75bff7c..00000000 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton_v2.hpp +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED -#define STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -namespace boost { -namespace numeric { -namespace odeint { - - - -template< -size_t Steps, -class State, -class Value = double, -class Deriv = State, -class Time = Value, -class Algebra = typename algebra_dispatcher< State >::algebra_type, -class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer, -class StepAdjuster = detail::pid_step_adjuster -> -class controlled_adams_bashforth_moulton -{ - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order = steps; - - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef StepAdjuster step_adjuster_type; - typedef Resizer resizer_type; - - typedef Algebra algebra_type; - typedef Operations operations_type; - - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; - - typedef detail::adaptive_adams_coefficients coeff_type; - - typedef detail::rotating_buffer error_storage_type; - - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef controlled_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer, StepAdjuster > stepper_type; - - typedef explicit_controlled_stepper_tag stepper_category; - - controlled_adams_bashforth_moulton() - :m_aab(), m_aam(m_aab.algebra()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff(), m_step_adjuster() - {}; - - controlled_adams_bashforth_moulton(const algebra_type &algebra) - :m_aab(algebra), m_aam(m_aab.algebra()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff(), m_step_adjuster() - {}; - - template - controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); - - if(res == success) - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - - return res; - }; - - template - controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - // std::cout << "T: " << t << std::endl; - - if(m_coeff.m_effective_order == 1) - { - system(in, m_dxdt.m_v, t); - - m_coeff.step(m_dxdt.m_v, t); - m_coeff.confirm(); - } - // predict - m_aab.do_step_impl(m_coeff, in, t, out, dt); - // std::cout << "Pred: " << out[0] << std::endl; - - // evaluate - system(out, m_dxdt.m_v, t + dt); - m_coeff.step(m_dxdt.m_v, t + dt); - - m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - boost::numeric::odeint::copy( out, m_xerr.m_v); - - // // correct - m_aam.do_step(m_coeff, in, t, out, dt); - m_aab.algebra().for_each3(m_xerr.m_v, m_xerr.m_v, out, typename Operations::template scale_sum2(-1.0, 1.0)); - - // std::cout << "Corr: " << out[0] << std::endl; - // std::cout << "Err: " << m_xerr.m_v[0] << std::endl; - - double ratio = m_step_adjuster.adjust_stepsize(m_xerr.m_v, dt); - - // std::cout << "Ratio: " << ratio << std::endl; - - if(ratio >= 0.9) - { - // evaluate - system(out, m_dxdt.m_v, t+dt); - m_coeff.step(m_dxdt.m_v, t+dt); - m_coeff.confirm(); - - t += dt; - dt *= ratio; - - return success; - } - else - { - dt *= ratio; - return fail; - } - }; - - const coeff_type& coeff() const - { - return m_coeff; - }; - - coeff_type& coeff() - { - return m_coeff; - }; - - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; - - aab_type m_aab; - aam_type m_aam; - - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; - - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xnew; - wrapped_state_type m_xerr; - - coeff_type m_coeff; - - step_adjuster_type m_step_adjuster; -}; - -}}} - -#endif diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 36621740..cd5b805f 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -11,10 +11,17 @@ namespace numeric{ namespace odeint{ namespace detail{ -template +template< +size_t Steps, +class State, +class Time, +size_t Type = H211PI +> struct pid_step_adjuster { public: + const static size_t steps = Steps; + typedef State state_type; typedef Time time_type; @@ -23,12 +30,11 @@ struct pid_step_adjuster typedef pid_step_adjuster_coefficients coeff_type; pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol), m_failed(0) + :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) {}; - double adjust_stepsize(const state_type &err, const time_type &dt) + time_type adjust_stepsize(time_type dt, const state_type &err) { - // basic controller m_error_storage[0] = err; m_time_storage[0] = dt; @@ -39,16 +45,16 @@ struct pid_step_adjuster { if(m_init >= 2) { - r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(Steps + 1)) * - pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(Steps + 1)) * - pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(Steps + 1)) * - pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(Steps + 1))* - pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(Steps + 1)); - } - else - { - r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(Steps + 1)); // purely integrating controller for startup - } + r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * + pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* + pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); + } + else + { + r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup + } if(r= m_dtmax) { - ratio = m_dtmax / dt; + dt = m_dtmax; } if(ratio >= 0.9) @@ -72,11 +78,9 @@ struct pid_step_adjuster else { m_init = 0; - m_failed ++; - //std::cout << m_failed << std::endl; } - return ratio; + return dt*ratio; }; private: @@ -87,8 +91,6 @@ struct pid_step_adjuster size_t m_init; double m_tol; - size_t m_failed; - coeff_type m_coeff; }; diff --git a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp index c3db2a15..b734d146 100644 --- a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp @@ -28,13 +28,13 @@ struct controller_factory< Stepper , controlled_adams_bashforth_moulton< Stepper controller_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper ) { - return controller_type( step_adjuster_type(rel_error)); + return controller_type(step_adjuster_type(abs_error)); } controller_type operator()( value_type abs_error , value_type rel_error , time_type max_dt, const stepper_type &stepper ) { - return controller_type( step_adjuster_type(rel_error, max_dt)); + return controller_type( step_adjuster_type(abs_error, max_dt)); } }; From 073e1e014310b850fb36f90314408a855089a7f0 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 21 Jun 2017 18:14:46 +0200 Subject: [PATCH 35/65] more test cases --- test/adaptive_adams_bashforth.cpp | 4 ++++ test/adaptive_adams_coefficients.cpp | 3 +++ test/polynomial.cpp | 20 ++++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/test/adaptive_adams_bashforth.cpp b/test/adaptive_adams_bashforth.cpp index 36e0001f..82de5fa7 100644 --- a/test/adaptive_adams_bashforth.cpp +++ b/test/adaptive_adams_bashforth.cpp @@ -56,4 +56,8 @@ BOOST_AUTO_TEST_CASE( test_instantiation ) s9.do_step(const_sys(), x0, t0, dt); } +BOOST_AUTO_TEST_CASE( test_copy ) +{ +} + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp index 4ef194dd..1fd6c52f 100644 --- a/test/adaptive_adams_coefficients.cpp +++ b/test/adaptive_adams_coefficients.cpp @@ -72,7 +72,10 @@ BOOST_AUTO_TEST_CASE( test_copy ) BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); aac_type c3; + deriv_type *p1 = &(c3.m_ss[0][0].m_v); + c3 = c1; + // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); } diff --git a/test/polynomial.cpp b/test/polynomial.cpp index 2b1c356a..1d993809 100644 --- a/test/polynomial.cpp +++ b/test/polynomial.cpp @@ -25,12 +25,28 @@ BOOST_AUTO_TEST_CASE( test_add_roots ) { Polynomial<3, double> poly; poly.add_root(1); - poly.add_root(0); } BOOST_AUTO_TEST_CASE( test_copy ) { - + typedef Polynomial<5, double> poly_type; + poly_type p1; + p1.add_root(1); + p1.add_root(0); + + poly_type p2(p1); + BOOST_CHECK_EQUAL(p1.m_coeff[0], p2.m_coeff[0]); + BOOST_CHECK_EQUAL(p1.m_coeff[1], p2.m_coeff[1]); + + poly_type p3; + double* a1 = &(p3.m_coeff[0]); + + p3 = p1; + + BOOST_CHECK(a1 == &(p3.m_coeff[0])); + + BOOST_CHECK_EQUAL(p1.m_coeff[0], p3.m_coeff[0]); + BOOST_CHECK_EQUAL(p1.m_coeff[1], p3.m_coeff[1]); } BOOST_AUTO_TEST_CASE( test_remove ) { From 079f3ffa4dcd4d0f32bfd60cb45f10c00656d785 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 21 Jun 2017 21:32:18 +0200 Subject: [PATCH 36/65] fixed problems in testcases --- test/controlled_adams_bashforth_moulton.cpp | 43 +++++---------------- test/integrate.cpp | 5 ++- 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/test/controlled_adams_bashforth_moulton.cpp b/test/controlled_adams_bashforth_moulton.cpp index 215902fc..2a570782 100644 --- a/test/controlled_adams_bashforth_moulton.cpp +++ b/test/controlled_adams_bashforth_moulton.cpp @@ -7,6 +7,7 @@ #include +#include #include using namespace boost::unit_test; @@ -26,41 +27,17 @@ typedef double value_type; BOOST_AUTO_TEST_SUITE( controlled_adams_bashforth_moulton_test ) -BOOST_AUTO_TEST_CASE( test_copy ) -{ - controlled_adams_bashforth_moulton<3, state_type> s1; - - state_type deriv = {{1.0}}; - s1.coeff().step(deriv, 0.0); - s1.coeff().confirm(); - s1.coeff().step(deriv, 1.0); - s1.coeff().confirm(); - s1.coeff().step(deriv, 2.0); - s1.coeff().confirm(); - - controlled_adams_bashforth_moulton<3, state_type> s2(s1); - BOOST_CHECK_CLOSE(s2.coeff().m_ss[0][0].m_v[0], s1.coeff().m_ss[0][0].m_v[0], 1e-14); - BOOST_CHECK_CLOSE(s2.coeff().m_ss[1][0].m_v[0], s1.coeff().m_ss[1][0].m_v[0], 1e-14); - BOOST_CHECK((&(s2.coeff().m_ss[0]) != &(s1.coeff().m_ss[0]))); - - controlled_adams_bashforth_moulton<3, state_type> s3; - s3 = s1; - - BOOST_CHECK_CLOSE(s3.coeff().m_ss[0][0].m_v[0], s1.coeff().m_ss[0][0].m_v[0], 1e-14); - BOOST_CHECK_CLOSE(s3.coeff().m_ss[1][0].m_v[0], s1.coeff().m_ss[1][0].m_v[0], 1e-14); -} - BOOST_AUTO_TEST_CASE( test_instantiation ) { - controlled_adams_bashforth_moulton<1, state_type> s1; - controlled_adams_bashforth_moulton<2, state_type> s2; - controlled_adams_bashforth_moulton<3, state_type> s3; - controlled_adams_bashforth_moulton<4, state_type> s4; - controlled_adams_bashforth_moulton<5, state_type> s5; - controlled_adams_bashforth_moulton<6, state_type> s6; - controlled_adams_bashforth_moulton<7, state_type> s7; - controlled_adams_bashforth_moulton<8, state_type> s8; - controlled_adams_bashforth_moulton<9, state_type> s9; + controlled_adams_bashforth_moulton > s1; + controlled_adams_bashforth_moulton > s2; + controlled_adams_bashforth_moulton > s3; + controlled_adams_bashforth_moulton > s4; + controlled_adams_bashforth_moulton > s5; + controlled_adams_bashforth_moulton > s6; + controlled_adams_bashforth_moulton > s7; + controlled_adams_bashforth_moulton > s8; + controlled_adams_bashforth_moulton > s9; state_type x = {{ 10.0 }}; value_type t = 0.0 , dt = 0.01; diff --git a/test/integrate.cpp b/test/integrate.cpp index 2f8b7459..0c4ee7ff 100644 --- a/test/integrate.cpp +++ b/test/integrate.cpp @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -242,8 +243,8 @@ class stepper_methods : public mpl::vector< bulirsch_stoer< state_type > , dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > >, adaptive_adams_bashforth<3, state_type>, - controlled_adams_bashforth_moulton<3, state_type, value_type>, - controlled_adams_bashforth_moulton<5, state_type, value_type> + controlled_adams_bashforth_moulton >, + controlled_adams_bashforth_moulton > //bulirsch_stoer_dense_out< state_type > > { }; From d0dad9a53a61e082ef274f6afd9365c38e147ed3 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 22 Jun 2017 17:44:49 +0200 Subject: [PATCH 37/65] changed tabs to spaces in all files --- .../stepper/adaptive_adams_bashforth.hpp | 172 ++++++------- .../adaptive_adams_bashforth_moulton.hpp | 238 +++++++++--------- .../odeint/stepper/adaptive_adams_moulton.hpp | 64 ++--- .../controlled_adams_bashforth_moulton.hpp | 154 ++++++------ .../detail/adaptive_adams_coefficients.hpp | 187 ++++++-------- .../stepper/detail/pid_step_adjuster.hpp | 116 ++++----- .../detail/pid_step_adjuster_coefficients.hpp | 180 ++++++------- .../odeint/stepper/detail/polynomial.hpp | 206 +++++++-------- test/adaptive_adams_bashforth.cpp | 48 ++-- test/adaptive_adams_coefficients.cpp | 70 +++--- test/controlled_adams_bashforth_moulton.cpp | 38 +-- test/polynomial.cpp | 62 ++--- 12 files changed, 755 insertions(+), 780 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index 1b8821bd..4101d2ba 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -35,114 +35,114 @@ class Resizer = initially_resizer > class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps; + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef Resizer resizer_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; - typedef stepper_tag stepper_category; + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + typedef stepper_tag stepper_category; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; + typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; - adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) - :algebra_stepper_base_type( algebra ) , - m_dxdt_resizer(), m_xnew_resizer() - {}; + adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) + :algebra_stepper_base_type( algebra ) , + m_dxdt_resizer(), m_xnew_resizer() + {}; - order_type order() const - { - return order_value; - }; + order_type order() const + { + return order_value; + }; - template - void do_step(System system, state_type & inOut, time_type t, time_type dt) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + void do_step(System system, state_type & inOut, time_type t, time_type dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, m_xnew.m_v, dt); - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - }; + do_step(system, inOut, t, m_xnew.m_v, dt); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; - template - void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - system(in, m_dxdt.m_v, t); - m_coeff.step(m_dxdt.m_v, t); - m_coeff.confirm(); + system(in, m_dxdt.m_v, t); + m_coeff.step(m_dxdt.m_v, t); + m_coeff.confirm(); - do_step_impl(m_coeff, in, t, out, dt); - }; + do_step_impl(m_coeff, in, t, out, dt); + }; - void do_step_impl(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type dt) - { - coeff.poly.reset(); - out = in; + void do_step_impl(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type dt) + { + coeff.poly.reset(); + out = in; - // integrating - for(size_t i=0; i0) - { - coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); - } + // integrating + for(size_t i=0; i0) + { + coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); + } - time_type c = coeff.poly.evaluate_integrated(dt); - coeff.m_c[i] = c; + time_type c = coeff.poly.evaluate_integrated(dt); + coeff.m_c[i] = c; - // predict next state - this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, typename Operations::template scale_sum2(1.0, c)); - } - }; + // predict next state + this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, typename Operations::template scale_sum2(1.0, c)); + } + }; - const coeff_type& coeff() const - { - return m_coeff; - }; + const coeff_type& coeff() const + { + return m_coeff; + }; - coeff_type& coeff() - { - return m_coeff; - }; + coeff_type& coeff() + { + return m_coeff; + }; - void reset() - { - m_coeff.reset(); - }; + void reset() + { + m_coeff.reset(); + }; - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; - resizer_type m_dxdt_resizer; - resizer_type m_xnew_resizer; + resizer_type m_dxdt_resizer; + resizer_type m_xnew_resizer; - coeff_type m_coeff; - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xnew; + coeff_type m_coeff; + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; }; } diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index cd90db78..f882e158 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -37,158 +37,158 @@ class Resizer = initially_resizer > class adaptive_adams_bashforth_moulton: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps; + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef Resizer resizer_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef detail::rotating_buffer error_storage_type; + typedef detail::rotating_buffer error_storage_type; - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; - typedef error_stepper_tag stepper_category; + typedef error_stepper_tag stepper_category; - adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff() - {}; + adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff() + {}; - order_type order() - { - return order_value + 1; - } + order_type order() + { + return order_value + 1; + } - order_type stepper_order() - { - return order_value + 1; - } + order_type stepper_order() + { + return order_value + 1; + } - order_type error_order() - { - return order_value; - } + order_type error_order() + { + return order_value; + } - template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt) - { - m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, dt, m_xerr.m_v); - }; + do_step(system, inOut, t, dt, m_xerr.m_v); + }; - template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) - { - m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, in, t, out, dt, m_xerr.m_v); - }; + do_step(system, in, t, out, dt, m_xerr.m_v); + }; - template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, m_xnew.m_v, dt, xerr); - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - }; + do_step(system, inOut, t, m_xnew.m_v, dt, xerr); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; - template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) - { - do_step_impl(system, m_coeff, in, t, out, dt, xerr); + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + do_step_impl(system, m_coeff, in, t, out, dt, xerr); - system(out, m_dxdt.m_v, t+dt); - m_coeff.step(m_dxdt.m_v, t+dt); - m_coeff.confirm(); - }; + system(out, m_dxdt.m_v, t+dt); + m_coeff.step(m_dxdt.m_v, t+dt); + m_coeff.confirm(); + }; - template - void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - if(coeff.m_effective_order == 1) - { - system(in, m_dxdt.m_v, t); + template + void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + if(coeff.m_effective_order == 1) + { + system(in, m_dxdt.m_v, t); - coeff.step(m_dxdt.m_v, t); - coeff.confirm(); - } - // predict - m_aab.do_step_impl(coeff, in, t, out, dt); + coeff.step(m_dxdt.m_v, t); + coeff.confirm(); + } + // predict + m_aab.do_step_impl(coeff, in, t, out, dt); - // evaluate - system(out, m_dxdt.m_v, t + dt); - coeff.step(m_dxdt.m_v, t + dt); + // evaluate + system(out, m_dxdt.m_v, t + dt); + coeff.step(m_dxdt.m_v, t + dt); - boost::numeric::odeint::copy( out, xerr); + boost::numeric::odeint::copy( out, xerr); - // correct - m_aam.do_step(coeff, in, t, out, dt); + // correct + m_aam.do_step(coeff, in, t, out, dt); - // Error calculation - m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); - }; + // Error calculation + m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); + }; - const coeff_type& coeff() const - { - return m_coeff; - }; + const coeff_type& coeff() const + { + return m_coeff; + }; - coeff_type& coeff() - { - return m_coeff; - }; + coeff_type& coeff() + { + return m_coeff; + }; - wrapped_deriv_type m_dxdt; + wrapped_deriv_type m_dxdt; - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; - aab_type m_aab; - aam_type m_aam; + aab_type m_aab; + aam_type m_aam; - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; - wrapped_state_type m_xnew; - wrapped_state_type m_xerr; + wrapped_state_type m_xnew; + wrapped_state_type m_xerr; - coeff_type m_coeff; + coeff_type m_coeff; }; }}} diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp index 88693b7f..6f0745e7 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -28,46 +28,46 @@ class Resizer = initially_resizer > class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps + 1; + public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps + 1; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; + typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; - adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ) - {}; + adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ) + {}; - order_type order() const - { - return order_value; - }; + order_type order() const + { + return order_value; + }; - void do_step(coeff_type & coeff, const state_type & in, - time_type t, state_type & out, time_type &dt) - { - coeff.poly.add_root(0); - out = in; + void do_step(coeff_type & coeff, const state_type & in, + time_type t, state_type & out, time_type &dt) + { + coeff.poly.add_root(0); + out = in; - // integrating - for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); - } - }; + // integrating + for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); + } + }; }; } diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 2002d5d4..4e4c739c 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -18,106 +18,106 @@ namespace odeint { template< class ErrorStepper, class StepAdjuster = detail::pid_step_adjuster, + typename ErrorStepper::state_type, + typename ErrorStepper::time_type, + detail::H211PI>, class Resizer = initially_resizer > class controlled_adams_bashforth_moulton { - public: - typedef ErrorStepper 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; + public: + typedef ErrorStepper 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::algebra_type algebra_type; - typedef typename stepper_type::operations_type operations_type; - typedef Resizer resizer_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + typedef Resizer resizer_type; - typedef StepAdjuster step_adjuster_type; - typedef controlled_stepper_tag stepper_category; + typedef StepAdjuster step_adjuster_type; + typedef controlled_stepper_tag stepper_category; - typedef typename stepper_type::wrapped_state_type wrapped_state_type; - typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; + typedef typename stepper_type::wrapped_state_type wrapped_state_type; + typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; - typedef controlled_adams_bashforth_moulton controlled_stepper_type; + typedef controlled_adams_bashforth_moulton controlled_stepper_type; - controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) - :m_stepper(), m_coeff(m_stepper.coeff()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_step_adjuster(step_adjuster) - {}; + controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) + :m_stepper(), m_coeff(m_stepper.coeff()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_step_adjuster(step_adjuster) + {}; - template - controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + template + controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); + controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); - if(res == success) - boost::numeric::odeint::copy( m_xnew.m_v , inOut); + if(res == success) + boost::numeric::odeint::copy( m_xnew.m_v , inOut); - return res; - }; + return res; + }; - template - controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) - { - m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); + template + controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); - time_type dtPrev = dt; - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); + time_type dtPrev = dt; + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); - if(dt / dtPrev >= 0.9) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + if(dt / dtPrev >= 0.9) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - system(out, m_dxdt.m_v, t+dtPrev); - m_coeff.step(m_dxdt.m_v, t+dtPrev); - m_coeff.confirm(); + system(out, m_dxdt.m_v, t+dtPrev); + m_coeff.step(m_dxdt.m_v, t+dtPrev); + m_coeff.confirm(); - t += dtPrev; - return success; - } - else - { - return fail; - } - }; + t += dtPrev; + return success; + } + else + { + return fail; + } + }; - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; + private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; - stepper_type m_stepper; - typename stepper_type::coeff_type &m_coeff; + stepper_type m_stepper; + typename stepper_type::coeff_type &m_coeff; - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xerr; - wrapped_state_type m_xnew; + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xerr; + wrapped_state_type m_xnew; - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; - step_adjuster_type m_step_adjuster; + step_adjuster_type m_step_adjuster; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index b58fb7e5..e4c35bc1 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -32,130 +32,105 @@ class Resizer = initially_resizer > struct adaptive_adams_coefficients { - public: - static const size_t steps = Steps; + public: + static const size_t steps = Steps; - typedef Deriv deriv_type; - typedef Time time_type; - typedef state_wrapper wrapped_deriv_type; - typedef detail::rotating_buffer step_storage_type; // +1 for moulton - typedef detail::rotating_buffer time_storage_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef state_wrapper wrapped_deriv_type; + typedef detail::rotating_buffer step_storage_type; // +1 for moulton + typedef detail::rotating_buffer time_storage_type; - typedef Algebra algebra_type; - typedef Operations operations_type; + typedef Algebra algebra_type; + typedef Operations operations_type; - typedef Resizer resizer_type; + typedef Resizer resizer_type; - typedef adaptive_adams_coefficients aac_type; - typedef detail::Polynomial poly_type; + typedef adaptive_adams_coefficients aac_type; + typedef detail::Polynomial poly_type; - adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) - :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) - {}; + adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) + :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) + {}; - /*aac_type &operator=(const aac_type & rhs) - { - this->poly = rhs.poly; - this->m_c = rhs.m_c; - // this->m_ss = rhs.m_ss; + void step(const deriv_type &deriv, const time_type &t) + { + m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); - for(size_t i=0; im_ss[i][j] = rhs.m_ss[i][j]; - } - } + m_tts[0] = t; + m_tss[0][0].m_v = deriv; - this->m_ts = rhs.m_ts; - this->m_tss = rhs.m_tss; - this->m_tts = rhs.m_tts; - this->m_effective_order = rhs.m_effective_order; + for(size_t i=1; i(1/dt, -1/dt)); + } + }; + void confirm() + { + for(size_t i=0; im_algebra = rhs.m_algebra; - this->m_resizer = rhs.m_resizer; + m_ts = m_tts; + m_tts.rotate(); - return *this; - }*/ + if(m_effective_order < steps+1) + { + ++m_effective_order; + } + }; - void step(const deriv_type &deriv, const time_type &t) - { - m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); + void reset() + { + poly.reset(); + m_effective_order = 1; + }; - m_tts[0] = t; - m_tss[0][0].m_v = deriv; + void pretty_print() + { + for(size_t k=0; k<2; ++k) + { + for(size_t i=0; i(1/dt, -1/dt)); - } - }; - void confirm() - { - for(size_t i=0; i m_ss; + time_storage_type m_ts; - if(m_effective_order < steps+1) - { - ++m_effective_order; - } - }; + boost::array m_tss; + time_storage_type m_tts; - void reset() - { - poly.reset(); - m_effective_order = 1; - }; + size_t m_effective_order; - void pretty_print() - { - for(size_t k=0; k<2; ++k) - { - for(size_t i=0; i + bool resize_tss_impl( const StateType &x ) + { + bool resized( false ); + for( size_t i=0 ; i::type() ); + + m_tts[i] = 0; + } + return resized; + }; - poly_type poly; - time_storage_type m_c; - - boost::array m_ss; - time_storage_type m_ts; - - boost::array m_tss; - time_storage_type m_tts; - - size_t m_effective_order; - - private: - template< class StateType > - bool resize_tss_impl( const StateType &x ) - { - bool resized( false ); - for( size_t i=0 ; i::type() ); - - m_tts[i] = 0; - } - return resized; - }; - - resizer_type m_resizer; - algebra_type m_algebra; + resizer_type m_resizer; + algebra_type m_algebra; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index cd5b805f..06ec3492 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -19,79 +19,79 @@ size_t Type = H211PI > struct pid_step_adjuster { - public: - const static size_t steps = Steps; + public: + const static size_t steps = Steps; - typedef State state_type; - typedef Time time_type; + typedef State state_type; + typedef Time time_type; - typedef rotating_buffer error_storage_type; - typedef rotating_buffer time_storage_type; - typedef pid_step_adjuster_coefficients coeff_type; + typedef rotating_buffer error_storage_type; + typedef rotating_buffer time_storage_type; + typedef pid_step_adjuster_coefficients coeff_type; - pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) - {}; + pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) + :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) + {}; - time_type adjust_stepsize(time_type dt, const state_type &err) - { - m_error_storage[0] = err; - m_time_storage[0] = dt; + time_type adjust_stepsize(time_type dt, const state_type &err) + { + m_error_storage[0] = err; + m_time_storage[0] = dt; - double ratio = 100; - double r; + double ratio = 100; + double r; - for(size_t i=0; i= 2) - { - r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * - pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* - pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); - } - else - { - r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup - } + for(size_t i=0; i= 2) + { + r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * + pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* + pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); + } + else + { + r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup + } - if(r= m_dtmax) - { - dt = m_dtmax; - } + if(ratio*dt >= m_dtmax) + { + dt = m_dtmax; + } - if(ratio >= 0.9) - { - m_error_storage.rotate(); - m_time_storage.rotate(); + if(ratio >= 0.9) + { + m_error_storage.rotate(); + m_time_storage.rotate(); - ++m_init; - } - else - { - m_init = 0; - } + ++m_init; + } + else + { + m_init = 0; + } - return dt*ratio; - }; + return dt*ratio; + }; - private: - time_type m_dtmax; - error_storage_type m_error_storage; - time_storage_type m_time_storage; + private: + time_type m_dtmax; + error_storage_type m_error_storage; + time_storage_type m_time_storage; - size_t m_init; - double m_tol; + size_t m_init; + double m_tol; - coeff_type m_coeff; + coeff_type m_coeff; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp index 2cd7ce03..1b7c7735 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -9,15 +9,15 @@ namespace odeint{ namespace detail{ enum adjuster_type{ - BASIC, - H0211, - H211b, - H211PI, - H0312, - H312b, - H312PID, - H0321, - H321 + BASIC, + H0211, + H211b, + H211PI, + H0312, + H312b, + H312PID, + H0321, + H321 }; template @@ -27,135 +27,135 @@ template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1; - (*this)[1] = 0; - (*this)[2] = 0; - (*this)[3] = 0; - (*this)[4] = 0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1; + (*this)[1] = 0; + (*this)[2] = 0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/2.0; - (*this)[1] = 1.0/2.0; - (*this)[2] = 0; - (*this)[3] = 1.0/2.0; - (*this)[4] = 0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/2.0; + (*this)[1] = 1.0/2.0; + (*this)[2] = 0; + (*this)[3] = 1.0/2.0; + (*this)[4] = 0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/5.0; - (*this)[1] = 2.0/5.0; - (*this)[2] = 0; - (*this)[3] = 1.0/5.0; - (*this)[4] = 0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/5.0; + (*this)[1] = 2.0/5.0; + (*this)[2] = 0; + (*this)[3] = 1.0/5.0; + (*this)[4] = 0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/6.0; - (*this)[1] = 2.0/6.0; - (*this)[2] = 0; - (*this)[3] = 0; - (*this)[4] = 0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/6.0; + (*this)[1] = 2.0/6.0; + (*this)[2] = 0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/4.0; - (*this)[1] = 2.0/2.0; - (*this)[2] = 1.0/4.0; - (*this)[3] = 3.0/4.0; - (*this)[4] = 1.0/4.0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/4.0; + (*this)[1] = 2.0/2.0; + (*this)[2] = 1.0/4.0; + (*this)[3] = 3.0/4.0; + (*this)[4] = 1.0/4.0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/6.0; - (*this)[1] = 2.0/6.0; - (*this)[2] = 1.0/6.0; - (*this)[3] = 3.0/6.0; - (*this)[4] = 1.0/6.0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/6.0; + (*this)[1] = 2.0/6.0; + (*this)[2] = 1.0/6.0; + (*this)[3] = 3.0/6.0; + (*this)[4] = 1.0/6.0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/18.0; - (*this)[1] = 2.0/9.0; - (*this)[2] = 1.0/18.0; - (*this)[3] = 0; - (*this)[4] = 0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/18.0; + (*this)[1] = 2.0/9.0; + (*this)[2] = 1.0/18.0; + (*this)[3] = 0; + (*this)[4] = 0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 5.0/4.0; - (*this)[1] = 1.0/2.0; - (*this)[2] = -3.0/4.0; - (*this)[3] = -1.0/4.0; - (*this)[4] = -3.0/4.0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 5.0/4.0; + (*this)[1] = 1.0/2.0; + (*this)[2] = -3.0/4.0; + (*this)[3] = -1.0/4.0; + (*this)[4] = -3.0/4.0; + } }; template<> class pid_step_adjuster_coefficients : public boost::array { public: - pid_step_adjuster_coefficients() - : boost::array() - { - (*this)[0] = 1.0/3.0; - (*this)[1] = 1.0/18.0; - (*this)[2] = -5.0/18.0; - (*this)[3] = -5.0/16.0; - (*this)[4] = -1.0/6.0; - } + pid_step_adjuster_coefficients() + : boost::array() + { + (*this)[0] = 1.0/3.0; + (*this)[1] = 1.0/18.0; + (*this)[2] = -5.0/18.0; + (*this)[3] = -5.0/16.0; + (*this)[4] = -1.0/6.0; + } }; } diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp index e8d25ad8..39f5cbb7 100644 --- a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp +++ b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp @@ -15,127 +15,127 @@ class Time > class Polynomial { - public: - typedef Time time_type; - typedef Polynomial poly_type; + public: + typedef Time time_type; + typedef Polynomial poly_type; - Polynomial() - { - for(size_t i = 0; i coeff) - { - m_coeff = coeff; - }; + Polynomial(boost::array coeff) + { + m_coeff = coeff; + }; - Polynomial integrate() - { - boost::array coeff_int; - coeff_int[order] = 0; + Polynomial integrate() + { + boost::array coeff_int; + coeff_int[order] = 0; - for(size_t i=0; i polyInt(coeff_int); - return polyInt; - }; + Polynomial polyInt(coeff_int); + return polyInt; + }; - time_type evaluate(const time_type &t) - { - // fma: x*y+z - m_res = m_coeff[0]; - for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); - m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; - } + time_type evaluate_integrated(const time_type &t) + { + m_res = m_coeff[0]/order; + for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); + m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; + } - return m_res; - } + return m_res; + } - void add_root(const time_type &root) - { - for(size_t j=0; j from_roots(time_type * roots, unsigned short num_roots) - { - time_type coeff[order] = {0}; - coeff[order-1] = 1; + static Polynomial from_roots(time_type * roots, unsigned short num_roots) + { + time_type coeff[order] = {0}; + coeff[order-1] = 1; - for(size_t i=0; i poly(coeff); - return poly; - }; + for(size_t i=0; i poly(coeff); + return poly; + }; - // first element is highest order - boost::array m_coeff; - private: - time_type m_res; + // first element is highest order + boost::array m_coeff; + private: + time_type m_res; }; }}}} diff --git a/test/adaptive_adams_bashforth.cpp b/test/adaptive_adams_bashforth.cpp index 82de5fa7..3ec1a62c 100644 --- a/test/adaptive_adams_bashforth.cpp +++ b/test/adaptive_adams_bashforth.cpp @@ -27,33 +27,33 @@ BOOST_AUTO_TEST_SUITE( adaptive_adams_bashforth_test ) BOOST_AUTO_TEST_CASE( test_instantiation ) { - typedef double time_type; - typedef std::vector state_type; + typedef double time_type; + typedef std::vector state_type; - adaptive_adams_bashforth<1, state_type> s1; - adaptive_adams_bashforth<2, state_type> s2; - adaptive_adams_bashforth<3, state_type> s3; - adaptive_adams_bashforth<4, state_type> s4; - adaptive_adams_bashforth<5, state_type> s5; - adaptive_adams_bashforth<6, state_type> s6; - adaptive_adams_bashforth<7, state_type> s7; - adaptive_adams_bashforth<8, state_type> s8; - adaptive_adams_bashforth<9, state_type> s9; + adaptive_adams_bashforth<1, state_type> s1; + adaptive_adams_bashforth<2, state_type> s2; + adaptive_adams_bashforth<3, state_type> s3; + adaptive_adams_bashforth<4, state_type> s4; + adaptive_adams_bashforth<5, state_type> s5; + adaptive_adams_bashforth<6, state_type> s6; + adaptive_adams_bashforth<7, state_type> s7; + adaptive_adams_bashforth<8, state_type> s8; + adaptive_adams_bashforth<9, state_type> s9; - state_type x0; - x0.push_back(0); - time_type t0 = 0.0; - time_type dt = 0.1; + state_type x0; + x0.push_back(0); + time_type t0 = 0.0; + time_type dt = 0.1; - s1.do_step(const_sys(), x0, t0, dt); - s2.do_step(const_sys(), x0, t0, dt); - s3.do_step(const_sys(), x0, t0, dt); - s4.do_step(const_sys(), x0, t0, dt); - s5.do_step(const_sys(), x0, t0, dt); - s6.do_step(const_sys(), x0, t0, dt); - s7.do_step(const_sys(), x0, t0, dt); - s8.do_step(const_sys(), x0, t0, dt); - s9.do_step(const_sys(), x0, t0, dt); + s1.do_step(const_sys(), x0, t0, dt); + s2.do_step(const_sys(), x0, t0, dt); + s3.do_step(const_sys(), x0, t0, dt); + s4.do_step(const_sys(), x0, t0, dt); + s5.do_step(const_sys(), x0, t0, dt); + s6.do_step(const_sys(), x0, t0, dt); + s7.do_step(const_sys(), x0, t0, dt); + s8.do_step(const_sys(), x0, t0, dt); + s9.do_step(const_sys(), x0, t0, dt); } BOOST_AUTO_TEST_CASE( test_copy ) diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp index 1fd6c52f..9632ad19 100644 --- a/test/adaptive_adams_coefficients.cpp +++ b/test/adaptive_adams_coefficients.cpp @@ -25,58 +25,58 @@ 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; + const static size_t steps = step_type::value; - typedef std::vector deriv_type; - typedef double time_type; + typedef std::vector deriv_type; + typedef double time_type; typedef detail::adaptive_adams_coefficients aac_type; - std::vector deriv; - deriv.push_back(-1); + std::vector deriv; + deriv.push_back(-1); - aac_type coeff; - for(size_t i=0; i deriv_type; - typedef double time_type; + typedef std::vector deriv_type; + typedef double time_type; - typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; - aac_type c1; + typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; + aac_type c1; - deriv_type deriv(1); - deriv[0] = 1.0; + deriv_type deriv(1); + deriv[0] = 1.0; - c1.step(deriv, 0.0); - c1.confirm(); - c1.step(deriv, 1.0); - c1.confirm(); - c1.step(deriv, 2.0); - c1.confirm(); + c1.step(deriv, 0.0); + c1.confirm(); + c1.step(deriv, 1.0); + c1.confirm(); + c1.step(deriv, 2.0); + c1.confirm(); - aac_type c2(c1); - BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); - BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); + aac_type c2(c1); + BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); + BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); - aac_type c3; - deriv_type *p1 = &(c3.m_ss[0][0].m_v); + aac_type c3; + deriv_type *p1 = &(c3.m_ss[0][0].m_v); - c3 = c1; - // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); - BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); + c3 = c1; + // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); + BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/controlled_adams_bashforth_moulton.cpp b/test/controlled_adams_bashforth_moulton.cpp index 2a570782..40d65720 100644 --- a/test/controlled_adams_bashforth_moulton.cpp +++ b/test/controlled_adams_bashforth_moulton.cpp @@ -29,28 +29,28 @@ BOOST_AUTO_TEST_SUITE( controlled_adams_bashforth_moulton_test ) BOOST_AUTO_TEST_CASE( test_instantiation ) { - controlled_adams_bashforth_moulton > s1; - controlled_adams_bashforth_moulton > s2; - controlled_adams_bashforth_moulton > s3; - controlled_adams_bashforth_moulton > s4; - controlled_adams_bashforth_moulton > s5; - controlled_adams_bashforth_moulton > s6; - controlled_adams_bashforth_moulton > s7; - controlled_adams_bashforth_moulton > s8; - controlled_adams_bashforth_moulton > s9; + controlled_adams_bashforth_moulton > s1; + controlled_adams_bashforth_moulton > s2; + controlled_adams_bashforth_moulton > s3; + controlled_adams_bashforth_moulton > s4; + controlled_adams_bashforth_moulton > s5; + controlled_adams_bashforth_moulton > s6; + controlled_adams_bashforth_moulton > s7; + controlled_adams_bashforth_moulton > s8; + controlled_adams_bashforth_moulton > s9; - state_type x = {{ 10.0 }}; + 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); + 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/test/polynomial.cpp b/test/polynomial.cpp index 1d993809..52bf30d8 100644 --- a/test/polynomial.cpp +++ b/test/polynomial.cpp @@ -16,61 +16,61 @@ BOOST_AUTO_TEST_SUITE( polynomial_test ) BOOST_AUTO_TEST_CASE( test_init ) { - Polynomial<3, double> p1; + Polynomial<3, double> p1; - boost::array coeff = {0, 1, 2}; - Polynomial<3, double> p2(coeff); + boost::array coeff = {0, 1, 2}; + Polynomial<3, double> p2(coeff); } BOOST_AUTO_TEST_CASE( test_add_roots ) { - Polynomial<3, double> poly; - poly.add_root(1); - poly.add_root(0); + Polynomial<3, double> poly; + poly.add_root(1); + poly.add_root(0); } BOOST_AUTO_TEST_CASE( test_copy ) { - typedef Polynomial<5, double> poly_type; - poly_type p1; - p1.add_root(1); - p1.add_root(0); + typedef Polynomial<5, double> poly_type; + poly_type p1; + p1.add_root(1); + p1.add_root(0); - poly_type p2(p1); - BOOST_CHECK_EQUAL(p1.m_coeff[0], p2.m_coeff[0]); - BOOST_CHECK_EQUAL(p1.m_coeff[1], p2.m_coeff[1]); + poly_type p2(p1); + BOOST_CHECK_EQUAL(p1.m_coeff[0], p2.m_coeff[0]); + BOOST_CHECK_EQUAL(p1.m_coeff[1], p2.m_coeff[1]); - poly_type p3; - double* a1 = &(p3.m_coeff[0]); + poly_type p3; + double* a1 = &(p3.m_coeff[0]); - p3 = p1; + p3 = p1; - BOOST_CHECK(a1 == &(p3.m_coeff[0])); + BOOST_CHECK(a1 == &(p3.m_coeff[0])); - BOOST_CHECK_EQUAL(p1.m_coeff[0], p3.m_coeff[0]); - BOOST_CHECK_EQUAL(p1.m_coeff[1], p3.m_coeff[1]); + BOOST_CHECK_EQUAL(p1.m_coeff[0], p3.m_coeff[0]); + BOOST_CHECK_EQUAL(p1.m_coeff[1], p3.m_coeff[1]); } BOOST_AUTO_TEST_CASE( test_remove ) { - + } BOOST_AUTO_TEST_CASE( test_integrate ) { - + } BOOST_AUTO_TEST_CASE( test_evaluate ) { - boost::array c1 = {2, 1, 0}; - Polynomial<3, double> p1(c1); + boost::array c1 = {2, 1, 0}; + Polynomial<3, double> p1(c1); - BOOST_CHECK_EQUAL(p1.evaluate(0), 0); - BOOST_CHECK_EQUAL(p1.evaluate(1), 3); - BOOST_CHECK_EQUAL(p1.evaluate(2), 10); + BOOST_CHECK_EQUAL(p1.evaluate(0), 0); + BOOST_CHECK_EQUAL(p1.evaluate(1), 3); + BOOST_CHECK_EQUAL(p1.evaluate(2), 10); - boost::array c2 = {0.001, 10, 0, 3, 1}; - Polynomial<5, double> p2(c2); + boost::array c2 = {0.001, 10, 0, 3, 1}; + Polynomial<5, double> p2(c2); - BOOST_CHECK_CLOSE(p2.evaluate(0), 1, 0.001); - BOOST_CHECK_CLOSE(p2.evaluate(0.001), 1.003, 0.001); - BOOST_CHECK_CLOSE(p2.evaluate(1.001), 14.034, 0.001); + BOOST_CHECK_CLOSE(p2.evaluate(0), 1, 0.001); + BOOST_CHECK_CLOSE(p2.evaluate(0.001), 1.003, 0.001); + BOOST_CHECK_CLOSE(p2.evaluate(1.001), 14.034, 0.001); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 92e76299f1c6474569c926e36daef82760a01110 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 22 Jun 2017 17:50:49 +0200 Subject: [PATCH 38/65] corrected indentation --- .../stepper/adaptive_adams_bashforth.hpp | 185 ++++++------- .../adaptive_adams_bashforth_moulton.hpp | 258 +++++++++--------- .../odeint/stepper/adaptive_adams_moulton.hpp | 66 ++--- .../controlled_adams_bashforth_moulton.hpp | 156 +++++------ .../detail/adaptive_adams_coefficients.hpp | 152 +++++------ .../stepper/detail/pid_step_adjuster.hpp | 118 ++++---- .../odeint/stepper/detail/polynomial.hpp | 230 ++++++++-------- 7 files changed, 585 insertions(+), 580 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index 4101d2ba..bb39fca8 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -35,114 +35,115 @@ class Resizer = initially_resizer > class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps; +public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef Resizer resizer_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; - typedef stepper_tag stepper_category; + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; + typedef stepper_tag stepper_category; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; + typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; - adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) - :algebra_stepper_base_type( algebra ) , - m_dxdt_resizer(), m_xnew_resizer() - {}; + adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) + :algebra_stepper_base_type( algebra ) , + m_dxdt_resizer(), m_xnew_resizer() + {}; - order_type order() const + order_type order() const + { + return order_value; + }; + + template + void do_step(System system, state_type & inOut, time_type t, time_type dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, m_xnew.m_v, dt); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; + + template + void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + system(in, m_dxdt.m_v, t); + m_coeff.step(m_dxdt.m_v, t); + m_coeff.confirm(); + + do_step_impl(m_coeff, in, t, out, dt); + }; + + void do_step_impl(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type dt) + { + coeff.poly.reset(); + out = in; + + // integrating + for(size_t i=0; i - void do_step(System system, state_type & inOut, time_type t, time_type dt) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - do_step(system, inOut, t, m_xnew.m_v, dt); - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - }; - - template - void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - system(in, m_dxdt.m_v, t); - m_coeff.step(m_dxdt.m_v, t); - m_coeff.confirm(); - - do_step_impl(m_coeff, in, t, out, dt); - }; - - void do_step_impl(coeff_type & coeff, const state_type & in, time_type t, state_type & out, time_type dt) - { - coeff.poly.reset(); - out = in; - - // integrating - for(size_t i=0; i0) { - if(i>0) - { - coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); - } - - time_type c = coeff.poly.evaluate_integrated(dt); - coeff.m_c[i] = c; - - // predict next state - this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, typename Operations::template scale_sum2(1.0, c)); + coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); } - }; - const coeff_type& coeff() const - { - return m_coeff; - }; + time_type c = coeff.poly.evaluate_integrated(dt); + coeff.m_c[i] = c; - coeff_type& coeff() - { - return m_coeff; - }; + // predict next state + this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, + typename Operations::template scale_sum2(1.0, c)); + } + }; - void reset() - { - m_coeff.reset(); - }; + const coeff_type& coeff() const + { + return m_coeff; + }; - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; + coeff_type& coeff() + { + return m_coeff; + }; - resizer_type m_dxdt_resizer; - resizer_type m_xnew_resizer; + void reset() + { + m_coeff.reset(); + }; - coeff_type m_coeff; - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xnew; +private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; + + resizer_type m_dxdt_resizer; + resizer_type m_xnew_resizer; + + coeff_type m_coeff; + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; }; } diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index f882e158..dd70a05c 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -37,158 +37,158 @@ class Resizer = initially_resizer > class adaptive_adams_bashforth_moulton: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps; +public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef Resizer resizer_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; + typedef state_wrapper wrapped_state_type; + typedef state_wrapper wrapped_deriv_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef detail::rotating_buffer error_storage_type; + typedef detail::rotating_buffer error_storage_type; - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; + typedef adaptive_adams_bashforth aab_type; + typedef adaptive_adams_moulton aam_type; + typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; - typedef error_stepper_tag stepper_category; + typedef error_stepper_tag stepper_category; - adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff() - {}; + adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_coeff() + {}; - order_type order() + order_type order() + { + return order_value + 1; + } + + order_type stepper_order() + { + return order_value + 1; + } + + order_type error_order() + { + return order_value; + } + + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, dt, m_xerr.m_v); + }; + + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, in, t, out, dt, m_xerr.m_v); + }; + + template + void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, m_xnew.m_v, dt, xerr); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + }; + + template + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + do_step_impl(system, m_coeff, in, t, out, dt, xerr); + + system(out, m_dxdt.m_v, t+dt); + m_coeff.step(m_dxdt.m_v, t+dt); + m_coeff.confirm(); + }; + + template + void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + { + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + if(coeff.m_effective_order == 1) { - return order_value + 1; + system(in, m_dxdt.m_v, t); + + coeff.step(m_dxdt.m_v, t); + coeff.confirm(); } + // predict + m_aab.do_step_impl(coeff, in, t, out, dt); - order_type stepper_order() - { - return order_value + 1; - } + // evaluate + system(out, m_dxdt.m_v, t + dt); + coeff.step(m_dxdt.m_v, t + dt); - order_type error_order() - { - return order_value; - } + boost::numeric::odeint::copy( out, xerr); - template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt) - { - m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + // correct + m_aam.do_step(coeff, in, t, out, dt); - do_step(system, inOut, t, dt, m_xerr.m_v); - }; + // Error calculation + m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); + }; - template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) - { - m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + const coeff_type& coeff() const + { + return m_coeff; + }; - do_step(system, in, t, out, dt, m_xerr.m_v); - }; + coeff_type& coeff() + { + return m_coeff; + }; - template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + wrapped_deriv_type m_dxdt; - do_step(system, inOut, t, m_xnew.m_v, dt, xerr); - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - }; +private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; - template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) - { - do_step_impl(system, m_coeff, in, t, out, dt, xerr); + aab_type m_aab; + aam_type m_aam; - system(out, m_dxdt.m_v, t+dt); - m_coeff.step(m_dxdt.m_v, t+dt); - m_coeff.confirm(); - }; + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; - template - void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - if(coeff.m_effective_order == 1) - { - system(in, m_dxdt.m_v, t); + wrapped_state_type m_xnew; + wrapped_state_type m_xerr; - coeff.step(m_dxdt.m_v, t); - coeff.confirm(); - } - // predict - m_aab.do_step_impl(coeff, in, t, out, dt); - - // evaluate - system(out, m_dxdt.m_v, t + dt); - coeff.step(m_dxdt.m_v, t + dt); - - boost::numeric::odeint::copy( out, xerr); - - // correct - m_aam.do_step(coeff, in, t, out, dt); - - // Error calculation - m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); - }; - - const coeff_type& coeff() const - { - return m_coeff; - }; - - coeff_type& coeff() - { - return m_coeff; - }; - - wrapped_deriv_type m_dxdt; - - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; - - aab_type m_aab; - aam_type m_aam; - - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; - - wrapped_state_type m_xnew; - wrapped_state_type m_xerr; - - coeff_type m_coeff; + coeff_type m_coeff; }; }}} diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp index 6f0745e7..191ad34a 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp @@ -28,46 +28,46 @@ class Resizer = initially_resizer > class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations > { - public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps + 1; +public: + static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps + 1; - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; + typedef State state_type; + typedef Value value_type; + typedef Deriv deriv_type; + typedef Time time_type; - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; + typedef Algebra algebra_type; + typedef Operations operations_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; - typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; + typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; - adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ) - {}; + adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) + :algebra_stepper_base_type( algebra ) + {}; - order_type order() const + order_type order() const + { + return order_value; + }; + + void do_step(coeff_type & coeff, const state_type & in, + time_type t, state_type & out, time_type &dt) + { + coeff.poly.add_root(0); + out = in; + + // integrating + for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); - } - }; + time_type c = ((i!=coeff.m_effective_order-1)?coeff.m_c[i]:coeff.poly.evaluate_integrated(dt)); + this->m_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); + } + }; }; } diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 4e4c739c..6b96150f 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -25,99 +25,99 @@ class Resizer = initially_resizer > class controlled_adams_bashforth_moulton { - public: - typedef ErrorStepper 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; +public: + typedef ErrorStepper 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::algebra_type algebra_type; - typedef typename stepper_type::operations_type operations_type; - typedef Resizer resizer_type; + typedef typename stepper_type::algebra_type algebra_type; + typedef typename stepper_type::operations_type operations_type; + typedef Resizer resizer_type; - typedef StepAdjuster step_adjuster_type; - typedef controlled_stepper_tag stepper_category; + typedef StepAdjuster step_adjuster_type; + typedef controlled_stepper_tag stepper_category; - typedef typename stepper_type::wrapped_state_type wrapped_state_type; - typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; + typedef typename stepper_type::wrapped_state_type wrapped_state_type; + typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; - typedef controlled_adams_bashforth_moulton controlled_stepper_type; + typedef controlled_adams_bashforth_moulton controlled_stepper_type; - controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) - :m_stepper(), m_coeff(m_stepper.coeff()), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_step_adjuster(step_adjuster) - {}; + controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) + :m_stepper(), m_coeff(m_stepper.coeff()), + m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), + m_step_adjuster(step_adjuster) + {}; - template - controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) + template + controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); + + if(res == success) + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + + return res; + }; + + template + controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + { + m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); + + time_type dtPrev = dt; + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); + + if(dt / dtPrev >= 0.9) { - m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); + system(out, m_dxdt.m_v, t+dtPrev); + m_coeff.step(m_dxdt.m_v, t+dtPrev); + m_coeff.confirm(); - if(res == success) - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - - return res; - }; - - template - controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + t += dtPrev; + return success; + } + else { - m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); + return fail; + } + }; - time_type dtPrev = dt; - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); +private: + template< class StateType > + bool resize_dxdt_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + }; + template< class StateType > + bool resize_xnew_impl( const StateType &x ) + { + return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); + }; - if(dt / dtPrev >= 0.9) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + stepper_type m_stepper; + typename stepper_type::coeff_type &m_coeff; - system(out, m_dxdt.m_v, t+dtPrev); - m_coeff.step(m_dxdt.m_v, t+dtPrev); - m_coeff.confirm(); + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xerr; + wrapped_state_type m_xnew; - t += dtPrev; - return success; - } - else - { - return fail; - } - }; + resizer_type m_dxdt_resizer; + resizer_type m_xerr_resizer; + resizer_type m_xnew_resizer; - private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; - - stepper_type m_stepper; - typename stepper_type::coeff_type &m_coeff; - - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xerr; - wrapped_state_type m_xnew; - - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; - - step_adjuster_type m_step_adjuster; + step_adjuster_type m_step_adjuster; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index e4c35bc1..aad33cfa 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -32,105 +32,105 @@ class Resizer = initially_resizer > struct adaptive_adams_coefficients { - public: - static const size_t steps = Steps; +public: + static const size_t steps = Steps; - typedef Deriv deriv_type; - typedef Time time_type; - typedef state_wrapper wrapped_deriv_type; - typedef detail::rotating_buffer step_storage_type; // +1 for moulton - typedef detail::rotating_buffer time_storage_type; + typedef Deriv deriv_type; + typedef Time time_type; + typedef state_wrapper wrapped_deriv_type; + typedef detail::rotating_buffer step_storage_type; // +1 for moulton + typedef detail::rotating_buffer time_storage_type; - typedef Algebra algebra_type; - typedef Operations operations_type; + typedef Algebra algebra_type; + typedef Operations operations_type; - typedef Resizer resizer_type; + typedef Resizer resizer_type; - typedef adaptive_adams_coefficients aac_type; - typedef detail::Polynomial poly_type; + typedef adaptive_adams_coefficients aac_type; + typedef detail::Polynomial poly_type; - adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) - :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) - {}; + adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) + :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) + {}; - void step(const deriv_type &deriv, const time_type &t) + void step(const deriv_type &deriv, const time_type &t) + { + m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); + + m_tts[0] = t; + m_tss[0][0].m_v = deriv; + + for(size_t i=1; i , detail::ref( *this ) , detail::_1 ) ); - - m_tts[0] = t; - m_tss[0][0].m_v = deriv; - - for(size_t i=1; i(1/dt, -1/dt)); - } - }; - void confirm() + time_type dt = t - m_ts[i-1]; + m_algebra.for_each3(m_tss[i][0].m_v, m_tss[i-1][0].m_v, m_ss[i-1][0].m_v, typename Operations::template scale_sum2(1/dt, -1/dt)); + } + }; + void confirm() + { + for(size_t i=0; i m_ss; - time_storage_type m_ts; + boost::array m_ss; + time_storage_type m_ts; - boost::array m_tss; - time_storage_type m_tts; + boost::array m_tss; + time_storage_type m_tts; - size_t m_effective_order; + size_t m_effective_order; - private: - template< class StateType > - bool resize_tss_impl( const StateType &x ) +private: + template< class StateType > + bool resize_tss_impl( const StateType &x ) + { + bool resized( false ); + for( size_t i=0 ; i::type() ); - - m_tts[i] = 0; - } - return resized; - }; + for(size_t j=0; j::type() ); + + m_tts[i] = 0; + } + return resized; + }; - resizer_type m_resizer; - algebra_type m_algebra; + resizer_type m_resizer; + algebra_type m_algebra; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 06ec3492..59dc46bc 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -19,79 +19,79 @@ size_t Type = H211PI > struct pid_step_adjuster { - public: - const static size_t steps = Steps; +public: + const static size_t steps = Steps; - typedef State state_type; - typedef Time time_type; + typedef State state_type; + typedef Time time_type; - typedef rotating_buffer error_storage_type; - typedef rotating_buffer time_storage_type; - typedef pid_step_adjuster_coefficients coeff_type; + typedef rotating_buffer error_storage_type; + typedef rotating_buffer time_storage_type; + typedef pid_step_adjuster_coefficients coeff_type; - pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) - {}; + pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) + :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) + {}; - time_type adjust_stepsize(time_type dt, const state_type &err) + time_type adjust_stepsize(time_type dt, const state_type &err) + { + m_error_storage[0] = err; + m_time_storage[0] = dt; + + double ratio = 100; + double r; + + for(size_t i=0; i= 2) { - if(m_init >= 2) - { - r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * - pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* - pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); - } - else - { - r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup - } - - if(r= m_dtmax) - { - dt = m_dtmax; - } - - if(ratio >= 0.9) - { - m_error_storage.rotate(); - m_time_storage.rotate(); - - ++m_init; + r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * + pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * + pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* + pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); } else { - m_init = 0; + r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup } - return dt*ratio; - }; + if(r= m_dtmax) + { + dt = m_dtmax; + } - coeff_type m_coeff; + if(ratio >= 0.9) + { + m_error_storage.rotate(); + m_time_storage.rotate(); + + ++m_init; + } + else + { + m_init = 0; + } + + return dt*ratio; + }; + +private: + time_type m_dtmax; + error_storage_type m_error_storage; + time_storage_type m_time_storage; + + size_t m_init; + double m_tol; + + coeff_type m_coeff; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp index 39f5cbb7..6ab80e32 100644 --- a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp +++ b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp @@ -15,128 +15,132 @@ class Time > class Polynomial { - public: - typedef Time time_type; - typedef Polynomial poly_type; +public: + typedef Time time_type; + typedef Polynomial poly_type; - Polynomial() + Polynomial() + { + for(size_t i = 0; i coeff) + { + m_coeff = coeff; + }; + + Polynomial integrate() + { + boost::array coeff_int; + coeff_int[order] = 0; + + for(size_t i=0; i coeff) - { - m_coeff = coeff; - }; - - Polynomial integrate() - { - boost::array coeff_int; - coeff_int[order] = 0; - - for(size_t i=0; i polyInt(coeff_int); - return polyInt; - }; - - time_type evaluate(const time_type &t) - { - // fma: x*y+z - m_res = m_coeff[0]; - for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); - m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; - } - - return m_res; + if(i != order) + coeff_int[i] = m_coeff[i] / (order - i); } - void add_root(const time_type &root) + Polynomial polyInt(coeff_int); + return polyInt; + }; + + time_type evaluate(const time_type &t) + { + // fma: x*y+z + m_res = m_coeff[0]; + for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); + m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; + } + + return m_res; + } + + void add_root(const time_type &root) + { + for(size_t j=0; j from_roots(time_type * roots, unsigned short num_roots) + { + time_type coeff[order] = {0}; + coeff[order-1] = 1; + + for(size_t i=0; i poly(coeff); + return poly; + }; - void reset() - { - for(size_t i = 0; i from_roots(time_type * roots, unsigned short num_roots) - { - time_type coeff[order] = {0}; - coeff[order-1] = 1; - - for(size_t i=0; i poly(coeff); - return poly; - }; - - // first element is highest order - boost::array m_coeff; - private: - time_type m_res; + // first element is highest order + boost::array m_coeff; +private: + time_type m_res; }; -}}}} + +} +} +} +} #endif \ No newline at end of file From dc2fbddd7ab408f96fe69dd9b6e5b53ab7cd3beb Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Fri, 23 Jun 2017 11:14:22 +0200 Subject: [PATCH 39/65] added self-initialization to adaptive adams stepper --- .../odeint/stepper/adaptive_adams_bashforth.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp index bb39fca8..3b745df1 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp @@ -89,6 +89,18 @@ public: do_step_impl(m_coeff, in, t, out, dt); }; + template + void initialize(System system, state_type &inOut, time_type &t, time_type dt) + { + m_coeff.reset(); + + for(size_t i=0; i Date: Fri, 23 Jun 2017 15:05:20 +0200 Subject: [PATCH 40/65] Tests for numeric precision, initializing procedure for steppers --- .../adaptive_adams_bashforth_moulton.hpp | 22 +++- .../odeint/stepper/adaptive_adams_moulton.hpp | 7 +- test/numeric/Jamfile.v2 | 2 + test/numeric/adaptive_adams_bashforth.cpp | 116 ++++++++++++++++++ .../adaptive_adams_bashforth_moulton.cpp | 113 +++++++++++++++++ 5 files changed, 252 insertions(+), 8 deletions(-) create mode 100644 test/numeric/adaptive_adams_bashforth.cpp create mode 100644 test/numeric/adaptive_adams_bashforth_moulton.cpp diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index dd70a05c..6d3808c9 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -73,7 +73,7 @@ public: order_type order() { - return order_value + 1; + return order_value; } order_type stepper_order() @@ -87,7 +87,7 @@ public: } template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt) + void do_step(System system, state_type & inOut, time_type t, time_type &dt) { m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -95,7 +95,7 @@ public: }; template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) + void do_step(System system, const state_type & in, time_type t, state_type & out, time_type &dt) { m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -103,7 +103,7 @@ public: }; template - void do_step(System system, state_type & inOut, time_type &t, time_type &dt, state_type &xerr) + void do_step(System system, state_type & inOut, time_type t, time_type &dt, state_type &xerr) { m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -112,7 +112,7 @@ public: }; template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type dt, state_type &xerr) { do_step_impl(system, m_coeff, in, t, out, dt, xerr); @@ -149,6 +149,18 @@ public: m_aab.algebra().for_each3(xerr, xerr, out, typename Operations::template scale_sum2(-1.0, 1.0)); }; + template + void initialize(System system, state_type &inOut, time_type &t, time_type dt) + { + m_coeff.reset(); + + for(size_t i=0; i algebra_stepper_base_type; - typedef detail::adaptive_adams_coefficients coeff_type; + typedef detail::adaptive_adams_coefficients coeff_type; typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; @@ -64,8 +64,9 @@ public: // integrating for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, typename Operations::template scale_sum2(1.0, c)); + time_type c = ((i != coeff.m_effective_order-1) ? coeff.m_c[i] : coeff.poly.evaluate_integrated(dt)); + this->m_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, + typename Operations::template scale_sum2(1.0, c)); } }; }; diff --git a/test/numeric/Jamfile.v2 b/test/numeric/Jamfile.v2 index 1915a325..55aa0e82 100644 --- a/test/numeric/Jamfile.v2 +++ b/test/numeric/Jamfile.v2 @@ -27,7 +27,9 @@ test-suite "odeint" [ run symplectic.cpp ] [ run rosenbrock.cpp ] [ run adams_bashforth.cpp ] + [ run adaptive_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 ] diff --git a/test/numeric/adaptive_adams_bashforth.cpp b/test/numeric/adaptive_adams_bashforth.cpp new file mode 100644 index 00000000..265881ea --- /dev/null +++ b/test/numeric/adaptive_adams_bashforth.cpp @@ -0,0 +1,116 @@ +/* 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 +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adaptive_adams_bashforth + +#include +#include + +#include + +#include + +#include + +#include + +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_adaptive_adams_bashforth_test ) + + +/* generic test for all adams bashforth steppers */ +template< class Stepper > +struct perform_adaptive_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 to self-start the stepper with a small stepsize + stepper.initialize( osc() , x1 , t , 1e-5); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // more steps necessary to "counteract" the effect from the lower order steps + for( size_t n=0 ; n < (stepper.steps+1)*3 ; ++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 << " , " + << 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 , 1e-5 ); + 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< + adaptive_adams_bashforth< 2 , state_type > , + adaptive_adams_bashforth< 3 , state_type > , + adaptive_adams_bashforth< 4 , state_type > , + adaptive_adams_bashforth< 5 , state_type > , + adaptive_adams_bashforth< 6 , state_type > , + adaptive_adams_bashforth< 7 , state_type > , + adaptive_adams_bashforth< 8 , state_type > + > adaptive_adams_bashforth_steppers; + +BOOST_AUTO_TEST_CASE_TEMPLATE( adaptive_adams_bashforth_test , Stepper, adaptive_adams_bashforth_steppers ) +{ + perform_adaptive_adams_bashforth_test< Stepper > tester; + tester(); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/numeric/adaptive_adams_bashforth_moulton.cpp b/test/numeric/adaptive_adams_bashforth_moulton.cpp new file mode 100644 index 00000000..5ba2117d --- /dev/null +++ b/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 +#ifdef BOOST_MSVC + #pragma warning(disable:4996) +#endif + +#define BOOST_TEST_MODULE numeric_adaptive_adams_bashforth_moulton + +#include +#include + +#include + +#include + +#include + +#include + +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_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; + 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( osc() , x1 , t , 1e-3); + double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); + double phi = std::asin(x1[0]/A) - t; + // more steps necessary to "counteract" the effect from the lower order steps + for( size_t n=0 ; n < (stepper.steps+1)*3 ; ++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 << " , " + << 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 , 1e-3 ); + 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< + 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_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() From c5aab453864858338ee780997a49dee7daebb7f7 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Sun, 2 Jul 2017 15:14:09 +0200 Subject: [PATCH 41/65] moving to new formulation --- include/boost/numeric/odeint.hpp | 1 - .../stepper/adaptive_adams_bashforth.hpp | 165 ----------- .../adaptive_adams_bashforth_moulton.hpp | 275 ++++++++++-------- .../odeint/stepper/adaptive_adams_moulton.hpp | 78 ----- .../controlled_adams_bashforth_moulton.hpp | 99 ++++++- .../detail/adaptive_adams_coefficients.hpp | 156 +++++----- .../odeint/stepper/detail/polynomial.hpp | 146 ---------- 7 files changed, 318 insertions(+), 602 deletions(-) delete mode 100644 include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp delete mode 100644 include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp delete mode 100644 include/boost/numeric/odeint/stepper/detail/polynomial.hpp diff --git a/include/boost/numeric/odeint.hpp b/include/boost/numeric/odeint.hpp index d577b6a4..642e46fe 100644 --- a/include/boost/numeric/odeint.hpp +++ b/include/boost/numeric/odeint.hpp @@ -51,7 +51,6 @@ #include -#include #include #include diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp deleted file mode 100644 index 3b745df1..00000000 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#ifndef STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED -#define STEPPER_ADAMS_BASHFORTH_HPP_INCLUDED - -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include - -namespace boost { -namespace numeric { -namespace odeint { - -template< -size_t Steps, -class State, -class Value = double, -class Deriv = State, -class Time = Value, -class Algebra = typename algebra_dispatcher< State >::algebra_type, -class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer -> -class adaptive_adams_bashforth: public algebra_stepper_base< Algebra , Operations > -{ -public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps; - - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - typedef Resizer resizer_type; - - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; - typedef stepper_tag stepper_category; - - typedef detail::adaptive_adams_coefficients coeff_type; - - typedef adaptive_adams_bashforth< Steps , State , Value , Deriv , Time , Algebra, Operations, Resizer > stepper_type; - - adaptive_adams_bashforth( const algebra_type &algebra = algebra_type() ) - :algebra_stepper_base_type( algebra ) , - m_dxdt_resizer(), m_xnew_resizer() - {}; - - order_type order() const - { - return order_value; - }; - - template - void do_step(System system, state_type & inOut, time_type t, time_type dt) - { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - do_step(system, inOut, t, m_xnew.m_v, dt); - boost::numeric::odeint::copy( m_xnew.m_v , inOut); - }; - - template - void do_step(System system, const state_type & in, time_type t, state_type & out, time_type dt) - { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - system(in, m_dxdt.m_v, t); - m_coeff.step(m_dxdt.m_v, t); - m_coeff.confirm(); - - do_step_impl(m_coeff, in, t, out, dt); - }; - - template - void initialize(System system, state_type &inOut, time_type &t, time_type dt) - { - m_coeff.reset(); - - for(size_t i=0; i0) - { - coeff.poly.add_root(coeff.m_ts[coeff.m_effective_order -1 -i] - coeff.m_ts[0]); - } - - time_type c = coeff.poly.evaluate_integrated(dt); - coeff.m_c[i] = c; - - // predict next state - this->m_algebra.for_each3(out, out, coeff.m_ss[i][coeff.m_effective_order-i-2].m_v, - typename Operations::template scale_sum2(1.0, c)); - } - }; - - const coeff_type& coeff() const - { - return m_coeff; - }; - - coeff_type& coeff() - { - return m_coeff; - }; - - void reset() - { - m_coeff.reset(); - }; - -private: - template< class StateType > - bool resize_dxdt_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); - }; - template< class StateType > - bool resize_xnew_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); - }; - - resizer_type m_dxdt_resizer; - resizer_type m_xnew_resizer; - - coeff_type m_coeff; - wrapped_deriv_type m_dxdt; - wrapped_state_type m_xnew; -}; - -} -} -} - -#endif diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 6d3808c9..afec1b80 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -1,44 +1,46 @@ -#ifndef STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED -#define STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#ifndef BOOST_NUMERIC_ODEINT_STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED -#include -#include -#include #include -#include +#include +#include + +#include +#include +#include +#include -#include #include #include #include -#include -#include - #include -#include + +#include +#include + +#include namespace boost { namespace numeric { namespace odeint { - - template< size_t Steps, class State, class Value = double, class Deriv = State, class Time = Value, -class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Algebra = typename algebra_dispatcher< State >::algebra_type , class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer +class Resizer = initially_resizer > class adaptive_adams_bashforth_moulton: public algebra_stepper_base< Algebra , Operations > { public: static const size_t steps = Steps; + typedef unsigned short order_type; static const order_type order_value = steps; @@ -46,132 +48,143 @@ public: typedef Value value_type; typedef Deriv deriv_type; typedef Time time_type; - typedef Resizer resizer_type; - typedef Algebra algebra_type; - typedef Operations operations_type; + typedef state_wrapper< state_type > wrapped_state_type; + typedef state_wrapper< deriv_type > wrapped_deriv_type; + typedef boost::array error_storage_type; + typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - - typedef state_wrapper wrapped_state_type; - typedef state_wrapper wrapped_deriv_type; - - typedef detail::adaptive_adams_coefficients coeff_type; - - typedef detail::rotating_buffer error_storage_type; - - typedef adaptive_adams_bashforth aab_type; - typedef adaptive_adams_moulton aam_type; - typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time, Algebra, Operations, Resizer > stepper_type; - + typedef typename algebra_stepper_base_type::algebra_type algebra_type; + typedef typename algebra_stepper_base_type::operations_type operations_type; + typedef Resizer resizer_type; typedef error_stepper_tag stepper_category; - adaptive_adams_bashforth_moulton(const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ), m_aab(algebra), m_aam(algebra), - m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_coeff() + typedef detail::adaptive_adams_coefficients< Steps, Deriv, Value, Time, Algebra, Operations, Resizer> coeff_type; + typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_type; + + order_type order() const { return order_value; }; + order_type stepper_order() const {return order_value + 1; }; + order_type error_order() const {return order_value; }; + + adaptive_adams_bashforth_moulton( const algebra_type &algebra = algebra_type() ) + :algebra_stepper_base_type( algebra ), m_coeff(), + m_dxdt_resizer(), m_xnew_resizer(), m_xerr_resizer() {}; - order_type order() - { - return order_value; - } - - order_type stepper_order() - { - return order_value + 1; - } - - order_type error_order() - { - return order_value; - } - - template - void do_step(System system, state_type & inOut, time_type t, time_type &dt) - { - m_xerr_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - do_step(system, inOut, t, dt, m_xerr.m_v); - }; - - template - void do_step(System system, const state_type & in, time_type t, state_type & out, time_type &dt) - { - m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - do_step(system, in, t, out, dt, m_xerr.m_v); - }; - - template - void do_step(System system, state_type & inOut, time_type t, time_type &dt, state_type &xerr) + template< class System > + void do_step(System system, state_type &inOut, time_type t, time_type dt ) { m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - do_step(system, inOut, t, m_xnew.m_v, dt, xerr); + + do_step(system, inOut, t, m_xnew.m_v, dt, m_xerr[1].m_v); boost::numeric::odeint::copy( m_xnew.m_v , inOut); }; - template - void do_step(System system, const state_type & in, time_type &t, state_type & out, time_type dt, state_type &xerr) - { - do_step_impl(system, m_coeff, in, t, out, dt, xerr); - - system(out, m_dxdt.m_v, t+dt); - m_coeff.step(m_dxdt.m_v, t+dt); - m_coeff.confirm(); + template< class System > + void do_step(System system, const state_type &in, time_type t, state_type &out, time_type dt ) + { + do_step(system, in, t, out, dt, m_xerr); }; - template - void do_step_impl(System system, coeff_type coeff, const state_type & in, time_type &t, state_type & out, time_type &dt, state_type &xerr) + template< class System > + void do_step(System system, state_type &inOut, time_type t, time_type dt, state_type &xerr) { - m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + do_step(system, inOut, t, m_xnew.m_v, dt, m_xerr[1].m_v); + boost::numeric::odeint::copy( m_xnew.m_v , inOut); + boost::numeric::odeint::copy( m_xerr[1].m_v , xerr); + }; + + template< class System > + void do_step(System system, const state_type &in, time_type t, state_type &out, time_type dt , state_type &xerr) + { + do_step_impl(system, in, t, out, dt, m_xerr); + boost::numeric::odeint::copy( m_xerr[1].m_v , xerr); - if(coeff.m_effective_order == 1) + system(out, m_dxdt.m_v, t+dt); + m_coeff.do_step(m_dxdt.m_v); + m_coeff.confirm(); + + if(m_coeff.m_eo < order_value) + m_coeff.m_eo ++; + }; + + template + void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) + { + m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + for( size_t i=0 ; i(-1.0, 1.0)); }; template void initialize(System system, state_type &inOut, time_type &t, time_type dt) { - m_coeff.reset(); - - for(size_t i=0; ido_step(system, inOut, t, dt/static_cast< Time >(order_value)); + t += dt/static_cast< Time >(order_value); + }; + }; + + template + void do_step_impl(System system, const state_type & in, time_type t, state_type & out, time_type &dt, error_storage_type &xerr) + { + size_t eO = m_coeff.m_eo; + + m_xerr_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + m_coeff.predict(t, dt); + if (eO == 1) + { + system(in, m_dxdt.m_v, t); + m_coeff.do_step(m_dxdt.m_v, 1); } - } - const coeff_type& coeff() const - { - return m_coeff; + out = in; + for(size_t i=0; im_algebra.for_each3(out, out, m_coeff.phi[1][i].m_v, + typename Operations::template scale_sum2(1.0, dt*m_coeff.g[i]*m_coeff.beta[0][i])); + } + + system(out, m_dxdt.m_v, t+dt); + m_coeff.do_step(m_dxdt.m_v); + + this->m_algebra.for_each3(out, out, m_coeff.phi[0][eO].m_v, + typename Operations::template scale_sum2(1.0, dt*m_coeff.g[eO])); + + // error for current order + this->m_algebra.for_each2(xerr[1].m_v, m_coeff.phi[0][eO].m_v, + typename Operations::template scale_sum1(dt*(m_coeff.g[eO]-m_coeff.g[eO-1]))); + + // error for order below/above + if (eO > 1) + { + this->m_algebra.for_each2(xerr[0].m_v, m_coeff.phi[0][eO-1].m_v, + typename Operations::template scale_sum1(dt*(m_coeff.g[eO-1]-m_coeff.g[eO-2]))); + } + + this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, + typename Operations::template scale_sum1(dt*(m_coeff.g[eO+1]-m_coeff.g[eO]))); }; - coeff_type& coeff() - { - return m_coeff; - }; + const coeff_type& coeff() const {return m_coeff;}; + coeff_type & coeff() {return m_coeff;}; - wrapped_deriv_type m_dxdt; + void reset() { m_coeff.reset(); }; private: template< class StateType > @@ -180,29 +193,35 @@ private: return adjust_size_by_resizeability( m_dxdt, x, typename is_resizeable::type() ); }; template< class StateType > - bool resize_xerr_impl( const StateType &x ) - { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); - }; - template< class StateType > bool resize_xnew_impl( const StateType &x ) { return adjust_size_by_resizeability( m_xnew, x, typename is_resizeable::type() ); }; + template< class StateType > + bool resize_xerr_impl( const StateType &x ) + { + bool resized( false ); - aab_type m_aab; - aam_type m_aam; - - resizer_type m_dxdt_resizer; - resizer_type m_xerr_resizer; - resizer_type m_xnew_resizer; - - wrapped_state_type m_xnew; - wrapped_state_type m_xerr; + for(size_t i=0; i<3; ++i) + { + resized |= adjust_size_by_resizeability( m_xerr[i], x, typename is_resizeable::type() ); + } + return resized; + }; coeff_type m_coeff; + + resizer_type m_dxdt_resizer; + resizer_type m_xnew_resizer; + resizer_type m_xerr_resizer; + + wrapped_deriv_type m_dxdt; + wrapped_state_type m_xnew; + error_storage_type m_xerr; }; -}}} +} // odeint +} // numeric +} // boost -#endif +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp deleted file mode 100644 index 8623b6a5..00000000 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_moulton.hpp +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef STEPPER_ADAMS_MOULTON_HPP_INCLUDED -#define STEPPER_ADAMS_MOULTON_HPP_INCLUDED - -// helper class for controlled_adams_bashforth_moulton - -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace numeric { -namespace odeint { - -template< -size_t Steps, -class State, -class Value = double, -class Deriv = State, -class Time = Value, -class Algebra = typename algebra_dispatcher< State >::algebra_type, -class Operations = typename operations_dispatcher< State >::operations_type , -class Resizer = initially_resizer -> -class adaptive_adams_moulton: public algebra_stepper_base< Algebra , Operations > -{ -public: - static const size_t steps = Steps; - typedef unsigned short order_type; - static const order_type order_value = steps + 1; - - typedef State state_type; - typedef Value value_type; - typedef Deriv deriv_type; - typedef Time time_type; - - typedef Algebra algebra_type; - typedef Operations operations_type; - typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; - - typedef detail::adaptive_adams_coefficients coeff_type; - - typedef adaptive_adams_moulton< Steps , State , Value , Deriv , Time , Resizer > stepper_type; - - adaptive_adams_moulton( const algebra_type &algebra = algebra_type()) - :algebra_stepper_base_type( algebra ) - {}; - - order_type order() const - { - return order_value; - }; - - void do_step(coeff_type & coeff, const state_type & in, - time_type t, state_type & out, time_type &dt) - { - coeff.poly.add_root(0); - out = in; - - // integrating - for(size_t i=0; im_algebra.for_each3(out, out, coeff.m_tss[i][coeff.m_effective_order-i-1].m_v, - typename Operations::template scale_sum2(1.0, c)); - } - }; -}; - -} -} -} - -#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 6b96150f..fa6c1374 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -15,18 +15,59 @@ namespace boost{ namespace numeric{ namespace odeint { +template< +size_t MaxOrder, +class State, +class Algebra = typename algebra_dispatcher< State >::algebra_type +> +class default_order_adjuster +{ +public: + typedef State state_type; + typedef state_wrapper< state_type > wrapped_state_type; + + typedef Algebra algebra_type; + + default_order_adjuster(const algebra_type &algebra = algebra_type()) + : m_algebra(algebra) + {}; + + void adjust_order(size_t &order, const boost::array & xerr) + { + if(order > 1 && m_algebra.norm_inf(xerr[0].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) + { + --order; + } + else if (order < MaxOrder && m_algebra.norm_inf(xerr[2].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) + { + ++order; + } + }; +private: + algebra_type m_algebra; + +}; + template< class ErrorStepper, class StepAdjuster = detail::pid_step_adjuster, + detail::H312PID + >, +class OrderAdjuster = default_order_adjuster, class Resizer = initially_resizer > class controlled_adams_bashforth_moulton { public: typedef ErrorStepper stepper_type; + + static const typename stepper_type::order_type order_value = stepper_type::order_value; + typedef typename stepper_type::state_type state_type; typedef typename stepper_type::value_type value_type; typedef typename stepper_type::deriv_type deriv_type; @@ -37,19 +78,34 @@ public: typedef Resizer resizer_type; typedef StepAdjuster step_adjuster_type; + typedef OrderAdjuster order_adjuster_type; typedef controlled_stepper_tag stepper_category; typedef typename stepper_type::wrapped_state_type wrapped_state_type; typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; + typedef boost::array error_storage_type; - typedef controlled_adams_bashforth_moulton controlled_stepper_type; + typedef typename stepper_type::coeff_type coeff_type; + typedef controlled_adams_bashforth_moulton controlled_stepper_type; controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) - :m_stepper(), m_coeff(m_stepper.coeff()), + :m_stepper(), m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_step_adjuster(step_adjuster) + m_step_adjuster(step_adjuster), m_order_adjuster() {}; + template + void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) + { + m_stepper.initialize(stepper, system, inOut, t, dt); + }; + + template + void initialize(System system, state_type &inOut, time_type &t, time_type dt) + { + m_stepper.initialize(system, inOut, t, dt); + }; + template controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) { @@ -67,18 +123,23 @@ public: controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) { m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - m_stepper.do_step_impl(system, m_coeff, in, t, out, dt, m_xerr.m_v); + m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + m_stepper.do_step_impl(system, in, t, out, dt, m_xerr); + + coeff_type &coeff = m_stepper.coeff(); + + size_t prevOrder = coeff.m_eo; + m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); time_type dtPrev = dt; - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr.m_v); + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); - if(dt / dtPrev >= 0.9) + if(dt / dtPrev >= step_adjuster_type::threshold()) { - m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - - system(out, m_dxdt.m_v, t+dtPrev); - m_coeff.step(m_dxdt.m_v, t+dtPrev); - m_coeff.confirm(); + system(out, m_dxdt.m_v, t+dt); + coeff.do_step(m_dxdt.m_v); + coeff.confirm(); t += dtPrev; return success; @@ -89,6 +150,8 @@ public: } }; + void reset() { m_stepper.reset(); }; + private: template< class StateType > bool resize_dxdt_impl( const StateType &x ) @@ -98,7 +161,13 @@ private: template< class StateType > bool resize_xerr_impl( const StateType &x ) { - return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); + bool resized( false ); + + for(size_t i=0; i<3; ++i) + { + resized |= adjust_size_by_resizeability( m_xerr[i], x, typename is_resizeable::type() ); + } + return resized; }; template< class StateType > bool resize_xnew_impl( const StateType &x ) @@ -107,10 +176,9 @@ private: }; stepper_type m_stepper; - typename stepper_type::coeff_type &m_coeff; wrapped_deriv_type m_dxdt; - wrapped_state_type m_xerr; + error_storage_type m_xerr; wrapped_state_type m_xnew; resizer_type m_dxdt_resizer; @@ -118,6 +186,7 @@ private: resizer_type m_xnew_resizer; step_adjuster_type m_step_adjuster; + order_adjuster_type m_order_adjuster; }; } diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index aad33cfa..f7a32787 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -1,8 +1,7 @@ -#ifndef ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED -#define ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED +#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED #include -#include #include #include @@ -12,8 +11,6 @@ #include #include -#include - #include #include @@ -25,112 +22,133 @@ namespace detail { template< size_t Steps, class Deriv, -class Time, +class Value = double, +class Time = double, class Algebra = typename algebra_dispatcher< Deriv >::algebra_type, class Operations = typename operations_dispatcher< Deriv >::operations_type , class Resizer = initially_resizer > -struct adaptive_adams_coefficients +class adaptive_adams_coefficients { public: static const size_t steps = Steps; + typedef unsigned short order_type; + static const order_type order_value = steps; + + typedef Value value_type; typedef Deriv deriv_type; typedef Time time_type; + typedef state_wrapper wrapped_deriv_type; - typedef detail::rotating_buffer step_storage_type; // +1 for moulton - typedef detail::rotating_buffer time_storage_type; + typedef rotating_buffer step_storage_type; // +1 for moulton + typedef rotating_buffer time_storage_type; typedef Algebra algebra_type; typedef Operations operations_type; - typedef Resizer resizer_type; - typedef adaptive_adams_coefficients aac_type; - typedef detail::Polynomial poly_type; + typedef adaptive_adams_coefficients aac_type; - adaptive_adams_coefficients(const algebra_type &algebra = algebra_type() ) - :poly(), m_effective_order(1), m_resizer(), m_algebra(algebra) - {}; - - void step(const deriv_type &deriv, const time_type &t) + adaptive_adams_coefficients( const algebra_type &algebra = algebra_type()) + :m_eo(1), beta(), phi(), m_ns(0), m_time_storage(), + m_algebra(algebra), + m_phi_resizer() { - m_resizer.adjust_size( deriv , detail::bind( &aac_type::template resize_tss_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); + for (size_t i=0; i 1e-16 || m_eo >= m_ns) { - time_type dt = t - m_ts[i-1]; - m_algebra.for_each3(m_tss[i][0].m_v, m_tss[i-1][0].m_v, m_ss[i-1][0].m_v, typename Operations::template scale_sum2(1/dt, -1/dt)); + m_ns = 0; + } + else if (m_ns < order_value + 2) + { + m_ns++; + } + + for(size_t i=1+m_ns; i , detail::ref( *this ) , detail::_1 ) ); + + phi[o][0].m_v = dxdt; + + for(size_t i=1; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, + typename Operations::template scale_sum2(1.0, -beta[o][i-1])); + } + }; + void confirm() { - for(size_t i=0; i m_ss; - time_storage_type m_ts; - - boost::array m_tss; - time_storage_type m_tts; - - size_t m_effective_order; + rotating_buffer, 2> beta; // beta[0] = beta(n) + rotating_buffer, 3> phi; // phi[0] = phi(n+1) + boost::array g; private: template< class StateType > - bool resize_tss_impl( const StateType &x ) + bool resize_phi_impl( const StateType &x ) { + bool resized( false ); - for( size_t i=0 ; i::type() ); - - m_tts[i] = 0; + resized |= adjust_size_by_resizeability( phi[0][i], x, typename is_resizeable::type() ); + resized |= adjust_size_by_resizeability( phi[1][i], x, typename is_resizeable::type() ); + resized |= adjust_size_by_resizeability( phi[2][i], x, typename is_resizeable::type() ); } return resized; }; - resizer_type m_resizer; + size_t m_ns; + + time_storage_type m_time_storage; + boost::array, order_value + 2> c; + algebra_type m_algebra; + + resizer_type m_phi_resizer; }; } @@ -138,4 +156,4 @@ private: } } -#endif +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp b/include/boost/numeric/odeint/stepper/detail/polynomial.hpp deleted file mode 100644 index 6ab80e32..00000000 --- a/include/boost/numeric/odeint/stepper/detail/polynomial.hpp +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef POLYNOMIAL_HPP_INCLUDED -#define POLYNOMIAL_HPP_INCLUDED - -#include -#include - -namespace boost { -namespace numeric { -namespace odeint { -namespace detail{ - -template< -size_t order, -class Time -> -class Polynomial -{ -public: - typedef Time time_type; - typedef Polynomial poly_type; - - Polynomial() - { - for(size_t i = 0; i coeff) - { - m_coeff = coeff; - }; - - Polynomial integrate() - { - boost::array coeff_int; - coeff_int[order] = 0; - - for(size_t i=0; i polyInt(coeff_int); - return polyInt; - }; - - time_type evaluate(const time_type &t) - { - // fma: x*y+z - m_res = m_coeff[0]; - for(size_t i=1; i= order)?0:m_coeff[i]/(order-i))); - m_res = ((i >= order)?0:m_coeff[i]/(order-i)) + m_res * t; - } - - return m_res; - } - - void add_root(const time_type &root) - { - for(size_t j=0; j from_roots(time_type * roots, unsigned short num_roots) - { - time_type coeff[order] = {0}; - coeff[order-1] = 1; - - for(size_t i=0; i poly(coeff); - return poly; - }; - - // first element is highest order - boost::array m_coeff; -private: - time_type m_res; -}; - -} -} -} -} - -#endif \ No newline at end of file From a463262c7dff6320886ca0370b9260bb8a96efb7 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Sun, 2 Jul 2017 15:16:32 +0200 Subject: [PATCH 42/65] slight changes to stepsize control --- .../numeric/odeint/stepper/detail/pid_step_adjuster.hpp | 5 +++-- .../odeint/stepper/detail/pid_step_adjuster_coefficients.hpp | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 59dc46bc..35af0ef0 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -21,6 +21,7 @@ struct pid_step_adjuster { public: const static size_t steps = Steps; + static double threshold() { return 0.9; }; typedef State state_type; typedef Time time_type; @@ -68,7 +69,7 @@ public: dt = m_dtmax; } - if(ratio >= 0.9) + if(ratio >= threshold() ) { m_error_storage.rotate(); m_time_storage.rotate(); @@ -98,4 +99,4 @@ private: } } } -#endif +#endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp index 1b7c7735..d60fb6f4 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -1,3 +1,4 @@ + #ifndef PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED #define PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED From 1b767b38d6e350174bbe98d422a7a931f57db825 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Sun, 2 Jul 2017 19:16:10 +0200 Subject: [PATCH 43/65] adapting tests to new formulation --- .../adaptive_adams_bashforth_moulton.hpp | 14 +-- .../controlled_adams_bashforth_moulton.hpp | 3 + .../detail/adaptive_adams_coefficients.hpp | 4 +- test/Jamfile.v2 | 2 - test/adaptive_adams_bashforth.cpp | 63 ---------- test/adaptive_adams_coefficients.cpp | 72 +++++------ test/integrate.cpp | 6 +- test/numeric/Jamfile.v2 | 1 - test/numeric/adaptive_adams_bashforth.cpp | 116 ------------------ .../adaptive_adams_bashforth_moulton.cpp | 17 ++- test/polynomial.cpp | 76 ------------ 11 files changed, 61 insertions(+), 313 deletions(-) delete mode 100644 test/adaptive_adams_bashforth.cpp delete mode 100644 test/numeric/adaptive_adams_bashforth.cpp delete mode 100644 test/polynomial.cpp diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index afec1b80..295cc859 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -3,10 +3,10 @@ #include +#include #include #include -#include #include #include #include @@ -113,18 +113,18 @@ public: template void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) { - m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + m_dxdt_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - for( size_t i=0 ; i(order_value) ); - m_coeff.predict(t, dt); + m_coeff.predict(t, dt/static_cast< Time >(order_value)); m_coeff.do_step(m_dxdt.m_v); m_coeff.confirm(); - t += dt; + t += dt/static_cast< Time >(order_value); } }; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index fa6c1374..6d93819b 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -7,8 +7,11 @@ #include #include +#include #include #include + +#include #include namespace boost{ diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index f7a32787..1bf76bfe 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -6,7 +6,9 @@ #include #include #include + #include +#include #include #include @@ -96,7 +98,7 @@ public: void do_step(const deriv_type &dxdt, const int o = 0) { - m_phi_resizer.adjust_size( dxdt , detail::bind( &aac_type::template resize_phi_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); + m_phi_resizer.adjust_size( dxdt , detail::bind( &aac_type::template resize_phi_impl< deriv_type > , ref( *this ) , detail::_1 ) ); phi[o][0].m_v = dxdt; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a67b0054..dd78e21c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -48,10 +48,8 @@ test-suite "odeint" [ run adams_bashforth.cpp ] [ run adams_moulton.cpp ] [ run adams_bashforth_moulton.cpp ] - [ run adaptive_adams_bashforth.cpp ] [ run controlled_adams_bashforth_moulton.cpp ] [ run adaptive_adams_coefficients.cpp ] - [ run polynomial.cpp ] [ run generic_stepper.cpp ] [ run generic_error_stepper.cpp ] [ run bulirsch_stoer.cpp ] diff --git a/test/adaptive_adams_bashforth.cpp b/test/adaptive_adams_bashforth.cpp deleted file mode 100644 index 3ec1a62c..00000000 --- a/test/adaptive_adams_bashforth.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#ifdef BOOST_MSVC - #pragma warning(disable:4996) -#endif - -#define BOOST_TEST_MODULE odeint_adaptive_adams_bashforth - -#include - -#include - -#include - -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; - } -}; - -BOOST_AUTO_TEST_SUITE( adaptive_adams_bashforth_test ) - -BOOST_AUTO_TEST_CASE( test_instantiation ) -{ - typedef double time_type; - typedef std::vector state_type; - - adaptive_adams_bashforth<1, state_type> s1; - adaptive_adams_bashforth<2, state_type> s2; - adaptive_adams_bashforth<3, state_type> s3; - adaptive_adams_bashforth<4, state_type> s4; - adaptive_adams_bashforth<5, state_type> s5; - adaptive_adams_bashforth<6, state_type> s6; - adaptive_adams_bashforth<7, state_type> s7; - adaptive_adams_bashforth<8, state_type> s8; - adaptive_adams_bashforth<9, state_type> s9; - - state_type x0; - x0.push_back(0); - time_type t0 = 0.0; - time_type dt = 0.1; - - s1.do_step(const_sys(), x0, t0, dt); - s2.do_step(const_sys(), x0, t0, dt); - s3.do_step(const_sys(), x0, t0, dt); - s4.do_step(const_sys(), x0, t0, dt); - s5.do_step(const_sys(), x0, t0, dt); - s6.do_step(const_sys(), x0, t0, dt); - s7.do_step(const_sys(), x0, t0, dt); - s8.do_step(const_sys(), x0, t0, dt); - s9.do_step(const_sys(), x0, t0, dt); -} - -BOOST_AUTO_TEST_CASE( test_copy ) -{ -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp index 9632ad19..7a7e8267 100644 --- a/test/adaptive_adams_coefficients.cpp +++ b/test/adaptive_adams_coefficients.cpp @@ -25,58 +25,58 @@ 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; + // const static size_t steps = step_type::value; - typedef std::vector deriv_type; - typedef double time_type; + // typedef std::vector deriv_type; + // typedef double time_type; - typedef detail::adaptive_adams_coefficients aac_type; + // typedef detail::adaptive_adams_coefficients aac_type; - std::vector deriv; - deriv.push_back(-1); + // std::vector deriv; + // deriv.push_back(-1); - aac_type coeff; - for(size_t i=0; i deriv_type; - typedef double time_type; + // typedef std::vector deriv_type; + // typedef double time_type; - typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; - aac_type c1; + // typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; + // aac_type c1; - deriv_type deriv(1); - deriv[0] = 1.0; + // deriv_type deriv(1); + // deriv[0] = 1.0; - c1.step(deriv, 0.0); - c1.confirm(); - c1.step(deriv, 1.0); - c1.confirm(); - c1.step(deriv, 2.0); - c1.confirm(); + // c1.step(deriv, 0.0); + // c1.confirm(); + // c1.step(deriv, 1.0); + // c1.confirm(); + // c1.step(deriv, 2.0); + // c1.confirm(); - aac_type c2(c1); - BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); - BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); + // aac_type c2(c1); + // BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); + // BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); - aac_type c3; - deriv_type *p1 = &(c3.m_ss[0][0].m_v); + // aac_type c3; + // deriv_type *p1 = &(c3.m_ss[0][0].m_v); - c3 = c1; - // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); - BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); + // c3 = c1; + // // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); + // BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/test/integrate.cpp b/test/integrate.cpp index 0c4ee7ff..8f43228f 100644 --- a/test/integrate.cpp +++ b/test/integrate.cpp @@ -54,7 +54,6 @@ #include #include -#include #include #include @@ -241,10 +240,7 @@ class stepper_methods : public mpl::vector< 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<3, state_type>, - controlled_adams_bashforth_moulton >, - controlled_adams_bashforth_moulton > + dense_output_runge_kutta< controlled_runge_kutta< runge_kutta_dopri5< state_type > > > //bulirsch_stoer_dense_out< state_type > > { }; diff --git a/test/numeric/Jamfile.v2 b/test/numeric/Jamfile.v2 index 55aa0e82..a4643f6a 100644 --- a/test/numeric/Jamfile.v2 +++ b/test/numeric/Jamfile.v2 @@ -27,7 +27,6 @@ test-suite "odeint" [ run symplectic.cpp ] [ run rosenbrock.cpp ] [ run adams_bashforth.cpp ] - [ run adaptive_adams_bashforth.cpp ] [ run adams_bashforth_moulton.cpp ] [ run adaptive_adams_bashforth_moulton.cpp ] [ run abm_time_dependent.cpp ] diff --git a/test/numeric/adaptive_adams_bashforth.cpp b/test/numeric/adaptive_adams_bashforth.cpp deleted file mode 100644 index 265881ea..00000000 --- a/test/numeric/adaptive_adams_bashforth.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 -#ifdef BOOST_MSVC - #pragma warning(disable:4996) -#endif - -#define BOOST_TEST_MODULE numeric_adaptive_adams_bashforth - -#include -#include - -#include - -#include - -#include - -#include - -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_adaptive_adams_bashforth_test ) - - -/* generic test for all adams bashforth steppers */ -template< class Stepper > -struct perform_adaptive_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 to self-start the stepper with a small stepsize - stepper.initialize( osc() , x1 , t , 1e-5); - double A = std::sqrt( x1[0]*x1[0] + x1[1]*x1[1] ); - double phi = std::asin(x1[0]/A) - t; - // more steps necessary to "counteract" the effect from the lower order steps - for( size_t n=0 ; n < (stepper.steps+1)*3 ; ++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 << " , " - << 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 , 1e-5 ); - 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< - adaptive_adams_bashforth< 2 , state_type > , - adaptive_adams_bashforth< 3 , state_type > , - adaptive_adams_bashforth< 4 , state_type > , - adaptive_adams_bashforth< 5 , state_type > , - adaptive_adams_bashforth< 6 , state_type > , - adaptive_adams_bashforth< 7 , state_type > , - adaptive_adams_bashforth< 8 , state_type > - > adaptive_adams_bashforth_steppers; - -BOOST_AUTO_TEST_CASE_TEMPLATE( adaptive_adams_bashforth_test , Stepper, adaptive_adams_bashforth_steppers ) -{ - perform_adaptive_adams_bashforth_test< Stepper > tester; - tester(); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/test/numeric/adaptive_adams_bashforth_moulton.cpp b/test/numeric/adaptive_adams_bashforth_moulton.cpp index 5ba2117d..663a2c4b 100644 --- a/test/numeric/adaptive_adams_bashforth_moulton.cpp +++ b/test/numeric/adaptive_adams_bashforth_moulton.cpp @@ -34,6 +34,7 @@ namespace mpl = boost::mpl; typedef double value_type; typedef boost::array< double , 2 > state_type; +typedef runge_kutta_fehlberg78 initializing_stepper; // harmonic oscillator, analytic solution x[0] = sin( t ) struct osc @@ -55,6 +56,8 @@ 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 }}; @@ -62,11 +65,11 @@ struct perform_adaptive_adams_bashforth_moulton_test 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( osc() , x1 , t , 1e-3); + 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; // more steps necessary to "counteract" the effect from the lower order steps - for( size_t n=0 ; n < (stepper.steps+1)*3 ; ++n ) + for( size_t n=0 ; n < stepper.steps ; ++n ) { stepper.do_step( osc() , x1 , t , dt ); t += dt; @@ -76,19 +79,19 @@ struct perform_adaptive_adams_bashforth_moulton_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 << " , " << 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 , 1e-3 ); + 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 ) ); @@ -101,7 +104,9 @@ 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< 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 ) diff --git a/test/polynomial.cpp b/test/polynomial.cpp deleted file mode 100644 index 52bf30d8..00000000 --- a/test/polynomial.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#ifdef BOOST_MSVC - #pragma warning(disable:4996) -#endif - -#define BOOST_TEST_MODULE odeint_polynomial - -#include - -#include - -using namespace boost::unit_test; -using namespace boost::numeric::odeint::detail; - -BOOST_AUTO_TEST_SUITE( polynomial_test ) - -BOOST_AUTO_TEST_CASE( test_init ) -{ - Polynomial<3, double> p1; - - boost::array coeff = {0, 1, 2}; - Polynomial<3, double> p2(coeff); -} -BOOST_AUTO_TEST_CASE( test_add_roots ) -{ - Polynomial<3, double> poly; - poly.add_root(1); - poly.add_root(0); -} -BOOST_AUTO_TEST_CASE( test_copy ) -{ - typedef Polynomial<5, double> poly_type; - poly_type p1; - p1.add_root(1); - p1.add_root(0); - - poly_type p2(p1); - BOOST_CHECK_EQUAL(p1.m_coeff[0], p2.m_coeff[0]); - BOOST_CHECK_EQUAL(p1.m_coeff[1], p2.m_coeff[1]); - - poly_type p3; - double* a1 = &(p3.m_coeff[0]); - - p3 = p1; - - BOOST_CHECK(a1 == &(p3.m_coeff[0])); - - BOOST_CHECK_EQUAL(p1.m_coeff[0], p3.m_coeff[0]); - BOOST_CHECK_EQUAL(p1.m_coeff[1], p3.m_coeff[1]); -} -BOOST_AUTO_TEST_CASE( test_remove ) -{ - -} -BOOST_AUTO_TEST_CASE( test_integrate ) -{ - -} -BOOST_AUTO_TEST_CASE( test_evaluate ) -{ - boost::array c1 = {2, 1, 0}; - Polynomial<3, double> p1(c1); - - BOOST_CHECK_EQUAL(p1.evaluate(0), 0); - BOOST_CHECK_EQUAL(p1.evaluate(1), 3); - BOOST_CHECK_EQUAL(p1.evaluate(2), 10); - - boost::array c2 = {0.001, 10, 0, 3, 1}; - Polynomial<5, double> p2(c2); - - BOOST_CHECK_CLOSE(p2.evaluate(0), 1, 0.001); - BOOST_CHECK_CLOSE(p2.evaluate(0.001), 1.003, 0.001); - BOOST_CHECK_CLOSE(p2.evaluate(1.001), 14.034, 0.001); -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 848d7f1938a1d2e7b67bf3c6f2b741f13988f689 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 3 Jul 2017 14:42:41 +0200 Subject: [PATCH 44/65] completed testcases --- .../adaptive_adams_bashforth_moulton.hpp | 3 +- .../detail/adaptive_adams_coefficients.hpp | 4 +- .../stepper/detail/pid_step_adjuster.hpp | 2 +- test/adaptive_adams_coefficients.cpp | 110 ++++++++++++------ test/integrate.cpp | 25 ++-- 5 files changed, 97 insertions(+), 47 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 295cc859..9bfd6cbe 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -124,7 +124,8 @@ public: m_coeff.do_step(m_dxdt.m_v); m_coeff.confirm(); - t += dt/static_cast< Time >(order_value); + if(m_coeff.m_eo < order_value) + m_coeff.m_eo ++; } }; diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 1bf76bfe..7f6d9d75 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -123,8 +123,8 @@ public: size_t m_eo; - rotating_buffer, 2> beta; // beta[0] = beta(n) - rotating_buffer, 3> phi; // phi[0] = phi(n+1) + rotating_buffer, 2> beta; // beta[0] = beta(n) + rotating_buffer, 3> phi; // phi[0] = phi(n+1) boost::array g; private: diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 35af0ef0..d0c75ee2 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -30,7 +30,7 @@ public: typedef rotating_buffer time_storage_type; typedef pid_step_adjuster_coefficients coeff_type; - pid_step_adjuster(double tol = 1e-5, time_type dtmax = 1.0) + pid_step_adjuster(double tol = 1e-6, time_type dtmax = 1.0) :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) {}; diff --git a/test/adaptive_adams_coefficients.cpp b/test/adaptive_adams_coefficients.cpp index 7a7e8267..362458f0 100644 --- a/test/adaptive_adams_coefficients.cpp +++ b/test/adaptive_adams_coefficients.cpp @@ -25,58 +25,96 @@ 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; + const static size_t steps = step_type::value; - // typedef std::vector deriv_type; - // typedef double time_type; + typedef std::vector deriv_type; + typedef double time_type; - // typedef detail::adaptive_adams_coefficients aac_type; + typedef detail::adaptive_adams_coefficients aac_type; - // std::vector deriv; - // deriv.push_back(-1); + std::vector deriv; + deriv.push_back(-1); - // aac_type coeff; - // for(size_t i=0; i 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 deriv_type; - // typedef double time_type; + typedef std::vector deriv_type; + typedef double time_type; - // typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; - // aac_type c1; + typedef detail::adaptive_adams_coefficients<3, deriv_type, time_type> aac_type; + aac_type c1; - // deriv_type deriv(1); - // deriv[0] = 1.0; + deriv_type deriv(1); + deriv[0] = 1.0; - // c1.step(deriv, 0.0); - // c1.confirm(); - // c1.step(deriv, 1.0); - // c1.confirm(); - // c1.step(deriv, 2.0); - // c1.confirm(); + time_type t = 0.0; + time_type dt = 0.01; - // aac_type c2(c1); - // BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c2.m_ss[0][0].m_v[0]); - // BOOST_CHECK(&(c1.m_ss[0][0].m_v) != &(c2.m_ss[0][0].m_v)); + for(size_t i=0; i<3; ++i) + { + c1.predict(t, dt); + c1.do_step(deriv); + c1.confirm(); - // aac_type c3; - // deriv_type *p1 = &(c3.m_ss[0][0].m_v); + t+= dt; - // c3 = c1; - // // BOOST_CHECK(p1 == (&(c3.m_ss[0][0].m_v))); - // BOOST_CHECK_EQUAL(c1.m_ss[0][0].m_v[0], c3.m_ss[0][0].m_v[0]); + 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/test/integrate.cpp b/test/integrate.cpp index 8f43228f..07d4617f 100644 --- a/test/integrate.cpp +++ b/test/integrate.cpp @@ -17,6 +17,8 @@ #define BOOST_TEST_MODULE odeint_integrate_functions +#include + #include #include #include @@ -240,7 +242,12 @@ class stepper_methods : public mpl::vector< 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 > > > + 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 >, + controlled_adams_bashforth_moulton > //bulirsch_stoer_dense_out< state_type > > { }; @@ -277,12 +284,16 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_times_test_case , Stepper, stepper_meth BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_n_steps_test_case , Stepper, stepper_methods ) { - perform_integrate_n_steps_test< Stepper > tester; - tester(); - tester( 200 , 0.01 ); - tester( 200 , 0.01 ); - tester( 200 , 0.01 ); - tester( 200 , -0.01 ); + if(!boost::is_same > >::value && + !boost::is_same > >::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() From dceea2015a7d847bed55919b85b6c895fe2faf43 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 3 Jul 2017 15:25:51 +0200 Subject: [PATCH 45/65] slight formatting changes --- .../adaptive_adams_bashforth_moulton.hpp | 22 ++++++------ .../controlled_adams_bashforth_moulton.hpp | 36 +++++++++---------- .../detail/adaptive_adams_coefficients.hpp | 29 +++++++-------- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 9bfd6cbe..a9ca9d80 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -20,8 +20,6 @@ #include #include -#include - namespace boost { namespace numeric { namespace odeint { @@ -33,7 +31,7 @@ class Value = double, class Deriv = State, class Time = Value, class Algebra = typename algebra_dispatcher< State >::algebra_type , -class Operations = typename operations_dispatcher< State >::operations_type , +class Operations = typename operations_dispatcher< State >::operations_type, class Resizer = initially_resizer > class adaptive_adams_bashforth_moulton: public algebra_stepper_base< Algebra , Operations > @@ -51,7 +49,7 @@ public: typedef state_wrapper< state_type > wrapped_state_type; typedef state_wrapper< deriv_type > wrapped_deriv_type; - typedef boost::array error_storage_type; + typedef boost::array< wrapped_state_type , 3 > error_storage_type; typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; typedef typename algebra_stepper_base_type::algebra_type algebra_type; @@ -59,12 +57,12 @@ public: typedef Resizer resizer_type; typedef error_stepper_tag stepper_category; - typedef detail::adaptive_adams_coefficients< Steps, Deriv, Value, Time, Algebra, Operations, Resizer> coeff_type; + typedef detail::adaptive_adams_coefficients< Steps , Deriv , Value , Time , Algebra , Operations , Resizer > coeff_type; typedef adaptive_adams_bashforth_moulton< Steps , State , Value , Deriv , Time , Algebra , Operations , Resizer > stepper_type; order_type order() const { return order_value; }; - order_type stepper_order() const {return order_value + 1; }; - order_type error_order() const {return order_value; }; + order_type stepper_order() const { return order_value + 1; }; + order_type error_order() const { return order_value; }; adaptive_adams_bashforth_moulton( const algebra_type &algebra = algebra_type() ) :algebra_stepper_base_type( algebra ), m_coeff(), @@ -110,7 +108,7 @@ public: m_coeff.m_eo ++; }; - template + template< class ExplicitStepper, class System > void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) { m_dxdt_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -129,7 +127,7 @@ public: } }; - template + template< class System > void initialize(System system, state_type &inOut, time_type &t, time_type dt) { for(size_t i=0; i + template< class System > void do_step_impl(System system, const state_type & in, time_type t, state_type & out, time_type &dt, error_storage_type &xerr) { size_t eO = m_coeff.m_eo; @@ -182,8 +180,8 @@ public: typename Operations::template scale_sum1(dt*(m_coeff.g[eO+1]-m_coeff.g[eO]))); }; - const coeff_type& coeff() const {return m_coeff;}; - coeff_type & coeff() {return m_coeff;}; + const coeff_type& coeff() const { return m_coeff; }; + coeff_type & coeff() { return m_coeff; }; void reset() { m_coeff.reset(); }; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 6d93819b..c7a4ca09 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -1,5 +1,5 @@ -#ifndef STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED -#define STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#ifndef BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #include #include @@ -14,8 +14,8 @@ #include #include -namespace boost{ -namespace numeric{ +namespace boost { +namespace numeric { namespace odeint { template< @@ -31,8 +31,8 @@ public: typedef Algebra algebra_type; - default_order_adjuster(const algebra_type &algebra = algebra_type()) - : m_algebra(algebra) + default_order_adjuster( const algebra_type &algebra = algebra_type() ) + : m_algebra( algebra ) {}; void adjust_order(size_t &order, const boost::array & xerr) @@ -53,12 +53,12 @@ private: template< class ErrorStepper, -class StepAdjuster = detail::pid_step_adjuster, -class OrderAdjuster = default_order_adjuster, @@ -86,30 +86,30 @@ public: typedef typename stepper_type::wrapped_state_type wrapped_state_type; typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; - typedef boost::array error_storage_type; + typedef boost::array< wrapped_state_type , 3 > error_storage_type; typedef typename stepper_type::coeff_type coeff_type; - typedef controlled_adams_bashforth_moulton controlled_stepper_type; + typedef controlled_adams_bashforth_moulton< ErrorStepper , StepAdjuster , OrderAdjuster , Resizer > controlled_stepper_type; controlled_adams_bashforth_moulton(step_adjuster_type step_adjuster = step_adjuster_type()) :m_stepper(), m_dxdt_resizer(), m_xerr_resizer(), m_xnew_resizer(), - m_step_adjuster(step_adjuster), m_order_adjuster() + m_step_adjuster( step_adjuster ), m_order_adjuster() {}; - template + template< class ExplicitStepper, class System > void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) { m_stepper.initialize(stepper, system, inOut, t, dt); }; - template + template< class System > void initialize(System system, state_type &inOut, time_type &t, time_type dt) { m_stepper.initialize(system, inOut, t, dt); }; - template + template< class System > controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) { m_xnew_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -122,7 +122,7 @@ public: return res; }; - template + template< class System > controlled_step_result try_step(System system, const state_type & in, time_type &t, state_type & out, time_type &dt) { m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); @@ -192,8 +192,8 @@ private: order_adjuster_type m_order_adjuster; }; -} -} -} +} // odeint +} // numeric +} // boost #endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 7f6d9d75..da948bd7 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -8,12 +8,10 @@ #include #include -#include #include #include -#include #include namespace boost { @@ -27,7 +25,7 @@ class Deriv, class Value = double, class Time = double, class Algebra = typename algebra_dispatcher< Deriv >::algebra_type, -class Operations = typename operations_dispatcher< Deriv >::operations_type , +class Operations = typename operations_dispatcher< Deriv >::operations_type, class Resizer = initially_resizer > class adaptive_adams_coefficients @@ -42,19 +40,19 @@ public: typedef Deriv deriv_type; typedef Time time_type; - typedef state_wrapper wrapped_deriv_type; - typedef rotating_buffer step_storage_type; // +1 for moulton - typedef rotating_buffer time_storage_type; + typedef state_wrapper< deriv_type > wrapped_deriv_type; + typedef rotating_buffer< wrapped_deriv_type , steps+1 > step_storage_type; // +1 for moulton + typedef rotating_buffer< time_type , steps+1 > time_storage_type; typedef Algebra algebra_type; typedef Operations operations_type; typedef Resizer resizer_type; - typedef adaptive_adams_coefficients aac_type; + typedef adaptive_adams_coefficients< Steps , Deriv , Value , Time , Algebra , Operations , Resizer > aac_type; adaptive_adams_coefficients( const algebra_type &algebra = algebra_type()) - :m_eo(1), beta(), phi(), m_ns(0), m_time_storage(), - m_algebra(algebra), + :m_eo( 1 ), beta(), phi(), m_ns( 0 ), m_time_storage(), + m_algebra( algebra ), m_phi_resizer() { for (size_t i=0; i Date: Mon, 3 Jul 2017 16:43:48 +0200 Subject: [PATCH 46/65] fix issues with compiling on travis --- .../odeint/stepper/detail/adaptive_adams_coefficients.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index da948bd7..1b6b980f 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include From 5a6c6bba5cf50d56cf599c4077d4bc32965350ea Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Mon, 3 Jul 2017 16:59:14 +0200 Subject: [PATCH 47/65] added detail:: to ref --- .../odeint/stepper/detail/adaptive_adams_coefficients.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 1b6b980f..f754ceb6 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -97,7 +97,7 @@ public: void do_step(const deriv_type &dxdt, const int o = 0) { - m_phi_resizer.adjust_size( dxdt , detail::bind( &aac_type::template resize_phi_impl< deriv_type > , ref( *this ) , detail::_1 ) ); + m_phi_resizer.adjust_size( dxdt , detail::bind( &aac_type::template resize_phi_impl< deriv_type > , detail::ref( *this ) , detail::_1 ) ); phi[o][0].m_v = dxdt; From ca9685010666650f659d7efc4de6c75d4e9dd87a Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 4 Jul 2017 01:21:35 +0200 Subject: [PATCH 48/65] fixed wrong order assignment when failing a step --- .../adaptive_adams_bashforth_moulton.hpp | 5 ++++- .../controlled_adams_bashforth_moulton.hpp | 21 ++++++++++++++---- .../detail/adaptive_adams_coefficients.hpp | 22 ++++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index a9ca9d80..582c2218 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -176,8 +176,11 @@ public: typename Operations::template scale_sum1(dt*(m_coeff.g[eO-1]-m_coeff.g[eO-2]))); } - this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, + if(m_coeff.m_init) + { + this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, typename Operations::template scale_sum1(dt*(m_coeff.g[eO+1]-m_coeff.g[eO]))); + } }; const coeff_type& coeff() const { return m_coeff; }; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index c7a4ca09..cf31d988 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace numeric { namespace odeint { @@ -132,11 +134,21 @@ public: coeff_type &coeff = m_stepper.coeff(); - size_t prevOrder = coeff.m_eo; - m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); - time_type dtPrev = dt; - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); + size_t prevOrder = coeff.m_eo; + + if(coeff.m_init) + { + m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); + } + else + { + if(coeff.m_eo < order_value) + coeff.m_eo ++; + + dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1].m_v); + } if(dt / dtPrev >= step_adjuster_type::threshold()) { @@ -149,6 +161,7 @@ public: } else { + coeff.m_eo = prevOrder; return fail; } }; diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index f754ceb6..63382568 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -52,7 +52,7 @@ public: typedef adaptive_adams_coefficients< Steps , Deriv , Value , Time , Algebra , Operations , Resizer > aac_type; adaptive_adams_coefficients( const algebra_type &algebra = algebra_type()) - :m_eo( 1 ), beta(), phi(), m_ns( 0 ), m_time_storage(), + :m_eo( 1 ), m_init( false ), beta(), phi(), m_ns( 0 ), m_time_storage(), m_algebra( algebra ), m_phi_resizer() { @@ -80,15 +80,20 @@ public: for(size_t i=1+m_ns; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, - typename Operations::template scale_sum2(1.0, -beta[o][i-1])); + if(im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, + typename Operations::template scale_sum2(1.0, -beta[o][i-1])); } }; @@ -113,11 +119,15 @@ public: beta.rotate(); phi.rotate(); m_time_storage.rotate(); + + if(m_eo == order_value) + m_init = true; }; void reset() { m_eo = 1; }; size_t m_eo; + bool m_init; rotating_buffer, 2> beta; // beta[0] = beta(n) rotating_buffer, 3> phi; // phi[0] = phi(n+1) From b5008296772a9f8799a9df7d06b271827fa9a93e Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 4 Jul 2017 11:46:20 +0200 Subject: [PATCH 49/65] enabling negative coefficients --- .../controlled_adams_bashforth_moulton.hpp | 3 +- .../stepper/detail/pid_step_adjuster.hpp | 31 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index cf31d988..507db6e5 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -57,8 +57,9 @@ template< class ErrorStepper, class StepAdjuster = detail::pid_step_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, + typename ErrorStepper::value_type, typename ErrorStepper::time_type, - detail::H312PID + detail::H0312 >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index d0c75ee2..07fec676 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -14,7 +14,8 @@ namespace detail{ template< size_t Steps, class State, -class Time, +class Value = double, +class Time = double, size_t Type = H211PI > struct pid_step_adjuster @@ -24,6 +25,7 @@ public: static double threshold() { return 0.9; }; typedef State state_type; + typedef Value value_type; typedef Time time_type; typedef rotating_buffer error_storage_type; @@ -39,18 +41,18 @@ public: m_error_storage[0] = err; m_time_storage[0] = dt; - double ratio = 100; - double r; + value_type ratio = 100; + value_type r; for(size_t i=0; i= 2) { - r = pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * - pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * - pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* - pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); + r = adapted_pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * + adapted_pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * + adapted_pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * + adapted_pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* + adapted_pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); } else { @@ -61,7 +63,7 @@ public: ratio = r; } - double kappa = 1.0; + value_type kappa = 1.0; ratio = 1.0 + kappa*atan((ratio - 1)/kappa); if(ratio*dt >= m_dtmax) @@ -81,10 +83,19 @@ public: m_init = 0; } - return dt*ratio; + return dt * static_cast (ratio); }; private: + template + inline value_type adapted_pow(T base, double exp) + { + if (exp > 0) + return pow(base, exp); + else + return 1/pow(base, -exp); + }; + time_type m_dtmax; error_storage_type m_error_storage; time_storage_type m_time_storage; From a21f49a7361d3f903703100f1b00c0343782e57c Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 4 Jul 2017 21:15:15 +0200 Subject: [PATCH 50/65] slight changes to initialization to allow for order correction --- .../adaptive_adams_bashforth_moulton.hpp | 2 +- .../controlled_adams_bashforth_moulton.hpp | 15 ++++++++++----- .../detail/adaptive_adams_coefficients.hpp | 17 +++++++---------- .../odeint/stepper/detail/pid_step_adjuster.hpp | 6 +++--- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 582c2218..ba7a9ac0 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -176,7 +176,7 @@ public: typename Operations::template scale_sum1(dt*(m_coeff.g[eO-1]-m_coeff.g[eO-2]))); } - if(m_coeff.m_init) + if(m_coeff.m_steps_init > eO) { this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, typename Operations::template scale_sum1(dt*(m_coeff.g[eO+1]-m_coeff.g[eO]))); diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 507db6e5..291ab7db 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -16,6 +16,10 @@ #include +#include +#include +#include + namespace boost { namespace numeric { namespace odeint { @@ -47,6 +51,7 @@ public: { ++order; } + //std::cout << order << std::endl; }; private: algebra_type m_algebra; @@ -59,7 +64,7 @@ class StepAdjuster = detail::pid_step_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, typename ErrorStepper::value_type, typename ErrorStepper::time_type, - detail::H0312 + detail::H312PID >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, @@ -138,16 +143,14 @@ public: time_type dtPrev = dt; size_t prevOrder = coeff.m_eo; - if(coeff.m_init) + if(coeff.m_steps_init+1 >= coeff.m_eo) { m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); } else { - if(coeff.m_eo < order_value) - coeff.m_eo ++; - + coeff.m_eo ++; dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1].m_v); } @@ -158,6 +161,8 @@ public: coeff.confirm(); t += dtPrev; + // std::cout << t << " " << dt << " " << coeff.m_eo << std::endl; + return success; } else diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 63382568..d3118dd0 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -52,7 +52,7 @@ public: typedef adaptive_adams_coefficients< Steps , Deriv , Value , Time , Algebra , Operations , Resizer > aac_type; adaptive_adams_coefficients( const algebra_type &algebra = algebra_type()) - :m_eo( 1 ), m_init( false ), beta(), phi(), m_ns( 0 ), m_time_storage(), + :m_eo( 1 ), m_steps_init( 1 ), beta(), phi(), m_ns( 0 ), m_time_storage(), m_algebra( algebra ), m_phi_resizer() { @@ -80,10 +80,7 @@ public: for(size_t i=1+m_ns; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, typename Operations::template scale_sum2(1.0, -beta[o][i-1])); } @@ -120,14 +117,14 @@ public: phi.rotate(); m_time_storage.rotate(); - if(m_eo == order_value) - m_init = true; + if(m_steps_init < order_value) + ++m_steps_init; }; void reset() { m_eo = 1; }; size_t m_eo; - bool m_init; + size_t m_steps_init; rotating_buffer, 2> beta; // beta[0] = beta(n) rotating_buffer, 3> phi; // phi[0] = phi(n+1) diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 07fec676..e695f980 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -1,5 +1,5 @@ -#ifndef PID_STEP_ADJUSTER_HPP_INCLUDED -#define PID_STEP_ADJUSTER_HPP_INCLUDED +#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_HPP_INCLUDED #include #include @@ -68,7 +68,7 @@ public: if(ratio*dt >= m_dtmax) { - dt = m_dtmax; + ratio = m_dtmax / dt; } if(ratio >= threshold() ) From ef866e14aae3f7380152ff7e5fea323f3b9365bd Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 4 Jul 2017 22:03:58 +0200 Subject: [PATCH 51/65] templating the pid adjuster --- .../controlled_adams_bashforth_moulton.hpp | 1 + .../stepper/detail/pid_step_adjuster.hpp | 100 ++++++++++++++++-- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 291ab7db..4a9ea986 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -64,6 +64,7 @@ class StepAdjuster = detail::pid_step_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, typename ErrorStepper::value_type, typename ErrorStepper::time_type, + typename ErrorStepper::algebra_type, detail::H312PID >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index e695f980..bbfad83c 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -4,6 +4,8 @@ #include #include +#include + #include namespace boost{ @@ -11,11 +13,70 @@ namespace numeric{ namespace odeint{ namespace detail{ +template< +size_t Steps, +class Value = double, +class Time = double +> +struct op +{ +public: + static const size_t steps = Steps; + + typedef Value value_type; + typedef Time time_type; + + const double beta1; + const double beta2; + const double beta3; + const double alpha1; + const double alpha2; + + const time_type t1; + const time_type t2; + const time_type t3; + + const double m_tol; + + op(const double tol, const double _t1, const double _t2, const double _t3, + const double b1 = 1, const double b2 = 0, const double b3 = 0, const double a1 = 0, const double a2 = 0) + :beta1(b1), beta2(b2), beta3(b3), alpha1(a1), alpha2(a2), + t1(_t1), t2(_t2), t3(_t3), m_tol(tol) + {}; + + template + void operator()(T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) + { + t1 = adapted_pow(fabs(m_tol/t2), beta1/(steps + 1)) * + adapted_pow(fabs(m_tol/t3), beta2/(steps + 1)) * + adapted_pow(fabs(m_tol/t4), beta3/(steps + 1)) * + adapted_pow(fabs(t1/t2), -alpha1/(steps + 1))* + adapted_pow(fabs(t2/t3), -alpha2/(steps + 1)); + }; + + template + void operator()(T1 &t1, const T2 &t2) + { + t1 = adapted_pow(fabs(m_tol/t2), beta1/(steps + 1)); + }; + +private: + template + inline value_type adapted_pow(T base, double exp) + { + if (exp > 0) + return pow(base, exp); + else + return 1/pow(base, -exp); + }; +}; + template< size_t Steps, class State, class Value = double, class Time = double, +class Algebra = typename algebra_dispatcher< State >::algebra_type, size_t Type = H211PI > struct pid_step_adjuster @@ -27,32 +88,47 @@ public: typedef State state_type; typedef Value value_type; typedef Time time_type; + typedef Algebra algebra_type; typedef rotating_buffer error_storage_type; typedef rotating_buffer time_storage_type; typedef pid_step_adjuster_coefficients coeff_type; pid_step_adjuster(double tol = 1e-6, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_time_storage(), m_init(0), m_tol(tol) + :m_dtmax(dtmax), m_error_storage(), m_dt_storage(), m_init(0), m_tol(tol) {}; - time_type adjust_stepsize(time_type dt, const state_type &err) + time_type adjust_stepsize(time_type dt, state_type &err) { m_error_storage[0] = err; - m_time_storage[0] = dt; + m_dt_storage[0] = dt; - value_type ratio = 100; - value_type r; + value_type ratio; + // value_type r; - for(size_t i=0; i= 2) + { + m_algebra.for_each4(err, m_error_storage[0], m_error_storage[1], m_error_storage[2], + op(m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], + m_coeff[0], m_coeff[1], m_coeff[2], m_coeff[3], m_coeff[4])); + } + else + { + m_algebra.for_each2(err, m_error_storage[0], + op(m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); + } + + ratio = m_algebra.norm_inf(err); + + /*for(size_t i=0; i= 2) { r = adapted_pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * adapted_pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * adapted_pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * - adapted_pow(fabs(m_time_storage[0]/m_time_storage[1]), -m_coeff[3]/(steps + 1))* - adapted_pow(fabs(m_time_storage[1]/m_time_storage[2]), -m_coeff[4]/(steps + 1)); + adapted_pow(fabs(m_dt_storage[0]/m_dt_storage[1]), -m_coeff[3]/(steps + 1))* + adapted_pow(fabs(m_dt_storage[1]/m_dt_storage[2]), -m_coeff[4]/(steps + 1)); } else { @@ -61,7 +137,7 @@ public: if(r= threshold() ) { m_error_storage.rotate(); - m_time_storage.rotate(); + m_dt_storage.rotate(); ++m_init; } @@ -96,9 +172,11 @@ private: return 1/pow(base, -exp); }; + algebra_type m_algebra; + time_type m_dtmax; error_storage_type m_error_storage; - time_storage_type m_time_storage; + time_storage_type m_dt_storage; size_t m_init; double m_tol; From 4a3477ed0b98f38cb043d7dc0b233c7d8e18a63e Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Wed, 5 Jul 2017 00:32:23 +0200 Subject: [PATCH 52/65] fixed ratio-selection --- .../adaptive_adams_bashforth_moulton.hpp | 3 +- .../controlled_adams_bashforth_moulton.hpp | 39 +++++---- .../detail/adaptive_adams_coefficients.hpp | 4 +- .../stepper/detail/pid_step_adjuster.hpp | 82 +++++++------------ 4 files changed, 55 insertions(+), 73 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index ba7a9ac0..abaaa0ad 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -169,13 +169,14 @@ public: this->m_algebra.for_each2(xerr[1].m_v, m_coeff.phi[0][eO].m_v, typename Operations::template scale_sum1(dt*(m_coeff.g[eO]-m_coeff.g[eO-1]))); - // error for order below/above + // error for order below if (eO > 1) { this->m_algebra.for_each2(xerr[0].m_v, m_coeff.phi[0][eO-1].m_v, typename Operations::template scale_sum1(dt*(m_coeff.g[eO-1]-m_coeff.g[eO-2]))); } + // error for order above if(m_coeff.m_steps_init > eO) { this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 4a9ea986..9d0cf0c3 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -16,10 +16,6 @@ #include -#include -#include -#include - namespace boost { namespace numeric { namespace odeint { @@ -27,12 +23,14 @@ namespace odeint { template< size_t MaxOrder, class State, +class Value = double, class Algebra = typename algebra_dispatcher< State >::algebra_type > class default_order_adjuster { public: typedef State state_type; + typedef Value value_type; typedef state_wrapper< state_type > wrapped_state_type; typedef Algebra algebra_type; @@ -43,15 +41,22 @@ public: void adjust_order(size_t &order, const boost::array & xerr) { - if(order > 1 && m_algebra.norm_inf(xerr[0].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) + if(order == 1 && m_algebra.norm_inf(xerr[2].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) { - --order; + order ++; } - else if (order < MaxOrder && m_algebra.norm_inf(xerr[2].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) + else { - ++order; + if(m_algebra.norm_inf(xerr[0].m_v) < m_algebra.norm_inf(xerr[1].m_v) && + m_algebra.norm_inf(xerr[0].m_v) < m_algebra.norm_inf(xerr[2].m_v)) + { + order--; + } + else if(order < MaxOrder && m_algebra.norm_inf(xerr[2].m_v) < m_algebra.norm_inf(xerr[1].m_v)) + { + order++; + } } - //std::cout << order << std::endl; }; private: algebra_type m_algebra; @@ -60,8 +65,7 @@ private: template< class ErrorStepper, -class StepAdjuster = detail::pid_step_adjuster< ErrorStepper::order_value, - typename ErrorStepper::state_type, +class StepAdjuster = detail::pid_step_adjuster< typename ErrorStepper::state_type, typename ErrorStepper::value_type, typename ErrorStepper::time_type, typename ErrorStepper::algebra_type, @@ -69,6 +73,7 @@ class StepAdjuster = detail::pid_step_adjuster< ErrorStepper::order_value, >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, + typename ErrorStepper::value_type, typename ErrorStepper::algebra_type >, class Resizer = initially_resizer @@ -144,15 +149,17 @@ public: time_type dtPrev = dt; size_t prevOrder = coeff.m_eo; - if(coeff.m_steps_init+1 >= coeff.m_eo) + if(coeff.m_steps_init > coeff.m_eo) { m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); + dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); } else { - coeff.m_eo ++; - dt = m_step_adjuster.adjust_stepsize(dt, m_xerr[1].m_v); + if(coeff.m_eo < order_value) + coeff.m_eo ++; + + dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1].m_v); } if(dt / dtPrev >= step_adjuster_type::threshold()) @@ -162,8 +169,6 @@ public: coeff.confirm(); t += dtPrev; - // std::cout << t << " " << dt << " " << coeff.m_eo << std::endl; - return success; } else diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index d3118dd0..159c6f37 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -85,7 +85,7 @@ public: m_time_storage[i-1])/(m_time_storage[0] - m_time_storage[i]); } - for(size_t i=1; i -struct op +struct pid_op { public: - static const size_t steps = Steps; - typedef Value value_type; typedef Time time_type; @@ -32,47 +29,58 @@ public: const double alpha1; const double alpha2; - const time_type t1; - const time_type t2; - const time_type t3; + const time_type dt1; + const time_type dt2; + const time_type dt3; const double m_tol; + const size_t m_steps; - op(const double tol, const double _t1, const double _t2, const double _t3, + pid_op(const size_t steps, const double tol, const double _dt1, const double _dt2, const double _dt3, const double b1 = 1, const double b2 = 0, const double b3 = 0, const double a1 = 0, const double a2 = 0) :beta1(b1), beta2(b2), beta3(b3), alpha1(a1), alpha2(a2), - t1(_t1), t2(_t2), t3(_t3), m_tol(tol) + dt1(_dt1), dt2(_dt2), dt3(_dt3), + m_tol(tol), m_steps(steps) {}; template void operator()(T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { - t1 = adapted_pow(fabs(m_tol/t2), beta1/(steps + 1)) * - adapted_pow(fabs(m_tol/t3), beta2/(steps + 1)) * - adapted_pow(fabs(m_tol/t4), beta3/(steps + 1)) * - adapted_pow(fabs(t1/t2), -alpha1/(steps + 1))* - adapted_pow(fabs(t2/t3), -alpha2/(steps + 1)); + t1 = adapted_pow(fabs(m_tol/t2), beta1/(m_steps + 1)) * + adapted_pow(fabs(m_tol/t3), beta2/(m_steps + 1)) * + adapted_pow(fabs(m_tol/t4), beta3/(m_steps + 1)) * + adapted_pow(fabs(dt1/dt2), -alpha1/(m_steps + 1))* + adapted_pow(fabs(dt2/dt3), -alpha2/(m_steps + 1)); + t1 = 1/t1; }; template void operator()(T1 &t1, const T2 &t2) { - t1 = adapted_pow(fabs(m_tol/t2), beta1/(steps + 1)); + t1 = adapted_pow(fabs(m_tol/t2), beta1/(m_steps + 1)); + t1 = 1/t1; }; private: template inline value_type adapted_pow(T base, double exp) { - if (exp > 0) + if(exp == 0) + { + return 1; + } + else if (exp > 0) + { return pow(base, exp); + } else + { return 1/pow(base, -exp); + } }; }; template< -size_t Steps, class State, class Value = double, class Time = double, @@ -82,7 +90,6 @@ size_t Type = H211PI struct pid_step_adjuster { public: - const static size_t steps = Steps; static double threshold() { return 0.9; }; typedef State state_type; @@ -98,46 +105,24 @@ public: :m_dtmax(dtmax), m_error_storage(), m_dt_storage(), m_init(0), m_tol(tol) {}; - time_type adjust_stepsize(time_type dt, state_type &err) + time_type adjust_stepsize(const size_t steps, time_type dt, state_type &err) { m_error_storage[0] = err; m_dt_storage[0] = dt; - value_type ratio; - // value_type r; - if(m_init >= 2) { m_algebra.for_each4(err, m_error_storage[0], m_error_storage[1], m_error_storage[2], - op(m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], + pid_op<>(steps, m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], m_coeff[0], m_coeff[1], m_coeff[2], m_coeff[3], m_coeff[4])); } else { m_algebra.for_each2(err, m_error_storage[0], - op(m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); + pid_op<>(steps, m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); } - ratio = m_algebra.norm_inf(err); - - /*for(size_t i=0; i= 2) - { - r = adapted_pow(fabs(m_tol/m_error_storage[0][i]), m_coeff[0]/(steps + 1)) * - adapted_pow(fabs(m_tol/m_error_storage[1][i]), m_coeff[1]/(steps + 1)) * - adapted_pow(fabs(m_tol/m_error_storage[2][i]), m_coeff[2]/(steps + 1)) * - adapted_pow(fabs(m_dt_storage[0]/m_dt_storage[1]), -m_coeff[3]/(steps + 1))* - adapted_pow(fabs(m_dt_storage[1]/m_dt_storage[2]), -m_coeff[4]/(steps + 1)); - } - else - { - r = pow(fabs(m_tol/m_error_storage[0][i]), 0.7/(steps + 1)); // purely integrating controller for startup - } - - if(r - inline value_type adapted_pow(T base, double exp) - { - if (exp > 0) - return pow(base, exp); - else - return 1/pow(base, -exp); - }; - algebra_type m_algebra; time_type m_dtmax; From fa6621e43cd16b5762b4d6834c8d00aec055fab9 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 6 Jul 2017 18:23:17 +0200 Subject: [PATCH 53/65] updated order selection --- .../controlled_adams_bashforth_moulton.hpp | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 9d0cf0c3..f01f7bfd 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -41,18 +41,33 @@ public: void adjust_order(size_t &order, const boost::array & xerr) { - if(order == 1 && m_algebra.norm_inf(xerr[2].m_v) < 0.5 * m_algebra.norm_inf(xerr[1].m_v)) + value_type errm = fabs(m_algebra.norm_inf(xerr[0].m_v)); + value_type errc = fabs(m_algebra.norm_inf(xerr[1].m_v)); + value_type errp = fabs(m_algebra.norm_inf(xerr[2].m_v)); + + if(order == 1) + { + if(errp < errc) + { + order ++; + } + } + else if(order == MaxOrder) { - order ++; + if(errm < errc) + { + order --; + } } else { - if(m_algebra.norm_inf(xerr[0].m_v) < m_algebra.norm_inf(xerr[1].m_v) && - m_algebra.norm_inf(xerr[0].m_v) < m_algebra.norm_inf(xerr[2].m_v)) + if(errm < errc && + errm < errp) { order--; } - else if(order < MaxOrder && m_algebra.norm_inf(xerr[2].m_v) < m_algebra.norm_inf(xerr[1].m_v)) + else if(errp < errm && + errp < errc) { order++; } @@ -69,7 +84,7 @@ class StepAdjuster = detail::pid_step_adjuster< typename ErrorStepper::state_typ typename ErrorStepper::value_type, typename ErrorStepper::time_type, typename ErrorStepper::algebra_type, - detail::H312PID + detail::BASIC >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, @@ -169,6 +184,7 @@ public: coeff.confirm(); t += dtPrev; + return success; } else From c673986a1315bafd6923cc3500b3e8f551d4aa9c Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Thu, 6 Jul 2017 20:07:56 +0200 Subject: [PATCH 54/65] formatting --- .../adaptive_adams_bashforth_moulton.hpp | 6 +- .../controlled_adams_bashforth_moulton.hpp | 3 +- .../detail/adaptive_adams_coefficients.hpp | 12 +- .../stepper/detail/pid_step_adjuster.hpp | 30 +++-- .../detail/pid_step_adjuster_coefficients.hpp | 111 +++++++++--------- 5 files changed, 89 insertions(+), 73 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index abaaa0ad..28ca7376 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -105,7 +105,9 @@ public: m_coeff.confirm(); if(m_coeff.m_eo < order_value) + { m_coeff.m_eo ++; + } }; template< class ExplicitStepper, class System > @@ -123,7 +125,9 @@ public: m_coeff.confirm(); if(m_coeff.m_eo < order_value) - m_coeff.m_eo ++; + { + ++m_coeff.m_eo; + } } }; diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index f01f7bfd..09759c6e 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -75,7 +75,6 @@ public: }; private: algebra_type m_algebra; - }; template< @@ -146,7 +145,9 @@ public: controlled_step_result res = try_step(system, inOut, t, m_xnew.m_v, dt); if(res == success) + { boost::numeric::odeint::copy( m_xnew.m_v , inOut); + } return res; }; diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 159c6f37..6693c2b6 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -52,8 +52,8 @@ public: typedef adaptive_adams_coefficients< Steps , Deriv , Value , Time , Algebra , Operations , Resizer > aac_type; adaptive_adams_coefficients( const algebra_type &algebra = algebra_type()) - :m_eo( 1 ), m_steps_init( 1 ), beta(), phi(), m_ns( 0 ), m_time_storage(), - m_algebra( algebra ), + :m_eo(1), m_steps_init(1), beta(), phi(), m_ns(0), m_time_storage(), + m_algebra(algebra), m_phi_resizer() { for (size_t i=0; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, typename Operations::template scale_sum2(1.0, -beta[o][i-1])); + } } }; @@ -118,7 +124,9 @@ public: m_time_storage.rotate(); if(m_steps_init < order_value+1) + { ++m_steps_init; + } }; void reset() { m_eo = 1; }; diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 63f97035..946cc2ac 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -8,10 +8,10 @@ #include -namespace boost{ -namespace numeric{ -namespace odeint{ -namespace detail{ +namespace boost { +namespace numeric { +namespace odeint { +namespace detail { template< class Value = double, @@ -51,6 +51,7 @@ public: adapted_pow(fabs(m_tol/t4), beta3/(m_steps + 1)) * adapted_pow(fabs(dt1/dt2), -alpha1/(m_steps + 1))* adapted_pow(fabs(dt2/dt3), -alpha2/(m_steps + 1)); + t1 = 1/t1; }; @@ -58,6 +59,7 @@ public: void operator()(T1 &t1, const T2 &t2) { t1 = adapted_pow(fabs(m_tol/t2), beta1/(m_steps + 1)); + t1 = 1/t1; }; @@ -85,7 +87,7 @@ class State, class Value = double, class Time = double, class Algebra = typename algebra_dispatcher< State >::algebra_type, -size_t Type = H211PI +size_t Type = BASIC > struct pid_step_adjuster { @@ -95,6 +97,7 @@ public: typedef State state_type; typedef Value value_type; typedef Time time_type; + typedef Algebra algebra_type; typedef rotating_buffer error_storage_type; @@ -122,17 +125,17 @@ public: pid_op<>(steps, m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); } - value_type ratio = 1/m_algebra.norm_inf(err); + value_type ratio = 1 / m_algebra.norm_inf(err); value_type kappa = 1.0; - ratio = 1.0 + kappa*atan((ratio - 1)/kappa); + ratio = 1.0 + kappa*atan((ratio - 1) / kappa); if(ratio*dt >= m_dtmax) { ratio = m_dtmax / dt; } - if(ratio >= threshold() ) + if(ratio >= threshold()) { m_error_storage.rotate(); m_dt_storage.rotate(); @@ -144,7 +147,7 @@ public: m_init = 0; } - return dt * static_cast (ratio); + return dt * static_cast(ratio); }; private: @@ -160,8 +163,9 @@ private: coeff_type m_coeff; }; -} -} -} -} +} // detail +} // odeint +} // numeric +} // boost + #endif \ No newline at end of file diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp index d60fb6f4..d3d8e6eb 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -1,13 +1,12 @@ - -#ifndef PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED -#define PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED +#ifndef BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED +#define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED #include -namespace boost{ -namespace numeric{ -namespace odeint{ -namespace detail{ +namespace boost { +namespace numeric { +namespace odeint { +namespace detail { enum adjuster_type{ BASIC, @@ -31,11 +30,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1; - (*this)[1] = 0; - (*this)[2] = 0; - (*this)[3] = 0; - (*this)[4] = 0; + (*this)[0] = 1.0; + (*this)[1] = 0.0; + (*this)[2] = 0.0; + (*this)[3] = 0.0; + (*this)[4] = 0.0; } }; @@ -46,11 +45,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/2.0; - (*this)[1] = 1.0/2.0; - (*this)[2] = 0; - (*this)[3] = 1.0/2.0; - (*this)[4] = 0; + (*this)[0] = 1.0 / 2.0; + (*this)[1] = 1.0 / 2.0; + (*this)[2] = 0.0; + (*this)[3] = 1.0 / 2.0; + (*this)[4] = 0.0; } }; @@ -61,11 +60,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/5.0; - (*this)[1] = 2.0/5.0; - (*this)[2] = 0; - (*this)[3] = 1.0/5.0; - (*this)[4] = 0; + (*this)[0] = 1.0 / 5.0; + (*this)[1] = 2.0 / 5.0; + (*this)[2] = 0.0; + (*this)[3] = 1.0 / 5.0; + (*this)[4] = 0.0; } }; @@ -76,11 +75,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/6.0; - (*this)[1] = 2.0/6.0; - (*this)[2] = 0; - (*this)[3] = 0; - (*this)[4] = 0; + (*this)[0] = 1.0 / 6.0; + (*this)[1] = 2.0 / 6.0; + (*this)[2] = 0.0; + (*this)[3] = 0.0; + (*this)[4] = 0.0; } }; @@ -91,11 +90,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/4.0; - (*this)[1] = 2.0/2.0; - (*this)[2] = 1.0/4.0; - (*this)[3] = 3.0/4.0; - (*this)[4] = 1.0/4.0; + (*this)[0] = 1.0 / 4.0; + (*this)[1] = 2.0 / 2.0; + (*this)[2] = 1.0 / 4.0; + (*this)[3] = 3.0 / 4.0; + (*this)[4] = 1.0 / 4.0; } }; @@ -106,11 +105,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/6.0; - (*this)[1] = 2.0/6.0; - (*this)[2] = 1.0/6.0; - (*this)[3] = 3.0/6.0; - (*this)[4] = 1.0/6.0; + (*this)[0] = 1.0 / 6.0; + (*this)[1] = 2.0 / 6.0; + (*this)[2] = 1.0 / 6.0; + (*this)[3] = 3.0 / 6.0; + (*this)[4] = 1.0 / 6.0; } }; @@ -121,11 +120,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/18.0; - (*this)[1] = 2.0/9.0; - (*this)[2] = 1.0/18.0; - (*this)[3] = 0; - (*this)[4] = 0; + (*this)[0] = 1.0 / 18.0; + (*this)[1] = 2.0 / 9.0; + (*this)[2] = 1.0 / 18.0; + (*this)[3] = 0.0; + (*this)[4] = 0.0; } }; @@ -136,11 +135,11 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 5.0/4.0; - (*this)[1] = 1.0/2.0; - (*this)[2] = -3.0/4.0; - (*this)[3] = -1.0/4.0; - (*this)[4] = -3.0/4.0; + (*this)[0] = 5.0 / 4.0; + (*this)[1] = 1.0 / 2.0; + (*this)[2] = -3.0 / 4.0; + (*this)[3] = -1.0 / 4.0; + (*this)[4] = -3.0 / 4.0; } }; @@ -151,17 +150,17 @@ public: pid_step_adjuster_coefficients() : boost::array() { - (*this)[0] = 1.0/3.0; - (*this)[1] = 1.0/18.0; - (*this)[2] = -5.0/18.0; - (*this)[3] = -5.0/16.0; - (*this)[4] = -1.0/6.0; + (*this)[0] = 1.0 / 3.0; + (*this)[1] = 1.0 / 18.0; + (*this)[2] = -5.0 / 18.0; + (*this)[3] = -5.0 / 16.0; + (*this)[4] = -1.0 / 6.0; } }; -} -} -} -} +} // detail +} // odeint +} // numeric +} // boost #endif \ No newline at end of file From b38159f51a1fee1f4df11651e6a282ebdb158c86 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Fri, 7 Jul 2017 17:25:26 +0200 Subject: [PATCH 55/65] add relative error to step adjuster --- .../adaptive_adams_bashforth_moulton.hpp | 1 + .../controlled_adams_bashforth_moulton.hpp | 14 ++++---- .../detail/adaptive_adams_coefficients.hpp | 27 ++++++-------- .../stepper/detail/pid_step_adjuster.hpp | 36 ++++++++++++------- ...ion_controlled_adams_bashforth_moulton.hpp | 4 +-- 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 28ca7376..df7359cc 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -192,6 +192,7 @@ public: coeff_type & coeff() { return m_coeff; }; void reset() { m_coeff.reset(); }; + const deriv_type & dxdt() const { return m_dxdt.m_v; }; private: template< class StateType > diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 09759c6e..9805d464 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -80,10 +80,12 @@ private: template< class ErrorStepper, class StepAdjuster = detail::pid_step_adjuster< typename ErrorStepper::state_type, - typename ErrorStepper::value_type, + typename ErrorStepper::value_type, + typename ErrorStepper::deriv_type, typename ErrorStepper::time_type, typename ErrorStepper::algebra_type, - detail::BASIC + typename ErrorStepper::operations_type, + detail::H211PI >, class OrderAdjuster = default_order_adjuster< ErrorStepper::order_value, typename ErrorStepper::state_type, @@ -168,14 +170,15 @@ public: if(coeff.m_steps_init > coeff.m_eo) { m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); - dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v); + dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v, in, m_stepper.dxdt()); } else { if(coeff.m_eo < order_value) + { coeff.m_eo ++; - - dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1].m_v); + } + dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1].m_v, in, m_stepper.dxdt()); } if(dt / dtPrev >= step_adjuster_type::threshold()) @@ -185,7 +188,6 @@ public: coeff.confirm(); t += dtPrev; - return success; } else diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 6693c2b6..feec9079 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -57,7 +57,9 @@ public: m_phi_resizer() { for (size_t i=0; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, - typename Operations::template scale_sum2(1.0, -beta[o][i-1])); - } + this->m_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, + typename Operations::template scale_sum2(1.0, -beta[o][i-1])); } }; diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 946cc2ac..1a53d54e 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -33,22 +34,21 @@ public: const time_type dt2; const time_type dt3; - const double m_tol; const size_t m_steps; - pid_op(const size_t steps, const double tol, const double _dt1, const double _dt2, const double _dt3, + pid_op(const size_t steps, const double _dt1, const double _dt2, const double _dt3, const double b1 = 1, const double b2 = 0, const double b3 = 0, const double a1 = 0, const double a2 = 0) :beta1(b1), beta2(b2), beta3(b3), alpha1(a1), alpha2(a2), dt1(_dt1), dt2(_dt2), dt3(_dt3), - m_tol(tol), m_steps(steps) + m_steps(steps) {}; template void operator()(T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { - t1 = adapted_pow(fabs(m_tol/t2), beta1/(m_steps + 1)) * - adapted_pow(fabs(m_tol/t3), beta2/(m_steps + 1)) * - adapted_pow(fabs(m_tol/t4), beta3/(m_steps + 1)) * + t1 = adapted_pow(fabs(t2), -beta1/(m_steps + 1)) * + adapted_pow(fabs(t3), -beta2/(m_steps + 1)) * + adapted_pow(fabs(t4), -beta3/(m_steps + 1)) * adapted_pow(fabs(dt1/dt2), -alpha1/(m_steps + 1))* adapted_pow(fabs(dt2/dt3), -alpha2/(m_steps + 1)); @@ -58,7 +58,7 @@ public: template void operator()(T1 &t1, const T2 &t2) { - t1 = adapted_pow(fabs(m_tol/t2), beta1/(m_steps + 1)); + t1 = adapted_pow(fabs(t2), -beta1/(m_steps + 1)); t1 = 1/t1; }; @@ -85,8 +85,10 @@ private: template< class State, class Value = double, +class Deriv = State, class Time = double, class Algebra = typename algebra_dispatcher< State >::algebra_type, +class Operations = typename operations_dispatcher< Deriv >::operations_type, size_t Type = BASIC > struct pid_step_adjuster @@ -96,33 +98,40 @@ public: typedef State state_type; typedef Value value_type; + typedef Deriv deriv_type; typedef Time time_type; typedef Algebra algebra_type; + typedef Operations operations_type; typedef rotating_buffer error_storage_type; typedef rotating_buffer time_storage_type; typedef pid_step_adjuster_coefficients coeff_type; - pid_step_adjuster(double tol = 1e-6, time_type dtmax = 1.0) - :m_dtmax(dtmax), m_error_storage(), m_dt_storage(), m_init(0), m_tol(tol) + pid_step_adjuster(double abs_tol = 1e-6, double rel_tol = 1e-6, time_type dtmax = 1.0) + :m_dtmax(dtmax), m_error_storage(), m_dt_storage(), m_init(0), + m_abs_tol(abs_tol), m_rel_tol(rel_tol) {}; - time_type adjust_stepsize(const size_t steps, time_type dt, state_type &err) + time_type adjust_stepsize(const size_t steps, time_type dt, state_type &err, const state_type &x, const deriv_type &dxdt) { + using std::abs; + m_algebra.for_each3( err , x , dxdt , + typename operations_type::template rel_error< value_type >( m_abs_tol , m_rel_tol , 1.0 , 1.0 * abs(get_unit_value( dt )) ) ); + m_error_storage[0] = err; m_dt_storage[0] = dt; if(m_init >= 2) { m_algebra.for_each4(err, m_error_storage[0], m_error_storage[1], m_error_storage[2], - pid_op<>(steps, m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], + pid_op<>(steps, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], m_coeff[0], m_coeff[1], m_coeff[2], m_coeff[3], m_coeff[4])); } else { m_algebra.for_each2(err, m_error_storage[0], - pid_op<>(steps, m_tol, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); + pid_op<>(steps, m_dt_storage[0], m_dt_storage[1], m_dt_storage[2], 0.7)); } value_type ratio = 1 / m_algebra.norm_inf(err); @@ -158,7 +167,8 @@ private: time_storage_type m_dt_storage; size_t m_init; - double m_tol; + double m_abs_tol; + double m_rel_tol; coeff_type m_coeff; }; diff --git a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp index b734d146..7d46f5bb 100644 --- a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp @@ -28,13 +28,13 @@ struct controller_factory< Stepper , controlled_adams_bashforth_moulton< Stepper controller_type operator()( value_type abs_error , value_type rel_error , const stepper_type &stepper ) { - return controller_type(step_adjuster_type(abs_error)); + return controller_type(step_adjuster_type(abs_error, rel_error)); } controller_type operator()( value_type abs_error , value_type rel_error , time_type max_dt, const stepper_type &stepper ) { - return controller_type( step_adjuster_type(abs_error, max_dt)); + return controller_type( step_adjuster_type(abs_error, rel_error, max_dt)); } }; From 11bf5d56c5cb31b686af4f830bcfdae23c6414de Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Sat, 8 Jul 2017 21:21:47 +0200 Subject: [PATCH 56/65] replace assignment with boost::copy --- .../numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index df7359cc..7856ddad 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -156,7 +156,7 @@ public: m_coeff.do_step(m_dxdt.m_v, 1); } - out = in; + boost::numeric::odeint::copy( in , out ); for(size_t i=0; im_algebra.for_each3(out, out, m_coeff.phi[1][i].m_v, From f1098483eaf11d58a158a4e80e7dcb0ca5876730 Mon Sep 17 00:00:00 2001 From: ds283 Date: Sun, 23 Jul 2017 22:31:35 +0100 Subject: [PATCH 57/65] Switch fabs for std::abs - controlled_adams_bashforth_moulton.hpp, adaptive_adams_coefficients.hpp and pid_step_adjuster.hpp extract absolute values using fabs() without a namespace qualifier - if the integration value type is not double then this can cause problems, since fabs() is not required to have a long double overload. In such cases it is safer to use std::abs, and also this matches the rest of the odeint-v2 codebase --- .../controlled_adams_bashforth_moulton.hpp | 8 +++++--- .../detail/adaptive_adams_coefficients.hpp | 4 +++- .../odeint/stepper/detail/pid_step_adjuster.hpp | 16 ++++++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 9805d464..adc537f5 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -41,9 +41,11 @@ public: void adjust_order(size_t &order, const boost::array & xerr) { - value_type errm = fabs(m_algebra.norm_inf(xerr[0].m_v)); - value_type errc = fabs(m_algebra.norm_inf(xerr[1].m_v)); - value_type errp = fabs(m_algebra.norm_inf(xerr[2].m_v)); + using std::abs; + + value_type errm = abs(m_algebra.norm_inf(xerr[0].m_v)); + value_type errc = abs(m_algebra.norm_inf(xerr[1].m_v)); + value_type errp = abs(m_algebra.norm_inf(xerr[2].m_v)); if(order == 1) { diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index feec9079..1a24d857 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -69,9 +69,11 @@ public: void predict(time_type t, time_type dt) { + using std::abs; + m_time_storage[0] = t; - if (fabs(m_time_storage[0] - m_time_storage[1] - dt) > 1e-16 || m_eo >= m_ns) + if (abs(m_time_storage[0] - m_time_storage[1] - dt) > 1e-16 || m_eo >= m_ns) { m_ns = 0; } diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 1a53d54e..96c6ef33 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -46,11 +46,13 @@ public: template void operator()(T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) { - t1 = adapted_pow(fabs(t2), -beta1/(m_steps + 1)) * - adapted_pow(fabs(t3), -beta2/(m_steps + 1)) * - adapted_pow(fabs(t4), -beta3/(m_steps + 1)) * - adapted_pow(fabs(dt1/dt2), -alpha1/(m_steps + 1))* - adapted_pow(fabs(dt2/dt3), -alpha2/(m_steps + 1)); + using std::abs; + + t1 = adapted_pow(abs(t2), -beta1/(m_steps + 1)) * + adapted_pow(abs(t3), -beta2/(m_steps + 1)) * + adapted_pow(abs(t4), -beta3/(m_steps + 1)) * + adapted_pow(abs(dt1/dt2), -alpha1/(m_steps + 1))* + adapted_pow(abs(dt2/dt3), -alpha2/(m_steps + 1)); t1 = 1/t1; }; @@ -58,7 +60,9 @@ public: template void operator()(T1 &t1, const T2 &t2) { - t1 = adapted_pow(fabs(t2), -beta1/(m_steps + 1)); + using std::abs; + + t1 = adapted_pow(abs(t2), -beta1/(m_steps + 1)); t1 = 1/t1; }; From 540f46f42cf1cd80f1dbfe0e6c1efa4bb70b2d6c Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Tue, 26 Sep 2017 00:22:51 +0200 Subject: [PATCH 58/65] Improvement to Order Selection, Error approximation in the ABM stepper (#218) * improves the order selection and modifies the error estimation accordingly - assumes constant stepsize for the next step to approximate error - moves the complete order adjustment to the class order_adjustment - slight changes to adaptive_adams_coefficients * changed the commit according to the requests and comments --- .../adaptive_adams_bashforth_moulton.hpp | 43 ++----- .../controlled_adams_bashforth_moulton.hpp | 118 +++++++++++------- .../detail/adaptive_adams_coefficients.hpp | 58 ++++++--- 3 files changed, 127 insertions(+), 92 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 7856ddad..5ba319c1 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -49,7 +49,6 @@ public: typedef state_wrapper< state_type > wrapped_state_type; typedef state_wrapper< deriv_type > wrapped_deriv_type; - typedef boost::array< wrapped_state_type , 3 > error_storage_type; typedef algebra_stepper_base< Algebra , Operations > algebra_stepper_base_type; typedef typename algebra_stepper_base_type::algebra_type algebra_type; @@ -74,14 +73,14 @@ public: { m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, m_xnew.m_v, dt, m_xerr[1].m_v); + do_step(system, inOut, t, m_xnew.m_v, dt, m_xerr.m_v); boost::numeric::odeint::copy( m_xnew.m_v , inOut); }; template< class System > void do_step(System system, const state_type &in, time_type t, state_type &out, time_type dt ) { - do_step(system, in, t, out, dt, m_xerr); + do_step(system, in, t, out, dt, m_xerr.m_v); }; template< class System > @@ -89,16 +88,14 @@ public: { m_xnew_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_xnew_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - do_step(system, inOut, t, m_xnew.m_v, dt, m_xerr[1].m_v); + do_step(system, inOut, t, m_xnew.m_v, dt, xerr); boost::numeric::odeint::copy( m_xnew.m_v , inOut); - boost::numeric::odeint::copy( m_xerr[1].m_v , xerr); }; template< class System > void do_step(System system, const state_type &in, time_type t, state_type &out, time_type dt , state_type &xerr) { - do_step_impl(system, in, t, out, dt, m_xerr); - boost::numeric::odeint::copy( m_xerr[1].m_v , xerr); + do_step_impl(system, in, t, out, dt, xerr); system(out, m_dxdt.m_v, t+dt); m_coeff.do_step(m_dxdt.m_v); @@ -142,7 +139,7 @@ public: }; template< class System > - void do_step_impl(System system, const state_type & in, time_type t, state_type & out, time_type &dt, error_storage_type &xerr) + void do_step_impl(System system, const state_type & in, time_type t, state_type & out, time_type &dt, state_type &xerr) { size_t eO = m_coeff.m_eo; @@ -150,7 +147,7 @@ public: m_dxdt_resizer.adjust_size( in , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); m_coeff.predict(t, dt); - if (eO == 1) + if (m_coeff.m_steps_init == 1) { system(in, m_dxdt.m_v, t); m_coeff.do_step(m_dxdt.m_v, 1); @@ -170,22 +167,8 @@ public: typename Operations::template scale_sum2(1.0, dt*m_coeff.g[eO])); // error for current order - this->m_algebra.for_each2(xerr[1].m_v, m_coeff.phi[0][eO].m_v, - typename Operations::template scale_sum1(dt*(m_coeff.g[eO]-m_coeff.g[eO-1]))); - - // error for order below - if (eO > 1) - { - this->m_algebra.for_each2(xerr[0].m_v, m_coeff.phi[0][eO-1].m_v, - typename Operations::template scale_sum1(dt*(m_coeff.g[eO-1]-m_coeff.g[eO-2]))); - } - - // error for order above - if(m_coeff.m_steps_init > eO) - { - this->m_algebra.for_each2(xerr[2].m_v, m_coeff.phi[0][eO+1].m_v, - typename Operations::template scale_sum1(dt*(m_coeff.g[eO+1]-m_coeff.g[eO]))); - } + this->m_algebra.for_each2(xerr, m_coeff.phi[0][eO].m_v, + typename Operations::template scale_sum1(dt*(m_coeff.g[eO]))); }; const coeff_type& coeff() const { return m_coeff; }; @@ -208,13 +191,7 @@ private: template< class StateType > bool resize_xerr_impl( const StateType &x ) { - bool resized( false ); - - for(size_t i=0; i<3; ++i) - { - resized |= adjust_size_by_resizeability( m_xerr[i], x, typename is_resizeable::type() ); - } - return resized; + return adjust_size_by_resizeability( m_xerr, x, typename is_resizeable::type() ); }; coeff_type m_coeff; @@ -225,7 +202,7 @@ private: wrapped_deriv_type m_dxdt; wrapped_state_type m_xnew; - error_storage_type m_xerr; + wrapped_state_type m_xerr; }; } // odeint diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index adc537f5..9372fd77 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -39,41 +39,58 @@ public: : m_algebra( algebra ) {}; - void adjust_order(size_t &order, const boost::array & xerr) + size_t adjust_order(size_t order, size_t init, boost::array &xerr) { using std::abs; - value_type errm = abs(m_algebra.norm_inf(xerr[0].m_v)); - value_type errc = abs(m_algebra.norm_inf(xerr[1].m_v)); - value_type errp = abs(m_algebra.norm_inf(xerr[2].m_v)); + value_type errc = abs(m_algebra.norm_inf(xerr[2].m_v)); - if(order == 1) - { - if(errp < errc) - { - order ++; - } - } - else if(order == MaxOrder) + value_type errm1 = 3*errc; + value_type errm2 = 3*errc; + + if(order > 2) { - if(errm < errc) - { - order --; - } + errm2 = abs(m_algebra.norm_inf(xerr[0].m_v)); } - else + if(order >= 2) { - if(errm < errc && - errm < errp) + errm1 = abs(m_algebra.norm_inf(xerr[1].m_v)); + } + + size_t o_new = order; + + if(order == 2 && errm1 <= 0.5*errc) + { + o_new = order - 1; + } + else if(order > 2 && errm2 < errc && errm1 < errc) + { + o_new = order - 1; + } + + if(init < order) + { + return order+1; + } + else if(o_new == order - 1) + { + return order-1; + } + else if(order <= MaxOrder) + { + value_type errp = abs(m_algebra.norm_inf(xerr[3].m_v)); + + if(order > 1 && errm1 < errc && errp) { - order--; + return order-1; } - else if(errp < errm && - errp < errc) + else if(order < MaxOrder && errp < (0.5-0.25*order/MaxOrder) * errc) { - order++; + return order+1; } } + + return order; }; private: algebra_type m_algebra; @@ -118,7 +135,7 @@ public: typedef typename stepper_type::wrapped_state_type wrapped_state_type; typedef typename stepper_type::wrapped_deriv_type wrapped_deriv_type; - typedef boost::array< wrapped_state_type , 3 > error_storage_type; + typedef boost::array< wrapped_state_type , 4 > error_storage_type; typedef typename stepper_type::coeff_type coeff_type; typedef controlled_adams_bashforth_moulton< ErrorStepper , StepAdjuster , OrderAdjuster , Resizer > controlled_stepper_type; @@ -162,39 +179,54 @@ public: m_xerr_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_xerr_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); m_dxdt_resizer.adjust_size( in , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); - m_stepper.do_step_impl(system, in, t, out, dt, m_xerr); + m_stepper.do_step_impl(system, in, t, out, dt, m_xerr[2].m_v); coeff_type &coeff = m_stepper.coeff(); time_type dtPrev = dt; - size_t prevOrder = coeff.m_eo; - - if(coeff.m_steps_init > coeff.m_eo) - { - m_order_adjuster.adjust_order(coeff.m_eo, m_xerr); - dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1 + coeff.m_eo - prevOrder].m_v, in, m_stepper.dxdt()); - } - else - { - if(coeff.m_eo < order_value) - { - coeff.m_eo ++; - } - dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[1].m_v, in, m_stepper.dxdt()); - } + dt = m_step_adjuster.adjust_stepsize(coeff.m_eo, dt, m_xerr[2].m_v, out, m_stepper.dxdt() ); if(dt / dtPrev >= step_adjuster_type::threshold()) { - system(out, m_dxdt.m_v, t+dt); + system(out, m_dxdt.m_v, t+dtPrev); + coeff.do_step(m_dxdt.m_v); coeff.confirm(); t += dtPrev; + + size_t eo = coeff.m_eo; + + // estimate errors for next step + double factor = 1; + algebra_type m_algebra; + + m_algebra.for_each2(m_xerr[2].m_v, coeff.phi[1][eo].m_v, + typename operations_type::template scale_sum1(factor*dt*(coeff.gs[eo]))); + + if(eo > 1) + { + m_algebra.for_each2(m_xerr[1].m_v, coeff.phi[1][eo-1].m_v, + typename operations_type::template scale_sum1(factor*dt*(coeff.gs[eo-1]))); + } + if(eo > 2) + { + m_algebra.for_each2(m_xerr[0].m_v, coeff.phi[1][eo-2].m_v, + typename operations_type::template scale_sum1(factor*dt*(coeff.gs[eo-2]))); + } + if(eo < order_value && coeff.m_eo < coeff.m_steps_init-1) + { + m_algebra.for_each2(m_xerr[3].m_v, coeff.phi[1][eo+1].m_v, + typename operations_type::template scale_sum1(factor*dt*(coeff.gs[eo+1]))); + } + + // adjust order + coeff.m_eo = m_order_adjuster.adjust_order(coeff.m_eo, coeff.m_steps_init-1, m_xerr); + return success; } else { - coeff.m_eo = prevOrder; return fail; } }; @@ -212,7 +244,7 @@ private: { bool resized( false ); - for(size_t i=0; i<3; ++i) + for(size_t i=0; i::type() ); } diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index 1a24d857..a68c151f 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -42,7 +42,6 @@ public: typedef Time time_type; typedef state_wrapper< deriv_type > wrapped_deriv_type; - typedef rotating_buffer< wrapped_deriv_type , steps+1 > step_storage_type; // +1 for moulton typedef rotating_buffer< time_type , steps+1 > time_storage_type; typedef Algebra algebra_type; @@ -58,13 +57,30 @@ public: { for (size_t i=0; im_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, - typename Operations::template scale_sum2(1.0, -beta[o][i-1])); - } + if (o == 0) + { + this->m_algebra.for_each3(phi[o][i].m_v, phi[o][i-1].m_v, phi[o+1][i-1].m_v, + typename Operations::template scale_sum2(1.0, -beta[o][i-1])); + } + else + { + this->m_algebra.for_each2(phi[o][i].m_v, phi[o][i-1].m_v, + typename Operations::template scale_sum1(1.0)); + } + } }; void confirm() @@ -124,7 +149,7 @@ public: } }; - void reset() { m_eo = 1; }; + void reset() { m_eo = 1; m_steps_init = 1; }; size_t m_eo; size_t m_steps_init; @@ -132,12 +157,12 @@ public: rotating_buffer, 2> beta; // beta[0] = beta(n) rotating_buffer, 3> phi; // phi[0] = phi(n+1) boost::array g; + boost::array gs; private: template< class StateType > bool resize_phi_impl( const StateType &x ) { - bool resized( false ); for(size_t i=0; i<(order_value + 2); ++i) @@ -152,7 +177,8 @@ private: size_t m_ns; time_storage_type m_time_storage; - boost::array, order_value + 2> c; + static const size_t c_size = order_value + 2; + boost::array c; algebra_type m_algebra; From 34def567d27001191a27eb8c9d65d7399a29e08b Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Sun, 12 Nov 2017 21:12:17 +0100 Subject: [PATCH 59/65] fix initialization with external stepper (#215) - time was not increased over the iterations - prediction of dxdt was taken before integrating with the supplied stepper instead of after --- .../adaptive_adams_bashforth_moulton.hpp | 20 ++++++++++++++----- .../adaptive_adams_bashforth_moulton.cpp | 7 +------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 5ba319c1..28154e02 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -110,16 +110,23 @@ public: template< class ExplicitStepper, class System > void initialize(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type dt) { + reset(); + dt = dt/static_cast< time_type >(order_value); + m_dxdt_resizer.adjust_size( inOut , detail::bind( &stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + system( inOut , m_dxdt.m_v , t ); for( size_t i=0 ; i(order_value) ); + stepper.do_step_dxdt_impl( system, inOut, m_dxdt.m_v, t, dt ); - m_coeff.predict(t, dt/static_cast< Time >(order_value)); + system( inOut , m_dxdt.m_v , t + dt); + + m_coeff.predict(t, dt); m_coeff.do_step(m_dxdt.m_v); m_coeff.confirm(); + + t += dt; if(m_coeff.m_eo < order_value) { @@ -131,10 +138,13 @@ public: template< class System > void initialize(System system, state_type &inOut, time_type &t, time_type dt) { + reset(); + dt = dt/static_cast< time_type >(order_value); + for(size_t i=0; ido_step(system, inOut, t, dt/static_cast< Time >(order_value)); - t += dt/static_cast< Time >(order_value); + this->do_step(system, inOut, t, dt); + t += dt; }; }; diff --git a/test/numeric/adaptive_adams_bashforth_moulton.cpp b/test/numeric/adaptive_adams_bashforth_moulton.cpp index 663a2c4b..0932dd1d 100644 --- a/test/numeric/adaptive_adams_bashforth_moulton.cpp +++ b/test/numeric/adaptive_adams_bashforth_moulton.cpp @@ -68,12 +68,7 @@ struct perform_adaptive_adams_bashforth_moulton_test 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; - // more steps necessary to "counteract" the effect from the lower order steps - 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 From 30fd68fbb3a72f428c66cefe962265192c8f1d79 Mon Sep 17 00:00:00 2001 From: Valentin Hartmann Date: Fri, 5 Jan 2018 17:22:52 +0100 Subject: [PATCH 60/65] adds controlled initialization (#216) - errors might already occur during the first few steps if the stepsize is chosen too big - initialize_controlled takes advantage of controlled steppers to initialize the controlled abm stepper --- .../adaptive_adams_bashforth_moulton.hpp | 15 +++++++ .../controlled_adams_bashforth_moulton.hpp | 45 +++++++++++++++++++ .../detail/adaptive_adams_coefficients.hpp | 14 ++++++ .../stepper/detail/pid_step_adjuster.hpp | 14 ++++++ .../detail/pid_step_adjuster_coefficients.hpp | 14 ++++++ ...ion_controlled_adams_bashforth_moulton.hpp | 14 ++++++ 6 files changed, 116 insertions(+) diff --git a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp index 28154e02..0d3d0c12 100644 --- a/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/adaptive_adams_bashforth_moulton.hpp @@ -1,3 +1,18 @@ +/* + boost/numeric/odeint/stepper/detail/adaptive_adams_bashforth_moulton.hpp + + [begin_description] + Implemetation of an adaptive adams bashforth moulton stepper. + Used as the stepper for the controlled adams bashforth moulton stepper. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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_NUMERIC_ODEINT_STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #define BOOST_NUMERIC_ODEINT_STEPPER_ADAPTIVE_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED diff --git a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp index 9372fd77..85ee4d01 100644 --- a/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_adams_bashforth_moulton.hpp @@ -1,3 +1,17 @@ +/* + boost/numeric/odeint/stepper/detail/controlled_adams_bashforth_moulton.hpp + + [begin_description] + Implemetation of an controlled adams bashforth moulton stepper. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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_NUMERIC_ODEINT_STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #define BOOST_NUMERIC_ODEINT_STEPPER_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED @@ -158,6 +172,37 @@ public: m_stepper.initialize(system, inOut, t, dt); }; + template< class ExplicitStepper, class System > + void initialize_controlled(ExplicitStepper stepper, System system, state_type &inOut, time_type &t, time_type &dt) + { + reset(); + coeff_type &coeff = m_stepper.coeff(); + + m_dxdt_resizer.adjust_size( inOut , detail::bind( &controlled_stepper_type::template resize_dxdt_impl< state_type > , detail::ref( *this ) , detail::_1 ) ); + + controlled_step_result res = fail; + + for( size_t i=0 ; i controlled_step_result try_step(System system, state_type & inOut, time_type &t, time_type &dt) { diff --git a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp index a68c151f..c1029a16 100644 --- a/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp @@ -1,3 +1,17 @@ +/* + boost/numeric/odeint/stepper/detail/adaptive_adams_coefficients.hpp + + [begin_description] + Calculation of the coefficients for the adaptive adams stepper. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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_NUMERIC_ODEINT_STEPPER_DETAIL_ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED #define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_ADAPTIVE_ADAMS_COEFFICIENTS_HPP_INCLUDED diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp index 96c6ef33..7c0f258b 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp @@ -1,3 +1,17 @@ +/* + boost/numeric/odeint/stepper/detail/pid_step_adjuster.hpp + + [begin_description] + Implementation of the stepsize controller for the controlled adams bashforth moulton stepper. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_HPP_INCLUDED #define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_HPP_INCLUDED diff --git a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp index d3d8e6eb..2dee6ed1 100644 --- a/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp +++ b/include/boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp @@ -1,3 +1,17 @@ +/* + boost/numeric/odeint/stepper/detail/pid_step_adjuster_coefficients.hpp + + [begin_description] + Coefficients for the PID stepsize controller. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED #define BOOST_NUMERIC_ODEINT_STEPPER_DETAIL_PID_STEP_ADJUSTER_COEFFICIENTS_HPP_INCLUDED diff --git a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp index 7d46f5bb..ca95a1f5 100644 --- a/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp +++ b/include/boost/numeric/odeint/stepper/generation/generation_controlled_adams_bashforth_moulton.hpp @@ -1,3 +1,17 @@ +/* + boost/numeric/odeint/stepper/detail/generation_controlled_adams_bashforth_moulton.hpp + + [begin_description] + Spezialization of the generation functions for creation of the controlled adams bashforth moulton stepper. + [end_description] + + Copyright 2017 Valentin Noah Hartmann + + 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 GENERATION_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED #define GENERATION_CONTROLLED_ADAMS_BASHFORTH_MOULTON_HPP_INCLUDED From a393540e17829f5c0179f6019222299999bb0d4a Mon Sep 17 00:00:00 2001 From: Markus Friedrich Date: Sat, 20 Jan 2018 20:24:22 +0100 Subject: [PATCH 61/65] Fixed dense_output_runge_kutta::do_step(...) (#224) do_step must return the pair (t, t+dt) but (t, dt) is returned. Note that dense_output_runge_kutta::do_step(...) works correctly. --- .../boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp index 94abc5af..83982dc7 100644 --- a/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp +++ b/include/boost/numeric/odeint/stepper/dense_output_runge_kutta.hpp @@ -126,7 +126,7 @@ public: m_t_old = m_t; m_t += m_dt; toggle_current_state(); - return std::make_pair( m_t_old , m_dt ); + return std::make_pair( m_t_old , m_t ); } /* From 5dd9519b7b603b7dd3d25d06900012405667426a Mon Sep 17 00:00:00 2001 From: Markus Friedrich Date: Tue, 13 Feb 2018 05:13:12 +0100 Subject: [PATCH 62/65] Enable the adaption of the maximal step size of dense output steppers. (#225) * Enable the adaption of the maximal step size of dense output steppers. For efficient simulation of "hybrid" systems the integrator must approach the sample points where the discrete variables change their value. (hybrid systems = systems of ODEs which include discrete variables, beeing internal variables of the system which only change their value at discrete sample points) Approaching sample points can be done by adapting the maximal integrator step size to min(max_step_size, next_sample_point_time - current_time) before each do_step. To achive this in odeint for all dense output steppers the following changes must be done (which does not change the existing API): - make private members in bulirsch_stoer_dense_out, default_step_adjuster, rosenbrock4_controller protected. - allow std::ref/boost::ref for step_adjuster in controlled_runge_kutta and controlled_runge_kutta and for stepper in rosenbrock4_dense_output by unwrapping these before use. This allows to pass the step adjusters by reference to the dense output steppers which than allows to change the maximal step size (in the step adjuster) before each call to do_step. * Added test for a reference controller in the Rosenbrock4 dense output stepper. * Make in bulirsch_stoer_dense_out only the required m_max_dt member protected not all. Extend the test in rosenbrock4.cpp to test that the controller is a reference and the maximal step size is applied. * Fixed build with gcc-4.8 --- .../stepper/bulirsch_stoer_dense_out.hpp | 7 ++-- .../odeint/stepper/controlled_runge_kutta.hpp | 24 ++++++++------ .../odeint/stepper/rosenbrock4_controller.hpp | 2 +- .../stepper/rosenbrock4_dense_output.hpp | 19 +++++++---- test/rosenbrock4.cpp | 33 +++++++++++++++++++ 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp index 6a1eed15..22eb373b 100644 --- a/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp +++ b/include/boost/numeric/odeint/stepper/bulirsch_stoer_dense_out.hpp @@ -391,6 +391,11 @@ public: } +protected: + + time_type m_max_dt; + + private: template< class StateInOut , class StateVector > @@ -667,8 +672,6 @@ private: default_error_checker< value_type, algebra_type , operations_type > m_error_checker; modified_midpoint_dense_out< state_type , value_type , deriv_type , time_type , algebra_type , operations_type , resizer_type > m_midpoint; - time_type m_max_dt; - bool m_control_interpolation; bool m_last_step_rejected; diff --git a/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp index aac2b02d..be00827f 100644 --- a/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp +++ b/include/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp @@ -163,7 +163,7 @@ public: time_type get_max_dt() { return m_max_dt; } -private: +protected: time_type m_max_dt; }; @@ -411,10 +411,11 @@ public: template< class System , class StateIn , class DerivIn , class StateOut > controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt , time_type &t , StateOut &out , time_type &dt ) { - if( !m_step_adjuster.check_step_size_limit(dt) ) + unwrapped_step_adjuster &step_adjuster = m_step_adjuster; + if( !step_adjuster.check_step_size_limit(dt) ) { // given dt was above step size limit - adjust and return fail; - dt = m_step_adjuster.get_max_dt(); + dt = step_adjuster.get_max_dt(); return fail; } @@ -428,13 +429,13 @@ public: if( max_rel_err > 1.0 ) { // error too big, decrease step size and reject this step - dt = m_step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order()); + dt = step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order()); return fail; } else { // otherwise, increase step size and accept t += dt; - dt = m_step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order()); + dt = step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order()); return success; } } @@ -505,6 +506,7 @@ private: stepper_type m_stepper; error_checker_type m_error_checker; step_adjuster_type m_step_adjuster; + typedef typename unwrap_reference< step_adjuster_type >::type unwrapped_step_adjuster; resizer_type m_dxdt_resizer; resizer_type m_xerr_resizer; @@ -584,7 +586,7 @@ public: const step_adjuster_type &step_adjuster = step_adjuster_type() , const stepper_type &stepper = stepper_type() ) - : m_stepper( stepper ) , m_error_checker( error_checker ) , m_step_adjuster(step_adjuster) , + : m_stepper( stepper ) , m_error_checker( error_checker ) , m_step_adjuster(step_adjuster) , m_first_call( true ) { } @@ -751,10 +753,11 @@ public: controlled_step_result try_step( System system , const StateIn &in , const DerivIn &dxdt_in , time_type &t , StateOut &out , DerivOut &dxdt_out , time_type &dt ) { - if( !m_step_adjuster.check_step_size_limit(dt) ) + unwrapped_step_adjuster &step_adjuster = m_step_adjuster; + if( !step_adjuster.check_step_size_limit(dt) ) { // given dt was above step size limit - adjust and return fail; - dt = m_step_adjuster.get_max_dt(); + dt = step_adjuster.get_max_dt(); return fail; } @@ -770,12 +773,12 @@ public: if( max_rel_err > 1.0 ) { // error too big, decrease step size and reject this step - dt = m_step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order()); + dt = step_adjuster.decrease_step(dt, max_rel_err, m_stepper.error_order()); return fail; } // otherwise, increase step size and accept t += dt; - dt = m_step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order()); + dt = step_adjuster.increase_step(dt, max_rel_err, m_stepper.stepper_order()); return success; } @@ -903,6 +906,7 @@ private: stepper_type m_stepper; error_checker_type m_error_checker; step_adjuster_type m_step_adjuster; + typedef typename unwrap_reference< step_adjuster_type >::type unwrapped_step_adjuster; resizer_type m_dxdt_resizer; resizer_type m_xerr_resizer; diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp index 61d6e511..5ad1600d 100644 --- a/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp +++ b/include/boost/numeric/odeint/stepper/rosenbrock4_controller.hpp @@ -200,7 +200,7 @@ public: -private: +protected: template< class StateIn > bool resize_m_xerr( const StateIn &x ) diff --git a/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp b/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp index 6695ba6a..d296246a 100644 --- a/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp +++ b/include/boost/numeric/odeint/stepper/rosenbrock4_dense_output.hpp @@ -41,7 +41,8 @@ class rosenbrock4_dense_output public: typedef ControlledStepper controlled_stepper_type; - typedef typename controlled_stepper_type::stepper_type stepper_type; + typedef typename unwrap_reference< controlled_stepper_type >::type unwrapped_controlled_stepper_type; + typedef typename unwrapped_controlled_stepper_type::stepper_type stepper_type; typedef typename stepper_type::value_type value_type; typedef typename stepper_type::state_type state_type; typedef typename stepper_type::wrapped_state_type wrapped_state_type; @@ -54,7 +55,7 @@ public: typedef rosenbrock4_dense_output< ControlledStepper > dense_output_stepper_type; rosenbrock4_dense_output( const controlled_stepper_type &stepper = controlled_stepper_type() ) - : m_stepper( stepper ) , + : m_stepper( stepper ) , m_x1() , m_x2() , m_current_state_x1( true ) , m_t() , m_t_old() , m_dt() @@ -75,16 +76,17 @@ public: template< class System > std::pair< time_type , time_type > do_step( System system ) { + unwrapped_controlled_stepper_type &stepper = m_stepper; failed_step_checker fail_checker; // to throw a runtime_error if step size adjustment fails controlled_step_result res = fail; m_t_old = m_t; do { - res = m_stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt ); + res = stepper.try_step( system , get_current_state() , m_t , get_old_state() , m_dt ); fail_checker(); // check for overflow of failed steps } while( res == fail ); - m_stepper.stepper().prepare_dense_output(); + stepper.stepper().prepare_dense_output(); this->toggle_current_state(); return std::make_pair( m_t_old , m_t ); } @@ -96,20 +98,23 @@ public: template< class StateOut > void calc_state( time_type t , StateOut &x ) { - m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); + unwrapped_controlled_stepper_type &stepper = m_stepper; + stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); } template< class StateOut > void calc_state( time_type t , const StateOut &x ) { - m_stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); + unwrapped_controlled_stepper_type &stepper = m_stepper; + stepper.stepper().calc_state( t , x , get_old_state() , m_t_old , get_current_state() , m_t ); } template< class StateType > void adjust_size( const StateType &x ) { - m_stepper.adjust_size( x ); + unwrapped_controlled_stepper_type &stepper = m_stepper; + stepper.adjust_size( x ); resize_impl( x ); } diff --git a/test/rosenbrock4.cpp b/test/rosenbrock4.cpp index f0b79d51..0b7bea4b 100644 --- a/test/rosenbrock4.cpp +++ b/test/rosenbrock4.cpp @@ -127,6 +127,39 @@ BOOST_AUTO_TEST_CASE( test_rosenbrock4_dense_output ) 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; From 75fe4e19ad2d0a5e34eefc253ac9432fb0db50c8 Mon Sep 17 00:00:00 2001 From: Garret McGraw Date: Sat, 2 Mar 2019 14:17:09 -0500 Subject: [PATCH 63/65] =?UTF-8?q?Fixed=20incorrect=20constant=20in=20Dorma?= =?UTF-8?q?nd=E2=80=93Prince=20Runge=E2=80=93Kutta=20Butcher=20tableau.=20?= =?UTF-8?q?(#235)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp index 260cd74f..07271830 100644 --- a/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp +++ b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp @@ -174,7 +174,7 @@ public : const value_type dc4 = c4 - static_cast ( 393 ) / static_cast( 640 ); const value_type dc5 = c5 - static_cast ( -92097 ) / static_cast( 339200 ); const value_type dc6 = c6 - static_cast ( 187 ) / static_cast( 2100 ); - const value_type dc7 = static_cast( -1 ) / static_cast ( 40 ); + const value_type dc7 = static_cast( 1 ) / static_cast ( 40 ); /* ToDo: copy only if &dxdt_in == &dxdt_out ? */ if( same_instance( dxdt_in , dxdt_out ) ) From ee44ba9e362f21dc0f3d0a99ac769401981fba3f Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sat, 2 Mar 2019 11:42:32 -0800 Subject: [PATCH 64/65] =?UTF-8?q?Revert=20"Fixed=20incorrect=20constant=20?= =?UTF-8?q?in=20Dormand=E2=80=93Prince=20Runge=E2=80=93Kutta=20Butcher=20t?= =?UTF-8?q?ableau.=20(#235)"=20(#236)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 75fe4e19ad2d0a5e34eefc253ac9432fb0db50c8. --- include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp index 07271830..260cd74f 100644 --- a/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp +++ b/include/boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp @@ -174,7 +174,7 @@ public : const value_type dc4 = c4 - static_cast ( 393 ) / static_cast( 640 ); const value_type dc5 = c5 - static_cast ( -92097 ) / static_cast( 339200 ); const value_type dc6 = c6 - static_cast ( 187 ) / static_cast( 2100 ); - const value_type dc7 = static_cast( 1 ) / static_cast ( 40 ); + const value_type dc7 = static_cast( -1 ) / static_cast ( 40 ); /* ToDo: copy only if &dxdt_in == &dxdt_out ? */ if( same_instance( dxdt_in , dxdt_out ) ) From db8b39ae27346e501941bf705362a1f4879b653c Mon Sep 17 00:00:00 2001 From: Mario Mulansky Date: Sat, 16 Mar 2019 16:20:44 -0700 Subject: [PATCH 65/65] Change eigen algebra to support Eigen>=3.3 (#237) * Change eigen algebra to support Eigen>=3.3 An internal change in Eigen made odeint incompatible with Eigen versions >=3.3. This commit changes odeint in such a way that it does not rely on the changed behvior, so it is now compatible with old and new Eigen. Fixes #194 * Remove obsolete Eigen fail compile test * Remove compile-fail test for C++98 unwrap_reference --- .../odeint/external/eigen/eigen_algebra.hpp | 45 +++++++----------- test/Jamfile.v2 | 1 - test_external/eigen/Jamfile.v2 | 1 - test_external/eigen/fail_integrate.cpp | 47 ------------------- 4 files changed, 17 insertions(+), 77 deletions(-) delete mode 100644 test_external/eigen/fail_integrate.cpp diff --git a/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp b/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp index b4ee5c3b..3783cd81 100644 --- a/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp +++ b/include/boost/numeric/odeint/external/eigen/eigen_algebra.hpp @@ -25,42 +25,36 @@ // from odeint // (that is, it lets odeint treat the eigen matrices correctly, knowing // how to add, multiply, compute the norm, etc) - namespace Eigen { - template inline const -typename Eigen::CwiseUnaryOp< - typename Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>, - const D > +typename Eigen::CwiseBinaryOp< + internal::scalar_sum_op::Scalar>, + typename DenseBase::ConstantReturnType, + const D> operator+(const typename Eigen::MatrixBase &m, const typename Eigen::internal::traits::Scalar &s) { - return Eigen::CwiseUnaryOp< - typename Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>, - const D >(m.derived(),Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>(s)); + return CwiseBinaryOp< + internal::scalar_sum_op::Scalar>, + typename DenseBase::ConstantReturnType, + const D>(DenseBase::Constant(m.rows(), m.cols(), s), m.derived()); } template inline const -typename Eigen::CwiseUnaryOp< - typename Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>, - const D > +typename Eigen::CwiseBinaryOp< + internal::scalar_sum_op::Scalar>, + typename DenseBase::ConstantReturnType, + const D> operator+(const typename Eigen::internal::traits::Scalar &s, -const typename Eigen::MatrixBase &m) { - return Eigen::CwiseUnaryOp< - typename Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>, - const D >(m.derived(),Eigen::internal::scalar_add_op< - typename Eigen::internal::traits::Scalar>(s)); + const typename Eigen::MatrixBase &m) { + return CwiseBinaryOp< + internal::scalar_sum_op::Scalar>, + typename DenseBase::ConstantReturnType, + const D>(DenseBase::Constant(m.rows(), m.cols(), s), m.derived()); } - - template inline const typename Eigen::CwiseBinaryOp< @@ -82,14 +76,9 @@ abs( const Eigen::MatrixBase< D > &m ) { return m.cwiseAbs(); } - - } // end Eigen namespace - - - namespace boost { namespace numeric { namespace odeint { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dd78e21c..68725822 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -84,7 +84,6 @@ test-suite "odeint" [ run integrate_overflow.cpp ] [ compile unwrap_boost_reference.cpp ] [ compile unwrap_reference.cpp : -std=c++0x : unwrap_reference_C++11 ] - [ compile-fail unwrap_reference.cpp : -std=c++98 : unwrap_reference_C++98 ] [ compile std_array.cpp : -std=c++0x ] : valgrind diff --git a/test_external/eigen/Jamfile.v2 b/test_external/eigen/Jamfile.v2 index 489f67ce..ad0cc2d2 100644 --- a/test_external/eigen/Jamfile.v2 +++ b/test_external/eigen/Jamfile.v2 @@ -31,6 +31,5 @@ test-suite "odeint" [ run runge_kutta4.cpp ] [ run runge_kutta_dopri5.cpp ] [ run integrate.cpp ] - [ compile-fail fail_integrate.cpp ] : valgrind ; diff --git a/test_external/eigen/fail_integrate.cpp b/test_external/eigen/fail_integrate.cpp deleted file mode 100644 index 4c71b018..00000000 --- a/test_external/eigen/fail_integrate.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - [auto_generated] - fail_integrate.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 -#ifdef BOOST_MSVC - #pragma warning(disable:4996) -#endif - -#define BOOST_TEST_MODULE odeint_dummy - -#include -#include - -#include - -#include "dummy_odes.hpp" - -using namespace boost::unit_test; -using namespace boost::numeric::odeint; - - -BOOST_AUTO_TEST_SUITE( eigen_fail_integrate ) - -BOOST_AUTO_TEST_CASE( test ) -{ - typedef Eigen::Matrix< double , 1 , 1 > state_type; - state_type x; - x[0] = 10.0; - double t_start = 0.0 , t_end = 1.0 , dt = 0.1; - integrate( constant_system_functor_standard() , x , t_start , t_end , dt ); -} - -BOOST_AUTO_TEST_SUITE_END() -