Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58036 - in sandbox/odeint: boost/numeric boost/numeric/odeint libs/numeric/odeint/examples libs/numeric/odeint/stuff/test
From: mario.mulansky_at_[hidden]
Date: 2009-11-29 15:36:33


Author: mariomulansky
Date: 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
New Revision: 58036
URL: http://svn.boost.org/trac/boost/changeset/58036

Log:
bulirsch stoer stepper with example - yeah
Added:
   sandbox/odeint/boost/numeric/odeint/controlled_stepper_bs.hpp (contents, props changed)
   sandbox/odeint/boost/numeric/odeint/error_checker_standard.hpp (contents, props changed)
   sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_bs.cpp (contents, props changed)
Text files modified:
   sandbox/odeint/boost/numeric/odeint.hpp | 3 +
   sandbox/odeint/boost/numeric/odeint/stepper_midpoint.hpp | 14 +++++--
   sandbox/odeint/boost/numeric/odeint/stepper_rk78_fehlberg.hpp | 3 -
   sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp | 68 ++++++++++++++++++++++++++++++---------
   sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_midpoint.cpp | 13 ++++--
   5 files changed, 73 insertions(+), 28 deletions(-)

Modified: sandbox/odeint/boost/numeric/odeint.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint.hpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -25,6 +25,9 @@
 #include <boost/numeric/odeint/stepper_rk78_fehlberg.hpp>
 
 #include <boost/numeric/odeint/controlled_stepper_standard.hpp>
+#include <boost/numeric/odeint/controlled_stepper_bs.hpp>
+
+#include <boost/numeric/odeint/error_checker_standard.hpp>
 
 #include <boost/numeric/odeint/integrator_adaptive_stepsize.hpp>
 #include <boost/numeric/odeint/integrator_constant_stepsize.hpp>

