]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
14 | There 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 | ||
21 | What 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 | ||
35 | The various enumerated values have the following meanings: | |
36 | ||
37 | [h5 throw_on_error] | |
38 | ||
39 | Will 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 | ||
54 | Will set global __errno `::errno` to one of the following values depending | |
55 | upon the error type (often EDOM = 33 and ERANGE = 34), | |
56 | and then return the same value as if the error | |
57 | had 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 | ||
71 | Will 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 | ||
86 | Will call a user defined error handler: these are forward declared | |
87 | in boost/math/policies/error_handling.hpp, but the actual definitions | |
88 | must 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 | ||
118 | Note that the strings ['function] and ['message] may contain "%1%" format specifiers | |
119 | designed to be used in conjunction with Boost.Format. | |
120 | If these strings are to be presented to the program's end-user then | |
121 | the "%1%" format specifier | |
122 | should be replaced with the name of type T in the ['function] string, and | |
123 | if there is a %1% specifier in the ['message] string then it | |
124 | should be replaced with the value of ['val]. | |
125 | ||
126 | There is more information on user-defined error handlers in | |
127 | the [link math_toolkit.pol_tutorial.user_def_err_pol | |
128 | tutorial here]. | |
129 | ||
130 | [h4 Kinds of Error Raised] | |
131 | ||
132 | There are six kinds of error reported by this library, | |
133 | which 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 | ||
214 | Suppose 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 | |
216 | using: | |
217 | ||
218 | [import ../../example/policy_ref_snip1.cpp] | |
219 | ||
220 | [policy_ref_snip1] | |
221 | ||
222 | Suppose we want a statistical distribution to return infinities, | |
223 | rather 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 | ||
233 | Normally when evaluating a function at say `float` precision, maximal | |
234 | accuracy is assured by conducting the calculation at `double` precision | |
235 | internally, and then rounding the result. There are two policies that | |
236 | control 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 | ||
250 | Suppose 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 | ||
256 | Alternatively, suppose we want a distribution to perform calculations | |
257 | without 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 | ||
266 | There are some functions that are generic | |
267 | (they are present for all the statistical distributions supported) | |
268 | but which may be mathematically undefined for certain distributions, but defined for others. | |
269 | ||
270 | For example, the Cauchy distribution does not have a meaningful mean, | |
271 | so what should | |
272 | ||
273 | mean(cauchy<>()); | |
274 | ||
275 | return, and should such an expression even compile at all? | |
276 | ||
277 | The 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 | |
281 | we 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 | ||
284 | This 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 | ||
293 | For 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 | ||
310 | at 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 | ||
316 | If a statistical distribution is ['discrete] then the random variable | |
317 | can only have integer values - this leaves us with a problem when calculating | |
318 | quantiles - we can either ignore the discreteness of the distribution and return | |
319 | a real value, or we can round to an integer. As it happens, computing integer | |
320 | values can be substantially faster than calculating a real value, so there are | |
321 | definite advantages to returning an integer, but we do then need to decide | |
322 | how best to round the result. The `discrete_quantile` policy defines how | |
323 | discrete 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 | ||
338 | The values that `discrete_quantile` can take have the following meanings: | |
339 | ||
340 | [h5 real] | |
341 | ||
342 | Ignores the discreteness of the distribution, and returns a real-valued | |
343 | result. For example: | |
344 | ||
345 | [import ../../example/policy_ref_snip5.cpp] | |
346 | [policy_ref_snip5] | |
347 | ||
348 | Results in `x = 27.3898` and `y = 68.1584`. | |
349 | ||
350 | [h5 integer_round_outwards] | |
351 | ||
352 | This 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 | |
355 | down. | |
356 | * Upper quantiles (where the probability is greater than 0.5) are rounded up. | |
357 | ||
358 | This is normally the safest rounding policy, since it ensures that both | |
359 | one and two sided intervals are guaranteed to have ['at least] | |
360 | the requested coverage. For example: | |
361 | ||
362 | [import ../../example/policy_ref_snip6.cpp] | |
363 | [policy_ref_snip6] | |
364 | ||
365 | Results in `x = 27` (rounded down from 27.3898) and `y = 69` (rounded up from 68.1584). | |
366 | ||
367 | The 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 | ||
372 | In other words we guarantee ['at least 90% coverage in the central region overall], | |
373 | and also ['no more than 5% coverage in each tail]. | |
374 | ||
375 | [h5 integer_round_inwards] | |
376 | ||
377 | This 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 | ||
383 | For example: | |
384 | ||
385 | [import ../../example/policy_ref_snip7.cpp] | |
386 | ||
387 | [policy_ref_snip7] | |
388 | ||
389 | Results in `x = 28` (rounded up from 27.3898) and `y = 68` (rounded down from 68.1584). | |
390 | ||
391 | The 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 | ||
396 | In other words we guarantee ['at no more than 90% coverage in the central region overall], | |
397 | and also ['at least 5% coverage in each tail]. | |
398 | ||
399 | [h5 integer_round_down] | |
400 | ||
401 | Always rounds down to an integer value, no matter whether it's an upper | |
402 | or a lower quantile. | |
403 | ||
404 | [h5 integer_round_up] | |
405 | ||
406 | Always rounds up to an integer value, no matter whether it's an upper | |
407 | or a lower quantile. | |
408 | ||
409 | [h5 integer_round_nearest] | |
410 | ||
411 | Always rounds to the nearest integer value, no matter whether it's an upper | |
412 | or a lower quantile. This will produce the requested coverage | |
413 | ['in the average case], but for any specific example may results in | |
414 | either significantly more or less coverage than the requested amount. | |
415 | For example: | |
416 | ||
417 | For example: | |
418 | ||
419 | [import ../../example/policy_ref_snip8.cpp] | |
420 | ||
421 | [policy_ref_snip8] | |
422 | ||
423 | Results 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 | ||
429 | There are two equivalent policies that effect the ['working precision] | |
430 | used to calculate results, these policies both default to 0 - meaning | |
431 | calculate to the maximum precision available in the type being used | |
432 | - but can be set to other values to cause lower levels of precision | |
433 | to 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 | ||
445 | As you would expect, ['digits10] specifies the number of decimal digits | |
446 | to use, and ['digits2] the number of binary digits. Internally, whichever | |
447 | is used, the precision is always converted to ['binary digits]. | |
448 | ||
449 | These policies are specified at compile-time, because many of the special | |
450 | functions use compile-time-dispatch to select which approximation to use | |
451 | based on the precision requested and the numeric type being used. | |
452 | ||
453 | For 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 | ||
459 | Or again using helper function `make_policy`: | |
460 | ||
461 | [import ../../example/policy_ref_snip10.cpp] | |
462 | ||
463 | [policy_ref_snip10] | |
464 | ||
465 | And 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 | ||
475 | There are two policies that effect the iterative algorithms | |
476 | used 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 | ||
484 | The class `max_series_iterations` determines the maximum number of | |
485 | iterations permitted in a series evaluation, before the special | |
486 | function gives up and returns the result of __evaluation_error. | |
487 | ||
488 | The class `max_root_iterations` determines the maximum number | |
489 | of iterations permitted in a root-finding algorithm before the special | |
490 | function 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 | ||
496 | You can use the various macros below to change any (or all) of the policies. | |
497 | ||
498 | You can make a local change by placing a macro definition *before* | |
499 | a function or distribution #include. | |
500 | ||
501 | [caution There is a danger of One-Definition-Rule violations if you | |
502 | add ad-hoc macros to more than one source files: these must be set the same in *every | |
503 | translation 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). | |
507 | This is probably not what you intend!] | |
508 | ||
509 | If you want to alter the defaults for any or all of | |
510 | the policies for *all* functions and distributions, installation-wide, | |
511 | then 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 | ||
516 | Defines what happens when a domain error occurs, if not defined then | |
517 | defaults to `throw_on_error`, but can be set to any of the enumerated | |
518 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
519 | `ignore_error` or `user_error`. | |
520 | ||
521 | [h5 BOOST_MATH_POLE_ERROR_POLICY] | |
522 | ||
523 | Defines what happens when a pole error occurs, if not defined then | |
524 | defaults to `throw_on_error`, but can be set to any of the enumerated | |
525 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
526 | `ignore_error` or `user_error`. | |
527 | ||
528 | [h5 BOOST_MATH_OVERFLOW_ERROR_POLICY] | |
529 | ||
530 | Defines what happens when an overflow error occurs, if not defined then | |
531 | defaults to `throw_on_error`, but can be set to any of the enumerated | |
532 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
533 | `ignore_error` or `user_error`. | |
534 | ||
535 | [h5 BOOST_MATH_ROUNDING_ERROR_POLICY] | |
536 | ||
537 | Defines what happens when a rounding error occurs, if not defined then | |
538 | defaults to `throw_on_error`, but can be set to any of the enumerated | |
539 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
540 | `ignore_error` or `user_error`. | |
541 | ||
542 | [h5 BOOST_MATH_EVALUATION_ERROR_POLICY] | |
543 | ||
544 | Defines what happens when an internal evaluation error occurs, if not defined then | |
545 | defaults to `throw_on_error`, but can be set to any of the enumerated | |
546 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
547 | `ignore_error` or `user_error`. | |
548 | ||
549 | [h5 BOOST_MATH_UNDERFLOW_ERROR_POLICY] | |
550 | ||
551 | Defines what happens when an overflow error occurs, if not defined then | |
552 | defaults to `ignore_error`, but can be set to any of the enumerated | |
553 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
554 | `ignore_error` or `user_error`. | |
555 | ||
556 | [h5 BOOST_MATH_DENORM_ERROR_POLICY] | |
557 | ||
558 | Defines what happens when a denormalisation error occurs, if not defined then | |
559 | defaults to `ignore_error`, but can be set to any of the enumerated | |
560 | actions 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 | ||
565 | Defines what happens when the result is indeterminate, but where there | |
566 | is none the less a convention for the result. If not defined then | |
567 | defaults to `ignore_error`, but can be set to any of the enumerated | |
568 | actions for error handing: `throw_on_error`, `errno_on_error`, | |
569 | `ignore_error` or `user_error`. | |
570 | ||
571 | [h5 BOOST_MATH_DIGITS10_POLICY] | |
572 | ||
573 | Defines how many decimal digits to use in internal computations: | |
574 | defaults to `0` - meaning use all available digits - but can be set | |
575 | to some other decimal value. Since setting this is likely to have | |
576 | a substantial impact on accuracy, it's not generally recommended | |
577 | that you change this from the default. | |
578 | ||
579 | [h5 BOOST_MATH_PROMOTE_FLOAT_POLICY] | |
580 | ||
581 | Determines whether `float` types get promoted to `double` | |
582 | internally to ensure maximum precision in the result, defaults | |
583 | to `true`, but can be set to `false` to turn promotion of | |
584 | `float`'s off. | |
585 | ||
586 | [h5 BOOST_MATH_PROMOTE_DOUBLE_POLICY] | |
587 | ||
588 | Determines whether `double` types get promoted to `long double` | |
589 | internally to ensure maximum precision in the result, defaults | |
590 | to `true`, but can be set to `false` to turn promotion of | |
591 | `double`'s off. | |
592 | ||
593 | [h5 BOOST_MATH_DISCRETE_QUANTILE_POLICY] | |
594 | ||
595 | Determines how discrete quantiles return their results: either | |
596 | as an integer, or as a real value, can be set to one of the | |
597 | enumerated 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 | ||
603 | Determines whether functions that are mathematically undefined | |
604 | for a specific distribution compile or raise a static (i.e. compile-time) | |
605 | assertion. Defaults to `true`: meaning that any mathematically | |
606 | undefined function will not compile. When set to `false` then the function | |
607 | will compile but return the result of a domain error: this can be useful | |
608 | for some generic code, that needs to work with all distributions and determine | |
609 | at runtime whether or not a particular property is well defined. | |
610 | ||
611 | [h5 BOOST_MATH_MAX_SERIES_ITERATION_POLICY] | |
612 | ||
613 | Determines how many series iterations a special function is permitted | |
614 | to perform before it gives up and returns an __evaluation_error: | |
615 | Defaults to 1000000. | |
616 | ||
617 | [h5 BOOST_MATH_MAX_ROOT_ITERATION_POLICY] | |
618 | ||
619 | Determines how many root-finding iterations a special function is permitted | |
620 | to perform before it gives up and returns an __evaluation_error: | |
621 | Defaults to 200. | |
622 | ||
623 | [h5 Example] | |
624 | ||
625 | Suppose we want overflow errors to set `::errno` and return an infinity, | |
626 | discrete quantiles to return a real-valued result (rather than round to | |
627 | integer), and for mathematically undefined functions to compile, but return | |
628 | a 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 | ||
634 | or we could place these definitions *before* | |
635 | ||
636 | #include <boost/math/distributions/normal.hpp> | |
637 | using boost::math::normal_distribution; | |
638 | ||
639 | in 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 | ||
645 | Sometimes what you really want to do is bring all the special functions, | |
646 | or all the distributions into a specific namespace-scope, along with | |
647 | a specific policy to use with them. There are two macros defined to | |
648 | assist with that: | |
649 | ||
650 | BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy) | |
651 | ||
652 | and: | |
653 | ||
654 | BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy) | |
655 | ||
656 | You can use either of these macros after including any special function | |
657 | or distribution header. For example: | |
658 | ||
659 | [import ../../example/policy_ref_snip12.cpp] | |
660 | ||
661 | [policy_ref_snip12] | |
662 | ||
663 | In this example, using BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS results in | |
664 | a 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 | ||
672 | and so on. Note that while a forwarding function is defined for all the special | |
673 | functions, however, unless you include the specific header for the special | |
674 | function you use (or boost/math/special_functions.hpp to include everything), | |
675 | you will get linker errors from functions that are forward declared, but not | |
676 | defined. | |
677 | ||
678 | We can do the same thing with the distributions, but this time we need to | |
679 | specify the floating-point type to use: | |
680 | ||
681 | [import ../../example/policy_ref_snip13.cpp] | |
682 | ||
683 | [policy_ref_snip13] | |
684 | ||
685 | In this example the result of BOOST_MATH_DECLARE_DISTRIBUTIONS is to | |
686 | declare 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 | ||
691 | and so on. The name given to each typedef is the name of the distribution | |
692 | with the "_distribution" suffix removed. | |
693 | ||
694 | [endsect][/section Changing the Policy Defaults] | |
695 | ||
696 | [section:pol_ref_ref Policy Class Reference] | |
697 | ||
698 | There's very little to say here, the `policy` class is just a rag-bag | |
699 | compile-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 | ||
761 | The member typedefs of class `policy` are intended for internal use | |
762 | but are documented briefly here for the sake of completeness. | |
763 | ||
764 | policy<...>::domain_error_type | |
765 | ||
766 | Specifies 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 | ||
772 | Specifies 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 | ||
778 | Specifies 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 | ||
784 | Specifies 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 | ||
790 | Specifies 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 | ||
796 | Specifies 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 | ||
802 | Specifies 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 | ||
808 | Specifies how indeterminate result errors are handled, will be an instance of | |
809 | `boost::math::policies::indeterminate_result_error<>` with the template argument | |
810 | to `indeterminate_result_error` one of the `error_policy_type` enumerated | |
811 | values. | |
812 | ||
813 | policy<...>::precision_type | |
814 | ||
815 | Specifies the internal precision to use in binary digits (uses zero | |
816 | to represent whatever the default precision is). Will be an instance | |
817 | of `boost::math::policies::digits2<N>` which in turn inherits from | |
818 | `boost::mpl::int_<N>`. | |
819 | ||
820 | policy<...>::promote_float_type | |
821 | ||
822 | Specifies whether or not to promote `float` arguments to `double` precision | |
823 | internally. Will be an instance of `boost::math::policies::promote_float<B>` | |
824 | which in turn inherits from `boost::mpl::bool_<B>`. | |
825 | ||
826 | policy<...>::promote_double_type | |
827 | ||
828 | Specifies whether or not to promote `double` arguments to `long double` precision | |
829 | internally. Will be an instance of `boost::math::policies::promote_float<B>` | |
830 | which in turn inherits from `boost::mpl::bool_<B>`. | |
831 | ||
832 | policy<...>::discrete_quantile_type | |
833 | ||
834 | Specifies how discrete quantiles are evaluated, will be an instance | |
835 | of `boost::math::policies::discrete_quantile<>` instantiated with one of | |
836 | the `discrete_quantile_policy_type` enumerated type. | |
837 | ||
838 | policy<...>::assert_undefined_type | |
839 | ||
840 | Specifies whether mathematically-undefined properties are | |
841 | asserted as compile-time errors, or treated as runtime errors | |
842 | instead. Will be an instance of `boost::math::policies::assert_undefined<B>` | |
843 | which in turn inherits from `boost::math::mpl::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 | |
850 | a 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 | ||
871 | The `normalise` class template converts one instantiation of the | |
872 | `policy` class into a normalised form. This is used internally | |
873 | to reduce code bloat: so that instantiating a special function | |
874 | on `policy<A,B>` or `policy<B,A>` actually both generate the same | |
875 | code internally. | |
876 | ||
877 | Further more, `normalise` can be used to combine | |
878 | a policy with one or more policies: for example many of the | |
879 | special functions will use this to set policies which they don't | |
880 | make use of to their default values, before forwarding to the actual | |
881 | implementation. In this way code bloat is reduced, since the | |
882 | actual implementation depends only on the policy types that they | |
883 | actually 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 | [/ 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 |