Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Trading Accuracy for Performance

There are a number of Policies that can be used to trade accuracy for performance:

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]


PrevUpHomeNext