Squashed 'third_party/boostorg/odeint/' content from commit 6ff2719
Change-Id: If4892e29c1a5e6cf3a7aa51486a2725c251b0c7d
git-subtree-dir: third_party/boostorg/odeint
git-subtree-split: 6ff2719b6907b86596c3d43e88c1bcfdf29df560
diff --git a/examples/adaptive_iterator.cpp b/examples/adaptive_iterator.cpp
new file mode 100644
index 0000000..343699d
--- /dev/null
+++ b/examples/adaptive_iterator.cpp
@@ -0,0 +1,361 @@
+/*
+ * adaptive_iterator.cpp
+ *
+ * Copyright 2012-2013 Karsten Ahnert
+ * Copyright 2012 Mario Mulansky
+ *
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or
+ * copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+
+
+#include <iostream>
+#include <iterator>
+#include <utility>
+#include <algorithm>
+#include <cassert>
+
+#include <boost/array.hpp>
+
+#include <boost/range/algorithm.hpp>
+#include <boost/range/adaptor/filtered.hpp>
+#include <boost/range/numeric.hpp>
+
+#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_dopri5.hpp>
+#include <boost/numeric/odeint/stepper/runge_kutta_cash_karp54.hpp>
+#include <boost/numeric/odeint/stepper/generation.hpp>
+
+#include <boost/numeric/odeint/iterator/adaptive_iterator.hpp>
+#include <boost/numeric/odeint/iterator/adaptive_time_iterator.hpp>
+
+#define tab "\t"
+
+using namespace std;
+using namespace boost::numeric::odeint;
+
+const double sigma = 10.0;
+const double R = 28.0;
+const double b = 8.0 / 3.0;
+
+struct lorenz
+{
+ template< class State , class Deriv >
+ void operator()( const State &x , Deriv &dxdt , double t ) const
+ {
+ dxdt[0] = sigma * ( x[1] - x[0] );
+ dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
+ dxdt[2] = -b * x[2] + x[0] * x[1];
+ }
+};
+
+#include <typeinfo>
+
+int main( int argc , char **argv )
+{
+ typedef boost::array< double , 3 > state_type;
+
+ /*
+ * Controlled steppers with time iterator
+ */
+
+ // std::for_each
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ std::for_each( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_time_iterator_end( stepper , lorenz() , x ) ,
+ []( const std::pair< const state_type&, double > &x ) {
+ std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
+ }
+
+ // std::copy_if
+ {
+ std::vector< pair< state_type , double > > res;
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ std::copy_if( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_time_iterator_end( stepper , lorenz() , x ) ,
+ std::back_inserter( res ) ,
+ []( const pair< const state_type& , double > &x ) {
+ return ( x.first[0] > 0.0 ) ? true : false; } );
+ for( size_t i=0 ; i<res.size() ; ++i )
+ cout << res[i].first[0] << tab << res[i].first[1] << tab << res[i].first[2] << "\n";
+ }
+
+ // std::accumulate
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ double res = std::accumulate( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_time_iterator_end( stepper , lorenz() , x ) ,
+ 0.0 ,
+ []( double sum , const pair< const state_type& , double > &x ) {
+ return sum + x.first[0]; } );
+ cout << res << endl;
+ }
+
+
+ // std::transform
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ vector< double > weights;
+ std::transform( make_adaptive_time_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_time_iterator_end( stepper , lorenz() , x ) ,
+ back_inserter( weights ) ,
+ []( const pair< const state_type& , double > &x ) {
+ return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } );
+ for( size_t i=0 ; i<weights.size() ; ++i )
+ cout << weights[i] << "\n";
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /*
+ * Boost.Range versions of controlled stepper with time iterator
+ */
+
+
+ // boost::range::for_each
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ boost::range::for_each( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ []( const std::pair< const state_type& , double > &x ) {
+ std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
+ }
+
+
+ // boost::range::copy with filtered adaptor (simulating std::copy_if)
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ std::vector< std::pair< state_type , double > > res;
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ boost::range::copy( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) |
+ boost::adaptors::filtered( [] ( const pair< const state_type& , double > &x ) { return ( x.first[0] > 0.0 ); } ) ,
+ std::back_inserter( res ) );
+ for( size_t i=0 ; i<res.size() ; ++i )
+ cout << res[i].first[0] << tab << res[i].first[1] << tab << res[i].first[2] << "\n";
+ }
+
+ // boost::range::accumulate
+ {
+ //[adaptive_time_iterator_accumulate_range
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ double res = boost::accumulate( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 ,
+ []( double sum , const pair< const state_type& , double > &x ) {
+ return sum + x.first[0]; } );
+ cout << res << endl;
+ //]
+ }
+
+
+ // boost::range::transform
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ vector< double > weights;
+ boost::transform( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) ,
+ []( const pair< const state_type& , double > &x ) {
+ return sqrt( x.first[0] * x.first[0] + x.first[1] * x.first[1] + x.first[2] * x.first[2] ); } );
+ for( size_t i=0 ; i<weights.size() ; ++i )
+ cout << weights[i] << "\n";
+ }
+
+
+ // boost::range::find with time iterator
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ auto iter = boost::find_if( make_adaptive_time_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ []( const std::pair< const state_type & , double > &x ) {
+ return ( x.first[0] < 0.0 ); } );
+ cout << iter->second << "\t" << iter->first[0] << "\t" << iter->first[1] << "\t" << iter->first[2] << "\n";
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ // /*
+ // * Boost.Range versions for dense output steppers
+ // */
+
+ // // boost::range::for_each
+ // {
+ // runge_kutta_dopri5< state_type > stepper;
+ // state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ // boost::range::for_each( make_adaptive_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ // []( const state_type &x ) {
+ // std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } );
+ // }
+
+
+ // // boost::range::for_each with time iterator
+ // {
+ // runge_kutta_dopri5< state_type > stepper;
+ // state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ // boost::range::for_each( make_adaptive_time_range( make_dense_output( 1.0e-6 , 1.0e-6 , stepper ) , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ // []( const std::pair< state_type& , double > &x ) {
+ // std::cout << x.second << tab << x.first[0] << tab << x.first[1] << tab << x.first[2] << "\n"; } );
+
+ // }
+
+
+
+
+
+ /*
+ * Pure iterators for controlled stepper without time iterator
+ */
+
+ // std::for_each
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ std::for_each( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_iterator_end( stepper , lorenz() , x ) ,
+ []( const state_type& x ) {
+ std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } );
+ }
+
+ // std::copy_if
+ {
+ std::vector< state_type > res;
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ std::copy_if( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_iterator_end( stepper , lorenz() , x ) ,
+ std::back_inserter( res ) ,
+ []( const state_type& x ) {
+ return ( x[0] > 0.0 ) ? true : false; } );
+ for( size_t i=0 ; i<res.size() ; ++i )
+ cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n";
+ }
+
+ // std::accumulate
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ double res = std::accumulate( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_iterator_end( stepper , lorenz() , x ) ,
+ 0.0 ,
+ []( double sum , const state_type& x ) {
+ return sum + x[0]; } );
+ cout << res << endl;
+ }
+
+
+ // std::transform
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ vector< double > weights;
+ std::transform( make_adaptive_iterator_begin( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ make_adaptive_iterator_end( stepper , lorenz() , x ) ,
+ back_inserter( weights ) ,
+ []( const state_type& x ) {
+ return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } );
+ for( size_t i=0 ; i<weights.size() ; ++i )
+ cout << weights[i] << "\n";
+ }
+
+
+
+
+
+
+
+
+
+
+ /*
+ * Boost.Range versions of controlled stepper WITHOUT time iterator
+ */
+
+
+ // boost::range::for_each
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ boost::range::for_each( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ []( const state_type &x ) {
+ std::cout << x[0] << tab << x[1] << tab << x[2] << "\n"; } );
+ }
+
+
+ // boost::range::copy with filtered adaptor (simulating std::copy_if)
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ std::vector< state_type > res;
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ boost::range::copy( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) |
+ boost::adaptors::filtered( [] ( const state_type& x ) { return ( x[0] > 0.0 ); } ) ,
+ std::back_inserter( res ) );
+ for( size_t i=0 ; i<res.size() ; ++i )
+ cout << res[i][0] << tab << res[i][1] << tab << res[i][2] << "\n";
+ }
+
+ // boost::range::accumulate
+ {
+ //[adaptive_iterator_accumulate_range
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ double res = boost::accumulate( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , 0.0 ,
+ []( double sum , const state_type& x ) {
+ return sum + x[0]; } );
+ cout << res << endl;
+ //]
+ }
+
+
+ // boost::range::transform
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ vector< double > weights;
+ boost::transform( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) , back_inserter( weights ) ,
+ []( const state_type& x ) {
+ return sqrt( x[0] * x[0] + x[1] * x[1] + x[2] * x[2] ); } );
+ for( size_t i=0 ; i<weights.size() ; ++i )
+ cout << weights[i] << "\n";
+ }
+
+
+ // boost::range::find
+ {
+ auto stepper = make_controlled( 1.0e-6 , 1.0e-6 , runge_kutta_cash_karp54< state_type >() );
+ state_type x = {{ 10.0 , 10.0 , 10.0 }};
+ auto iter = boost::find_if( make_adaptive_range( stepper , lorenz() , x , 0.0 , 1.0 , 0.01 ) ,
+ []( const state_type &x ) {
+ return ( x[0] < 0.0 ); } );
+ cout << (*iter)[0] << "\t" << (*iter)[1] << "\t" << (*iter)[2] << "\n";
+ }
+
+
+
+
+
+ return 0;
+}