• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2[mathpart policy Policies: Controlling Precision, Error Handling etc]
3
4[section:pol_overview Policy Overview]
5[policy_overview]
6[endsect] [/section:pol_overview Policy Overview]
7
8[include policy_tutorial.qbk]
9
10[section:pol_ref Policy Reference]
11
12[section:error_handling_policies Error Handling Policies]
13
14There are two orthogonal aspects to error handling:
15
16* What to do (if anything) with the error.
17* What kind of error is being raised.
18
19[h4 Available Actions When an Error is Raised]
20
21What to do with the error is encapsulated by an enumerated type:
22
23   namespace boost { namespace math { namespace policies {
24
25   enum error_policy_type
26   {
27      throw_on_error = 0, // throw an exception.
28      errno_on_error = 1, // set ::errno & return 0, NaN, infinity or best guess.
29      ignore_error = 2, // return 0, NaN, infinity or best guess.
30      user_error = 3  // call a user-defined error handler.
31   };
32
33   }}} // namespaces
34
35The various enumerated values have the following meanings:
36
37[h5 throw_on_error]
38
39Will throw one of the following exceptions, depending upon the
40 type of the error:
41    [table
42       [[Error Type][Exception]]
43       [[Domain Error][std::domain_error]]
44       [[Pole Error][std::domain_error]]
45       [[Overflow Error][std::overflow_error]]
46       [[Underflow Error][std::underflow_error]]
47       [[Denorm Error][std::underflow_error]]
48       [[Evaluation Error][boost::math::evaluation_error]]
49       [[Indeterminate Result Error][std::domain_error]]
50    ]
51
52[h5 errno_on_error]
53
54Will set global __errno `::errno` to one of the following values depending
55upon the error type (often EDOM = 33 and ERANGE = 34),
56and then return the same value as if the error
57had been ignored:
58 [table
59    [[Error Type][errno value]]
60    [[Domain Error][EDOM]]
61    [[Pole Error][EDOM]]
62    [[Overflow Error][ERANGE]]
63    [[Underflow Error][ERANGE]]
64    [[Denorm Error][ERANGE]]
65    [[Evaluation Error][EDOM]]
66    [[Indeterminate Result Error][EDOM]]
67 ]
68
69[h5 ignore_error]
70
71Will return one of the values below depending on the error type (`::errno` is NOT changed)::
72 [table
73    [[Error Type][Returned Value]]
74    [[Domain Error][std::numeric_limits<T>::quiet_NaN()]]
75    [[Pole Error][std::numeric_limits<T>::quiet_NaN()]]
76    [[Overflow Error][std::numeric_limits<T>::infinity()]]
77    [[Underflow Error][0]]
78    [[Denorm Error][The denormalised value.]]
79    [[Evaluation Error][The best guess (perhaps NaN) as to the result: which
80          may be significantly in error.]]
81    [[Indeterminate Result Error][Depends on the function where the error occurred]]
82 ]
83
84[h5 user_error]
85
86Will call a user defined error handler: these are forward declared
87in boost/math/policies/error_handling.hpp, but the actual definitions
88must be provided by the user:
89
90   namespace boost{ namespace math{ namespace policies{
91
92   template <class T>
93   T user_domain_error(const char* function, const char* message, const T& val);
94
95   template <class T>
96   T user_pole_error(const char* function, const char* message, const T& val);
97
98   template <class T>
99   T user_overflow_error(const char* function, const char* message, const T& val);
100
101   template <class T>
102   T user_underflow_error(const char* function, const char* message, const T& val);
103
104   template <class T>
105   T user_denorm_error(const char* function, const char* message, const T& val);
106
107   template <class T>
108   T user_rounding_error(const char* function, const char* message, const T& val);
109
110   template <class T>
111   T user_evaluation_error(const char* function, const char* message, const T& val);
112
113   template <class T>
114   T user_indeterminate_result_error(const char* function, const char* message, const T& val);
115
116   }}} // namespaces
117
118Note that the strings ['function] and ['message] may contain "%1%" format specifiers
119designed to be used in conjunction with Boost.Format.
120If these strings are to be presented to the program's end-user then
121the "%1%" format specifier
122should be replaced with the name of type T in the ['function] string, and
123if there is a %1% specifier in the ['message] string then it
124should be replaced with the value of ['val].
125
126There is more information on user-defined error handlers in
127the [link math_toolkit.pol_tutorial.user_def_err_pol
128tutorial here].
129
130[h4 Kinds of Error Raised]
131
132There are six kinds of error reported by this library,
133which are summarised in the following table:
134
135[table
136[[Error Type]
137   [Policy Class]
138      [Description]]
139[[Domain Error]
140   [boost::math::policies::domain_error<['action]>]
141      [Raised when more or more arguments are outside the
142      defined range of the function.
143
144      Defaults to `boost::math::policies::domain_error<throw_on_error>`
145
146      When the action is set to ['throw_on_error]
147      then throws `std::domain_error`]]
148[[Pole Error]
149   [boost::math::policies::pole_error<['action]>]
150      [Raised when more or more arguments would cause the function
151      to be evaluated at a pole.
152
153      Defaults to `boost::math::policies::pole_error<throw_on_error>`
154
155      When the action is ['throw_on_error] then
156      throw a `std::domain_error`]]
157[[Overflow Error]
158   [boost::math::policies::overflow_error<['action]>]
159      [Raised when the result of the function is outside
160      the representable range of the floating point type used.
161
162      Defaults to `boost::math::policies::overflow_error<throw_on_error>`.
163
164      When the action is ['throw_on_error] then throws a `std::overflow_error`.]]
165[[Underflow Error]
166   [boost::math::policies::underflow_error<['action]>]
167      [Raised when the result of the function is too small
168      to be represented in the floating point type used.
169
170      Defaults to `boost::math::policies::underflow_error<ignore_error>`
171
172      When the specified action is ['throw_on_error] then
173      throws a `std::underflow_error`]]
174[[Denorm Error]
175   [boost::math::policies::denorm_error<['action]>]
176      [Raised when the result of the function is a
177      denormalised value.
178
179      Defaults to `boost::math::policies::denorm_error<ignore_error>`
180
181      When the action is ['throw_on_error] then throws a `std::underflow_error`]]
182[[Rounding Error]
183   [boost::math::policies::rounding_error<['action]>]
184      [Raised When one of the rounding functions __round, __trunc or __modf is
185      called with an argument that has no integer representation, or
186      is too large to be represented in the result type
187
188      Defaults to `boost::math::policies::rounding_error<throw_on_error>`
189
190      When the action is ['throw_on_error] then throws `boost::math::rounding_error`]]
191[[Evaluation Error]
192   [boost::math::policies::evaluation_error<['action]>]
193      [Raised when the result of the function is well defined and
194      finite, but we were unable to compute it.  Typically
195      this occurs when an iterative method fails to converge.
196      Of course ideally this error should never be raised: feel free
197      to report it as a bug if it is!
198
199      Defaults to `boost::math::policies::evaluation_error<throw_on_error>`
200
201      When the action is ['throw_on_error] then throws `boost::math::evaluation_error`]]
202[[Indeterminate Result Error]
203   [boost::math::policies::indeterminate_result_error<['action]>]
204      [Raised when the result of a function is not defined for the values that
205      were passed to it.
206
207      Defaults to `boost::math::policies::indeterminate_result_error<ignore_error>`
208
209      When the action is ['throw_on_error] then throws `std::domain_error`]]
210]
211
212[h4 Examples]
213
214Suppose we want a call to `tgamma` to behave in a C-compatible way and set global
215`::errno` rather than throw an exception, we can achieve this at the call site
216using:
217
218[import ../../example/policy_ref_snip1.cpp]
219
220[policy_ref_snip1]
221
222Suppose we want a statistical distribution to return infinities,
223rather than throw exceptions, then we can use:
224
225[import ../../example/policy_ref_snip2.cpp]
226
227[policy_ref_snip2]
228
229[endsect] [/section:error_handling_policies Error Handling Policies]
230
231[section:internal_promotion Internal Floating-point Promotion Policies]
232
233Normally when evaluating a function at say `float` precision, maximal
234accuracy is assured by conducting the calculation at `double` precision
235internally, and then rounding the result.  There are two policies that
236control whether internal promotion to a higher precision floating-point type takes place, or not:
237
238[table
239[[Policy][Meaning]]
240[[`boost::math::policies::promote_float<B>`]
241   [Indicates whether `float` arguments should be promoted to `double`
242   precision internally: defaults to `boost::math::policies::promote_float<true>`]]
243[[`boost::math::policies::promote_double<B>`]
244   [Indicates whether `double` arguments should be promoted to `long double`
245   precision internally: defaults to `boost::math::policies::promote_double<true>`]]
246]
247
248[h4 Examples]
249
250Suppose we want `tgamma` to be evaluated without internal promotion to
251`long double`, then we could use:
252
253[import ../../example/policy_ref_snip3.cpp]
254[policy_ref_snip3]
255
256Alternatively, suppose we want a distribution to perform calculations
257without promoting `float` to `double`, then we could use:
258
259[import ../../example/policy_ref_snip4.cpp]
260[policy_ref_snip4]
261
262[endsect] [/section:internal_promotion Internal Promotion Policies]
263
264[section:assert_undefined Mathematically Undefined Function Policies]
265
266There are some functions that are generic
267(they are present for all the statistical distributions supported)
268but which may be mathematically undefined for certain distributions, but defined for others.
269
270For example, the Cauchy distribution does not have a meaningful mean,
271so what should
272
273   mean(cauchy<>());
274
275return, and should such an expression even compile at all?
276
277The default behaviour is for all such functions to not compile at all
278 - in fact they will raise a
279[@http://www.boost.org/libs/static_assert/index.html static assertion]
280 - but by changing the policy
281we can have them return the result of a domain error instead
282(which may well throw an exception, depending on the error handling policy).
283
284This behaviour is controlled by the `assert_undefined<>` policy:
285
286   namespace boost{ namespace math{ namespace policies {
287
288   template <bool b>
289   class assert_undefined;
290
291   }}} //namespaces
292
293For example:
294
295   #include <boost/math/distributions/cauchy.hpp>
296
297   using namespace boost::math::policies;
298   using namespace boost::math;
299
300   // This will not compile, cauchy has no mean!
301   double m1 = mean(cauchy());
302
303   // This will compile, but raises a domain error!
304   double m2 = mean(cauchy_distribution<double, policy<assert_undefined<false> > >());
305
306`policy<assert_undefined<false>` behaviour can also be obtained by defining the macro
307
308  #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
309
310at the head of the file - see __policy_macros.
311
312[endsect] [/section:assert_undefined Mathematically Undefined Function Policies]
313
314[section:discrete_quant_ref Discrete Quantile Policies]
315
316If a statistical distribution is ['discrete] then the random variable
317can only have integer values - this leaves us with a problem when calculating
318quantiles - we can either ignore the discreteness of the distribution and return
319a real value, or we can round to an integer.  As it happens, computing integer
320values can be substantially faster than calculating a real value, so there are
321definite advantages to returning an integer, but we do then need to decide
322how best to round the result.  The `discrete_quantile` policy defines how
323discrete quantiles work, and how integer results are rounded:
324
325   enum discrete_quantile_policy_type
326   {
327      real,
328      integer_round_outwards, // default
329      integer_round_inwards,
330      integer_round_down,
331      integer_round_up,
332      integer_round_nearest
333   };
334
335   template <discrete_quantile_policy_type>
336   struct discrete_quantile;
337
338The values that `discrete_quantile` can take have the following meanings:
339
340[h5 real]
341
342Ignores the discreteness of the distribution, and returns a real-valued
343result.  For example:
344
345[import ../../example/policy_ref_snip5.cpp]
346[policy_ref_snip5]
347
348Results in `x = 27.3898` and `y = 68.1584`.
349
350[h5 integer_round_outwards]
351
352This is the default policy: an integer value is returned so that:
353
354* Lower quantiles (where the probability is less than 0.5) are rounded
355down.
356* Upper quantiles (where the probability is greater than 0.5) are rounded up.
357
358This is normally the safest rounding policy, since it ensures that both
359one and two sided intervals are guaranteed to have ['at least]
360the requested coverage.  For example:
361
362[import ../../example/policy_ref_snip6.cpp]
363[policy_ref_snip6]
364
365Results in `x = 27` (rounded down from 27.3898) and `y = 69` (rounded up from 68.1584).
366
367The variables x and y are now defined so that:
368
369   cdf(negative_binomial(20), x) <= 0.05
370   cdf(negative_binomial(20), y) >= 0.95
371
372In other words we guarantee ['at least 90% coverage in the central region overall],
373and also ['no more than 5% coverage in each tail].
374
375[h5 integer_round_inwards]
376
377This is the opposite of ['integer_round_outwards]: an integer value is returned so that:
378
379* Lower quantiles (where the probability is less than 0.5) are rounded
380['up].
381* Upper quantiles (where the probability is greater than 0.5) are rounded ['down].
382
383For example:
384
385[import ../../example/policy_ref_snip7.cpp]
386
387[policy_ref_snip7]
388
389Results in `x = 28` (rounded up from 27.3898) and `y = 68` (rounded down from 68.1584).
390
391The variables x and y are now defined so that:
392
393   cdf(negative_binomial(20), x) >= 0.05
394   cdf(negative_binomial(20), y) <= 0.95
395
396In other words we guarantee ['at no more than 90% coverage in the central region overall],
397and also ['at least 5% coverage in each tail].
398
399[h5 integer_round_down]
400
401Always rounds down to an integer value, no matter whether it's an upper
402or a lower quantile.
403
404[h5 integer_round_up]
405
406Always rounds up to an integer value, no matter whether it's an upper
407or a lower quantile.
408
409[h5 integer_round_nearest]
410
411Always rounds to the nearest integer value, no matter whether it's an upper
412or a lower quantile.  This will produce the requested coverage
413['in the average case], but for any specific example may results in
414either significantly more or less coverage than the requested amount.
415For example:
416
417For example:
418
419[import ../../example/policy_ref_snip8.cpp]
420
421[policy_ref_snip8]
422
423Results in `x = 27` (rounded from 27.3898) and `y = 68` (rounded from 68.1584).
424
425[endsect] [/section:discrete_quant_ref Discrete Quantile Policies]
426
427[section:precision_pol Precision Policies]
428
429There are two equivalent policies that effect the ['working precision]
430used to calculate results, these policies both default to 0 - meaning
431calculate to the maximum precision available in the type being used
432 - but can be set to other values to cause lower levels of precision
433to be used. One might want to trade precision for evaluation speed.
434
435   namespace boost{ namespace math{ namespace policies{
436
437   template <int N>
438   digits10;
439
440   template <int N>
441   digits2;
442
443   }}} // namespaces
444
445As you would expect, ['digits10] specifies the number of decimal digits
446to use, and ['digits2] the number of binary digits.  Internally, whichever
447is used, the precision is always converted to ['binary digits].
448
449These policies are specified at compile-time, because many of the special
450functions use compile-time-dispatch to select which approximation to use
451based on the precision requested and the numeric type being used.
452
453For example we could calculate `tgamma` to approximately 5 decimal digits using:
454
455[import ../../example/policy_ref_snip9.cpp]
456
457[policy_ref_snip9]
458
459Or again using helper function `make_policy`:
460
461[import ../../example/policy_ref_snip10.cpp]
462
463[policy_ref_snip10]
464
465And for a quantile of a distribution to approximately 25-bit precision:
466
467[import ../../example/policy_ref_snip11.cpp]
468
469[policy_ref_snip11]
470
471[endsect] [/section:precision_pol Precision Policies]
472
473[section:iteration_pol Iteration Limits Policies]
474
475There are two policies that effect the iterative algorithms
476used to implement the special functions in this library:
477
478   template <unsigned long limit = BOOST_MATH_MAX_SERIES_ITERATION_POLICY>
479   class max_series_iterations;
480
481   template <unsigned long limit = BOOST_MATH_MAX_ROOT_ITERATION_POLICY>
482   class max_root_iterations;
483
484The class `max_series_iterations` determines the maximum number of
485iterations permitted in a series evaluation, before the special
486function gives up and returns the result of __evaluation_error.
487
488The class `max_root_iterations` determines the maximum number
489of iterations permitted in a root-finding algorithm before the special
490function gives up and returns the result of __evaluation_error.
491
492[endsect] [/section:iteration_pol Iteration Limits Policies]
493
494[section:policy_defaults Using Macros to Change the Policy Defaults]
495
496You can use the various macros below to change any (or all) of the policies.
497
498You can make a local change by placing a macro definition *before*
499a function or distribution #include.
500
501[caution There is a danger of One-Definition-Rule violations if you
502add ad-hoc macros to more than one source files: these must be set the same in *every
503translation unit*.]
504
505[caution If you place it after the #include it will have no effect,
506(and it will affect only any other following #includes).
507This is probably not what you intend!]
508
509If you want to alter the defaults for any or all of
510the policies for *all* functions and distributions, installation-wide,
511then you can do so by defining various macros in
512[@../../../../boost/math/tools/user.hpp boost/math/tools/user.hpp].
513
514[h5 BOOST_MATH_DOMAIN_ERROR_POLICY]
515
516Defines what happens when a domain error occurs, if not defined then
517defaults to `throw_on_error`, but can be set to any of the enumerated
518actions for error handing: `throw_on_error`, `errno_on_error`,
519`ignore_error` or `user_error`.
520
521[h5 BOOST_MATH_POLE_ERROR_POLICY]
522
523Defines what happens when a pole error occurs, if not defined then
524defaults to `throw_on_error`, but can be set to any of the enumerated
525actions for error handing: `throw_on_error`, `errno_on_error`,
526`ignore_error` or `user_error`.
527
528[h5 BOOST_MATH_OVERFLOW_ERROR_POLICY]
529
530Defines what happens when an overflow error occurs, if not defined then
531defaults to `throw_on_error`, but can be set to any of the enumerated
532actions for error handing: `throw_on_error`, `errno_on_error`,
533`ignore_error` or `user_error`.
534
535[h5 BOOST_MATH_ROUNDING_ERROR_POLICY]
536
537Defines what happens when a rounding error occurs, if not defined then
538defaults to `throw_on_error`, but can be set to any of the enumerated
539actions for error handing: `throw_on_error`, `errno_on_error`,
540`ignore_error` or `user_error`.
541
542[h5 BOOST_MATH_EVALUATION_ERROR_POLICY]
543
544Defines what happens when an internal evaluation error occurs, if not defined then
545defaults to `throw_on_error`, but can be set to any of the enumerated
546actions for error handing: `throw_on_error`, `errno_on_error`,
547`ignore_error` or `user_error`.
548
549[h5 BOOST_MATH_UNDERFLOW_ERROR_POLICY]
550
551Defines what happens when an overflow error occurs, if not defined then
552defaults to `ignore_error`, but can be set to any of the enumerated
553actions for error handing: `throw_on_error`, `errno_on_error`,
554`ignore_error` or `user_error`.
555
556[h5 BOOST_MATH_DENORM_ERROR_POLICY]
557
558Defines what happens when a denormalisation error occurs, if not defined then
559defaults to `ignore_error`, but can be set to any of the enumerated
560actions for error handing: `throw_on_error`, `errno_on_error`,
561`ignore_error` or `user_error`.
562
563[h5 BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY]
564
565Defines what happens when the result is indeterminate, but where there
566is none the less a convention for the result.  If not defined then
567defaults to `ignore_error`, but can be set to any of the enumerated
568actions for error handing: `throw_on_error`, `errno_on_error`,
569`ignore_error` or `user_error`.
570
571[h5 BOOST_MATH_DIGITS10_POLICY]
572
573Defines how many decimal digits to use in internal computations:
574defaults to `0` - meaning use all available digits - but can be set
575to some other decimal value.  Since setting this is likely to have
576a substantial impact on accuracy, it's not generally recommended
577that you change this from the default.
578
579[h5 BOOST_MATH_PROMOTE_FLOAT_POLICY]
580
581Determines whether `float` types get promoted to `double`
582internally to ensure maximum precision in the result, defaults
583to `true`, but can be set to `false` to turn promotion of
584`float`'s off.
585
586[h5 BOOST_MATH_PROMOTE_DOUBLE_POLICY]
587
588Determines whether `double` types get promoted to `long double`
589internally to ensure maximum precision in the result, defaults
590to `true`, but can be set to `false` to turn promotion of
591`double`'s off.
592
593[h5 BOOST_MATH_DISCRETE_QUANTILE_POLICY]
594
595Determines how discrete quantiles return their results: either
596as an integer, or as a real value, can be set to one of the
597enumerated values: `real`, `integer_round_outwards`, `integer_round_inwards`,
598`integer_round_down`, `integer_round_up`, `integer_round_nearest`.  Defaults to
599`integer_round_outwards`.
600
601[h5 BOOST_MATH_ASSERT_UNDEFINED_POLICY]
602
603Determines whether functions that are mathematically undefined
604for a specific distribution compile or raise a static (i.e. compile-time)
605assertion.  Defaults to `true`: meaning that any mathematically
606undefined function will not compile.  When set to `false` then the function
607will compile but return the result of a domain error: this can be useful
608for some generic code, that needs to work with all distributions and determine
609at runtime whether or not a particular property is well defined.
610
611[h5 BOOST_MATH_MAX_SERIES_ITERATION_POLICY]
612
613Determines how many series iterations a special function is permitted
614to perform before it gives up and returns an __evaluation_error:
615Defaults to 1000000.
616
617[h5 BOOST_MATH_MAX_ROOT_ITERATION_POLICY]
618
619Determines how many root-finding iterations a special function is permitted
620to perform before it gives up and returns an __evaluation_error:
621Defaults to 200.
622
623[h5 Example]
624
625Suppose we want overflow errors to set `::errno` and return an infinity,
626discrete quantiles to return a real-valued result (rather than round to
627integer), and for mathematically undefined functions to compile, but return
628a domain error. Then we could add the following to boost/math/tools/user.hpp:
629
630   #define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error
631   #define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
632   #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
633
634or we could place these definitions *before*
635
636   #include <boost/math/distributions/normal.hpp>
637     using boost::math::normal_distribution;
638
639in a source .cpp file.
640
641[endsect] [/section:policy_defaults Changing the Policy Defaults]
642
643[section:namespace_pol Setting Polices at Namespace Scope]
644
645Sometimes what you really want to do is bring all the special functions,
646or all the distributions into a specific namespace-scope, along with
647a specific policy to use with them.  There are two macros defined to
648assist with that:
649
650   BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)
651
652and:
653
654   BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)
655
656You can use either of these macros after including any special function
657or distribution header.  For example:
658
659[import ../../example/policy_ref_snip12.cpp]
660
661[policy_ref_snip12]
662
663In this example, using BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS results in
664a set of thin inline forwarding functions being defined:
665
666   template <class T>
667   inline T tgamma(T a){ return ::boost::math::tgamma(a, mypolicy()); }
668
669   template <class T>
670   inline T lgamma(T a) ( return ::boost::math::lgamma(a, mypolicy()); }
671
672and so on.  Note that while a forwarding function is defined for all the special
673functions, however, unless you include the specific header for the special
674function you use (or boost/math/special_functions.hpp to include everything),
675you will get linker errors from functions that are forward declared, but not
676defined.
677
678We can do the same thing with the distributions, but this time we need to
679specify the floating-point type to use:
680
681[import ../../example/policy_ref_snip13.cpp]
682
683[policy_ref_snip13]
684
685In this example the result of BOOST_MATH_DECLARE_DISTRIBUTIONS is to
686declare a typedef for each distribution like this:
687
688   typedef boost::math::cauchy_distribution<double, my_policy> cauchy;
689   tyepdef boost::math::gamma_distribution<double, my_policy> gamma;
690
691and so on.  The name given to each typedef is the name of the distribution
692with the "_distribution" suffix removed.
693
694[endsect] [/section Changing the Policy Defaults]
695
696[section:pol_ref_ref Policy Class Reference]
697
698There's very little to say here, the `policy` class is just a rag-bag
699compile-time container for a collection of policies:
700
701```#include <boost/math/policies/policy.hpp>```
702
703
704   namespace boost{
705   namespace math{
706   namespace policies
707
708   template <class A1 = default_policy,
709             class A2 = default_policy,
710             class A3 = default_policy,
711             class A4 = default_policy,
712             class A5 = default_policy,
713             class A6 = default_policy,
714             class A7 = default_policy,
715             class A8 = default_policy,
716             class A9 = default_policy,
717             class A10 = default_policy,
718             class A11 = default_policy,
719             class A12 = default_policy,
720             class A13 = default_policy>
721   struct policy
722   {
723   public:
724      typedef ``['computed-from-template-arguments]`` domain_error_type;
725      typedef ``['computed-from-template-arguments]`` pole_error_type;
726      typedef ``['computed-from-template-arguments]`` overflow_error_type;
727      typedef ``['computed-from-template-arguments]`` underflow_error_type;
728      typedef ``['computed-from-template-arguments]`` denorm_error_type;
729      typedef ``['computed-from-template-arguments]`` rounding_error_type;
730      typedef ``['computed-from-template-arguments]`` evaluation_error_type;
731      typedef ``['computed-from-template-arguments]`` indeterminate_result_error_type;
732      typedef ``['computed-from-template-arguments]`` precision_type;
733      typedef ``['computed-from-template-arguments]`` promote_float_type;
734      typedef ``['computed-from-template-arguments]`` promote_double_type;
735      typedef ``['computed-from-template-arguments]`` discrete_quantile_type;
736      typedef ``['computed-from-template-arguments]`` assert_undefined_type;
737   };
738
739   template <...argument list...>
740   typename normalise<policy<>, A1>::type make_policy(...argument list..);
741
742   template <class Policy,
743             class A1 = default_policy,
744             class A2 = default_policy,
745             class A3 = default_policy,
746             class A4 = default_policy,
747             class A5 = default_policy,
748             class A6 = default_policy,
749             class A7 = default_policy,
750             class A8 = default_policy,
751             class A9 = default_policy,
752             class A10 = default_policy,
753             class A11 = default_policy,
754             class A12 = default_policy,
755             class A13 = default_policy>
756   struct normalise
757   {
758      typedef ``computed-from-template-arguments`` type;
759   };
760
761The member typedefs of class `policy` are intended for internal use
762but are documented briefly here for the sake of completeness.
763
764   policy<...>::domain_error_type
765
766Specifies how domain errors are handled, will be an instance of
767`boost::math::policies::domain_error<>` with the template argument to
768`domain_error` one of the `error_policy_type` enumerated values.
769
770   policy<...>::pole_error_type
771
772Specifies how pole-errors are handled, will be an instance of
773`boost::math::policies::pole_error<>` with the template argument to
774`pole_error` one of the `error_policy_type` enumerated values.
775
776   policy<...>::overflow_error_type
777
778Specifies how overflow errors are handled, will be an instance of
779`boost::math::policies::overflow_error<>` with the template argument to
780`overflow_error` one of the `error_policy_type` enumerated values.
781
782   policy<...>::underflow_error_type
783
784Specifies how underflow errors are handled, will be an instance of
785`boost::math::policies::underflow_error<>` with the template argument to
786`underflow_error` one of the `error_policy_type` enumerated values.
787
788   policy<...>::denorm_error_type
789
790Specifies how denorm errors are handled, will be an instance of
791`boost::math::policies::denorm_error<>` with the template argument to
792`denorm_error` one of the `error_policy_type` enumerated values.
793
794   policy<...>::rounding_error_type
795
796Specifies how rounding errors are handled, will be an instance of
797`boost::math::policies::rounding_error<>` with the template argument to
798`rounding_error` one of the `error_policy_type` enumerated values.
799
800   policy<...>::evaluation_error_type
801
802Specifies how evaluation errors are handled, will be an instance of
803`boost::math::policies::evaluation_error<>` with the template argument to
804`evaluation_error` one of the `error_policy_type` enumerated values.
805
806   policy<...>::indeterminate_error_type
807
808Specifies how indeterminate result errors are handled, will be an instance of
809`boost::math::policies::indeterminate_result_error<>` with the template argument
810to `indeterminate_result_error` one of the `error_policy_type` enumerated
811values.
812
813   policy<...>::precision_type
814
815Specifies the internal precision to use in binary digits (uses zero
816to represent whatever the default precision is).  Will be an instance
817of `boost::math::policies::digits2<N>` which in turn inherits from
818`boost::boost::integral_constant<int, N>`.
819
820   policy<...>::promote_float_type
821
822Specifies whether or not to promote `float` arguments to `double` precision
823internally.  Will be an instance of `boost::math::policies::promote_float<B>`
824which in turn inherits from `boost::integral_constant<bool, B>`.
825
826   policy<...>::promote_double_type
827
828Specifies whether or not to promote `double` arguments to `long double` precision
829internally.  Will be an instance of `boost::math::policies::promote_float<B>`
830which in turn inherits from `boost::integral_constant<bool, B>`.
831
832   policy<...>::discrete_quantile_type
833
834Specifies how discrete quantiles are evaluated, will be an instance
835of `boost::math::policies::discrete_quantile<>` instantiated with one of
836the `discrete_quantile_policy_type` enumerated type.
837
838   policy<...>::assert_undefined_type
839
840Specifies whether mathematically-undefined properties are
841asserted as compile-time errors, or treated as runtime errors
842instead.  Will be an instance of `boost::math::policies::assert_undefined<B>`
843which in turn inherits from `boost::integral_constant<bool, B>`.
844
845
846   template <...argument list...>
847   typename normalise<policy<>, A1>::type make_policy(...argument list..);
848
849`make_policy` is a helper function that converts a list of policies into
850a normalised `policy` class.
851
852   template <class Policy,
853             class A1 = default_policy,
854             class A2 = default_policy,
855             class A3 = default_policy,
856             class A4 = default_policy,
857             class A5 = default_policy,
858             class A6 = default_policy,
859             class A7 = default_policy,
860             class A8 = default_policy,
861             class A9 = default_policy,
862             class A10 = default_policy,
863             class A11 = default_policy,
864             class A12 = default_policy,
865             class A13 = default_policy>
866   struct normalise
867   {
868      typedef ``computed-from-template-arguments`` type;
869   };
870
871The `normalise` class template converts one instantiation of the
872`policy` class into a normalised form.  This is used internally
873to reduce code bloat: so that instantiating a special function
874on `policy<A,B>` or `policy<B,A>` actually both generate the same
875code internally.
876
877Further more, `normalise` can be used to combine
878a policy with one or more policies: for example many of the
879special functions will use this to set policies which they don't
880make use of to their default values, before forwarding to the actual
881implementation.  In this way code bloat is reduced, since the
882actual implementation depends only on the policy types that they
883actually use.
884
885[endsect] [/section:pol_ref_ref Policy Class Reference]
886
887[endsect] [/section:pol_ref Policy Reference]
888[endmathpart] [/section:policy Policies]
889
890[/ policy.qbk
891  Copyright 2007, 2010 John Maddock and Paul A. Bristow.
892  Distributed under the Boost Software License, Version 1.0.
893  (See accompanying file LICENSE_1_0.txt or copy at
894  http://www.boost.org/LICENSE_1_0.txt).
895]
896
897
898