mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			171 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  [auto_generated]
 | |
|  libs/numeric/odeint/examples/heun.cpp
 | |
| 
 | |
|  [begin_description]
 | |
|  Examplary implementation of the method of Heun.
 | |
|  [end_description]
 | |
| 
 | |
|  Copyright 2012 Karsten Ahnert
 | |
|  Copyright 2012 Mario Mulansky
 | |
| 
 | |
|  Distributed under the Boost Software License, Version 1.0.
 | |
|  (See accompanying file LICENSE_1_0.txt or
 | |
|  copy at http://www.boost.org/LICENSE_1_0.txt)
 | |
|  */
 | |
| 
 | |
| #include <iostream>
 | |
| 
 | |
| 
 | |
| #include <boost/fusion/container/vector.hpp>
 | |
| #include <boost/fusion/container/generation/make_vector.hpp>
 | |
| 
 | |
| #include <boost/array.hpp>
 | |
| 
 | |
| #include <boost/numeric/odeint.hpp>
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| namespace fusion = boost::fusion;
 | |
| 
 | |
| //[ heun_define_coefficients
 | |
| template< class Value = double >
 | |
| struct heun_a1 : boost::array< Value , 1 > {
 | |
|     heun_a1( void )
 | |
|     {
 | |
|         (*this)[0] = static_cast< Value >( 1 ) / static_cast< Value >( 3 );
 | |
|     }
 | |
| };
 | |
| 
 | |
| template< class Value = double >
 | |
| struct heun_a2 : boost::array< Value , 2 >
 | |
| {
 | |
|     heun_a2( void )
 | |
|     {
 | |
|         (*this)[0] = static_cast< Value >( 0 );
 | |
|         (*this)[1] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| template< class Value = double >
 | |
| struct heun_b : boost::array< Value , 3 >
 | |
| {
 | |
|     heun_b( void )
 | |
|     {
 | |
|         (*this)[0] = static_cast<Value>( 1 ) / static_cast<Value>( 4 );
 | |
|         (*this)[1] = static_cast<Value>( 0 );
 | |
|         (*this)[2] = static_cast<Value>( 3 ) / static_cast<Value>( 4 );
 | |
|     }
 | |
| };
 | |
| 
 | |
| template< class Value = double >
 | |
| struct heun_c : boost::array< Value , 3 >
 | |
| {
 | |
|     heun_c( void )
 | |
|     {
 | |
|         (*this)[0] = static_cast< Value >( 0 );
 | |
|         (*this)[1] = static_cast< Value >( 1 ) / static_cast< Value >( 3 );
 | |
|         (*this)[2] = static_cast< Value >( 2 ) / static_cast< Value >( 3 );
 | |
|     }
 | |
| };
 | |
| //]
 | |
| 
 | |
| 
 | |
| //[ heun_stepper_definition
 | |
| template<
 | |
|     class State ,
 | |
|     class Value = double ,
 | |
|     class Deriv = State ,
 | |
|     class Time = Value ,
 | |
|     class Algebra = boost::numeric::odeint::range_algebra ,
 | |
|     class Operations = boost::numeric::odeint::default_operations ,
 | |
|     class Resizer = boost::numeric::odeint::initially_resizer
 | |
| >
 | |
| class heun : public
 | |
| boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time ,
 | |
|                                              Algebra , Operations , Resizer >
 | |
| {
 | |
| 
 | |
| public:
 | |
| 
 | |
|     typedef boost::numeric::odeint::explicit_generic_rk< 3 , 3 , State , Value , Deriv , Time ,
 | |
|                                                          Algebra , Operations , Resizer > stepper_base_type;
 | |
| 
 | |
|     typedef typename stepper_base_type::state_type state_type;
 | |
|     typedef typename stepper_base_type::wrapped_state_type wrapped_state_type;
 | |
|     typedef typename stepper_base_type::value_type value_type;
 | |
|     typedef typename stepper_base_type::deriv_type deriv_type;
 | |
|     typedef typename stepper_base_type::wrapped_deriv_type wrapped_deriv_type;
 | |
|     typedef typename stepper_base_type::time_type time_type;
 | |
|     typedef typename stepper_base_type::algebra_type algebra_type;
 | |
|     typedef typename stepper_base_type::operations_type operations_type;
 | |
|     typedef typename stepper_base_type::resizer_type resizer_type;
 | |
|     typedef typename stepper_base_type::stepper_type stepper_type;
 | |
| 
 | |
|     heun( const algebra_type &algebra = algebra_type() )
 | |
|     : stepper_base_type(
 | |
|             fusion::make_vector(
 | |
|                 heun_a1<Value>() ,
 | |
|                 heun_a2<Value>() ) ,
 | |
|             heun_b<Value>() , heun_c<Value>() , algebra )
 | |
|     { }
 | |
| };
 | |
| //]
 | |
| 
 | |
| 
 | |
| 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
 | |
|     {
 | |
|         typename boost::range_iterator< const State >::type x = boost::begin( x_ );
 | |
|         typename boost::range_iterator< Deriv >::type dxdt = boost::begin( dxdt_ );
 | |
| 
 | |
|         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];
 | |
|     }
 | |
| };
 | |
| 
 | |
| struct streaming_observer
 | |
| {
 | |
|     std::ostream &m_out;
 | |
|     streaming_observer( std::ostream &out ) : m_out( out ) { }
 | |
|     template< typename State , typename Value >
 | |
|     void operator()( const State &x , Value t ) const
 | |
|     {
 | |
|         m_out << t;
 | |
|         for( size_t i=0 ; i<x.size() ; ++i ) m_out << "\t" << x[i];
 | |
|         m_out << "\n";
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| int main( int argc , char **argv )
 | |
| {
 | |
|     using namespace std;
 | |
|     using namespace boost::numeric::odeint;
 | |
| 
 | |
| 
 | |
|     //[ heun_example
 | |
|     typedef boost::array< double , 3 > state_type;
 | |
|     heun< state_type > h;
 | |
|     state_type x = {{ 10.0 , 10.0 , 10.0 }};
 | |
| 
 | |
|     integrate_const( h , lorenz() , x , 0.0 , 100.0 , 0.01 ,
 | |
|                      streaming_observer( std::cout ) );
 | |
| 
 | |
|     //]
 | |
| 
 | |
|     return 0;
 | |
| }
 |