|  | Home | Libraries | People | FAQ | More | 
There are a number of Policies that can be used to trade accuracy for performance:
float
          arguments are evaluated at double
          precision internally to ensure full precision in the result. Similarly
          double precision functions
          are evaluated at long double
          precision internally by default. Changing these defaults can have a significant
          speed advantage at the expense of accuracy, note also that evaluating using
          float internally may result
          in numerical instability for some of the more complex algorithms, we suggest
          you use this option with care.
        double
          precision doesn't mean you necessarily want to target full 16-digit accuracy,
          if you wish you can change the default (full machine precision) to whatever
          is "good enough" for your particular use case.
        
      For example, suppose you want to evaluate double
      precision functions at double
      precision internally, you can change the global default by passing -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false on the
      command line, or at the point of call via something like this:
    
double val = boost::math::erf(my_argument, boost::math::policies::make_policy(boost::math::policies::promote_double<false>()));
However, an easier option might be:
#include <boost/math/special_functions.hpp> // Or any individual special function header namespace math{ namespace precise{ // // Define a Policy for accurate evaluation - this is the same as the default, unless // someone has changed the global defaults. // typedef boost::math::policies::policy<> accurate_policy; // // Invoke BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS to declare // functions that use the above policy. Note no trailing // ";" required on the macro call: // BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(accurate_policy) } namespace fast{ // // Define a Policy for fast evaluation: // using namespace boost::math::polcies; typedef policy<promote_double<false> > fast_policy; // // Invoke BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS: // BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(fast_policy) } }
And now one can call:
math::accurate::tgamma(x);
For the "accurate" version of tgamma, and:
math::fast::tgamma(x);
For the faster version.
Had we wished to change the target precision (to 9 decimal places) as well as the evaluation type used, we might have done:
namespace math{ namespace fast{ // // Define a Policy for fast evaluation: // using namespace boost::math::polcies; typedef policy<promote_double<false>, digits10<9> > fast_policy; // // Invoke BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS: // BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(fast_policy) } }
One can do a similar thing with the distribution classes:
#include <boost/math/distributions.hpp> // or any individual distribution header namespace math{ namespace fast{ // // Define a policy for fastest possible evaluation: // using namespace boost::math::polcies; typedef policy<promote_float<false> > fast_float_policy; // // Invoke BOOST_MATH_DECLARE_DISTRIBUTIONS // BOOST_MATH_DECLARE_DISTRIBUTIONS(float, fast_float_policy) }} // namespaces // // And use: // float p_val = cdf(math::fast::normal(1.0f, 3.0f), 0.25f);
Here's how these options change the relative performance of the distributions on Linux:
[table_Distribution_performance_comparison_for_different_performance_options_with_GNU_C_version_5_1_0_on_linux]