Added: sandbox/odeint/boost/numeric/odeint/controlled_stepper_bs.hpp
==============================================================================
--- (empty file)
+++ sandbox/odeint/boost/numeric/odeint/controlled_stepper_bs.hpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,371 @@
+/* Boost odeint/controlled_stepper_bs.hpp header file
+
+ Copyright 2009 Karsten Ahnert
+ Copyright 2009 Mario Mulansky
+
+ This file includes the explicit Burlisch Stoer
+ solver for ordinary differential equations.
+
+ It solves any ODE dx/dt = f(x,t) via
+ x(t+dt) = x(t) + dt*f(x,t)
+
+ 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_CONTROLLED_STEPPER_BS_HPP
+#define BOOST_NUMERIC_ODEINT_CONTROLLED_STEPPER_BS_HPP
+
+#include <limits>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/numeric/odeint/detail/iterator_algebra.hpp>
+#include <boost/numeric/odeint/concepts/state_concept.hpp>
+#include <boost/numeric/odeint/resizer.hpp>
+#include <boost/numeric/odeint/stepper_midpoint.hpp>
+#include <boost/numeric/odeint/error_checker_standard.hpp>
+
+#include <iostream>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+ // typedef enum{success, step_size_decreased, step_size_increased} controlled_step_result;
+
+ template<
+ class Container ,
+ class Time = double ,
+ class Resizer = resizer< Container >
+ >
+ class controlled_stepper_bs
+ {
+ // provide basic typedefs
+ public:
+
+ typedef Container container_type;
+ typedef Resizer resizer_type;
+ typedef Time time_type;
+ typedef const unsigned short order_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::iterator iterator;
+
+
+ // check the concept of the ContainerType
+ private:
+
+ BOOST_CLASS_REQUIRE( container_type ,
+ boost::numeric::odeint, Container );
+
+
+ // private memebers
+ private:
+ stepper_midpoint< Container, Time, Resizer > m_stepper_mp;
+ resizer_type m_resizer;
+ error_checker_standard<container_type, time_type> m_error_checker;
+
+ const unsigned short m_k_max;
+
+ const time_type m_safety1;
+ const time_type m_safety2;
+ const time_type m_max_dt_factor;
+ const time_type m_min_step_scale;
+ const time_type m_max_step_scale;
+
+ bool m_continuous_calls;
+ bool m_decreased_step_during_last_call;
+
+ time_type m_dt_last;
+ time_type m_t_last;
+ time_type m_current_eps;
+
+ unsigned short m_current_k_max;
+ unsigned short m_current_k_opt;
+
+ container_type m_x0;
+ container_type m_xerr;
+ container_type m_x_mp;
+ container_type m_x_scale;
+ container_type m_dxdt;
+
+ typedef std::vector< time_type > value_vector;
+ typedef std::vector< std::vector< time_type > > value_matrix;
+ typedef std::vector< unsigned short > us_vector;
+
+ value_vector m_error;
+ value_vector m_a;
+ value_matrix m_alpha;
+ us_vector m_interval_sequence;
+
+ value_vector m_times;
+ std::vector< container_type > m_d;
+ container_type m_c;
+
+ // public functions
+ public:
+
+ // constructor
+ controlled_stepper_bs(
+ time_type abs_err, time_type rel_err,
+ time_type factor_x, time_type factor_dxdt )
+ : m_error_checker( abs_err, rel_err, factor_x, factor_dxdt ),
+ m_k_max(8),
+ m_safety1(0.25), m_safety2(0.7),
+ m_max_dt_factor( 0.1 ), m_min_step_scale(5E-5), m_max_step_scale(0.7),
+ m_continuous_calls(false), m_decreased_step_during_last_call( false ),
+ m_dt_last( 1.0E30),
+ m_current_eps( -1.0 )
+ {
+ m_error.resize(m_k_max);
+ m_a.resize(m_k_max+1);
+ m_alpha.resize(m_k_max); // k_max * k_max matrix
+ typename value_matrix::iterator it = m_alpha.begin();
+ while( it != m_alpha.end() )
+ (*it++).resize(m_k_max);
+ m_interval_sequence.resize(m_k_max+1);
+ for( unsigned short i = 1; i <= m_k_max+1; i++ )
+ m_interval_sequence[i-1] = (2*i);
+
+ m_times.resize(m_k_max);
+ m_d.resize(m_k_max);
+ }
+
+
+ template< class DynamicalSystem >
+ controlled_step_result try_step(
+ DynamicalSystem &system ,
+ container_type &x ,
+ container_type &dxdt ,
+ time_type &t ,
+ time_type &dt )
+ {
+ m_resizer.adjust_size(x, m_xerr);
+ m_resizer.adjust_size(x, m_x_mp);
+ m_resizer.adjust_size(x, m_x_scale);
+
+ // get error scale
+ m_error_checker.fill_scale(x, dxdt, dt, m_x_scale);
+
+ //std::clog << " x scale: " << m_x_scale[0] << '\t' << m_x_scale[1] << std::endl;
+
+ m_x0 = x; // save starting state
+ time_type max_eps = m_error_checker.get_epsilon();
+ if( m_current_eps != max_eps )
+ { // error changed -> recalculate tableau
+ initialize_step_adjust_tableau( max_eps );
+ m_current_eps = max_eps;
+ m_dt_last = m_t_last = std::numeric_limits< value_type >::max(); // unrealistic
+ }
+ // if t and dt are exactly the parameters from last step we are called continuously
+ bool continuous_call = ((t == m_t_last) || (dt == m_dt_last ));
+ if( !continuous_call )
+ m_current_k_opt = m_current_k_max;
+
+ bool converged = false;
+ value_type step_scale = 1.0;
+ unsigned short k_conv = 0;
+
+ for( unsigned short k=0; k<=m_current_k_max; k++ )
+ {
+ unsigned short stepcount = m_interval_sequence[k];
+ //out-of-place midpoint step
+ m_stepper_mp.set_stepcount(stepcount);
+ m_stepper_mp.do_step(system, m_x0, dxdt, t, dt, m_x_mp);
+ //std::clog << "x_mp: " << k << '\t' << m_x_mp[0] << '\t' << m_x_mp[1] << std::endl;
+ time_type t_est = (dt/stepcount)*(dt/stepcount);
+ extrapolate(k, t_est, m_x_mp, x, m_xerr);
+ //std::clog << "Error: " << k << '\t' << m_xerr[0] << '\t' << m_xerr[1] << std::endl;
+ if( k != 0 )
+ {
+ value_type max_err = m_error_checker.get_max_error_ratio(m_xerr, m_x_scale);
+ m_error[k-1] = std::pow( max_err/m_safety1, 1.0/(2*k+1) );
+ if( (k >= m_current_k_opt-1) || !continuous_call )
+ { //we're in the order window where convergence is expected
+ if( max_err < 1.0 )
+ {
+ k_conv = k;
+ converged = true;
+ //std::clog << "Converged at: " << k << '\t' << max_err << std::endl;
+ break;
+ } else {
+ converged = false;
+ if( (k == m_current_k_max) || (k == m_current_k_opt+1) )
+ {
+ step_scale = m_safety2/m_error[k-1];
+ break;
+ } else if( (k == m_current_k_opt) &&
+ (m_alpha[m_current_k_opt-1][m_current_k_opt] < m_error[k-1] ) )
+ {
+ step_scale = static_cast<value_type>(1.0)/m_error[k-1];
+ break;
+ } else if( (m_current_k_opt == m_current_k_max) &&
+ (m_alpha[k-1][m_current_k_max-1] < m_error[k-1]) )
+ {
+ step_scale = m_alpha[k-1][m_current_k_max-1]*m_safety2/m_error[k-1];
+ //std::clog << " Case 3 " << m_alpha[k-1][m_current_k_max-1] << '\t' << m_error[k-1] << '\t' << step_scale << std::endl;
+ break;
+ } else if( m_alpha[k-1][m_current_k_opt] < m_error[k-1] )
+ {
+ step_scale = m_alpha[k-1][m_current_k_opt-1]/m_error[k-1];
+ break;
+ }
+ }
+ }
+ }
+ }
+ if( !converged ) { // dt was too large - no converge up to order k_max
+
+ // step_scale is always > 1
+ step_scale = std::max(step_scale, m_min_step_scale); // at least m_min ...
+ step_scale = std::min(step_scale, m_max_step_scale); // at most m_max ...
+ dt *= step_scale;
+ m_dt_last = dt;
+ m_t_last = t;
+ m_decreased_step_during_last_call = true;
+ x = m_x0; // copy the state back
+ return step_size_decreased;
+
+ } else { //converged
+
+ t += dt; // step accomplished
+
+ time_type work_min = std::numeric_limits< time_type >::max();
+ for( unsigned short k=0; k < k_conv ; k++ )
+ { // compute optimal convergence order and corresponding stepsize
+ time_type factor = std::max(m_error[k], m_max_dt_factor);
+ time_type work = factor * m_a[k+1];
+ if( work < work_min )
+ {
+ step_scale = factor;
+ work_min = work;
+ m_current_k_opt = k+1;
+ }
+ }
+ m_dt_last = dt/step_scale;
+
+ //std::clog << "Internal: " << dt << '\t' << k_conv-1 << '\t' << m_current_k_opt << '\t' << m_current_k_max << '\t' << m_decreased_step_during_last_call << std::endl;
+
+ if( (m_current_k_opt >= k_conv) &&
+ (m_current_k_opt != m_current_k_max) &&
+ !m_decreased_step_during_last_call )
+ { // check possible order increase, if step was not decreased before
+ time_type factor = std::max(
+ step_scale/m_alpha[m_current_k_opt-1][m_current_k_opt],
+ m_max_dt_factor );
+ if( m_a[m_current_k_opt+1]*factor <= work_min )
+ {
+ m_dt_last = dt/factor;
+ m_current_k_opt++;
+ }
+ }
+ dt = m_dt_last;
+ m_t_last = t;
+ m_decreased_step_during_last_call = false;
+ //std::clog << "Internal: " << dt << '\t' << m_current_k_opt << std::endl;
+ return step_size_increased;
+ }
+ }
+
+ template< class System >
+ controlled_step_result try_step(
+ System &system,
+ container_type &x,
+ time_type &t,
+ time_type &dt )
+ {
+ m_resizer.adjust_size(x, m_dxdt);
+ system(x, m_dxdt, t);
+ return try_step(system, x, m_dxdt, t, dt );
+ }
+
+
+ private: // private functions
+
+ void initialize_step_adjust_tableau( time_type eps )
+ {
+ m_a[0] = m_interval_sequence[0]+1;
+ for( unsigned short k=0; k<m_k_max; k++ )
+ m_a[k+1] = m_a[k] + m_interval_sequence[k+1];
+ for( unsigned short i=1; i<m_k_max; i++ )
+ {
+ for( unsigned short k=0; k<i; k++ )
+ {
+ m_alpha[k][i] = std::pow(
+ m_safety1*eps,
+ (m_a[k+1]-m_a[i+1])/
+ ((m_a[i+1]-m_a[0]+1.0)*(2*k+3))
+ );
+ }
+ }
+ m_current_k_opt = m_k_max-1;
+ for( unsigned short k=1; k<m_k_max-1; k++ )
+ {
+ if( m_a[k+1] > m_a[k]*m_alpha[k-1][k] )
+ {
+ m_current_k_opt = k;
+ break;
+ }
+ }
+ m_current_k_max = m_current_k_opt;
+ }
+
+ void extrapolate(
+ unsigned short k_est,
+ time_type t_est,
+ container_type &x_est,
+ container_type &x,
+ container_type &x_err )
+ {
+ //m_resizer.adjust_size(x, m_c);
+ //std::vector< container_type > m_d_iter = m_d.begin();
+ //while( m_d_iter != m_d.end() )
+ // m_resizer.adjust_size(x, (*m_d_iter++));
+
+ m_times[k_est] = t_est;
+ x_err = x = x_est;
+
+ const iterator x_end = x.end();
+
+ if( k_est == 0 )
+ {
+ m_d[0] = x_est;
+ } else
+ {
+ m_c = x_est;
+ for( unsigned short k=0; k<k_est; k++ )
+ {
+ value_type delta = static_cast<value_type>(1.0) /
+ (m_times[k_est-k-1]-static_cast<value_type>(t_est));
+ value_type val1 = static_cast<value_type>(t_est)*delta;
+ value_type val2 = m_times[k_est-k-1]*delta;
+
+ //std::clog << " values: " << delta << '\t' << val1 << '\t' << val2 << std::endl;
+
+ iterator x_iter = x.begin();
+ iterator x_err_iter = x_err.begin();
+ iterator d_k_iter = m_d[k].begin();
+ iterator c_iter = m_c.begin();
+ while( x_iter != x_end )
+ {
+ //std::clog << " extrapolate: " << '\t' << *x_iter << '\t' << *x_err_iter << '\t' << *d_k_iter << std::endl;
+ value_type q = *d_k_iter;
+ *d_k_iter++ = *x_err_iter;
+ delta = *c_iter - q;
+ *x_err_iter = val1 * delta;
+ *c_iter++ = val2 * delta;
+ *x_iter++ += *x_err_iter++;
+ }
+ //std::clog << " extrapolate: " << '\t' << x[1] << '\t' << x_err[1] << '\t' << m_d[k][1] << std::endl;
+ m_d[k_est] = x_err;
+ }
+ }
+ }
+
+ };
+}
+}
+}
+
+#endif

Added: sandbox/odeint/boost/numeric/odeint/error_checker_standard.hpp
==============================================================================
--- (empty file)
+++ sandbox/odeint/boost/numeric/odeint/error_checker_standard.hpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,79 @@
+
+
+#ifndef BOOST_NUMERIC_ODEINT_ERROR_CHECKER_STANDARD_HPP
+#define BOOST_NUMERIC_ODEINT_ERROR_CHECKER_STANDARD_HPP
+
+#include <cmath>
+
+namespace boost {
+namespace numeric {
+namespace odeint {
+
+ template< class Container, class Time >
+ class error_checker_standard {
+
+
+ public:
+ typedef Container container_type;
+ typedef Time time_type;
+ typedef typename container_type::value_type value_type;
+ typedef typename container_type::iterator iterator;
+
+ private:
+ time_type m_eps_abs;
+ time_type m_eps_rel;
+ time_type m_a_x;
+ time_type m_a_dxdt;
+
+ public:
+ // constructor
+ error_checker_standard(
+ time_type abs_err, time_type rel_err,
+ time_type factor_x, time_type factor_dxdt )
+ : m_eps_abs( abs_err ), m_eps_rel( rel_err ),
+ m_a_x( factor_x ), m_a_dxdt( factor_dxdt )
+ { }
+
+ void fill_scale(
+ container_type &x,
+ container_type &dxdt,
+ time_type dt,
+ container_type &scale )
+ {
+ iterator x_iter = x.begin();
+ const iterator x_end = x.end();
+ iterator dxdt_iter = dxdt.begin();
+ iterator scale_iter = scale.begin();
+ while( x_iter != x_end )
+ {
+ *scale_iter++ = m_eps_abs +
+ m_eps_rel * (m_a_x * std::abs(*x_iter++) +
+ m_a_dxdt * dt * std::abs(*dxdt_iter++));
+ }
+ }
+
+ time_type get_max_error_ratio( container_type &x_err, container_type &scale)
+ {
+ iterator x_err_iter = x_err.begin();
+ const iterator x_err_end = x_err.end();
+ iterator scale_iter = scale.begin();
+ time_type max_rel_error = static_cast<time_type>(0.0);
+ while( x_err_iter != x_err_end )
+ {
+ max_rel_error = std::max(
+ static_cast<time_type>(std::abs(*x_err_iter++)/(*scale_iter++)) ,
+ max_rel_error);
+ }
+ return max_rel_error;
+ }
+
+ const time_type get_epsilon() { return std::max(m_eps_rel, m_eps_abs); }
+
+
+ };
+
+}
+}
+}
+
+#endif

Modified: sandbox/odeint/boost/numeric/odeint/stepper_midpoint.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint/stepper_midpoint.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint/stepper_midpoint.hpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -23,7 +23,7 @@
 #include <boost/numeric/odeint/concepts/state_concept.hpp>
 #include <boost/numeric/odeint/resizer.hpp>
 
-
+#include <iostream>
 
 namespace boost {
 namespace numeric {
@@ -105,12 +105,14 @@
             using namespace detail::it_algebra;
 
             // m_x0 = x + h*dxdt
- scale_sum( m_x0.begin(), m_x0.end(),
+ scale_sum( m_x1.begin(), m_x1.end(),
                        t_1, x.begin(),
                        h, dxdt.begin() );
- system( m_x0, m_dxdt, th );
+ system( m_x1, m_dxdt, th );
 
- m_x1 = x;
+ m_x0 = x;
+
+ //std::clog<< "mp: " << 0 << '\t' << m_x1[0] << '\t' << m_x1[1] << '\t' << m_dxdt[0] << '\t' << m_dxdt[1] << std::endl;
 
             unsigned short i = 1;
             while( i != m_stepcount )
@@ -123,9 +125,11 @@
                 system( m_x1, m_dxdt, th);
                 i++;
             }
+
+ //std::clog<< "mp: " << i << '\t' << m_x1[0] << '\t' << m_x1[1] << '\t' << m_dxdt[0] << '\t' << m_dxdt[1] << std::endl;
             
             // last step
- // x = 0.5*( m_x0 + m_x1 + h*m_dxdt
+ // x = 0.5*( m_x0 + m_x1 + h*m_dxdt )
             scale_sum( x_out.begin(), x_out.end(),
                        t_05, m_x0.begin(),
                        t_05, m_x1.begin(),

Modified: sandbox/odeint/boost/numeric/odeint/stepper_rk78_fehlberg.hpp
==============================================================================
--- sandbox/odeint/boost/numeric/odeint/stepper_rk78_fehlberg.hpp (original)
+++ sandbox/odeint/boost/numeric/odeint/stepper_rk78_fehlberg.hpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -58,8 +58,7 @@
         // public interface
     public:
 
- order_type order() const { return 8; }
-
+ order_type order() const { return 7; }
 
         template< class DynamicalSystem >
         void do_step( DynamicalSystem &system ,

Modified: sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp
==============================================================================
--- sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp (original)
+++ sandbox/odeint/libs/numeric/odeint/examples/lorenz_controlled.cpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -18,11 +18,13 @@
 */
 
 #include <iostream>
