mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-29 20:10:28 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			170 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			5.0 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 <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 the 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_integrate_const_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;
 | |
|         value_type t0( 0.0 );
 | |
|         value_type tend( 1.0 );
 | |
|         value_type dt(0.1);
 | |
| 
 | |
|         integrate_const( stepper , constant_system , x , t0 , tend , dt );
 | |
| 
 | |
|         x = 0.0;
 | |
|         t0 = 0.0;
 | |
|         dt = 0.1;
 | |
|         size_t steps = 10;
 | |
|         
 | |
|         integrate_n_steps( stepper , constant_system , x , t0 , dt , steps );
 | |
| 
 | |
|         BOOST_CHECK_MESSAGE( abs( x - 10*dt ) < eps , x );
 | |
|     }
 | |
| };
 | |
| 
 | |
| 
 | |
| BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_const_test , Stepper , stepper_types )
 | |
| {
 | |
|     perform_integrate_const_test< Stepper > tester;
 | |
|     tester();
 | |
| }
 | |
| 
 | |
| 
 | |
| 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_integrate_adaptive_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 t0( 0.0 );
 | |
|         value_type tend( 1.0 );
 | |
|         value_type dt(0.1);
 | |
| 
 | |
|         integrate_adaptive( stepper , constant_system , x , t0 , tend , dt );
 | |
| 
 | |
|         BOOST_CHECK_MESSAGE( abs( x - tend ) < eps , x - 0.1 );
 | |
|     }
 | |
| };
 | |
| 
 | |
| BOOST_AUTO_TEST_CASE_TEMPLATE( integrate_adaptive__test , Stepper , controlled_stepper_types )
 | |
| {
 | |
|     perform_integrate_adaptive_test< Stepper > tester;
 | |
|     tester();
 | |
| }
 |