Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/numeric/interval/doc/checking.htm @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 11.4 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2    "http://www.w3.org/TR/html4/loose.dtd">
3<html>
4<head>
5  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6  <link rel="stylesheet" type="text/css" href="../../../../boost.css">
7  <title>Checking policies</title>
8</head>
9
10<body>
11<h1>Checking policies</h1>
12
13<p>A checking policy controls how the <code>interval</code> class will deal
14with special cases like: empty intervals, infinite numbers, invalid
15values.</p>
16
17<p>For example, let's consider <code>operator+(interval, T)</code>. The
18second argument could be an invalid value (for a floating-point number, it is
19a NaN). What to do in such a case? First, we could say that the second
20argument can never be an invalid number. Second, we could also say such a
21situation can arise but is forbidden. Third, we could allow such values and
22generate an empty interval when encountered. And there is many other
23possibilities.</p>
24
25<p>It is the reason why such a policy is used: there is a lot of interesting
26behaviors and it would be sad to arbitrarily select one of these.</p>
27
28<h2>Requirements</h2>
29
30<p>The checking class should satisfy the following requirement (in the form
31of an interface):</p>
32<pre>/* requirements for checking policy */
33struct checking
34{
35  static T pos_inf();
36  static T neg_inf();
37  static T nan();
38  static bool is_nan(const T&amp;);
39  static T empty_lower();
40  static T empty_upper();
41  static bool is_empty(const T&amp;, const T&amp;);
42};</pre>
43
44<p>The first two functions, <code>pos_inf</code> and <code>neg_inf</code>,
45are invoked each time the library has to create the infinite bound of an
46interval. For example, <code>interval::whole</code> computes
47<code>interval(checking::neg_inf(), checking::pos_inf())</code>. If infinite
48values are allowed and <code>std::numeric_limits&lt;T&gt;::infinity()</code>
49returns a correct value, such a value can be used.</p>
50
51<p>Next comes <code>nan</code>. This function is used each time a function
52need to return a value of type <code>T</code> but is unable to compute it. It
53only happens when one of the arguments of the function is invalid. For
54example, if you ask what the median value of an empty interval is,
55<code>nan</code> will be used. But please remember: <code>lower</code> and
56<code>upper</code> directly return the value stocked in the interval; so, if
57the interval is empty, <code>lower</code> will not answer <code>by</code> a
58call to <code>checking::nan</code> (but will return the same value than
59<code>checking::empty_lower</code> could return).</p>
60
61<p><code>empty_lower</code> and <code>empty_upper</code> respectively return
62the lower and upper bound of the empty interval. There is no requirements for
63<code>empty_lower</code> and <code>empty_upper</code> to return the same
64value than <code>checking::nan</code>. For example, if the type
65<code>T</code> does not have any invalid value, the <code>empty_</code>
66functions can return the [1;0] interval.</p>
67
68<p><code>is_nan</code> is used to test if a value of type <code>T</code> is
69invalid or not. <code>is_empty</code> tests if the interval formed by the two
70arguments is empty or not. Such tests will generally be at the beginning of
71each function which involves an argument of type <code>T</code>. If one of
72the inputs is declared invalid, the the function will try to produce an
73invalid value or an input interval.</p>
74
75<h2>Synopsis</h2>
76<pre>namespace boost {
77namespace numeric {
78namespace interval_lib {
79
80template&lt;class T&gt;
81struct checking_base;
82template&lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_create_empty&lt;T&gt; &gt;
83struct checking_no_empty;
84template&lt;class T, class Checking = checking_base&lt;T&gt; &gt;
85struct checking_no_nan;
86template&lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_invalid_number&lt;T&gt; &gt;
87struct checking_catch_nan;
88
89template&lt;class T&gt; struct exception_create_empty { T operator()(); };
90template&lt;class T&gt; struct exception_invalid_number { void operator()(); };
91
92} // namespace numeric
93} // namespace interval_lib
94} // namespace boost</pre>
95
96<h2>Predefined classes</h2>
97
98<p>In order to simplify the customization of the policy, some templates are
99already defined in the library.</p>
100
101<p>First of all, there is <code>checking_base</code>. Thanks to the
102information provided by <code>std::numeric_limits&lt;T&gt;</code>, this class
103is able to generate a base for the policy. If <code>T</code> has quiet NaNs
104(as said by <code>numeric_limits::has_quiet_NaN</code>), then the value is
105used for <code>nan</code>, <code>empty_lower</code>,
106<code>empty_upper</code>; and a basic test is used for <code>is_nan</code>
107(it is <code>x!=x</code>). If <code>T</code> does not have quiet NaNs, then
108<code>nan</code> is an <code>assert(false)</code>, the empty interval is
109[1,0], and <code>is_nan</code> always return <code>false</code>. As for
110<code>nan</code>, <code>pos_inf</code> returns
111<code>numeric_limits::infinity()</code> if possible, or is an
112<code>assert(false</code>) otherwise. <code>neg_inf</code> returns the
113opposite. Finally, <code>is_empty(T l,T u)</code> is always defined by
114<code>!(l&lt;=u)</code>.</p>
115
116<p>Next comes <code>checking_no_empty</code>. Using it means that each time
117an empty interval should be produced (by <code>empty_lower</code> and
118<code>empty_upper</code>), the function object given by the
119<code>Exception</code> argument of the template is invoked and the value it
120returns is propagated. So, if <code>Exception</code> is appropriately defined
121(for example it could throw an exception, hence the name of the argument),
122you can be sure no empty interval will ever be created. So
123<code>is_empty</code> will always return <code>false</code> (since there is
124no need to test for an empty interval). And as explained before, in that case
125we can also replace <code>nan</code> by an <code>assert(false)</code>; you
126will be sure no invalid number will ever be produced. If this template is not
127used, it implicitly means that all the functions can produce empty intervals
128and they correctly deal with empty interval arguments.</p>
129
130<p>Finally there are <code>checking_no_nan</code> and
131<code>checking_catch_nan</code>. The first one expresses the functions of the
132library will never get an invalid number as argument. So <code>is_nan</code>
133will only return <code>false</code>. The other one means the arguments can be
134an invalid number but in that case, <code>is_nan</code> will call the
135function object <code>Exception</code> and return <code>false</code>. Indeed,
136this template means invalid numbers should never make their way through to
137the body of the function. If none of this two templates is used, it
138implicitly means that all the functions can get invalid number arguments and
139they will correctly deal with them.</p>
140
141<p><code>exception_create_empty</code> throws <code>std::runtime_error</code>
142with the message <code>"boost::interval: empty interval created"</code> and
143<code>exception_invalid_number</code> throws
144<code>std::invalid_argument</code> with the message <code>"boost::interval:
145invalid number"</code>.</p>
146
147<h2>Customizing your own checking policy</h2>
148
149<p>In order to define a suitable policy, you need to correctly say what you
150expect from your interval class. First of all, are you interested in getting
151empty intervals at the end of a calculus? If you do not want to obtain empty
152intervals, <code>empty_lower</code> and <code>empty_upper</code> have to fail
153when invoked (they can throw an exception, set a flag, etc). However, if no
154function is able to produce an empty interval, it is no more necessary to do
155the test, so <code>is_empty</code> may always return <code>false</code>. In
156this case, a good compiler will do a lot of optimizations.</p>
157
158<p>You could also be interested in getting empty intervals at the end of the
159calculus. For example, if you need to transform an array of unsure values (or
160intervals) in a new array of intervals, you may not want to stop the
161conversion at the first encountered problem. So <code>empty_lower</code> and
162<code>empty_upper</code> need to return suitable values in order to define an
163empty interval (you can use an upper bound which is not greater or equal than
164the lower bound for example); and <code>is_empty</code> must be able to
165distinguish empty intervals from the valid intervals.</p>
166
167<p>Another important question is: is it possible that some base numbers
168(objects of type <code>T</code>) are invalid? And if it is possible, are they
169allowed or not ? If it is not possible, no test is necessary;
170<code>is_nan</code> may always return <code>false</code>. In this case too, a
171good compiler will do a lot of optimizations. If function arguments can hold
172invalid numbers, two cases must be considered according to whether they are
173allowed or not. If they are allowed, <code>is_nan</code> just has to test if
174they are invalid or not. If they are forbidden, <code>is_nan</code> should
175fail (exception, assert, etc.) when invoked on an invalid argument and return
176<code>false</code> otherwise. The value returned by <code>nan</code> does not
177have any interest since the interval functions are guaranteed not to produce
178invalid interval bounds unless the user passes invalid numbers to the
179constructors. So you can put an assert inside if you do not trust the
180library. :-)</p>
181
182<p>And finally, you need to decide what to do with <code>nan</code> if it has
183not already been decided at the beginning, and with <code>pos_inf</code> and
184<code>neg_inf</code>. These functions should return a value or start an
185exceptional behavior (especially if the base type does not have corresponding
186values).</p>
187
188<h2>Some examples</h2>
189<ul>
190  <li>If you need a checking policy that allows the library to correctly
191    manipulate data, even if they contain invalid numbers and empty
192    intervals, then <code>checking_base&lt;T&gt;</code> is a possibility.</li>
193  <li>If you do not want empty intervals to be created and are not sure all
194    the numbers are valid, then <code>checking_catch_nan&lt;T,
195    checking_no_empty&lt;T&gt; &gt;</code> can help you.</li>
196  <li>If all the numbers will be valid and if no empty interval is supposed
197    to be created (or if you do not want them to be created), then you can
198    use <code>checking_no_nan&lt;T, checking_no_empty&lt;T&gt; &gt;</code>.
199    Please note that if <code>T</code> does not have a way to represent
200    invalid numbers, then this policy will behave the same way as
201    <code>checking_no_empty&lt;T&gt;</code>. This is the default policy and
202    it is also called <code>interval_lib::checking_strict</code>.</li>
203  <li>If all numerical data are valid but the algorithm can produce and
204    manipulate empty intervals, then <code>checking_no_nan&lt;T&gt;</code>
205    should be used.</li>
206  <li>Similarly, if invalid data have to be signaled and the algorithm can
207    manipulate empty intervals, the <code>checking_catch_nan&lt;T&gt;</code>
208    is a solution.</li>
209  <li>If you do not mind having undefined results when an empty interval or
210    an interval number is produced, your best bet is to create your own
211    policy by overloading <code>checking_base</code> and modifying
212    <code>is_nan</code> et <code>is_empty</code> in order for them to always
213    return <code>false</code>. It is probably the fastest checking policy
214    available; however, it suffers from its deficient security.</li>
215</ul>
216<hr>
217
218<p>Revised: 2004-02-16<br>
219Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
220Polytechnic University.<br>
221Copyright (c) Guillaume Melquiond, 2003-2004.</p>
222</body>
223</html>
Note: See TracBrowser for help on using the repository browser.