+#include <fstream>
 #include <vector>
 #include <list>
 #include <tr1/array>
 
 #include <boost/numeric/odeint.hpp>
+#include <boost/numeric/odeint/controlled_stepper_bs.hpp>
 
 #define tab "\t"
 
@@ -34,43 +36,77 @@
 const double R = 28.0;
 const double b = 8.0 / 3.0;
 
-const size_t olen = 10000;
-
-const double eps_abs = 1E-2;
-const double eps_rel = 1E-3;;
-
 typedef array<double, 3> state_type;
 
+size_t function_calls = 0;
+
 void lorenz( state_type &x , state_type &dxdt , double t )
 {
     dxdt[0] = sigma * ( x[1] - x[0] );
     dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
     dxdt[2] = x[0]*x[1] - b * x[2];
+ function_calls++;
 }
 
-void print_state( double t, state_type &x, ... )
+
+class output_observer
 {
- cout << t << tab << x[0] << tab << x[1] << tab << x[2] << endl;
-}
+
+ ofstream m_file;
+
+public:
+ output_observer( const char* file_name )
+ : m_file( file_name )
+ {
+ m_file.precision(10);
+ //m_file.setf(ios::fixed,ios::floatfield);
+ }
+
+ ~output_observer()
+ {
+ m_file.close();
+ }
+
+ void operator()( double t, state_type &x, ... )
+ {
+ m_file << t << tab << x[0] << tab << x[1] << tab << x[2] << endl;
+ }
+};
 
 int main( int argc , char **argv )
 {
+ const double end_time = 25.0;
+
+ const double eps_abs = 1E-10;
+ const double eps_rel = 1E-10;;
+
     state_type x;
     x[0] = 1.0;
     x[1] = 0.0;
     x[2] = 20.0;
 
- stepper_half_step< stepper_euler< state_type > > euler;
- controlled_stepper_standard< stepper_half_step< stepper_euler< state_type > > >
- controlled_stepper( euler, eps_abs , eps_rel, 1.0, 1.0);
-
- cout.precision(5);
- cout.setf(ios::fixed,ios::floatfield);
+ stepper_rk5_ck< state_type > rk5;
+ controlled_stepper_standard< stepper_rk5_ck< state_type > > controlled_rk5( rk5, eps_abs , eps_rel, 1.0, 1.0 );
+ output_observer rk5_obs("lorenz_rk5.dat");
+ size_t steps = integrate_adaptive( controlled_rk5, lorenz, x, 0.0, end_time, 1E-2, rk5_obs );
+
+ clog << "RK5: " << steps << " steps. (" << function_calls << " function calls)" << endl;
+
+ x[0] = 1.0;
+ x[1] = 0.0;
+ x[2] = 20.0;
+
+ function_calls = 0;
+
+ controlled_stepper_bs< state_type > controlled_bs(eps_abs, eps_rel, 1.0, 1.0);
     
- size_t steps = integrate_adaptive( controlled_stepper, lorenz, x, 0.0, 10.0, 1E-2, print_state );
+ output_observer bs_obs("lorenz_bs.dat");
+ steps = integrate_adaptive( controlled_bs, lorenz, x, 0.0, end_time, 1E-2, bs_obs );
 
- clog << "Number of steps: " << steps << endl;
+ clog << "BS: " << steps << " steps. (" << function_calls << " function calls)" << endl;
 
+
+
     return 0;
 }
 

