Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added boost

File size: 53.7 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>Boost Interval Arithmetic Library</title>
8</head>
9
10<body lang="en">
11<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)"
12align="middle">
13 Interval Arithmetic Library</h1>
14
15<center>
16
17<table width="80%">
18  <tbody>
19    <tr>
20      <td><b>Contents of this page:</b><br>
21        <a href="#intro">Introduction</a><br>
22        <a href="#synopsis">Synopsis</a><br>
23        <a href="#interval">Template class <code>interval</code></a><br>
24        <a href="#opers">Operations and functions</a><br>
25        <a href="#interval_lib">Interval support library</a><br>
26        <!--<a href="#compil">Compilation notes</a><br>-->
27        <a href="#dangers">Common pitfalls and dangers</a><br>
28        <a href="#rationale">Rationale</a><br>
29        <a href="#acks">History and Acknowledgments</a></td>
30      <td><b>Other pages associated with this page:</b><br>
31        <a href="rounding.htm">Rounding policies</a><br>
32        <a href="checking.htm">Checking policies</a><br>
33        <a href="policies.htm">Policies manipulation</a><br>
34        <a href="comparisons.htm">Comparisons</a><br>
35        <a href="numbers.htm">Base number type requirements</a><br>
36        <a href="guide.htm">Choosing your own interval type</a><br>
37        <a href="examples.htm">Test and example programs</a><br>
38        <a href="includes.htm">Headers inclusion</a><br>
39        <a href="todo.htm">Some items on the todo list</a></td>
40    </tr>
41  </tbody>
42</table>
43</center>
44
45<h2 id="intro">Introduction and Overview</h2>
46
47<p>As implied by its name, this library is intended to help manipulating
48mathematical intervals. It consists of a single header &lt;<a
49href="../../../../boost/numeric/interval.hpp">boost/numeric/interval.hpp</a>&gt;
50and principally a type which can be used as <code>interval&lt;T&gt;</code>.
51In fact, this interval template is declared as
52<code>interval&lt;T,Policies&gt;</code> where <code>Policies</code> is a
53policy class that controls the various behaviours of the interval class;
54<code>interval&lt;T&gt;</code> just happens to pick the default policies for
55the type <code>T</code>.</p>
56
57<h3>Interval Arithmetic</h3>
58
59<p>An interval is a pair of numbers which represents all the numbers between
60these two. (Intervals are considered close so the bounds are included.) The
61purpose of this library is to extend the usual arithmetic functions to
62intervals. These intervals will be written [<i>a</i>,<i>b</i>] to represent
63all the numbers between <i>a</i> and <i>b</i> (included). <i>a</i> and
64<i>b</i> can be infinite (but they can not be the same infinite) and <i>a</i>
65&#x2264; <i>b</i>.</p>
66
67<p>The fundamental property of interval arithmetic is the
68<em><strong>inclusion property</strong></em>:</p>
69<dl>
70    <dd>``if <i>f</i> is a function on a set of numbers, <i>f</i> can be
71      extended to a new function defined on intervals. This new function
72      <i>f</i> takes one interval argument and returns an interval result
73      such as: &#x2200; <i>x</i> &#x2208; [<i>a</i>,<i>b</i>],
74      <i>f</i>(<i>x</i>) &#x2208; <i>f</i>([<i>a</i>,<i>b</i>]).''</dd>
75</dl>
76
77<p>Such a property is not limited to functions with only one argument.
78Whenever possible, the interval result should be the smallest one able to
79satisfy the property (it is not really useful if the new functions always
80answer [-&#x221e;,+&#x221e;]).</p>
81
82<p>There are at least two reasons a user would like to use this library. The
83obvious one is when the user has to compute with intervals. One example is
84when input data have some builtin imprecision: instead of a number, an input
85variable can be passed as an interval. Another example application is to
86solve equations, by bisecting an interval until the interval width is small
87enough. A third example application is in computer graphics, where
88computations with boxes, segments or rays can be reduced to computations with
89points via intervals.</p>
90
91<p>Another common reason to use interval arithmetic is when the computer
92doesn't produce exact results: by using intervals, it is possible to quantify
93the propagation of rounding errors. This approach is used often in numerical
94computation. For example, let's assume the computer stores numbers with ten
95decimal significant digits. To the question 1 + 1E-100 - 1, the computer will
96answer 0 although the correct answer would be 1E-100. With the help of
97interval arithmetic, the computer will answer [0,1E-9]. This is quite a huge
98interval for such a little result, but the precision is now known, without
99having to compute error propagation.</p>
100
101<h3>Numbers, rounding, and exceptional behavior</h3>
102
103<p>The <em><strong>base number type</strong></em> is the type that holds the
104bounds of the interval. In order to successfully use interval arithmetic, the
105base number type must present some <a
106href="rounding.htm">characteristics</a>. Firstly, due to the definition of an
107interval, the base numbers have to be totally ordered so, for instance,
108<code>complex&lt;T&gt;</code> is not usable as base number type for
109intervals.  The mathematical functions for the base number type should also
110be compatible with the total order (for instance if x&gt;y and z&gt;t, then
111it should also hold that x+z &gt; y+t), so modulo types are not usable
112either.</p>
113
114<p>Secondly, the computations must be exact or provide some rounding methods
115(for instance, toward minus or plus infinity) if we want to guarantee the
116inclusion property. Note that we also may explicitely specify no rounding,
117for instance if the base number type is exact, i.e. the result of a
118mathematic operation is always computed and represented without loss of
119precision. If the number type is not exact, we may still explicitely specify
120no rounding, with the obvious consequence that the inclusion property is no
121longuer guaranteed.</p>
122
123<p>Finally, because heavy loss of precision is always possible, some numbers
124have to represent infinities or an exceptional behavior must be defined. The
125same situation also occurs for NaN (<i>Not a Number</i>).</p>
126
127<p>Given all this, one may want to limit the template argument T of the class
128template <code>interval</code> to the floating point types
129<code>float</code>, <code>double</code>, and <code>long double</code>, as
130defined by the IEEE-754 Standard. Indeed, if the interval arithmetic is
131intended to replace the arithmetic provided by the floating point unit of a
132processor, these types are the best choice. Unlike <code>std::complex</code>,
133however, we don't want to limit <code>T</code> to these types. This is why we
134allow the rounding and exceptional behaviors to be given by the two policies
135(rounding and checking). We do nevertheless provide highly optimized rounding
136and checking class specializations for the above-mentioned floating point
137types.</p>
138
139<h3>Operations and functions</h3>
140
141<p>It is straightforward to define the elementary arithmetic operations on
142intervals, being guided by the inclusion property. For instance, if [a,b] and
143[c,d] are intervals, [a,b]+[c,d] can be computed by taking the smallest
144interval that contains all the numbers x+y for x in [a,b] and y in [c,d]; in
145this case, rounding a+c down and b+d up will suffice. Other operators and
146functions are similarly defined (see their definitions below).</p>
147
148<h3>Comparisons</h3>
149
150<p>It is also possible to define some comparison operators. Given two
151intervals, the result is a tri-state boolean type
152{<i>false</i>,<i>true,indeterminate</i>}. The answers <i>false</i> and
153<i>true</i> are easy to manipulate since they can directly be mapped on the
154boolean <i>true</i> and <i>false</i>. But it is not the case for the answer
155<em>indeterminate</em> since comparison operators are supposed to be boolean
156functions. So, what to do in order to obtain boolean answers?</p>
157
158<p>One solution consists of deciding to adopt an exceptional behavior, such
159as a failed assertion or raising an exception. In this case, the exceptional
160behavior will be triggered when the result is indeterminate.</p>
161
162<p>Another solution is to  map <em>indeterminate</em> always to <i>false,</i>
163or always to <i>true</i>. If <i>false</i> is chosen, the comparison will be
164called "<i>certain</i>;" indeed, the result of [<i>a</i>,<i>b</i>] &lt;
165[<i>c</i>,<i>d</i>] will be <i>true</i> if and only if: &#x2200; <i>x</i>
166&#x2208; [<i>a</i>,<i>b</i>] &#x2200; <i>y</i> &#x2208; [<i>c</i>,<i>d</i>],
167<i>x</i> &lt; <i>y</i>. If <i>true</i> is chosen, the comparison will be
168called "<i>possible</i>;" indeed, the result of [<i>a</i>,<i>b</i>] &lt;
169[<i>c</i>,<i>d</i>] will be <i>true</i> if and only if: &#x2203; <i>x</i>
170&#x2208; [<i>a</i>,<i>b</i>] &#x2203; <i>y</i> &#x2208; [<i>c</i>,<i>d</i>],
171<i>x</i> &lt; <i>y</i>.</p>
172
173<p>Since any of these solution has a clearly defined semantics, it is not
174clear that we should enforce either of them. For this reason, the default
175behavior consists to mimic the real comparisons by throwing an exception in
176the indeterminate case. Other behaviors can be selected bu using specific
177comparison namespace. There is also a bunch of explicitely named comparison
178functions. See <a href="comparisons.htm">comparisons</a> pages for further
179details.</p>
180
181<h3>Overview of the library, and usage</h3>
182
183<p>This library provides two quite distinct levels of usage. One is to use
184the basic class template <code>interval&lt;T&gt;</code> without specifying
185the policy. This only requires to know and understand the concepts developed
186above and the content of the namespace boost. In addition to the class
187<code>interval&lt;T&gt;</code>, this level of usage provides arithmetic
188operators (<code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>),
189algebraic and piecewise-algebraic functions (<code>abs</code>,
190<code>square</code>, <code>sqrt</code>, <code>pow</code>), transcendental and
191trigonometric functions (<code>exp</code>, <code>log</code>,
192<code>sin</code>, <code>cos</code>, <code>tan</code>, <code>asin</code>,
193<code>acos</code>, <code>atan</code>, <code>sinh</code>, <code>cosh</code>,
194<code>tanh</code>, <code>asinh</code>, <code>acosh</code>,
195<code>atanh</code>), and the standard comparison operators
196(<code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>,
197<code>&gt;=</code>, <code>==</code>, <code>!=</code>), as well as several
198interval-specific functions (<code>min</code>, <code>max</code>, which have a
199different meaning than <code>std::min</code> and <code>std::max</code>;
200<code>lower</code>, <code>upper</code>, <code>width</code>,
201<code>median</code>, <code>empty</code>, <code>singleton</code>,
202<code>equal</code>, <code>in</code>, <code>in_zero</code>,
203<code>subset</code>, <code>proper_subset</code>, <code>overlap</code>,
204<code>intersection</code>, <code>hull</code>, <code>bisect</code>).</p>
205
206<p>For some functions which take several parameters of type
207<code>interval&lt;T&gt;</code>, all combinations of argument types
208<code>T</code> and <code>interval&lt;T&gt;</code> which contain at least one
209<code>interval&lt;T&gt;</code>, are considered in order to avoid a conversion
210from the arguments of type <code>T</code> to a singleton of type
211<code>interval&lt;T&gt;</code>. This is done for efficiency reasons (the fact
212that an argument is a singleton sometimes renders some tests unnecessary).</p>
213
214<p>A somewhat more advanced usage of this library is to hand-pick the
215policies <code>Rounding</code> and <code>Checking</code> and pass them to
216<code>interval&lt;T, Policies&gt;</code> through the use of <code>Policies :=
217boost::numeric::interval_lib::policies&lt;Rounding,Checking&gt;</code>.
218Appropriate policies can be fabricated by using the various classes provided
219in the namespace <code>boost::numeric::interval_lib</code> as detailed in
220section <a href="#interval_lib">Interval Support Library</a>. It is also
221possible to choose the comparison scheme by overloading operators through
222namespaces.</p>
223
224<h2><a name="synopsis"></a>Synopsis</h2>
225<pre>namespace boost {
226namespace numeric {
227
228namespace interval_lib {
229
230/* this declaration is necessary for the declaration of interval */
231template &lt;class T&gt; struct default_policies;
232
233/* ... ; the full synopsis of namespace interval_lib can be found <a href="#interval_lib">here</a> */
234
235} // namespace interval_lib
236
237
238/* template interval_policies; class definition can be found <a href="policies.htm">here</a> */
239template&lt;class Rounding, class Checking&gt;
240struct interval_policies;
241
242/* template class interval; class definition can be found <a href="#interval">here</a> */
243template&lt;class T, class Policies = typename interval_lib::default_policies&lt;T&gt;::type &gt; class interval;
244
245/* arithmetic operators involving intervals */
246template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator+(const interval&lt;T, Policies&gt;&amp; x);
247template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator-(const interval&lt;T, Policies&gt;&amp; x);
248
249template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator+(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
250template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator+(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
251template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator+(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
252
253template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator-(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
254template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator-(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
255template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator-(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
256
257template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator*(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
258template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator*(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
259template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator*(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
260
261template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator/(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
262template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator/(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
263template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; operator/(const T&amp; r, const interval&lt;T, Policies&gt;&amp; x);
264
265/* algebraic functions: sqrt, abs, square, pow */
266template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; abs(const interval&lt;T, Policies&gt;&amp; x);
267template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; sqrt(const interval&lt;T, Policies&gt;&amp; x);
268template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; square(const interval&lt;T, Policies&gt;&amp; x);
269template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; pow(const interval&lt;T, Policies&gt;&amp; x, int y);
270
271/* transcendental functions: exp, log */
272template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; exp(const interval&lt;T, Policies&gt;&amp; x);
273template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; log(const interval&lt;T, Policies&gt;&amp; x);
274
275/* fmod, for trigonometric function argument reduction (see below) */
276template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; fmod(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
277template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; fmod(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
278template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; fmod(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
279
280/* trigonometric functions */
281template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; sin(const interval&lt;T, Policies&gt;&amp; x);
282template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; cos(const interval&lt;T, Policies&gt;&amp; x);
283template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; tan(const interval&lt;T, Policies&gt;&amp; x);
284template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; asin(const interval&lt;T, Policies&gt;&amp; x);
285template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; acos(const interval&lt;T, Policies&gt;&amp; x);
286template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; atan(const interval&lt;T, Policies&gt;&amp; x);
287
288/* hyperbolic trigonometric functions */
289template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; sinh(const interval&lt;T, Policies&gt;&amp; x);
290template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; cosh(const interval&lt;T, Policies&gt;&amp; x);
291template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; tanh(const interval&lt;T, Policies&gt;&amp; x);
292template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; asinh(const interval&lt;T, Policies&gt;&amp; x);
293template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; acosh(const interval&lt;T, Policies&gt;&amp; x);
294template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; atanh(const interval&lt;T, Policies&gt;&amp; x);
295
296/* min, max external functions (NOT std::min/max, see below) */
297template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; max(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
298template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; max(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
299template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; max(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
300template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; min(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
301template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; min(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
302template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; min(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
303
304/* bounds-related interval functions */
305template &lt;class T, class Policies&gt;  T lower(const interval&lt;T, Policies&gt;&amp; x);
306template &lt;class T, class Policies&gt;  T upper(const interval&lt;T, Policies&gt;&amp; x);
307template &lt;class T, class Policies&gt;  T width(const interval&lt;T, Policies&gt;&amp; x);
308template &lt;class T, class Policies&gt;  T median(const interval&lt;T, Policies&gt;&amp; x);
309template &lt;class T, class Policies&gt;  T norm(const interval&lt;T, Policies&gt;&amp; x);
310
311/* bounds-related interval functions */
312template &lt;class T, class Policies&gt;  bool empty(const interval&lt;T, Policies&gt;&amp; b);
313template &lt;class T, class Policies&gt;  bool singleton(const interval&lt;T, Policies&gt;&amp; x);
314template &lt;class T, class Policies&gt;  bool equal(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
315template &lt;class T, class Policies&gt;  bool in(const T&amp; r, const interval&lt;T, Policies&gt;&amp; b);
316template &lt;class T, class Policies&gt;  bool in_zero(const interval&lt;T, Policies&gt;&amp; b);
317template &lt;class T, class Policies&gt;  bool subset(const interval&lt;T, Policies&gt;&amp; a, const interval&lt;T, Policies&gt;&amp; b);
318template &lt;class T, class Policies&gt;  bool proper_subset(const interval&lt;T, Policies&gt;&amp; a, const interval&lt;T, Policies&gt;&amp; b);
319template &lt;class T, class Policies&gt;  bool overlap(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
320
321/* set manipulation interval functions */
322template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; intersection(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
323template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; hull(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
324template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; hull(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
325template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; hull(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
326template &lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; hull(const T&amp; x, const T&amp; y);
327template &lt;class T, class Policies&gt;  std::pair&lt;interval&lt;T, Policies&gt;, interval&lt;T, Policies&gt; &gt; bisect(const interval&lt;T, Policies&gt;&amp; x);
328
329/* interval comparison operators */
330template&lt;class T, class Policies&gt;  bool operator&lt;(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
331template&lt;class T, class Policies&gt;  bool operator&lt;(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
332template&lt;class T, class Policies&gt;  bool operator&lt;(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
333
334template&lt;class T, class Policies&gt;  bool operator&lt;=(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
335template&lt;class T, class Policies&gt;  bool operator&lt;=(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
336template&lt;class T, class Policies&gt;  bool operator&lt;=(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
337
338template&lt;class T, class Policies&gt;  bool operator&gt;(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
339template&lt;class T, class Policies&gt;  bool operator&gt;(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
340template&lt;class T, class Policies&gt;  bool operator&gt;(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
341
342template&lt;class T, class Policies&gt;  bool operator&gt;=(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
343template&lt;class T, class Policies&gt;  bool operator&gt;=(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
344template&lt;class T, class Policies&gt;  bool operator&gt;=(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);</pre>
345<pre>template&lt;class T, class Policies&gt;  bool operator==(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
346template&lt;class T, class Policies&gt;  bool operator==(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
347template&lt;class T, class Policies&gt;  bool operator==(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
348
349template&lt;class T, class Policies&gt;  bool operator!=(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
350template&lt;class T, class Policies&gt;  bool operator!=(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
351template&lt;class T, class Policies&gt;  bool operator!=(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
352
353namespace interval_lib {
354
355template&lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; division_part1(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&amp; y, bool&amp; b);
356template&lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; division_part2(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&amp; y, bool b = true);
357template&lt;class T, class Policies&gt;  interval&lt;T, Policies&gt; multiplicative_inverse(const interval&lt;T, Policies&gt;&amp; x);
358
359template&lt;class I&gt;  I add(const typename I::base_type&amp; x, const typename I::base_type&amp; y);
360template&lt;class I&gt;  I sub(const typename I::base_type&amp; x, const typename I::base_type&amp; y);
361template&lt;class I&gt;  I mul(const typename I::base_type&amp; x, const typename I::base_type&amp; y);
362template&lt;class I&gt;  I div(const typename I::base_type&amp; x, const typename I::base_type&amp; y);
363
364} // namespace interval_lib
365
366} // namespace numeric
367} // namespace boost</pre>
368
369<h2><a name="interval"></a>Template class <code>interval</code></h2>
370The public interface of the template class interval itself is kept at a
371simplest minimum:
372<pre>template &lt;class T, class Policies = typename interval_lib::default_policies&lt;T&gt;::type&gt;
373class interval
374{
375  public:
376  typedef T base_type;
377  typedef Policies traits_type;
378
379  interval();
380  interval(T const &amp;v);
381  template&lt;class T1&gt; interval(T1 const &amp;v);
382  interval(T const &amp;l, T const &amp;u);
383  template&lt;class T1, class T2&gt; interval(T1 const &amp;l, T2 const &amp;u);
384  interval(interval&lt;T, Policies&gt; const &amp;r);
385  template&lt;class Policies1&gt; interval(interval&lt;T, Policies1&gt; const &amp;r);
386  template&lt;class T1, class Policies1&gt; interval(interval&lt;T1, Policies1&gt; const &amp;r);
387
388  interval &amp;operator=(T const &amp;v);
389  template&lt;class T1&gt; interval &amp;operator=(T1 const &amp;v);
390  interval &amp;operator=(interval&lt;T, Policies&gt; const &amp;r);
391  template&lt;class Policies1&gt; interval &amp;operator=(interval&lt;T, Policies1&gt; const &amp;r);
392  template&lt;class T1, class Policies1&gt; interval &amp;operator=(interval&lt;T1, Policies1&gt; const &amp;r);
393
394  void assign(T const &amp;l, T const &amp;u);
395
396  T const &amp;lower() const;
397  T const &amp;upper() const;
398
399  static interval empty();
400  static interval whole();
401  static interval hull(T const &amp;x, T const &amp;y);
402
403  interval&amp; operator+= (T const &amp;r);
404  interval&amp; operator-= (T const &amp;r);
405  interval&amp; operator*= (T const &amp;r);
406  interval&amp; operator/= (T const &amp;r);
407  interval&amp; operator+= (interval const &amp;r);
408  interval&amp; operator-= (interval const &amp;r);
409  interval&amp; operator*= (interval const &amp;r);
410  interval&amp; operator/= (interval const &amp;r);
411};</pre>
412
413<p>The constructors create an interval enclosing their arguments. If there
414are two arguments, the first one is assumed to be the left bound and the
415second one is the right bound. Consequently, the arguments need to be
416ordered. If the property !(l &lt;= u) is not respected, the checking policy
417will be used to create an empty interval. If no argument is given, the
418created interval is the singleton zero.</p>
419
420<p>If the type of the arguments is the same as the base number type, the
421values are directly used for the bounds. If it is not the same type, the
422library will use the rounding policy in order to convert the arguments
423(<code>conv_down</code> and <code>conv_up</code>) and create an enclosing
424interval. When the argument is an interval with a different policy, the input
425interval is checked in order to correctly propagate its emptiness (if
426empty).</p>
427
428<p>The assignment operators behave similarly, except they obviously take one
429argument only. There is also an <code>assign</code> function in order to
430directly change the bounds of an interval. It behaves like the two-arguments
431constructors if the bounds are not ordered. There is no assign function that
432directly takes an interval or only one number as a parameter; just use the
433assignment operators in such a case.</p>
434
435<p>The static functions <code>empty</code> and <code>whole</code> produce the
436corresponding intervals. They are static member functions rather than global
437functions because they cannot guess their return types. Likewise for
438<code>hull</code>. <code>empty</code> and <code>whole</code> involve the
439checking policy in order to get the bounds of the resulting intervals.</p>
440
441<h2><a name="opers"></a>Operations and Functions</h2>
442
443<p>Some of the following functions expect <code>min</code> and
444<code>max</code> to be defined for the base type. Those are the only
445requirements for the <code>interval</code> class (but the policies can have
446other requirements).</p>
447
448<h4>Operators <code>+</code> <code>-</code> <code>*</code> <code>/</code>
449<code>+=</code> <code>-=</code> <code>*=</code> <code>/=</code></h4>
450
451<p>The basic operations are the unary minus and the binary <code>+</code>
452<code>-</code> <code>*</code> <code>/</code>. The unary minus takes an
453interval and returns an interval. The binary operations take two intervals,
454or one interval and a number, and return an interval. If an argument is a
455number instead of an interval, you can expect the result to be the same as if
456the number was first converted to an interval. This property will be true for
457all the following functions and operators.</p>
458
459<p>There are also some assignment operators <code>+=</code> <code>-=</code>
460<code>*=</code> <code>/=</code>. There is not much to say: <code>x op=
461y</code> is equivalent to <code>x = x op y</code>. If an exception is thrown
462during the computations, the l-value is not modified (but it may be corrupt
463if an exception is thrown by the base type during an assignment).</p>
464
465<p>The operators <code>/</code> and <code>/=</code> will try to produce an
466empty interval if the denominator is exactly zero. If the denominator
467contains zero (but not only zero), the result will be the smallest interval
468containing the set of division results; so one of its bound will be infinite,
469but it may not be the whole interval.</p>
470
471<h4><code>lower</code> <code>upper</code> <code>median</code>
472<code>width</code> <code>norm</norm></code></h4>
473
474<p><code>lower</code>, <code>upper</code>, <code>median</code> respectively
475compute the lower bound, the upper bound, and the median number of an
476interval (<code>(lower+upper)/2</code> rounded to nearest).
477<code>width</code> computes the width of an interval
478(<code>upper-lower</code> rounded toward plus infinity). <code>norm</code>
479computes an upper bound of the interval in absolute value; it is a
480mathematical norm (hence the name) similar to the absolute value for real
481numbers.</p>
482
483<h4><code>min</code> <code>max</code> <code>abs</code> <code>square</code>
484<code>pow</code> <code>division_part?</code>
485<code>multiplicative_inverse</code></h4>
486
487<p>The functions <code>min</code>, <code>max</code> and <code>abs</code> are
488also defined. Please do not mistake them for the functions defined in the
489standard library (aka <code>a&lt;b?a:b</code>, <code>a&gt;b?a:b</code>,
490<code>a&lt;0?-a:a</code>). These functions are compatible with the elementary
491property of interval arithmetic. For example, max([<i>a</i>,<i>b</i>],
492[<i>c</i>,<i>d</i>]) = {max(<i>x</i>,<i>y</i>) such that <i>x</i> in
493[<i>a</i>,<i>b</i>] and <i>y</i> in [<i>c</i>,<i>d</i>]}. They are not
494defined in the <code>std</code> namespace but in the boost namespace in order
495to avoid conflict with the other definitions.</p>
496
497<p>The <code>square</code> function is quite particular. As you can expect
498from its name, it computes the square of its argument. The reason this
499function is provided is: <code>square(x)</code> is not <code>x*x</code> but
500only a subset when <code>x</code> contains zero. For example, [-2,2]*[-2,2] =
501[-4,4] but [-2,2]² = [0,4]; the result is a smaller interval.  Consequently,
502<code>square(x)</code> should be used instead of <code>x*x</code> because of
503its better accuracy and a small performance improvement.</p>
504
505<p>As for <code>square</code>, <code>pow</code> provides an efficient and
506more accurate way to compute the integer power of an interval. Please note:
507when the power is 0 and the interval is not empty, the result is 1, even if
508the input interval contains 0. <code>multiplicative_inverse</code> computes
5091/x.</p>
510
511<p>The functions <code>division_part1</code> and <code>division_part2</code>
512are useful when the user expects the division to return disjoint intervals if
513necessary. For example, the narrowest closed set containg [2,3] / [-2,1] is
514not ]-&#x221e;,&#x221e;[ but the union of ]-&#x221e;,-1] and [2,&#x221e;[.
515When the result of the division is representable by only one interval,
516<code>division_part1</code> returns this interval and sets the boolean
517reference to <code>false</code>. However, if the result needs two intervals,
518<code>division_part1</code> returns the negative part and sets the boolean
519reference to <code>true</code>; a call to <code>division_part2</code> is now
520needed to get the positive part. This second function can take the boolean
521returned by the first function as last argument. If this bool is not given,
522its value is assumed to be true and the behavior of the function is then
523undetermined if the division does not produce a second interval.</p>
524
525<h4><code>intersect</code> <code>hull</code> <code>overlap</code>
526<code>in</code> <code>in_zero</code> <code>subset</code>
527<code>proper_subset</code> <code>empty</code> <code>singleton</code>
528<code>equal</code></h4>
529
530<p><code>intersect</code> computes the set intersection of two closed sets,
531<code>hull</code> computes the smallest interval which contains the two
532parameters; those parameters can be numbers or intervals. If one of the
533arguments is an invalid number or an empty interval, the function will only
534use the other argument to compute the resulting interval (if allowed by the
535checking policy).</p>
536
537<p>There is no union function since the union of two intervals is not an
538interval if they do not overlap. If they overlap, the <code>hull</code>
539function computes the union.</p>
540
541<p>The function <code>overlap</code> tests if two intervals have some common
542subset. <code>in</code> tests if a number is in an interval;
543<code>in_zero</code> is a variant which tests if zero is in the interval.
544<code>subset</code> tests if the first interval is a subset of the second;
545and <code>proper_subset</code> tests if it is a proper subset.
546<code>empty</code> and <code>singleton</code> test if an interval is empty or
547is a singleton. Finally, <code>equal</code> tests if two intervals are
548equal.</p>
549
550<h4><code>sqrt</code> <code>log</code> <code>exp</code> <code>sin</code>
551<code>cos</code> <code>tan</code> <code>asin</code> <code>acos</code>
552<code>atan</code> <code>sinh</code> <code>cosh</code> <code>tanh</code>
553<code>asinh</code> <code>acosh</code> <code>atanh</code>
554<code>fmod</code></h4>
555
556<p>The functions <code>sqrt</code>, <code>log</code>, <code>exp</code>,
557<code>sin</code>, <code>cos</code>, <code>tan</code>, <code>asin</code>,
558<code>acos</code>, <code>atan</code>, <code>sinh</code>, <code>cosh</code>,
559<code>tanh</code>, <code>asinh</code>, <code>acosh</code>, <code>atanh</code>
560are also defined. There is not much to say; these functions extend the
561traditional functions to the intervals and respect the basic property of
562interval arithmetic. They use the <a href="checking.htm">checking</a> policy to
563produce empty intervals when the input interval is strictly outside of the
564domain of the function.</p>
565
566<p>The function <code>fmod(interval x, interval y)</code> expects the lower
567bound of <code>y</code> to be strictly positive and returns an interval
568<code>z</code> such as <code>0 &lt;= z.lower() &lt; y.upper()</code> and such
569as <code>z</code> is a superset of <code>x-n*y</code> (with <code>n</code>
570being an integer). So, if the two arguments are positive singletons, this
571function <code>fmod(interval, interval)</code> will behave like the
572traditional function <code>fmod(double, double)</code>.</p>
573
574<p>Please note that <code>fmod</code> does not respect the inclusion property
575of arithmetic interval. For example, the result of
576<code>fmod</code>([13,17],[7,8]) should be [0,8] (since it must contain [0,3]
577and [5,8]). But this answer is not really useful when the purpose is to
578restrict an interval in order to compute a periodic function. It is the
579reason why <code>fmod</code> will answer [5,10].</p>
580
581<h4><code>add</code> <code>sub</code> <code>mul</code> <code>div</code></h4>
582
583<p>These four functions take two numbers and return the enclosing interval
584for the operations. It avoids converting a number to an interval before an
585operation, it can result in a better code with poor optimizers.</p>
586
587<h3>Constants</h3>
588
589<p>Some constants are hidden in the <code>boost::numeric::interval_lib</code>
590namespace. They need to be explicitely templated by the interval type. The
591functions are <code>pi&lt;I&gt;()</code>, <code>pi_half&lt;I&gt;()</code> and
592<code>pi_twice&lt;I&gt;()</code>, and they return an object of interval type
593<code>I</code>. Their respective values are &#x3c0;, &#x3c0;/2 and
5942&#x3c0;.</p>
595
596<h3>Exception throwing</h3>
597
598<p>The interval class and all the functions defined around this class never
599throw any exceptions by themselves. However, it does not mean that an
600operation will never throw an exception. For example, let's consider the copy
601constructor. As explained before, it is the default copy constructor
602generated by the compiler. So it will not throw an exception if the copy
603constructor of the base type does not throw an exception.</p>
604
605<p>The same situation applies to all the functions: exceptions will only be
606thrown if the base type or one of the two policies throws an exception.</p>
607
608<h2 id="interval_lib">Interval Support Library</h2>
609
610<p>The interval support library consists of a collection of classes that can
611be used and combined to fabricate almost various commonly-needed interval
612policies. In contrast to the basic classes and functions which are used in
613conjunction with <code>interval&lt;T&gt;</code> (and the default policies as
614the implicit second template parameter in this type), which belong simply to
615the namespace <code>boost</code>, these components belong to the namespace
616<code>boost::numeric::interval_lib</code>.</p>
617
618<p>We merely give the synopsis here and defer each section to a separate web
619page since it is only intended for the advanced user. This allows to expand
620on each topic with examples, without unduly stretching the limits of this
621document.</p>
622
623<h4>Synopsis</h4>
624<pre>namespace boost {
625namespace numeric {
626namespace interval_lib {
627
628<font color="#ff0000">/* built-in rounding policy and its specializations */</font>
629template &lt;class T&gt;  struct rounded_math;
630template &lt;&gt;         struct rounded_math&lt;float&gt;;
631template &lt;&gt;         struct rounded_math&lt;double&gt;;
632template &lt;&gt;         struct rounded_math&lt;long double&gt;;
633
634<span style="color: #FF0000">/* built-in rounding construction blocks */</span>
635template &lt;class T&gt;  struct rounding_control;
636
637template &lt;class T, class Rounding = rounding_control&lt;T&gt; &gt;  struct rounded_arith_exact;
638template &lt;class T, class Rounding = rounding_control&lt;T&gt; &gt;  struct rounded_arith_std;
639template &lt;class T, class Rounding = rounding_control&lt;T&gt; &gt;  struct rounded_arith_opp;
640
641template &lt;class T, class Rounding&gt;  struct rounded_transc_dummy;
642template &lt;class T, class Rounding = rounded_arith_exact&lt;T&gt; &gt;  struct rounded_transc_exact;
643template &lt;class T, class Rounding = rounded_arith_std  &lt;T&gt; &gt;  struct rounded_transc_std;
644template &lt;class T, class Rounding = rounded_arith_opp  &lt;T&gt; &gt;  struct rounded_transc_opp;
645
646template &lt;class Rounding&gt; struct save_state;
647template &lt;class Rounding&gt; struct save_state_nothing;
648
649<font color="#ff0000">/* built-in checking policies */</font>
650template &lt;class T&gt; struct checking_base;
651template &lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_create_empty&gt;   struct checking_no_empty;
652template &lt;class T, class Checking = checking_base&lt;T&gt; &gt;                                            struct checking_no_nan;
653template &lt;class T, class Checking = checking_base&lt;T&gt;, class Exception = exception_invalid_number&gt; struct checking_catch_nan;
654template &lt;class T&gt; struct checking_strict;
655
656<span style="color: #FF0000">/* some metaprogramming to manipulate interval policies */</span>
657template &lt;class Rounding, class Checking&gt; struct policies;
658template &lt;class OldInterval, class NewRounding&gt; struct change_rounding;
659template &lt;class OldInterval, class NewChecking&gt; struct change_checking;
660template &lt;class OldInterval&gt; struct unprotect;
661
662<span style="color: #FF0000">/* constants, need to be explicitly templated */</span>
663template&lt;class I&gt; I pi();
664template&lt;class I&gt; I pi_half();
665template&lt;class I&gt; I pi_twice();
666
667<span style="color: #FF0000">/* interval explicit comparison functions</span><span style="color: #FF0000">:
668 * the mode can be cer=certainly or pos=possibly,
669 * the function lt=less_than, gt=greater_than, le=less_than_or_equal_to, ge=greater_than_or_equal_to
670 *   eq=equal_to, ne= not_equal_to */</span>
671template &lt;class T, class Policies&gt;  bool cerlt(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
672template &lt;class T, class Policies&gt;  bool cerlt(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
673template &lt;class T, class Policies&gt;  bool cerlt(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
674
675template &lt;class T, class Policies&gt;  bool cerle(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
676template &lt;class T, class Policies&gt;  bool cerle(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
677template &lt;class T, class Policies&gt;  bool cerle(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
678
679template &lt;class T, class Policies&gt;  bool cergt(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
680template &lt;class T, class Policies&gt;  bool cergt(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
681template &lt;class T, class Policies&gt;  bool cergt(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
682
683template &lt;class T, class Policies&gt;  bool cerge(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
684template &lt;class T, class Policies&gt;  bool cerge(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
685template &lt;class T, class Policies&gt;  bool cerge(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
686
687template &lt;class T, class Policies&gt;  bool cereq(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
688template &lt;class T, class Policies&gt;  bool cereq(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
689template &lt;class T, class Policies&gt;  bool cereq(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
690
691template &lt;class T, class Policies&gt;  bool cerne(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
692template &lt;class T, class Policies&gt;  bool cerne(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
693template &lt;class T, class Policies&gt;  bool cerne(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
694
695template &lt;class T, class Policies&gt;  bool poslt(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
696template &lt;class T, class Policies&gt;  bool poslt(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
697template &lt;class T, class Policies&gt;  bool poslt(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
698
699template &lt;class T, class Policies&gt;  bool posle(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
700template &lt;class T, class Policies&gt;  bool posle(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
701template &lt;class T, class Policies&gt;  bool posle(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
702
703template &lt;class T, class Policies&gt;  bool posgt(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
704template &lt;class T, class Policies&gt;  bool posgt(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
705template &lt;class T, class Policies&gt;  bool posgt(const T&amp; x, const interval&lt;T, Policies&gt; &amp; y);
706
707template &lt;class T, class Policies&gt;  bool posge(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
708template &lt;class T, class Policies&gt;  bool posge(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
709template &lt;class T, class Policies&gt;  bool posge(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
710
711template &lt;class T, class Policies&gt;  bool poseq(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
712template &lt;class T, class Policies&gt;  bool poseq(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
713template &lt;class T, class Policies&gt;  bool poseq(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
714
715template &lt;class T, class Policies&gt;  bool posne(const interval&lt;T, Policies&gt;&amp; x, const interval&lt;T, Policies&gt;&amp; y);
716template &lt;class T, class Policies&gt;  bool posne(const interval&lt;T, Policies&gt;&amp; x, const T&amp; y);
717template &lt;class T, class Policies&gt;  bool posne(const T&amp; x, const interval&lt;T, Policies&gt;&amp; y);
718
719<font color="#ff0000">/* comparison namespaces */</font>
720namespace compare {
721  namespace certain;
722  namespace possible;
723  namespace lexicographic;
724  namespace set;
725  namespace tribool;
726} // namespace compare
727
728} // namespace interval_lib
729} // namespace numeric
730} // namespace boost</pre>
731
732<p>Each component of the interval support library is detailed in its own
733page.</p>
734<ul>
735  <li><a href="comparisons.htm">Comparisons</a></li>
736  <li><a href="rounding.htm">Rounding</a></li>
737  <li><a href="checking.htm">Checking</a></li>
738</ul>
739
740<h2 id="dangers">Common Pitfalls and Dangers</h2>
741
742<h4>Comparisons</h4>
743
744<p>One of the biggest problems is problably the correct use of the comparison
745functions and operators. First, functions and operators do not try to know if
746two intervals are the same mathematical object. So, if the comparison used is
747"certain", then <code>x != x</code> is always true unless <code>x</code> is a
748singleton interval; and the same problem arises with <code>cereq</code> and
749<code>cerne</code>.</p>
750
751<p>Another misleading interpretation of the comparison is: you cannot always
752expect [a,b] &lt; [c,d] to be !([a,b] &gt;= [c,d]) since the comparison is
753not necessarily total. Equality and less comparison should be seen as two
754distincts relational operators. However the default comparison operators do
755respect this property since they throw an exception whenever [a,b] and [c,d]
756overlap.</p>
757
758<h4>Interval values and references</h4>
759
760<p>This problem is a corollary of the previous problem with <code>x !=
761x</code>. All the functions of the library only consider the value of an
762interval and not the reference of an interval. In particular, you should not
763expect (unless <code>x</code> is a singleton) the following values to be
764equal: <code>x/x</code> and 1, <code>x*x</code> and <code>square(x)</code>,
765<code>x-x</code> and 0, etc. So the main cause of wide intervals is that
766interval arithmetic does not identify different occurences of the same
767variable. So, whenever possible, the user has to rewrite the formulas to
768eliminate multiple occurences of the same variable. For example,
769<code>square(x)-2*x</code> is far less precise than
770<code>square(x-1)-1</code>.</p>
771
772<h4>Unprotected rounding</h4>
773
774<p>As explained in <a href="rounding.htm#perf">this section</a>, a good way
775to speed up computations when the base type is a basic floating-point type is
776to unprotect the intervals at the hot spots of the algorithm. This method is
777safe and really an improvement for interval computations. But please remember
778that any basic floating-point operation executed inside the unprotection
779blocks will probably have an undefined behavior (but only for the current
780thread). And do not forget to create a rounding object as explained in the <a
781href="rounding.htm#perfexp">example</a>.</p>
782
783<h2 id="rationale">Rationale</h2>
784
785<p>The purpose of this library is to provide an efficient and generalized way
786to deal with interval arithmetic through the use of a templatized class
787<code>boost::interval</code>. The big contention for which we provide a
788rationale is the format of this class template.</p>
789
790<p>It would have been easier to provide a class interval whose base type is
791double. Or to follow <code>std::complex</code> and allow only specializations
792for <code>float</code>, <code>double</code>, and <code>long double</code>. We
793decided not to do this to allow intervals on custom types, e.g.
794fixed-precision bigfloat library types (MPFR, etc), rational numbers, and so
795on.</p>
796
797<p><strong>Policy design.</strong> Although it was tempting to make it a
798class template with only one template argument, the diversity of uses for an
799interval arithmetic practically forced us to use policies. The behavior of
800this class can be fixed by two policies. These policies are packaged into a
801single policy class, rather than making <code>interval</code> with three
802template parameters. This is both for ease of use (the policy class can be
803picked by default) and for readability.</p>
804
805<p>The first policy provides all the mathematical functions on the base type
806needed to define the functions on the interval type. The second one sets the
807way exceptional cases encountered during computations are handled.</p>
808
809<p>We could foresee situations where any combination of these policies would
810be appropriate. Moreover, we wanted to enable the user of the library to
811reuse the <code>interval</code> class template while at the same time
812choosing his own behavior. See this <a href="guide.htm">page</a>  for some
813examples.</p>
814
815<p><strong>Rounding policy.</strong> The library provides specialized
816implementations of the rounding policy for the primitive types float and
817double. In order for these implementations to be correct and fast, the
818library needs to work a lot with rounding modes. Some processors are directly
819dealt with and some mecanisms are provided in order to speed up the
820computations. It seems to be heavy and hazardous optimizations for a gain of
821only a few computer cycles; but in reality, the speed-up factor can easily go
822past 2 or 3 depending on the computer. Moreover, these optimizations do not
823impact the interface in any major way (with the design we have chosen,
824everything can be added by specialization or by passing different template
825parameters).</p>
826
827<p><strong>Pred/succ.</strong> In a previous version, two functions
828<code>pred</code> and <code>succ</code>, with various corollaries like
829<code>widen</code>, were supplied. The intent was to enlarge the interval by
830one ulp (as little as possible), e.g. to ensure the inclusion property. Since
831making interval a template of T, we could not define <i>ulp</i> for a random
832parameter. In turn, rounding policies let us eliminate entirely the use of
833ulp while making the intervals tighter (if a result is a representable
834singleton, there is no use to widen the interval). We decided to drop those
835functions.</p>
836
837<p><strong>Specialization of <code>std::less</code>.</strong> Since the
838operator <code>&lt;</code> depends on the comparison namespace locally chosen
839by the user, it is not possible to correctly specialize
840<code>std::less</code>. So you have to explicitely provide such a class to
841all the algorithms and templates that could require it (for example,
842<code>std::map</code>).</p>
843
844<p><strong>Input/output.</strong> The interval library does not include I/O
845operators. Printing an interval value allows a lot of customization: some
846people may want to output the bounds, others may want to display the median
847and the width of intervals, and so on. The example file io.cpp<code></code>
848shows some possibilities and may serve as a foundation in order for the user
849to define her own operators.</p>
850
851<p><strong>Mixed operations with integers.</strong> When using and reusing
852template codes, it is common there are operations like <code>2*x</code>.
853However, the library does not provide them by default because the conversion
854from <code>int</code> to the base number type is not always correct (think
855about the conversion from a 32bit integer to a single precision
856floating-point number). So the functions have been put in a separate header
857and the user needs to include them explicitely if she wants to benefit from
858these mixed operators. Another point, there is no mixed comparison operators
859due to the technical way they are defined.</p>
860
861<p><strong>Interval-aware functions.</strong> All the functions defined by
862the library are obviously aware they manipulate intervals and they do it
863accordingly to general interval arithmetic principles. Consequently they may
864have a different behavior than the one commonly encountered with functions
865not interval-aware. For example, <code>max</code> is defined by canonical set
866extension and the result is not always one of the two arguments (if the
867intervals do not overlap, then the result is one of the two intervals).</p>
868
869<p>This behavior is different from <code>std::max</code> which returns a
870reference on one of its arguments. So if the user expects a reference to be
871returned, she should use <code>std::max</code> since it is exactly what this
872function does. Please note that <code>std::max</code> will throw an exception
873when the intervals overlap. This behavior does not predate the one described
874by the C++ standard since the arguments are not "equivalent" and it allows to
875have an equivalence between <code>a &lt;= b</code> and <code>&amp;b ==
876&amp;std::max(a,b)</code>(some particular cases may be
877implementation-defined). However it is different from the one described by
878SGI since it does not return the first argument even if "neither is greater
879than the other".</p>
880
881<h2 id="acks">History and Acknowledgments</h2>
882
883<p>This library was mostly inspired by previous work from Jens Maurer. Some
884discussions about his work are reproduced <a
885href="http://www.mscs.mu.edu/%7Egeorgec/IFAQ/maurer1.html">here</a>.
886Jeremy Siek and Maarten Keijzer provided some rounding control for MSVC and
887Sparc platforms.</p>
888
889<p>Guillaume Melquiond, Hervé Brönnimann and Sylvain Pion started from the
890library left by Jens and added the policy design. Guillaume and Sylvain
891worked hard on the code, especially the porting and mostly tuning of the
892rounding modes to the different architectures. Guillaume did most of the
893coding, while Sylvain and Hervé have provided some useful comments in order
894for this library to be written. Hervé reorganized and wrote chapters of the
895documentation based on Guillaume's great starting point.</p>
896
897<p>This material is partly based upon work supported by the National Science
898Foundation under NSF CAREER Grant CCR-0133599. Any opinions, findings and
899conclusions or recommendations expressed in this material are those of the
900author(s) and do not necessarily reflect the views of the National Science
901Foundation (NSF).</p>
902<hr>
903
904<p>Revised: 2004-03-11<br>
905Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002.
906Polytechnic University.<br>
907Copyright (c) Guillaume Melquiond, 2003-2004. ENS Lyon.</p>
908</body>
909</html>
Note: See TracBrowser for help on using the repository browser.