File: policy.qbk

package info (click to toggle)
boost1.74 1.74.0-9
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 464,084 kB
  • sloc: cpp: 3,338,324; xml: 131,293; python: 33,088; ansic: 14,336; asm: 4,034; sh: 3,351; makefile: 1,193; perl: 1,036; yacc: 478; php: 212; ruby: 102; lisp: 24; sql: 13; csh: 6
file content (897 lines) | stat: -rw-r--r-- 32,493 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897

[mathpart policy Policies: Controlling Precision, Error Handling etc]

[section:pol_overview Policy Overview]
[policy_overview]
[endsect] [/section:pol_overview Policy Overview]

[include policy_tutorial.qbk]

[section:pol_ref Policy Reference]

[section:error_handling_policies Error Handling Policies]

There are two orthogonal aspects to error handling:

* What to do (if anything) with the error.
* What kind of error is being raised.

[h4 Available Actions When an Error is Raised]

What to do with the error is encapsulated by an enumerated type:

   namespace boost { namespace math { namespace policies {
   
   enum error_policy_type
   {
      throw_on_error = 0, // throw an exception.
      errno_on_error = 1, // set ::errno & return 0, NaN, infinity or best guess.
      ignore_error = 2, // return 0, NaN, infinity or best guess.
      user_error = 3  // call a user-defined error handler.
   };

   }}} // namespaces
   
The various enumerated values have the following meanings:

[h5 throw_on_error]

Will throw one of the following exceptions, depending upon the
 type of the error:
    [table
       [[Error Type][Exception]]
       [[Domain Error][std::domain_error]]
       [[Pole Error][std::domain_error]]
       [[Overflow Error][std::overflow_error]]
       [[Underflow Error][std::underflow_error]]
       [[Denorm Error][std::underflow_error]]
       [[Evaluation Error][boost::math::evaluation_error]]
       [[Indeterminate Result Error][std::domain_error]]
    ]

[h5 errno_on_error]

Will set global __errno `::errno` to one of the following values depending 
upon the error type (often EDOM = 33 and ERANGE = 34),
and then return the same value as if the error
had been ignored:
 [table
    [[Error Type][errno value]]
    [[Domain Error][EDOM]]
    [[Pole Error][EDOM]]
    [[Overflow Error][ERANGE]]
    [[Underflow Error][ERANGE]]
    [[Denorm Error][ERANGE]]
    [[Evaluation Error][EDOM]]
    [[Indeterminate Result Error][EDOM]]
 ]

[h5 ignore_error]

Will return one of the values below depending on the error type (`::errno` is NOT changed)::
 [table
    [[Error Type][Returned Value]]
    [[Domain Error][std::numeric_limits<T>::quiet_NaN()]]
    [[Pole Error][std::numeric_limits<T>::quiet_NaN()]]
    [[Overflow Error][std::numeric_limits<T>::infinity()]]
    [[Underflow Error][0]]
    [[Denorm Error][The denormalised value.]]
    [[Evaluation Error][The best guess (perhaps NaN) as to the result: which
          may be significantly in error.]]
    [[Indeterminate Result Error][Depends on the function where the error occurred]]
 ]

[h5 user_error]

Will call a user defined error handler: these are forward declared
in boost/math/policies/error_handling.hpp, but the actual definitions
must be provided by the user:

   namespace boost{ namespace math{ namespace policies{

   template <class T>
   T user_domain_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_pole_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_overflow_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_underflow_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_denorm_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_rounding_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_evaluation_error(const char* function, const char* message, const T& val);

   template <class T>
   T user_indeterminate_result_error(const char* function, const char* message, const T& val);

   }}} // namespaces