Added: sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_bs.cpp
==============================================================================
--- (empty file)
+++ sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_bs.cpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -0,0 +1,51 @@
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <cmath>
+
+#include <boost/numeric/odeint.hpp>
+
+#define tab "\t"
+
+using namespace std;
+using namespace boost::numeric::odeint;
+
+
+typedef std::tr1::array< double , 2 > state_type;
+
+
+const double gam = .15;
+
+void harmonic_oscillator(const state_type &x, state_type &dxdt, const double t)
+{
+ dxdt[0] = x[1];
+ dxdt[1] = -x[0] - gam*x[1];
+}
+
+
+int main( int argc , char **argv )
+{
+ state_type x1 = {{ 1.0, 0.0 }};
+
+ const size_t step_count = 100;
+ controlled_stepper_bs< state_type > stepper_bs(0.0, 1E-11, 1.0, 1.0);
+ double t = 0.0;
+ double dt = 0.01;
+ cout << " Everything initialized - starting time evolution " << endl;
+ cout.precision(16);
+ clog.precision(16);
+ for( size_t step=0; step < step_count; step++ )
+ {
+ stepper_bs.try_step(harmonic_oscillator, x1, t, dt);
+ //clog << " ####################################################### " << endl;
+ cout << t << tab << dt << tab << x1[0] << tab << x1[1] << endl;
+ //clog << " ####################################################### " << endl;
+ }
+}
+
+/*
+ Compile with
+ g++ -Wall -O3 -I$BOOST_ROOT -I../../../../../ stepper_bs.cpp
+*/
+

