
Following the successful review of the math-toolkit of special functions and statistical distributions the main feature request was for a better way of customising the library: both for choosing between precision vs speed tradeoffs, and for determining how errors are best handled. I've been experimenting with various policy-based interfaced based on Boost.Parameter, and I think I now have something useable, so I'd like to know what people think: Policy Defaults ~~~~~~~~~~~~~~~ The library will use a sensible set of defaults (throw on domain errors and internal evaluation errors, favour accuracy over speed etc), which can be changed via the usual macro mechanism, so adding: #define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignor_error to a user-config header would do what they say to the default policies. Add Hock Changes: ~~~~~~~~~~~~~~~~~ We can create an ad-hock policy change at the call site by using the make_policy function, for example: using namespace boost::math::policy; using namespace boost::math; quantile( poisson(100), 0.05, make_policy( // 5 dicimal digits precision only digits10<10>(), // don't internally promote double->long double for extra precision: promote_double<false>(), // return integer result, immediately below the "real" value: discrete_quantile<integer_below>() )); Which returns the lower 95% quantile (ie critical value) of a poisson distribution with rate parameter of 100 event's per unit time. The result is calculated using only 10 decimal digits internal precision, truncated to the largest integer that gives a CDF less than 0.05. Predefined Policies ~~~~~~~~~~~~~~~~~~~ Although ad-hock policies are useful for testing, I imagine most sites would want a few carefully controlled (and tested) policies. To achieve that you define a typedef of the policy class: using namespace boost::math::policy; typedef policy< // Set error handling: domain_error<throw_on_error>, pole_error<throw_on_error>, overflow_error<throw_on_error>, evaluation_error<throw_on_error>, denorm_error<ignor_error>, underflow_error<ignor_error>, // calculate to 8 decimal digits internally digits10<8>, // don't promote double->long double for accuracy promote_double<false>, // Integer quantiles return the "outside edge": // below the real value for lower critical values, // above it for upper critical values, so that the // area inside contains *at least* the requested coverage: discrete_quantile<integer_outside_edge> > fast_quantile_policy; static fast_quantile_policy fast_quantile; Then we can just use: quantile( poisson(100), 0.05, fast_quantile); In our actual code. Currently this policy interface is vapourware: I have enough of a prototype implemented to know that it's possible to achieve this syntax (this is revision #3 already !), but there's a lot of hairy meta-programming to convert that into something that the library's internals can make use of... so I'd like to know what folks think before I invest too much time messing about with MPL :-) The main disadvantage I've noticed at present, is that the mangled names of the policy class - and therefore all the special functions etc - are *very* long. This has an impact on error messages: in particular we currently use BOOST_CURRENT_FUNCTION to get a nice formatted name of a function that's about to throw, but with function names a couple of pages long I don't think that will be possible with this interface any more :-( Thanks in advance, John Maddock.