Using arbitrary precision floating point types

| Home | Libraries | People | FAQ | More

### Using arbitrary precision floating point types

Sometimes one needs results with higher precision than provided by the standard floating point types. As odeint allows to configure the fundamental numerical type, it is well suited to be run with arbitrary precision types. Therefore, one only needs a library that provides a type representing values with arbitrary precision and the fundamental operations for those values. Boost.Multiprecision is a boost library that does exactly this. Making use of Boost.Multiprecision to solve odes with odeint is very simple, as the following example shows.

Here we use `cpp_dec_float_50` as the fundamental value type, which ensures exact computations up to 50 decimal digits.

    #include <boost/numeric/odeint.hpp>
    #include <boost/multiprecision/cpp_dec_float.hpp>

    using namespace std;
    using namespace boost::numeric::odeint;

    typedef boost::multiprecision::cpp_dec_float_50 value_type;

    typedef boost::array< value_type , 3 > state_type;

As exemplary ODE again the lorenz system is chosen, but here we have to make sure all constants are initialized as high precision values.

    struct lorenz
    {
        void operator()( const state_type &x , state_type &dxdt , value_type t ) const
        {
            const value_type sigma( 10 );
            const value_type R( 28 );
            const value_type b( value_type( 8 ) / value_type( 3 ) );

            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];
        }
    };

The actual integration then is straight forward:

    state_type x = {{ value_type( 10.0 ) , value_type( 10.0 ) , value_type( 10.0 ) }};

    cout.precision( 50 );
    integrate_const( runge_kutta4< state_type , value_type >() ,
            lorenz() , x , value_type( 0.0 ) , value_type( 10.0 ) , value_type( value_type( 1.0 ) / value_type( 10.0 ) ) ,
            streaming_observer( cout ) );

The full example can be found at lorenz_mp.cpp. Another example that compares the accuracy of the high precision type with standard double can be found at cmp_precision.cpp.

Furthermore, odeint can also be run with other multiprecision libraries, e.g. gmp. An example for this is given in lorenz_gmpxx.cpp.