Note that the strings ['function] and ['message] may contain "%1%" format specifiers
designed to be used in conjunction with Boost.Format.  
If these strings are to be presented to the program's end-user then 
the "%1%" format specifier
should be replaced with the name of type T in the ['function] string, and 
if there is a %1% specifier in the ['message] string then it 
should be replaced with the value of ['val].

There is more information on user-defined error handlers in
the [link math_toolkit.pol_tutorial.user_def_err_pol 
tutorial here].

[h4 Kinds of Error Raised]                  

There are six kinds of error reported by this library,
which are summarised in the following table:

[table
[[Error Type]
   [Policy Class]
      [Description]]
[[Domain Error]
   [boost::math::policies::domain_error<['action]>]
      [Raised when more or more arguments are outside the 
      defined range of the function.

      Defaults to `boost::math::policies::domain_error<throw_on_error>`

      When the action is set to ['throw_on_error] 
      then throws `std::domain_error`]]
[[Pole Error]
   [boost::math::policies::pole_error<['action]>]
      [Raised when more or more arguments would cause the function
      to be evaluated at a pole.

      Defaults to `boost::math::policies::pole_error<throw_on_error>`

      When the action is ['throw_on_error] then
      throw a `std::domain_error`]]
[[Overflow Error]
   [boost::math::policies::overflow_error<['action]>]
      [Raised when the result of the function is outside
      the representable range of the floating point type used.

      Defaults to `boost::math::policies::overflow_error<throw_on_error>`.

      When the action is ['throw_on_error] then throws a `std::overflow_error`.]]
[[Underflow Error]
   [boost::math::policies::underflow_error<['action]>]
      [Raised when the result of the function is too small
      to be represented in the floating point type used.

      Defaults to `boost::math::policies::underflow_error<ignore_error>`

      When the specified action is ['throw_on_error] then
      throws a `std::underflow_error`]]
[[Denorm Error]
   [boost::math::policies::denorm_error<['action]>]
      [Raised when the result of the function is a
      denormalised value.

      Defaults to `boost::math::policies::denorm_error<ignore_error>`

      When the action is ['throw_on_error] then throws a `std::underflow_error`]]
[[Rounding Error]
   [boost::math::policies::rounding_error<['action]>]
      [Raised When one of the rounding functions __round, __trunc or __modf is
      called with an argument that has no integer representation, or
      is too large to be represented in the result type

      Defaults to `boost::math::policies::rounding_error<throw_on_error>`

      When the action is ['throw_on_error] then throws `boost::math::rounding_error`]]
[[Evaluation Error]
   [boost::math::policies::evaluation_error<['action]>]
      [Raised when the result of the function is well defined and
      finite, but we were unable to compute it.  Typically
      this occurs when an iterative method fails to converge.
      Of course ideally this error should never be raised: feel free
      to report it as a bug if it is!

      Defaults to `boost::math::policies::evaluation_error<throw_on_error>`

      When the action is ['throw_on_error] then throws `boost::math::evaluation_error`]]
[[Indeterminate Result Error]
   [boost::math::policies::indeterminate_result_error<['action]>]
      [Raised when the result of a function is not defined for the values that
      were passed to it.

      Defaults to `boost::math::policies::indeterminate_result_error<ignore_error>`

      When the action is ['throw_on_error] then throws `std::domain_error`]]
]

[h4 Examples]

Suppose we want a call to `tgamma` to behave in a C-compatible way and set global
`::errno` rather than throw an exception, we can achieve this at the call site
using:

[import ../../example/policy_ref_snip1.cpp]

[policy_ref_snip1]
   
Suppose we want a statistical distribution to return infinities,
rather than throw exceptions, then we can use:

[import ../../example/policy_ref_snip2.cpp]

[policy_ref_snip2]

[endsect] [/section:error_handling_policies Error Handling Policies]

[section:internal_promotion Internal Floating-point Promotion Policies]

Normally when evaluating a function at say `float` precision, maximal
accuracy is assured by conducting the calculation at `double` precision
internally, and then rounding the result.  There are two policies that
control whether internal promotion to a higher precision floating-point type takes place, or not:

[table
[[Policy][Meaning]]
[[`boost::math::policies::promote_float<B>`]
   [Indicates whether `float` arguments should be promoted to `double`
   precision internally: defaults to `boost::math::policies::promote_float<true>`]]
[[`boost::math::policies::promote_double<B>`]
   [Indicates whether `double` arguments should be promoted to `long double`
   precision internally: defaults to `boost::math::policies::promote_double<true>`]]
]

[h4 Examples]

Suppose we want `tgamma` to be evaluated without internal promotion to
`long double`, then we could use:

[import ../../example/policy_ref_snip3.cpp]
[policy_ref_snip3]
   
Alternatively, suppose we want a distribution to perform calculations
without promoting `float` to `double`, then we could use:

[import ../../example/policy_ref_snip4.cpp]
[policy_ref_snip4]
   
[endsect] [/section:internal_promotion Internal Promotion Policies]

[section:assert_undefined Mathematically Undefined Function Policies]

There are some functions that are generic
(they are present for all the statistical distributions supported)
but which may be mathematically undefined for certain distributions, but defined for others.

For example, the Cauchy distribution does not have a meaningful mean,
so what should

   mean(cauchy<>());
   
return, and should such an expression even compile at all?

The default behaviour is for all such functions to not compile at all
 - in fact they will raise a 
[@http://www.boost.org/libs/static_assert/index.html static assertion]
 - but by changing the policy
we can have them return the result of a domain error instead
(which may well throw an exception, depending on the error handling policy). 

This behaviour is controlled by the `assert_undefined<>` policy:

   namespace boost{ namespace math{ namespace policies {

   template <bool b>
   class assert_undefined;

   }}} //namespaces

For example:

   #include <boost/math/distributions/cauchy.hpp>
   
   using namespace boost::math::policies;
   using namespace boost::math;
   
   // This will not compile, cauchy has no mean!
   double m1 = mean(cauchy()); 
   
   // This will compile, but raises a domain error!
   double m2 = mean(cauchy_distribution<double, policy<assert_undefined<false> > >());

`policy<assert_undefined<false>` behaviour can also be obtained by defining the macro

  #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
  
at the head of the file - see __policy_macros. 
 
[endsect] [/section:assert_undefined Mathematically Undefined Function Policies]

[section:discrete_quant_ref Discrete Quantile Policies]

If a statistical distribution is ['discrete] then the random variable
can only have integer values - this leaves us with a problem when calculating
quantiles - we can either ignore the discreteness of the distribution and return
a real value, or we can round to an integer.  As it happens, computing integer
values can be substantially faster than calculating a real value, so there are
definite advantages to returning an integer, but we do then need to decide
how best to round the result.  The `discrete_quantile` policy defines how
discrete quantiles work, and how integer results are rounded:

   enum discrete_quantile_policy_type
   {
      real,
      integer_round_outwards, // default
      integer_round_inwards,
      integer_round_down,
      integer_round_up,
      integer_round_nearest
   };
   
   template <discrete_quantile_policy_type>
   struct discrete_quantile;
   
The values that `discrete_quantile` can take have the following meanings:

[h5 real]

Ignores the discreteness of the distribution, and returns a real-valued 
result.  For example:

[import ../../example/policy_ref_snip5.cpp]
[policy_ref_snip5]
   
Results in `x = 27.3898` and `y = 68.1584`.

[h5 integer_round_outwards]

This is the default policy: an integer value is returned so that:

* Lower quantiles (where the probability is less than 0.5) are rounded
down.
* Upper quantiles (where the probability is greater than 0.5) are rounded up.

This is normally the safest rounding policy, since it ensures that both
one and two sided intervals are guaranteed to have ['at least] 
the requested coverage.  For example:

[import ../../example/policy_ref_snip6.cpp]
[policy_ref_snip6]
   
Results in `x = 27` (rounded down from 27.3898) and `y = 69` (rounded up from 68.1584).

The variables x and y are now defined so that:

   cdf(negative_binomial(20), x) <= 0.05
   cdf(negative_binomial(20), y) >= 0.95
   
In other words we guarantee ['at least 90% coverage in the central region overall], 
and also ['no more than 5% coverage in each tail].

[h5 integer_round_inwards]

This is the opposite of ['integer_round_outwards]: an integer value is returned so that:

* Lower quantiles (where the probability is less than 0.5) are rounded
['up].
* Upper quantiles (where the probability is greater than 0.5) are rounded ['down].

For example:

[import ../../example/policy_ref_snip7.cpp]

[policy_ref_snip7]
   
Results in `x = 28` (rounded up from 27.3898) and `y = 68` (rounded down from 68.1584).

The variables x and y are now defined so that:

   cdf(negative_binomial(20), x) >= 0.05
   cdf(negative_binomial(20), y) <= 0.95
   
In other words we guarantee ['at no more than 90% coverage in the central region overall], 
and also ['at least 5% coverage in each tail].

[h5 integer_round_down]

Always rounds down to an integer value, no matter whether it's an upper 
or a lower quantile.

[h5 integer_round_up]

Always rounds up to an integer value, no matter whether it's an upper 
or a lower quantile.

[h5 integer_round_nearest]

Always rounds to the nearest integer value, no matter whether it's an upper 
or a lower quantile.  This will produce the requested coverage
['in the average case], but for any specific example may results in
either significantly more or less coverage than the requested amount.
For example:

For example:

[import ../../example/policy_ref_snip8.cpp]

[policy_ref_snip8]

Results in `x = 27` (rounded from 27.3898) and `y = 68` (rounded from 68.1584).

[endsect] [/section:discrete_quant_ref Discrete Quantile Policies]

[section:precision_pol Precision Policies]

There are two equivalent policies that effect the ['working precision]
used to calculate results, these policies both default to 0 - meaning
calculate to the maximum precision available in the type being used
 - but can be set to other values to cause lower levels of precision 
to be used. One might want to trade precision for evaluation speed.

   namespace boost{ namespace math{ namespace policies{
   
   template <int N>
   digits10;
   
   template <int N>
   digits2;
   
   }}} // namespaces
   
As you would expect, ['digits10] specifies the number of decimal digits
to use, and ['digits2] the number of binary digits.  Internally, whichever
is used, the precision is always converted to ['binary digits].

These policies are specified at compile-time, because many of the special
functions use compile-time-dispatch to select which approximation to use
based on the precision requested and the numeric type being used.

For example we could calculate `tgamma` to approximately 5 decimal digits using:

[import ../../example/policy_ref_snip9.cpp]

[policy_ref_snip9]
   
Or again using helper function `make_policy`:

[import ../../example/policy_ref_snip10.cpp]

[policy_ref_snip10]

And for a quantile of a distribution to approximately 25-bit precision:

[import ../../example/policy_ref_snip11.cpp]

[policy_ref_snip11]

[endsect] [/section:precision_pol Precision Policies]

[section:iteration_pol Iteration Limits Policies]

There are two policies that effect the iterative algorithms
used to implement the special functions in this library:

   template <unsigned long limit = BOOST_MATH_MAX_SERIES_ITERATION_POLICY>
   class max_series_iterations;
   
   template <unsigned long limit = BOOST_MATH_MAX_ROOT_ITERATION_POLICY>
   class max_root_iterations;

The class `max_series_iterations` determines the maximum number of
iterations permitted in a series evaluation, before the special
function gives up and returns the result of __evaluation_error.

The class `max_root_iterations` determines the maximum number
of iterations permitted in a root-finding algorithm before the special
function gives up and returns the result of __evaluation_error.

[endsect] [/section:iteration_pol Iteration Limits Policies]

[section:policy_defaults Using Macros to Change the Policy Defaults]

You can use the various macros below to change any (or all) of the policies.

You can make a local change by placing a macro definition *before*
a function or distribution #include.

[caution There is a danger of One-Definition-Rule violations if you 
add ad-hoc macros to more than one source files: these must be set the same in *every 
translation unit*.]

[caution If you place it after the #include it will have no effect,
(and it will affect only any other following #includes).
This is probably not what you intend!]

If you want to alter the defaults for any or all of 
the policies for *all* functions and distributions, installation-wide,
then you can do so by defining various macros in
[@../../../../boost/math/tools/user.hpp boost/math/tools/user.hpp].

[h5 BOOST_MATH_DOMAIN_ERROR_POLICY]

Defines what happens when a domain error occurs, if not defined then
defaults to `throw_on_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_POLE_ERROR_POLICY]

Defines what happens when a pole error occurs, if not defined then
defaults to `throw_on_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_OVERFLOW_ERROR_POLICY]

Defines what happens when an overflow error occurs, if not defined then
defaults to `throw_on_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_ROUNDING_ERROR_POLICY]

Defines what happens when a rounding error occurs, if not defined then
defaults to `throw_on_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_EVALUATION_ERROR_POLICY]

Defines what happens when an internal evaluation error occurs, if not defined then
defaults to `throw_on_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_UNDERFLOW_ERROR_POLICY]

Defines what happens when an overflow error occurs, if not defined then
defaults to `ignore_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_DENORM_ERROR_POLICY]

Defines what happens when a denormalisation error occurs, if not defined then
defaults to `ignore_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY]

Defines what happens when the result is indeterminate, but where there
is none the less a convention for the result.  If not defined then
defaults to `ignore_error`, but can be set to any of the enumerated
actions for error handing: `throw_on_error`, `errno_on_error`, 
`ignore_error` or `user_error`.

[h5 BOOST_MATH_DIGITS10_POLICY]

Defines how many decimal digits to use in internal computations: 
defaults to `0` - meaning use all available digits - but can be set
to some other decimal value.  Since setting this is likely to have
a substantial impact on accuracy, it's not generally recommended
that you change this from the default.

[h5 BOOST_MATH_PROMOTE_FLOAT_POLICY]

Determines whether `float` types get promoted to `double`
internally to ensure maximum precision in the result, defaults
to `true`, but can be set to `false` to turn promotion of
`float`'s off.

[h5 BOOST_MATH_PROMOTE_DOUBLE_POLICY]

Determines whether `double` types get promoted to `long double`
internally to ensure maximum precision in the result, defaults
to `true`, but can be set to `false` to turn promotion of
`double`'s off.

[h5 BOOST_MATH_DISCRETE_QUANTILE_POLICY]

Determines how discrete quantiles return their results: either
as an integer, or as a real value, can be set to one of the
enumerated values: `real`, `integer_round_outwards`, `integer_round_inwards`,
`integer_round_down`, `integer_round_up`, `integer_round_nearest`.  Defaults to
`integer_round_outwards`.

[h5 BOOST_MATH_ASSERT_UNDEFINED_POLICY]

Determines whether functions that are mathematically undefined
for a specific distribution compile or raise a static (i.e. compile-time)
assertion.  Defaults to `true`: meaning that any mathematically
undefined function will not compile.  When set to `false` then the function
will compile but return the result of a domain error: this can be useful
for some generic code, that needs to work with all distributions and determine
at runtime whether or not a particular property is well defined.

[h5 BOOST_MATH_MAX_SERIES_ITERATION_POLICY]

Determines how many series iterations a special function is permitted
to perform before it gives up and returns an __evaluation_error:
Defaults to 1000000.
   
[h5 BOOST_MATH_MAX_ROOT_ITERATION_POLICY]

Determines how many root-finding iterations a special function is permitted
to perform before it gives up and returns an __evaluation_error:
Defaults to 200.

[h5 Example]

Suppose we want overflow errors to set `::errno` and return an infinity,
discrete quantiles to return a real-valued result (rather than round to
integer), and for mathematically undefined functions to compile, but return
a domain error. Then we could add the following to boost/math/tools/user.hpp:

   #define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error
   #define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
   #define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
   
or we could place these definitions *before*

   #include <boost/math/distributions/normal.hpp>
     using boost::math::normal_distribution;

in a source .cpp file.

[endsect] [/section:policy_defaults Changing the Policy Defaults]

[section:namespace_pol Setting Polices at Namespace Scope]

Sometimes what you really want to do is bring all the special functions,
or all the distributions into a specific namespace-scope, along with
a specific policy to use with them.  There are two macros defined to
assist with that:

   BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)

and:

   BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)
   
You can use either of these macros after including any special function
or distribution header.  For example:

[import ../../example/policy_ref_snip12.cpp]

[policy_ref_snip12]

In this example, using BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS results in
a set of thin inline forwarding functions being defined:

   template <class T>
   inline T tgamma(T a){ return ::boost::math::tgamma(a, mypolicy()); }
   
   template <class T>
   inline T lgamma(T a) ( return ::boost::math::lgamma(a, mypolicy()); }
   
and so on.  Note that while a forwarding function is defined for all the special
functions, however, unless you include the specific header for the special
function you use (or boost/math/special_functions.hpp to include everything), 
you will get linker errors from functions that are forward declared, but not
defined.

We can do the same thing with the distributions, but this time we need to
specify the floating-point type to use:

[import ../../example/policy_ref_snip13.cpp]

[policy_ref_snip13]
   
In this example the result of BOOST_MATH_DECLARE_DISTRIBUTIONS is to
declare a typedef for each distribution like this:

   typedef boost::math::cauchy_distribution<double, my_policy> cauchy;
   tyepdef boost::math::gamma_distribution<double, my_policy> gamma;
   
and so on.  The name given to each typedef is the name of the distribution
with the "_distribution" suffix removed.

[endsect] [/section Changing the Policy Defaults]

[section:pol_ref_ref Policy Class Reference]

There's very little to say here, the `policy` class is just a rag-bag
compile-time container for a collection of policies:

```#include <boost/math/policies/policy.hpp>```


   namespace boost{
   namespace math{
   namespace policies
   
   template <class A1 = default_policy, 
             class A2 = default_policy, 
             class A3 = default_policy,
             class A4 = default_policy,
             class A5 = default_policy,
             class A6 = default_policy,
             class A7 = default_policy,
             class A8 = default_policy,
             class A9 = default_policy,
             class A10 = default_policy,
             class A11 = default_policy,
             class A12 = default_policy,
             class A13 = default_policy>
   struct policy
   {
   public:
      typedef ``['computed-from-template-arguments]`` domain_error_type;
      typedef ``['computed-from-template-arguments]`` pole_error_type;
      typedef ``['computed-from-template-arguments]`` overflow_error_type;
      typedef ``['computed-from-template-arguments]`` underflow_error_type;
      typedef ``['computed-from-template-arguments]`` denorm_error_type;
      typedef ``['computed-from-template-arguments]`` rounding_error_type;
      typedef ``['computed-from-template-arguments]`` evaluation_error_type;
      typedef ``['computed-from-template-arguments]`` indeterminate_result_error_type;
      typedef ``['computed-from-template-arguments]`` precision_type;
      typedef ``['computed-from-template-arguments]`` promote_float_type;
      typedef ``['computed-from-template-arguments]`` promote_double_type;
      typedef ``['computed-from-template-arguments]`` discrete_quantile_type;
      typedef ``['computed-from-template-arguments]`` assert_undefined_type;
   };

   template <...argument list...>
   typename normalise<policy<>, A1>::type make_policy(...argument list..);

   template <class Policy, 
             class A1 = default_policy, 
             class A2 = default_policy, 
             class A3 = default_policy,
             class A4 = default_policy,
             class A5 = default_policy,
             class A6 = default_policy,
             class A7 = default_policy,
             class A8 = default_policy,
             class A9 = default_policy,
             class A10 = default_policy,
             class A11 = default_policy,
             class A12 = default_policy,
             class A13 = default_policy>
   struct normalise
   {
      typedef ``computed-from-template-arguments`` type;
   };

The member typedefs of class `policy` are intended for internal use
but are documented briefly here for the sake of completeness.

   policy<...>::domain_error_type
   
Specifies how domain errors are handled, will be an instance of
`boost::math::policies::domain_error<>` with the template argument to
`domain_error` one of the `error_policy_type` enumerated values.

   policy<...>::pole_error_type
   
Specifies how pole-errors are handled, will be an instance of
`boost::math::policies::pole_error<>` with the template argument to
`pole_error` one of the `error_policy_type` enumerated values.

   policy<...>::overflow_error_type
   
Specifies how overflow errors are handled, will be an instance of
`boost::math::policies::overflow_error<>` with the template argument to
`overflow_error` one of the `error_policy_type` enumerated values.

   policy<...>::underflow_error_type
   
Specifies how underflow errors are handled, will be an instance of
`boost::math::policies::underflow_error<>` with the template argument to
`underflow_error` one of the `error_policy_type` enumerated values.

   policy<...>::denorm_error_type
   
Specifies how denorm errors are handled, will be an instance of
`boost::math::policies::denorm_error<>` with the template argument to
`denorm_error` one of the `error_policy_type` enumerated values.

   policy<...>::rounding_error_type
   
Specifies how rounding errors are handled, will be an instance of
`boost::math::policies::rounding_error<>` with the template argument to
`rounding_error` one of the `error_policy_type` enumerated values.

   policy<...>::evaluation_error_type
   
Specifies how evaluation errors are handled, will be an instance of
`boost::math::policies::evaluation_error<>` with the template argument to
`evaluation_error` one of the `error_policy_type` enumerated values.

   policy<...>::indeterminate_error_type

Specifies how indeterminate result errors are handled, will be an instance of
`boost::math::policies::indeterminate_result_error<>` with the template argument
to `indeterminate_result_error` one of the `error_policy_type` enumerated
values.

   policy<...>::precision_type
   
Specifies the internal precision to use in binary digits (uses zero
to represent whatever the default precision is).  Will be an instance
of `boost::math::policies::digits2<N>` which in turn inherits from 
`boost::boost::integral_constant<int, N>`.

   policy<...>::promote_float_type
   
Specifies whether or not to promote `float` arguments to `double` precision
internally.  Will be an instance of `boost::math::policies::promote_float<B>`
which in turn inherits from `boost::integral_constant<bool, B>`.

   policy<...>::promote_double_type
   
Specifies whether or not to promote `double` arguments to `long double` precision
internally.  Will be an instance of `boost::math::policies::promote_float<B>`
which in turn inherits from `boost::integral_constant<bool, B>`.

   policy<...>::discrete_quantile_type
   
Specifies how discrete quantiles are evaluated, will be an instance
of `boost::math::policies::discrete_quantile<>` instantiated with one of
the `discrete_quantile_policy_type` enumerated type.

   policy<...>::assert_undefined_type
   
Specifies whether mathematically-undefined properties are
asserted as compile-time errors, or treated as runtime errors
instead.  Will be an instance of `boost::math::policies::assert_undefined<B>`
which in turn inherits from `boost::integral_constant<bool, B>`.


   template <...argument list...>
   typename normalise<policy<>, A1>::type make_policy(...argument list..);

`make_policy` is a helper function that converts a list of policies into
a normalised `policy` class.

   template <class Policy, 
             class A1 = default_policy, 
             class A2 = default_policy, 
             class A3 = default_policy,
             class A4 = default_policy,
             class A5 = default_policy,
             class A6 = default_policy,
             class A7 = default_policy,
             class A8 = default_policy,
             class A9 = default_policy,
             class A10 = default_policy,
             class A11 = default_policy,
             class A12 = default_policy,
             class A13 = default_policy>
   struct normalise
   {
      typedef ``computed-from-template-arguments`` type;
   };
   
The `normalise` class template converts one instantiation of the
`policy` class into a normalised form.  This is used internally
to reduce code bloat: so that instantiating a special function
on `policy<A,B>` or `policy<B,A>` actually both generate the same
code internally.  

Further more, `normalise` can be used to combine
a policy with one or more policies: for example many of the
special functions will use this to set policies which they don't
make use of to their default values, before forwarding to the actual
implementation.  In this way code bloat is reduced, since the
actual implementation depends only on the policy types that they
actually use.

[endsect] [/section:pol_ref_ref Policy Class Reference]

[endsect] [/section:pol_ref Policy Reference]
[endmathpart] [/section:policy Policies]

[/ policy.qbk
  Copyright 2007, 2010 John Maddock and Paul A. Bristow.
  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
]