mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-04 05:50:31 -05:00 
			
		
		
		
	
		
			
	
	
		
			166 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			166 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/* Boost check_gmp.cpp test file
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 Copyright 2010-2012 Mario Mulansky
							 | 
						||
| 
								 | 
							
								 Copyright 2011-2012 Karsten Ahnert
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 This file tests the odeint library with the gmp arbitrary precision types
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 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_gmp
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <gmpxx.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/test/unit_test.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/array.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/mpl/vector.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/numeric/odeint.hpp>
							 | 
						||
| 
								 | 
							
								//#include <boost/numeric/odeint/algebra/vector_space_algebra.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using namespace boost::unit_test;
							 | 
						||
| 
								 | 
							
								using namespace boost::numeric::odeint;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace mpl = boost::mpl;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const int precision = 1024;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef mpf_class value_type;
							 | 
						||
| 
								 | 
							
								typedef mpf_class state_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//provide min, max and pow functions for mpf types - required for controlled steppers
							 | 
						||
| 
								 | 
							
								value_type min( const value_type a , const value_type b )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if( a<b ) return a;
							 | 
						||
| 
								 | 
							
								    else return b;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								value_type max( const value_type a , const value_type b )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if( a>b ) return a;
							 | 
						||
| 
								 | 
							
								    else return b;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								value_type pow( const value_type a , const value_type b )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    // do calculation in double precision
							 | 
						||
| 
								 | 
							
								    return value_type( std::pow( a.get_d() , b.get_d() ) );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//provide vector_space reduce:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace numeric { namespace odeint {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<>
							 | 
						||
| 
								 | 
							
								struct vector_space_reduce< state_type >
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  template< class Op >
							 | 
						||
| 
								 | 
							
								  state_type operator()( state_type x , Op op , state_type init ) const
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								      init = op( init , x );
							 | 
						||
| 
								 | 
							
								      return init;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void constant_system( const state_type &x , state_type &dxdt , value_type t )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    dxdt = value_type( 1.0 , precision );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* check runge kutta stepers */
							 | 
						||
| 
								 | 
							
								typedef mpl::vector<
							 | 
						||
| 
								 | 
							
								    euler< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    modified_midpoint< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta4< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta4_classic< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta_cash_karp54< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > ,
							 | 
						||
| 
								 | 
							
								    runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra >
							 | 
						||
| 
								 | 
							
								    > stepper_types;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template< class Stepper >
							 | 
						||
| 
								 | 
							
								struct perform_runge_kutta_test {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void operator()( void )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /* We have to specify the desired precision in advance! */
							 | 
						||
| 
								 | 
							
								        mpf_set_default_prec( precision );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        mpf_t eps_ , unity;
							 | 
						||
| 
								 | 
							
								        mpf_init( eps_ ); mpf_init( unity );
							 | 
						||
| 
								 | 
							
								        mpf_set_d( unity , 1.0 );
							 | 
						||
| 
								 | 
							
								        mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision
							 | 
						||
| 
								 | 
							
								        value_type eps( eps_ );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Stepper stepper;
							 | 
						||
| 
								 | 
							
								        state_type x;
							 | 
						||
| 
								 | 
							
								        x = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        stepper.do_step( constant_system , x , 0.0 , 0.1 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        BOOST_MESSAGE( eps );
							 | 
						||
| 
								 | 
							
								        BOOST_CHECK_MESSAGE( abs( x - value_type( 0.1 , precision ) ) < eps , x - 0.1 );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOST_AUTO_TEST_CASE_TEMPLATE( runge_kutta_stepper_test , Stepper , stepper_types )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    perform_runge_kutta_test< Stepper > tester;
							 | 
						||
| 
								 | 
							
								    tester();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* check controlled steppers */
							 | 
						||
| 
								 | 
							
								typedef mpl::vector<
							 | 
						||
| 
								 | 
							
								    controlled_runge_kutta< runge_kutta_cash_karp54_classic< state_type , value_type , state_type , value_type , vector_space_algebra > > ,
							 | 
						||
| 
								 | 
							
								    controlled_runge_kutta< runge_kutta_dopri5< state_type , value_type , state_type , value_type , vector_space_algebra > > , 
							 | 
						||
| 
								 | 
							
								    controlled_runge_kutta< runge_kutta_fehlberg78< state_type , value_type , state_type , value_type , vector_space_algebra > > ,
							 | 
						||
| 
								 | 
							
								    bulirsch_stoer< state_type , value_type , state_type , value_type , vector_space_algebra >
							 | 
						||
| 
								 | 
							
								    > controlled_stepper_types;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template< class Stepper >
							 | 
						||
| 
								 | 
							
								struct perform_controlled_test {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    void operator()( void )
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        mpf_set_default_prec( precision );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        mpf_t eps_ , unity;
							 | 
						||
| 
								 | 
							
								        mpf_init( eps_ ); mpf_init( unity );
							 | 
						||
| 
								 | 
							
								        mpf_set_d( unity , 1.0 );
							 | 
						||
| 
								 | 
							
								        mpf_div_2exp( eps_ , unity , precision-1 ); // 2^(-precision+1) : smallest number that can be represented with used precision
							 | 
						||
| 
								 | 
							
								        value_type eps( eps_ );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        Stepper stepper;
							 | 
						||
| 
								 | 
							
								        state_type x;
							 | 
						||
| 
								 | 
							
								        x = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        value_type t(0.0);
							 | 
						||
| 
								 | 
							
								        value_type dt(0.1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        stepper.try_step( constant_system , x , t , dt );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        BOOST_MESSAGE( eps );
							 | 
						||
| 
								 | 
							
								        BOOST_CHECK_MESSAGE( abs( x - value_type( 0.1 , precision ) ) < eps , x - 0.1 );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								BOOST_AUTO_TEST_CASE_TEMPLATE( controlled_stepper_test , Stepper , controlled_stepper_types )
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    perform_controlled_test< Stepper > tester;
							 | 
						||
| 
								 | 
							
								    tester();
							 | 
						||
| 
								 | 
							
								}
							 |