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>Tests and Examples</title> |
---|
8 | </head> |
---|
9 | |
---|
10 | <body lang="en"> |
---|
11 | <h1>Tests and Examples</h1> |
---|
12 | |
---|
13 | <h2>A first example</h2> |
---|
14 | |
---|
15 | <p>This example shows how to design a function which takes a polynomial and a |
---|
16 | value and returns the sign of this polynomial at this point. This function is |
---|
17 | a filter: if the answer is not guaranteed, the functions says so. The reason |
---|
18 | of using a filter rather than a simple evaluation function is: computations |
---|
19 | with floating-point numbers will incur approximations and it can be enough to |
---|
20 | change the sign of the polynomial. So, in order to validate the result, the |
---|
21 | function will use interval arithmetic.</p> |
---|
22 | |
---|
23 | <p>The first step is the inclusion of the appropriate headers. Because the |
---|
24 | function will handle floating-point bounds, the easiest solution is:</p> |
---|
25 | <pre>#include <boost/numeric/interval.hpp></pre> |
---|
26 | |
---|
27 | <p>Now, let's begin the function. The polynomial is given by the array of its |
---|
28 | coefficients and its size (strictly greater to its degree). In order to |
---|
29 | simplify the code, two namespaces of the library are included.</p> |
---|
30 | <pre>int sign_polynomial(double x, double P[], int sz) { |
---|
31 | using namespace boost::numeric; |
---|
32 | using namespace interval_lib;</pre> |
---|
33 | |
---|
34 | <p>Then we can define the interval type. Since no special behavior is |
---|
35 | required, the default policies are enough:</p> |
---|
36 | <pre> typedef interval<double> I;</pre> |
---|
37 | |
---|
38 | <p>For the evaluation, let's just use the Horner scheme with interval |
---|
39 | arithmetic. The library overloads all the arithmetic operators and provides |
---|
40 | mixed operations, so the only difference between the code with and without |
---|
41 | interval arithmetic lies in the type of the iterated value <code>y</code>:</p> |
---|
42 | <pre> I y = P[sz - 1]; |
---|
43 | for(int i = sz - 2; i >= 0; i--) |
---|
44 | y = y * x + P[i];</pre> |
---|
45 | |
---|
46 | <p>The last step is the computation of the sign of <code>y</code>. It is done |
---|
47 | by choosing an appropriate comparison scheme and then doing the comparison |
---|
48 | with the usual operators:</p> |
---|
49 | <pre> using namespace compare::certain; |
---|
50 | if (y > 0.) return 1; |
---|
51 | if (y < 0.) return -1; |
---|
52 | return 0; |
---|
53 | }</pre> |
---|
54 | |
---|
55 | <p>The answer <code>0</code> does not mean the polynomial is zero at this |
---|
56 | point. It only means the answer is not known since <code>y</code> contains |
---|
57 | zero and thus does not have a precise sign.</p> |
---|
58 | |
---|
59 | <p>Now we have the expected function. However, due to the poor |
---|
60 | implementations of floating-point rounding in most of the processors, it can |
---|
61 | be useful to say to optimize the code; or rather, to let the library optimize |
---|
62 | it. The main condition for this optimization is that the interval code should |
---|
63 | not be mixed with floating-point code. In this example, it is the case, since |
---|
64 | all the operations done in the functions involve the library. So the code can |
---|
65 | be rewritten:</p> |
---|
66 | <pre>int sign_polynomial(double x, double P[], int sz) { |
---|
67 | using namespace boost::numeric; |
---|
68 | using namespace interval_lib; |
---|
69 | typedef interval<double> I_aux; |
---|
70 | |
---|
71 | I_aux::traits_type::rounding rnd; |
---|
72 | typedef unprotect<I_aux>::type I; |
---|
73 | |
---|
74 | I y = P[sz - 1]; |
---|
75 | for(int i = sz - 2; i >= 0; i--) |
---|
76 | y = y * x + P[i]; |
---|
77 | |
---|
78 | using namespace compare::certain; |
---|
79 | if (y > 0.) return 1; |
---|
80 | if (y < 0.) return -1; |
---|
81 | return 0; |
---|
82 | }</pre> |
---|
83 | |
---|
84 | <p>The difference between this code and the previous is the use of another |
---|
85 | interval type. This new type <code>I</code> indicates to the library that all |
---|
86 | the computations can be done without caring for the rounding mode. And |
---|
87 | because of that, it is up to the function to care about it: a rounding object |
---|
88 | need to be alive whenever the optimized type is used.</p> |
---|
89 | |
---|
90 | <h2>Other tests and examples</h2> |
---|
91 | |
---|
92 | <p>In <code>libs/numeric/interval/test/</code> and |
---|
93 | <code>libs/numeric/interval/examples/</code> are some test and example |
---|
94 | programs.. The examples illustrate a few uses of intervals. For a general |
---|
95 | description and considerations on using this library, and some potential |
---|
96 | domains of application, please read this <a |
---|
97 | href="guide.htm">mini-guide</a>.</p> |
---|
98 | |
---|
99 | <h3>Tests</h3> |
---|
100 | |
---|
101 | <p>The test programs are as follows. Please note that they require the use of |
---|
102 | the Boost.test library and can be automatically tested by using |
---|
103 | <code>bjam</code> (except for interval_test.cpp).</p> |
---|
104 | |
---|
105 | <p><b>add.cpp</b> tests if the additive and subtractive operators and the |
---|
106 | respective _std and _opp rounding functions are correctly implemented. It is |
---|
107 | done by using symbolic expressions as a base type.</p> |
---|
108 | |
---|
109 | <p><b>cmp.cpp</b>, <b>cmp_lex.cpp</b>, <b>cmp_set.cpp</b>, and |
---|
110 | <b>cmp_tribool.cpp</b> test if the operators <code><</code> |
---|
111 | <code>></code> <code><=</code> <code>>=</code> <code>==</code> |
---|
112 | <code>!=</code> behave correctly for the default, lexicographic, set, and |
---|
113 | tristate comparisons. <b>cmp_exp.cpp</b> tests the explicit comparison |
---|
114 | functions <code>cer..</code> and <code>pos..</code> behave correctly. |
---|
115 | <b>cmp_exn.cpp</b> tests if the various policies correctly detect exceptional |
---|
116 | cases. All these tests use some simple intervals ([1,2] and [3,4], [1,3] and |
---|
117 | [2,4], [1,2] and [2,3], etc).</p> |
---|
118 | |
---|
119 | <p><b>det.cpp</b> tests if the <code>_std</code> and <code>_opp</code> |
---|
120 | versions in protected and unprotected mode produce the same result when Gauss |
---|
121 | scheme is used on an unstable matrix (in order to exercise rounding). The |
---|
122 | tests are done for <code>interval<float></code> and |
---|
123 | <code>interval<double></code>.</p> |
---|
124 | |
---|
125 | <p><b>fmod.cpp</b> defines a minimalistic version of |
---|
126 | <code>interval<int></code> and uses it in order to test |
---|
127 | <code>fmod</code> on some specific interval values.</p> |
---|
128 | |
---|
129 | <p><b>mul.cpp</b> exercises the multiplication, the finite division, the |
---|
130 | square and the square root with some integer intervals leading to exact |
---|
131 | results.</p> |
---|
132 | |
---|
133 | <p><b>pi.cpp</b> tests if the interval value of π (for |
---|
134 | <code>int</code>, <code>float</code> and <code>double</code> base types) |
---|
135 | contains the number π (defined with 21 decimal digits) and if it is a |
---|
136 | subset of [π±1ulp] (in order to ensure some precision).</p> |
---|
137 | |
---|
138 | <p><b>pow.cpp</b> tests if the <code>pow</code> function behaves correctly on |
---|
139 | some simple test cases.</p> |
---|
140 | |
---|
141 | <p><b>test_float.cpp</b> exercises the arithmetic operations of the library |
---|
142 | for floating point base types.</p> |
---|
143 | |
---|
144 | <p><b>interval_test.cpp</b> tests if the interval library respects the |
---|
145 | inclusion property of interval arithmetic by computing some functions and |
---|
146 | operations for both <code>double</code> and |
---|
147 | <code>interval<double></code>.</p> |
---|
148 | |
---|
149 | <h2>Examples</h2> |
---|
150 | |
---|
151 | <p><b>filter.cpp</b> contains filters for computational geometry able to find |
---|
152 | the sign of a determinant. This example is inspired by the article |
---|
153 | <em>Interval arithmetic yields efficient dynamic filters for computational |
---|
154 | geometry</em> by Brönnimann, Burnikel and Pion, 2001.</p> |
---|
155 | |
---|
156 | <p><b>findroot_demo.cpp</b> finds zeros of some functions by using dichotomy |
---|
157 | and even produces gnuplot data for one of them. The processor has to |
---|
158 | correctly handle elementary functions for this example to properly work.</p> |
---|
159 | |
---|
160 | <p><b>horner.cpp</b> is a really basic example of unprotecting the interval |
---|
161 | operations for a whole function (which computes the value of a polynomial by |
---|
162 | using Horner scheme).</p> |
---|
163 | |
---|
164 | <p><b>io.cpp</b> shows some stream input and output operators for intervals |
---|
165 | .The wide variety of possibilities explains why the library do not implement |
---|
166 | i/o operators and they are left to the user.</p> |
---|
167 | |
---|
168 | <p><b>newton-raphson.cpp</b> is an implementation of a specialized version of |
---|
169 | Newton-Raphson algorithm for finding the zeros of a function knowing its |
---|
170 | derivative. It exercises unprotecting, full division, some set operations and |
---|
171 | empty intervals.</p> |
---|
172 | |
---|
173 | <p><b>transc.cpp</b> implements the transcendental part of the rounding |
---|
174 | policy for <code>double</code> by using an external library (the MPFR subset |
---|
175 | of GMP in this case).</p> |
---|
176 | <hr> |
---|
177 | |
---|
178 | <p>Revised: 2003-08-16<br> |
---|
179 | Copyright (c) Guillaume Melquiond, Sylvain Pion, Hervé Brönnimann, 2002. |
---|
180 | Polytechnic University.<br> |
---|
181 | Copyright (c) Guillaume Melquiond, 2003.</p> |
---|
182 | </body> |
---|
183 | </html> |
---|