Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / math / doc / overview / error_handling.qbk
1 [section:error_handling Error Handling]
2
3 [def __format [@../../../format/index.html Boost.Format]]
4
5 [heading Quick Reference]
6
7 Handling of errors by this library is split into two orthogonal parts:
8
9 * What kind of error has been raised?
10 * What should be done when the error is raised?
11
12 [warning The default error actions are to throw an exception with an informative error message.
13 If you do not try to catch the exception, you will not see the message!]
14
15 The kinds of errors that can be raised are:
16
17 [variablelist
18 [[Domain Error][Occurs when one or more arguments to a function 
19   are out of range.]]
20 [[Pole Error][Occurs when the particular arguments cause the function to be
21    evaluated at a pole with no well defined residual value.  For example if
22    __tgamma is evaluated at exactly -2, the function approaches different limiting
23    values depending upon whether you approach from just above or just below
24    -2.  Hence the function has no well defined value at this point and a 
25    Pole Error will be raised.]]
26 [[Overflow Error][Occurs when the result is either infinite, or too large
27    to represent in the numeric type being returned by the function.]]
28 [[Underflow Error][Occurs when the result is not zero, but is too small
29    to be represented by any other value in the type being returned by 
30    the function.]]
31 [[Denormalisation Error][Occurs when the returned result would be a denormalised value.]]
32 [[Rounding Error][Occurs when the argument to one of the rounding functions __trunc, 
33    __round and __modf can not be represented as an integer type, is
34    outside the range of the result type.]]
35 [[Evaluation Error][Occurs if no method of evaluation is known,
36    or when an internal error occurred that prevented the
37    result from being evaluated: this should never occur, but if it does, then
38    it's likely to be due to an iterative method not converging fast enough.]]
39 [[Indeterminate Result Error][Occurs when the result of a function is not
40    defined for the values that were passed to it.]]
41 ]
42
43 The action undertaken by each error condition is determined by the current
44 __Policy in effect.  This can be changed program-wide by setting some 
45 configuration macros, or at namespace scope, or at the call site (by
46 specifying a specific policy in the function call).
47
48 The available actions are:
49
50 [variablelist
51 [[throw_on_error][Throws the exception most appropriate to the error condition.]]
52 [[errno_on_error][Sets ::errno to an appropriate value, and then returns the most
53 appropriate result]]
54 [[ignore_error][Ignores the error and simply the returns the most appropriate result.]]
55 [[user_error][Calls a 
56    [link math_toolkit.pol_tutorial.user_def_err_pol user-supplied error handler].]]
57 ]
58
59 The following tables show all the permutations of errors and actions, 
60 with the *default action for each error shown in bold*:
61
62 [table Possible Actions for Domain Errors
63 [[Action]         [Behaviour]]
64 [[throw_on_error][[*Throws `std::domain_error`]]]
65 [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]]
66 [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]]
67 [[user_error][Returns the result of `boost::math::policies::user_domain_error`: 
68             [link math_toolkit.pol_tutorial.user_def_err_pol 
69             this function must be defined by the user].]]
70 ]
71     
72 [table Possible Actions for Pole Errors
73 [[Action]   [Behaviour]]
74 [[throw_on_error]   [[*Throws `std::domain_error`]]]
75 [[errno_on_error][Sets `::errno` to `EDOM` and returns `std::numeric_limits<T>::quiet_NaN()`]]
76 [[ignore_error][Returns `std::numeric_limits<T>::quiet_NaN()`]]
77 [[user_error][Returns the result of `boost::math::policies::user_pole_error`: 
78             [link math_toolkit.pol_tutorial.user_def_err_pol 
79             this function must be defined by the user].]]
80 ]
81
82 [table Possible Actions for Overflow Errors
83 [[Action]   [Behaviour]]
84 [[throw_on_error][[*Throws `std::overflow_error`]]]
85 [[errno_on_error][Sets `::errno` to `ERANGE` and returns `std::numeric_limits<T>::infinity()`]]
86 [[ignore_error][Returns `std::numeric_limits<T>::infinity()`]]
87 [[user_error][Returns the result of `boost::math::policies::user_overflow_error`: 
88             [link math_toolkit.pol_tutorial.user_def_err_pol 
89             this function must be defined by the user].]]
90 ]
91
92 [table Possible Actions for Underflow Errors
93 [[Action]   [Behaviour]]
94 [[throw_on_error][Throws `std::underflow_error`]]
95 [[errno_on_error][Sets `::errno` to `ERANGE` and returns 0.]]
96 [[ignore_error][[*Returns 0]]]
97 [[user_error][Returns the result of `boost::math::policies::user_underflow_error`: 
98             [link math_toolkit.pol_tutorial.user_def_err_pol 
99             this function must be defined by the user].]]
100 ]
101
102 [table Possible Actions for Denorm Errors
103 [[Action]   [Behaviour]]
104 [[throw_on_error][Throws `std::underflow_error`]]
105 [[errno_on_error][Sets `::errno` to `ERANGE` and returns the denormalised value.]]
106 [[ignore_error][[*Returns the denormalised value.]]]
107 [[user_error][Returns the result of `boost::math::policies::user_denorm_error`: 
108             [link math_toolkit.pol_tutorial.user_def_err_pol 
109             this function must be defined by the user].]]
110 ]
111
112 [table Possible Actions for Rounding Errors
113 [[Action]   [Behaviour]]
114 [[throw_on_error][Throws `boost::math::rounding_error`]]
115 [[errno_on_error][Sets `::errno` to `ERANGE` and returns the largest representable value of the target integer type 
116 (or the most negative value if the argument to the function was less than zero).]]
117 [[ignore_error][[*Returns the largest representable value of the target integer type 
118 (or the most negative value if the argument to the function was less than zero).]]]
119 [[user_error][Returns the result of `boost::math::policies::user_rounding_error`: 
120             [link math_toolkit.pol_tutorial.user_def_err_pol 
121             this function must be defined by the user].]]
122 ]
123
124 [table Possible Actions for Internal Evaluation Errors
125 [[Action]   [Behaviour]]
126 [[throw_on_error][[*Throws `boost::math::evaluation_error`]]]
127 [[errno_on_error][Sets `::errno` to `EDOM` and returns the closest approximation found.]]
128 [[ignore_error][Returns the closest approximation found.]]
129 [[user_error][Returns the result of `boost::math::policies::user_evaluation_error`: 
130             [link math_toolkit.pol_tutorial.user_def_err_pol 
131             this function must be defined by the user].]]
132 ]
133
134 [table Possible Actions for Indeterminate Result Errors
135 [[Action]   [Behaviour]]
136 [[throw_on_error][Throws `std::domain_error`]]
137 [[errno_on_error][Sets `::errno` to `EDOM` and returns the same value as `ignore_error`.]]
138 [[ignore_error][[*Returns a default result that depends on the function where the error occurred.]]]
139 [[user_error][Returns the result of `boost::math::policies::user_indeterminate_result_error`:
140             [link math_toolkit.pol_tutorial.user_def_err_pol 
141             this function must be defined by the user].]]
142 ]
143
144 All these error conditions are in namespace boost::math::policies,
145 made available, for example, a by namespace declaration
146 using `namespace boost::math::policies;` or individual using declarations
147 `using boost::math::policies::overflow_error;`.
148
149 [heading Rationale]
150
151 The flexibility of the current implementation should be reasonably obvious: the
152 default behaviours were chosen based on feedback during the formal review of 
153 this library.  It was felt that: 
154
155 * Genuine errors should be flagged with exceptions
156 rather than following C-compatible behaviour and setting `::errno`.
157 * Numeric underflow and denormalised results were not considered to be
158 fatal errors in most cases, so it was felt that these should be ignored.
159 * If there is more than one error,
160 only the first detected will be reported in the throw message.
161
162 [heading Finding More Information]
163
164 There are some pre-processor macro defines that can be used to
165 [link math_toolkit.pol_ref.policy_defaults
166 change the policy defaults].  See also the [link policy 
167 policy section].
168
169 An example is at the Policy tutorial in
170 [link math_toolkit.pol_tutorial.changing_policy_defaults 
171 Changing the Policy Defaults].
172
173 Full source code of this typical example of passing a 'bad' argument
174 (negative degrees of freedom) to Student's t distribution 
175 is [link math_toolkit.stat_tut.weg.error_eg in the error handling example].
176
177 The various kind of errors are described in more detail below.
178
179 [heading:domain_error Domain Errors]
180
181 When a special function is passed an argument that is outside the range
182 of values for which that function is defined, then the function returns
183 the result of:
184
185    boost::math::policies::raise_domain_error<T>(FunctionName, Message, Val, __Policy);
186    
187 Where
188 `T` is the floating-point type passed to the function, `FunctionName` is the 
189 name of the function, `Message` is an error message describing the problem, 
190 Val is the value that was out of range, and __Policy is the current policy
191 in use for the function that was called.
192
193 The default policy behaviour of this function is to throw a 
194 std::domain_error C++ exception.  But if the __Policy is to ignore
195 the error, or set global `::errno`, then a NaN will be returned.
196
197 This behaviour is chosen to assist compatibility with the behaviour of 
198 ['ISO/IEC 9899:1999 Programming languages - C]
199 and with the
200 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Draft Technical Report on C++ Library Extensions, 2005-06-24, section 5.2.1, paragraph 6]:
201
202 [:['"Each of the functions declared above shall return a NaN (Not a Number)
203 if any argument value is a NaN, but it shall not report a domain error.
204 Otherwise, each of the functions declared above shall report a domain error
205 for just those argument values for which:]]
206
207 [:['"the function description's Returns clause explicitly specifies a domain, and those arguments fall outside the specified domain; or]
208
209 ['"the corresponding mathematical function value has a non-zero imaginary component; or]
210
211 ['"the corresponding mathematical function is not mathematically defined.]]
212
213 [:['"Note 2: A mathematical function is mathematically defined
214 for a given set of argument values if it is explicitly defined
215 for that set of argument values or
216 if its limiting value exists and does not depend on the direction of approach."]]
217
218 Note that in order to support information-rich error messages when throwing
219 exceptions, `Message` must contain
220 a __format recognised format specifier: the argument `Val` is inserted into
221 the error message according to the specifier used.
222
223 For example if `Message` contains a "%1%" then it is replaced by the value of
224 `Val` to the full precision of T, where as "%.3g" would contain the value of
225 `Val` to 3 digits.  See the __format documentation for more details.
226
227 [heading:pole_error Evaluation at a pole]
228
229 When a special function is passed an argument that is at a pole
230 without a well defined residual value, then the function returns
231 the result of:
232
233    boost::math::policies::raise_pole_error<T>(FunctionName, Message, Val, __Policy);
234    
235 Where
236 `T` is the floating point type passed to the function, `FunctionName` is the 
237 name of the function, `Message` is an error message describing the problem, 
238 `Val` is the value of the argument that is at a pole, and __Policy is the 
239 current policy in use for the function that was called.
240
241 The default behaviour of this function is to throw a std::domain_error exception.
242 But __error_policy can be used to change this, for example to `ignore_error`
243 and return NaN.
244
245 Note that in order to support information-rich error messages when throwing
246 exceptions, `Message` must contain
247 a __format recognised format specifier: the argument `val` is inserted into
248 the error message according to the specifier used.
249
250 For example if `Message` contains a "%1%" then it is replaced by the value of
251 `val` to the full precision of T, where as "%.3g" would contain the value of
252 `val` to 3 digits.  See the __format documentation for more details.
253
254 [heading:overflow_error Numeric Overflow]
255
256 When the result of a special function is too large to fit in the argument
257 floating-point type, then the function returns the result of:
258
259    boost::math::policies::raise_overflow_error<T>(FunctionName, Message, __Policy);
260    
261 Where
262 `T` is the floating-point type passed to the function, `FunctionName` is the 
263 name of the function, `Message` is an error message describing the problem,
264 and __Policy is the current policy
265 in use for the function that was called.
266
267 The default policy for this function is that `std::overflow_error` 
268 C++ exception is thrown. But if, for example, an `ignore_error` policy 
269 is used, then returns `std::numeric_limits<T>::infinity()`.
270 In this situation if the type `T` doesn't support infinities,
271 the maximum value for the type is returned.
272
273 [heading:underflow_error Numeric Underflow]
274
275 If the result of a special function is known to be non-zero, but the
276 calculated result underflows to zero, then the function returns the result of:
277
278    boost::math::policies::raise_underflow_error<T>(FunctionName, Message, __Policy);
279    
280 Where
281 `T` is the floating point type passed to the function, `FunctionName` is the 
282 name of the function, `Message` is an error message describing the problem,
283 and __Policy is the current policy
284 in use for the called function.
285
286 The default version of this function returns zero.
287 But with another policy, like `throw_on_error`, 
288 throws an `std::underflow_error` C++ exception.  
289
290 [heading:denorm_error Denormalisation Errors]
291
292 If the result of a special function is a denormalised value /z/ then the function
293 returns the result of:
294
295    boost::math::policies::raise_denorm_error<T>(z, FunctionName, Message, __Policy);
296    
297 Where
298 `T` is the floating point type passed to the function, `FunctionName` is the 
299 name of the function, `Message` is an error message describing the problem,
300 and __Policy is the current policy
301 in use for the called function.
302
303 The default version of this function returns /z/.
304 But with another policy, like `throw_on_error` 
305 throws an `std::underflow_error` C++ exception.
306
307 [heading:evaluation_error Evaluation Errors]
308
309 When a special function calculates a result that is known to be erroneous,
310 or where the result is incalculable then it calls:
311
312    boost::math::policies::raise_evaluation_error<T>(FunctionName, Message, Val, __Policy);
313    
314 Where
315 `T` is the floating point type passed to the function, `FunctionName` is the 
316 name of the function, `Message` is an error message describing the problem,
317 `Val` is the erroneous value,
318 and __Policy is the current policy
319 in use for the called function.
320
321 The default behaviour of this function is to throw a `boost::math::evaluation_error`.
322
323 Note that in order to support information rich error messages when throwing
324 exceptions, `Message` must contain
325 a __format recognised format specifier: the argument `val` is inserted into
326 the error message according to the specifier used.
327
328 For example if `Message` contains a "%1%" then it is replaced by the value of
329 `val` to the full precision of T, where as "%.3g" would contain the value of
330 `val` to 3 digits.  See the __format documentation for more details.
331
332 [heading:indeterminate_result_error Indeterminate Result Errors]
333
334 When the result of a special function is indeterminate for the value that was
335 passed to it, then the function returns the result of:
336
337    boost::math::policies::raise_overflow_error<T>(FunctionName, Message, Val, Default, __Policy);
338    
339 Where
340 `T` is the floating-point type passed to the function, `FunctionName` is the 
341 name of the function, `Message` is an error message describing the problem,
342 Val is the value for which the result is indeterminate, Default is an
343 alternative default result that must be returned for `ignore_error` and
344 `errno_on_erro` policies, and __Policy is the current policy in use for the
345 function that was called.
346
347 The default policy for this function is `ignore_error`: note that this error
348 type is reserved for situations where the result is mathematically
349 undefined or indeterminate, but there is none the less a convention for what
350 the result should be: for example the C99 standard specifies that the result
351 of 0[super 0] is 1, even though the result is actually mathematically indeterminate.
352
353 [heading:rounding_error Rounding Errors]
354
355 When one of the rounding functions __round, __trunc or __modf is
356 called with an argument that has no integer representation, or
357 is too large to be represented in the result type then the 
358 value returned is the result of a call to:
359
360    boost::math::policies::raise_rounding_error<T>(FunctionName, Message, Val, __Policy);
361    
362 Where
363 `T` is the floating point type passed to the function, `FunctionName` is the 
364 name of the function, `Message` is an error message describing the problem,
365 `Val` is the erroneous argument,
366 and __Policy is the current policy in use for the called function.
367
368 The default behaviour of this function is to throw a `boost::math::rounding_error`.
369
370 Note that in order to support information rich error messages when throwing
371 exceptions, `Message` must contain
372 a __format recognised format specifier: the argument `val` is inserted into
373 the error message according to the specifier used.
374
375 For example if `Message` contains a "%1%" then it is replaced by the value of
376 `val` to the full precision of T, where as "%.3g" would contain the value of
377 `val` to 3 digits.  See the __format documentation for more details.
378
379 [heading:checked_narrowing_cast Errors from typecasts]
380
381 Many special functions evaluate their results at a higher precision
382 than their arguments in order to ensure full machine precision in 
383 the result: for example, a function passed a float argument may evaluate
384 its result using double precision internally.  Many of the errors listed
385 above may therefore occur not during evaluation, but when converting 
386 the result to the narrower result type.  The function:
387
388    template <class T, class __Policy, class U>
389    T checked_narrowing_cast(U const& val, const char* function);
390    
391 Is used to perform these conversions, and will call the error handlers
392 listed above on [link math_toolkit.error_handling.overflow_error overflow], 
393 [link math_toolkit.error_handling.underflow_error underflow] or [link math_toolkit.error_handling.denorm_error denormalisation].
394
395 [endsect][/section:error_handling Error Handling]
396
397 [/ 
398   Copyright 2006 - 2012 John Maddock and Paul A. Bristow.
399   Distributed under the Boost Software License, Version 1.0.
400   (See accompanying file LICENSE_1_0.txt or copy at
401   http://www.boost.org/LICENSE_1_0.txt).
402 ]
403