Modified: sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_midpoint.cpp
==============================================================================
--- sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_midpoint.cpp (original)
+++ sandbox/odeint/libs/numeric/odeint/stuff/test/stepper_midpoint.cpp 2009-11-29 15:36:32 EST (Sun, 29 Nov 2009)
@@ -41,11 +41,14 @@
     double t = 0.0;
     for( size_t oi=0 ; oi<olen ; ++oi,t+=dt )
     {
- stepper_euler.next_step( harmonic_oscillator , x1 , t , dt );
- stepper_mp.next_step( harmonic_oscillator , x2 , t , dt , 2 );
- stepper_mp.next_step( harmonic_oscillator , x3 , t , dt , 4 );
- stepper_mp.next_step( harmonic_oscillator , x4 , t , dt , 8 );
- stepper_rk4.next_step( harmonic_oscillator , x5 , t , dt );
+ stepper_euler.do_step( harmonic_oscillator , x1 , t , dt );
+ stepper_mp.set_stepcount(2);
+ stepper_mp.do_step( harmonic_oscillator , x2 , t , dt );
+ stepper_mp.set_stepcount(4);
+ stepper_mp.do_step( harmonic_oscillator , x3 , t , dt );
+ stepper_mp.set_stepcount(8);
+ stepper_mp.do_step( harmonic_oscillator , x4 , t , dt );
+ stepper_rk4.do_step( harmonic_oscillator , x5 , t , dt );
         cout<< t << tab << x1[0]*x1[0] + x1[1]*x1[1];
         cout<< tab << x2[0]*x2[0] + x2[1]*x2[1];
         cout<< tab << x3[0]*x3[0] + x3[1]*x3[1];


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk