
Paris (U.E.), le 19/06/2007 Bonjour Sorry for the delay, I had yet another emergency these last few days. The proposed interface is certainly nice and could definitely be worked with. For the global choices it is perfectly adequate, IMO. For finer control however, it does appear very fine-grained (per-function), which, in addition to making error message harder to read, is perhaps not the most frequent level of interaction needed. For instance, while I certainly see the need sometimes for per-function disabling of internal double promotion, I believe that more frequently users may want to set these preferences at the translation unit level, when not at the global level. While (mostly) global objects may be evil, something along the lines of standard streams and their interaction with locales and facets may perhaps be easier to deal with. For instance, functions may requests their choices from some external "policy object", which may be locally altered, much as streams will enquire from a locale how to typeset dates. Granted, this would make multithreading all the hairier (which is not really a good idea). On the other hand, not all functions necessarily require information about every configuration choice possible, so passing in all the info when only some is needed may perhaps be excessive. Merci Hubert Holin On 12 juin 2007, at 11:37, John Maddock wrote:
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.