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::policies[
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::policies;
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::policies;
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 22.2. Distribution performance comparison for different performance options with GNU C++ version 9.2.1 20191008 on linux

Function

boost 1.73

Boost
promote_double<false>

Boost
promote_double<false>
digits10<10>

Boost
float
promote_float<false>

ArcSine (CDF)

1.75
(35ns)

1.65
(33ns)

1.65
(33ns)

1.00
(20ns)

ArcSine (PDF)

1.00
(5ns)

1.00
(5ns)

1.00
(5ns)

1.20
(6ns)

ArcSine (quantile)

1.04
(24ns)

1.00
(23ns)

1.04
(24ns)

1.00
(23ns)

Beta (CDF)

4.41
(437ns)

1.40
(139ns)

1.38
(137ns)

1.00
(99ns)

Beta (PDF)

4.29
(360ns)

1.23
(103ns)

1.24
(104ns)

1.00
(84ns)

Beta (quantile)

4.17
(2587ns)

1.60
(991ns)

1.44
(893ns)

1.00
(620ns)

Binomial (CDF)

3.97
(837ns)

1.54
(324ns)

1.26
(265ns)

1.00
(211ns)

Binomial (PDF)

2.90
(322ns)

1.09
(121ns)

1.09
(121ns)

1.00
(111ns)

Binomial (quantile)

3.88
(3917ns)

1.53
(1548ns)

1.26
(1273ns)

1.00
(1009ns)

Cauchy (CDF)

1.15
(23ns)

1.15
(23ns)

1.00
(20ns)

1.00
(20ns)

Cauchy (PDF)

1.00
(3ns)

1.00
(3ns)

1.00
(3ns)

1.33
(4ns)

Cauchy (quantile)

1.88
(45ns)

2.00
(48ns)

1.79
(43ns)

1.00
(24ns)

ChiSquared (CDF)

3.54
(1002ns)

1.79
(506ns)

1.40
(397ns)

1.00
(283ns)

ChiSquared (PDF)

4.84
(295ns)

1.41
(86ns)

1.38
(84ns)

1.00
(61ns)

ChiSquared (quantile)

3.76
(1664ns)

1.84
(815ns)

1.37
(609ns)

1.00
(443ns)

Exponential (CDF)

1.27
(19ns)

1.87
(28ns)

1.60
(24ns)

1.00
(15ns)

Exponential (PDF)

1.58
(30ns)

1.84
(35ns)

2.00
(38ns)

1.00
(19ns)

Exponential (quantile)

1.00
(23ns)

1.13
(26ns)

1.17
(27ns)

1.04
(24ns)

ExtremeValue (CDF)

1.78
(57ns)

1.81
(58ns)

1.81
(58ns)

1.00
(32ns)

ExtremeValue (PDF)

1.96
(90ns)

1.85
(85ns)

1.83
(84ns)

1.00
(46ns)

ExtremeValue (quantile)

1.43
(53ns)

1.38
(51ns)

1.43
(53ns)

1.00
(37ns)

F (CDF)

4.46
(817ns)

1.58
(289ns)

1.24
(227ns)

1.00
(183ns)

F (PDF)

3.37
(361ns)

1.18
(126ns)

1.12
(120ns)

1.00
(107ns)

F (quantile)

2.70
(2615ns)

1.28
(1241ns)

1.03
(995ns)

1.00
(969ns)

Gamma (CDF)

3.90
(714ns)

1.46
(267ns)

1.47
(269ns)

1.00
(183ns)

Gamma (PDF)

5.75
(437ns)

1.49
(113ns)

1.51
(115ns)

1.00
(76ns)

Gamma (quantile)

4.35
(1827ns)

1.80
(755ns)

1.22
(511ns)

1.00
(420ns)

Geometric (CDF)

1.00
(25ns)

1.08
(27ns)

1.08
(27ns)

1.16
(29ns)

Geometric (PDF)

1.44
(23ns)

1.44
(23ns)

1.56
(25ns)

1.00
(16ns)

Geometric (quantile)

1.00
(25ns)

1.12
(28ns)

1.04
(26ns)

1.24
(31ns)

Hypergeometric (CDF)

1.08
(66745ns)

1.00
(61922ns)

1.02
(62901ns)

1.07
(66289ns)

Hypergeometric (PDF)

1.16
(73824ns)

1.00
(63790ns)

1.02
(65130ns)

1.09
(69844ns)

Hypergeometric (quantile)

1.00
(131293ns)

1.27
(166268ns)

1.24
(163105ns)

1.14
(149745ns)

InverseChiSquared (CDF)

3.06
(1538ns)

1.60
(803ns)

1.31
(657ns)

1.00
(502ns)

InverseChiSquared (PDF)

4.42
(367ns)

1.63
(135ns)

1.52
(126ns)

1.00
(83ns)

InverseChiSquared (quantile)

2.92
(2328ns)

1.66
(1322ns)

1.21
(963ns)

1.00
(797ns)

InverseGamma (CDF)

3.17
(806ns)

1.41
(359ns)

1.18
(299ns)

1.00
(254ns)

InverseGamma (PDF)

5.26
(515ns)

1.54
(151ns)

1.49
(146ns)

1.00
(98ns)

InverseGamma (quantile)

4.02
(2187ns)

1.69
(921ns)

1.19
(645ns)

1.00
(544ns)

InverseGaussian (CDF)

1.89
(236ns)

1.94
(242ns)

1.99
(249ns)

1.00
(125ns)

InverseGaussian (PDF)

1.53
(23ns)

1.53
(23ns)

1.53
(23ns)

1.00
(15ns)

InverseGaussian (quantile)

2.09
(3530ns)

2.26
(3823ns)

2.14
(3611ns)

1.00
(1688ns)

Laplace (CDF)

1.58
(41ns)

1.62
(42ns)

1.62
(42ns)

1.00
(26ns)

Laplace (PDF)

1.56
(42ns)

1.59
(43ns)

1.59
(43ns)

1.00
(27ns)

Laplace (quantile)

1.39
(39ns)

1.43
(40ns)

1.36
(38ns)

1.00
(28ns)

LogNormal (CDF)

2.12
(225ns)

1.33
(141ns)

1.36
(144ns)

1.00
(106ns)

LogNormal (PDF)

1.68
(74ns)

1.73
(76ns)

1.70
(75ns)

1.00
(44ns)

LogNormal (quantile)

1.75
(105ns)

1.68
(101ns)

1.40
(84ns)

1.00
(60ns)

Logistic (CDF)

1.52
(41ns)

1.52
(41ns)

1.74
(47ns)

1.00
(27ns)

Logistic (PDF)

1.59
(43ns)

1.59
(43ns)

1.59
(43ns)

1.00
(27ns)

Logistic (quantile)

1.23
(37ns)

1.23
(37ns)

1.27
(38ns)

1.00
(30ns)

NegativeBinomial (CDF)

4.51
(1354ns)

1.80
(540ns)

1.37
(410ns)

1.00
(300ns)

NegativeBinomial (PDF)

3.62
(445ns)

1.07
(131ns)

1.07
(132ns)

1.00
(123ns)

NegativeBinomial (quantile)

3.26
(7468ns)

1.27
(2918ns)

1.00
(2294ns)

1.15
(2649ns)

NonCentralBeta (CDF)

4.88
(2083ns)

1.80
(769ns)

1.61
(689ns)

1.00
(427ns)

NonCentralBeta (PDF)

3.83
(1265ns)

1.55
(511ns)

1.42
(468ns)

1.00
(330ns)

NonCentralBeta (quantile)

7.51
(55809ns)

2.59
(19273ns)

2.26
(16812ns)

1.00
(7433ns)

NonCentralChiSquared (CDF)

2.90
(4498ns)

1.82
(2821ns)

1.43
(2220ns)

1.00
(1552ns)

NonCentralChiSquared (PDF)

3.52
(953ns)

1.61
(436ns)

1.54
(416ns)

1.00
(271ns)

NonCentralChiSquared (quantile)

4.15
(31465ns)

2.33
(17712ns)

1.56
(11870ns)

1.00
(7586ns)

NonCentralF (CDF)

4.26
(1828ns)

1.55
(667ns)

1.36
(584ns)

1.00
(429ns)

NonCentralF (PDF)

3.98
(1506ns)

1.49
(564ns)

1.29
(488ns)

1.00
(378ns)

NonCentralF (quantile)

4.52
(29414ns)

1.57
(10228ns)

1.31
(8543ns)

1.00
(6504ns)

NonCentralT (CDF)

3.79
(6416ns)

1.72
(2907ns)

1.52
(2572ns)

1.00
(1691ns)

NonCentralT (PDF)

3.41
(4034ns)

1.93
(2284ns)

1.75
(2065ns)

1.00
(1182ns)

NonCentralT (quantile)

5.06
(68590ns)

2.17
(29386ns)

1.65
(22334ns)

1.00
(13546ns)

Normal (CDF)

2.24
(150ns)

1.34
(90ns)

1.28
(86ns)

1.00
(67ns)

Normal (PDF)

1.55
(34ns)

1.50
(33ns)

1.59
(35ns)

1.00
(22ns)

Normal (quantile)

1.68
(57ns)

1.18
(40ns)

1.24
(42ns)

1.00
(34ns)

Pareto (CDF)

1.40
(49ns)

1.46
(51ns)

1.40
(49ns)

1.00
(35ns)

Pareto (PDF)

1.95
(86ns)

1.95
(86ns)

2.09
(92ns)

1.00
(44ns)

Pareto (quantile)

1.76
(51ns)

1.79
(52ns)

1.72
(50ns)

1.00
(29ns)

Poisson (CDF)

3.38
(264ns)

1.56
(122ns)

1.45
(113ns)

1.00
(78ns)

Poisson (PDF)

4.19
(218ns)

1.54
(80ns)

1.52
(79ns)

1.00
(52ns)

Poisson (quantile)

3.04
(1193ns)

1.38
(540ns)

1.35
(528ns)

1.00
(392ns)

Rayleigh (CDF)

1.35
(23ns)

1.41
(24ns)

1.41
(24ns)

1.00
(17ns)

Rayleigh (PDF)

1.68
(37ns)

1.64
(36ns)

1.64
(36ns)

1.00
(22ns)

Rayleigh (quantile)

1.04
(27ns)

1.04
(27ns)

1.00
(26ns)

1.08
(28ns)

SkewNormal (CDF)

1.43
(691ns)

1.31
(633ns)

1.31
(635ns)

1.00
(483ns)

SkewNormal (PDF)

2.07
(174ns)

1.31
(110ns)

1.29
(108ns)

1.00
(84ns)

SkewNormal (quantile)

2.16
(6788ns)

1.85
(5813ns)

1.31
(4118ns)

1.00
(3143ns)

StudentsT (CDF)

6.44
(1893ns)

2.23
(656ns)

2.21
(650ns)

1.00
(294ns)

StudentsT (PDF)

6.58
(724ns)

1.60
(176ns)

1.52
(167ns)

1.00
(110ns)

StudentsT (quantile)

5.79
(2959ns)

1.87
(954ns)

1.86
(951ns)

1.00
(511ns)

Weibull (CDF)

1.73
(69ns)

1.73
(69ns)

1.75
(70ns)

1.00
(40ns)

Weibull (PDF)

1.98
(117ns)

1.98
(117ns)

1.98
(117ns)

1.00
(59ns)

Weibull (quantile)

1.21
(69ns)

1.21
(69ns)

1.19
(68ns)

1.00
(57ns)



PrevUpHomeNext