mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-27 11:00:32 -04:00 
			
		
		
		
	
		
			
	
	
		
			362 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			362 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | /*
 | ||
|  |  * 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; | ||
|  | } |